llvm-project/clang/lib/AST/StmtOpenACC.cpp
erichkeane 39351f8e46 [OpenACC] Implement AST/Sema for combined constructs
Combined constructs (OpenACC 3.3 section 2.11) are a short-cut for
writing a `loop` construct immediately inside of a `compute` construct.
However, this interaction requires we do additional work to ensure that
we get the semantics between the two correct, as well as diagnostics.

This patch adds the semantic analysis for the constructs (but no
    clauses), as well as the AST nodes.
2024-11-12 09:26:25 -08:00

114 lines
4.7 KiB
C++

//===--- StmtOpenACC.cpp - Classes for OpenACC Constructs -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the subclasses of Stmt class declared in StmtOpenACC.h
//
//===----------------------------------------------------------------------===//
#include "clang/AST/StmtOpenACC.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtCXX.h"
using namespace clang;
OpenACCComputeConstruct *
OpenACCComputeConstruct::CreateEmpty(const ASTContext &C, unsigned NumClauses) {
void *Mem = C.Allocate(
OpenACCComputeConstruct::totalSizeToAlloc<const OpenACCClause *>(
NumClauses));
auto *Inst = new (Mem) OpenACCComputeConstruct(NumClauses);
return Inst;
}
OpenACCComputeConstruct *OpenACCComputeConstruct::Create(
const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc,
SourceLocation DirLoc, SourceLocation EndLoc,
ArrayRef<const OpenACCClause *> Clauses, Stmt *StructuredBlock) {
void *Mem = C.Allocate(
OpenACCComputeConstruct::totalSizeToAlloc<const OpenACCClause *>(
Clauses.size()));
auto *Inst = new (Mem) OpenACCComputeConstruct(K, BeginLoc, DirLoc, EndLoc,
Clauses, StructuredBlock);
return Inst;
}
OpenACCLoopConstruct::OpenACCLoopConstruct(unsigned NumClauses)
: OpenACCAssociatedStmtConstruct(
OpenACCLoopConstructClass, OpenACCDirectiveKind::Loop,
SourceLocation{}, SourceLocation{}, SourceLocation{},
/*AssociatedStmt=*/nullptr) {
std::uninitialized_value_construct(
getTrailingObjects<const OpenACCClause *>(),
getTrailingObjects<const OpenACCClause *>() + NumClauses);
setClauseList(
MutableArrayRef(getTrailingObjects<const OpenACCClause *>(), NumClauses));
}
OpenACCLoopConstruct::OpenACCLoopConstruct(
OpenACCDirectiveKind ParentKind, SourceLocation Start,
SourceLocation DirLoc, SourceLocation End,
ArrayRef<const OpenACCClause *> Clauses, Stmt *Loop)
: OpenACCAssociatedStmtConstruct(OpenACCLoopConstructClass,
OpenACCDirectiveKind::Loop, Start, DirLoc,
End, Loop),
ParentComputeConstructKind(ParentKind) {
// accept 'nullptr' for the loop. This is diagnosed somewhere, but this gives
// us some level of AST fidelity in the error case.
assert((Loop == nullptr || isa<ForStmt, CXXForRangeStmt>(Loop)) &&
"Associated Loop not a for loop?");
// Initialize the trailing storage.
std::uninitialized_copy(Clauses.begin(), Clauses.end(),
getTrailingObjects<const OpenACCClause *>());
setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
Clauses.size()));
}
OpenACCLoopConstruct *OpenACCLoopConstruct::CreateEmpty(const ASTContext &C,
unsigned NumClauses) {
void *Mem =
C.Allocate(OpenACCLoopConstruct::totalSizeToAlloc<const OpenACCClause *>(
NumClauses));
auto *Inst = new (Mem) OpenACCLoopConstruct(NumClauses);
return Inst;
}
OpenACCLoopConstruct *OpenACCLoopConstruct::Create(
const ASTContext &C, OpenACCDirectiveKind ParentKind,
SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc,
ArrayRef<const OpenACCClause *> Clauses, Stmt *Loop) {
void *Mem =
C.Allocate(OpenACCLoopConstruct::totalSizeToAlloc<const OpenACCClause *>(
Clauses.size()));
auto *Inst = new (Mem)
OpenACCLoopConstruct(ParentKind, BeginLoc, DirLoc, EndLoc, Clauses, Loop);
return Inst;
}
OpenACCCombinedConstruct *
OpenACCCombinedConstruct::CreateEmpty(const ASTContext &C,
unsigned NumClauses) {
void *Mem = C.Allocate(
OpenACCCombinedConstruct::totalSizeToAlloc<const OpenACCClause *>(
NumClauses));
auto *Inst = new (Mem) OpenACCCombinedConstruct(NumClauses);
return Inst;
}
OpenACCCombinedConstruct *OpenACCCombinedConstruct::Create(
const ASTContext &C, OpenACCDirectiveKind DK, SourceLocation BeginLoc,
SourceLocation DirLoc, SourceLocation EndLoc,
ArrayRef<const OpenACCClause *> Clauses, Stmt *Loop) {
void *Mem = C.Allocate(
OpenACCCombinedConstruct::totalSizeToAlloc<const OpenACCClause *>(
Clauses.size()));
auto *Inst = new (Mem)
OpenACCCombinedConstruct(DK, BeginLoc, DirLoc, EndLoc, Clauses, Loop);
return Inst;
}