
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.
114 lines
4.7 KiB
C++
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;
|
|
}
|