1212
1313#include " clang/AST/StmtOpenACC.h"
1414#include " clang/AST/ASTContext.h"
15+ #include " clang/AST/RecursiveASTVisitor.h"
16+ #include " clang/AST/StmtCXX.h"
1517using namespace clang ;
1618
1719OpenACCComputeConstruct *
@@ -26,11 +28,98 @@ OpenACCComputeConstruct::CreateEmpty(const ASTContext &C, unsigned NumClauses) {
2628OpenACCComputeConstruct *OpenACCComputeConstruct::Create (
2729 const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc,
2830 SourceLocation DirLoc, SourceLocation EndLoc,
29- ArrayRef<const OpenACCClause *> Clauses, Stmt *StructuredBlock) {
31+ ArrayRef<const OpenACCClause *> Clauses, Stmt *StructuredBlock,
32+ ArrayRef<OpenACCLoopConstruct *> AssociatedLoopConstructs) {
3033 void *Mem = C.Allocate (
3134 OpenACCComputeConstruct::totalSizeToAlloc<const OpenACCClause *>(
3235 Clauses.size ()));
3336 auto *Inst = new (Mem) OpenACCComputeConstruct (K, BeginLoc, DirLoc, EndLoc,
3437 Clauses, StructuredBlock);
38+
39+ llvm::for_each (AssociatedLoopConstructs, [&](OpenACCLoopConstruct *C) {
40+ C->setParentComputeConstruct (Inst);
41+ });
42+
43+ return Inst;
44+ }
45+
46+ void OpenACCComputeConstruct::findAndSetChildLoops () {
47+ struct LoopConstructFinder : RecursiveASTVisitor<LoopConstructFinder> {
48+ OpenACCComputeConstruct *Construct = nullptr ;
49+
50+ LoopConstructFinder (OpenACCComputeConstruct *Construct)
51+ : Construct(Construct) {}
52+
53+ bool TraverseOpenACCComputeConstruct (OpenACCComputeConstruct *C) {
54+ // Stop searching if we find a compute construct.
55+ return true ;
56+ }
57+ bool TraverseOpenACCLoopConstruct (OpenACCLoopConstruct *C) {
58+ // Stop searching if we find a loop construct, after taking ownership of
59+ // it.
60+ C->setParentComputeConstruct (Construct);
61+ return true ;
62+ }
63+ };
64+
65+ LoopConstructFinder f (this );
66+ f.TraverseStmt (getAssociatedStmt ());
67+ }
68+
69+ OpenACCLoopConstruct::OpenACCLoopConstruct (unsigned NumClauses)
70+ : OpenACCAssociatedStmtConstruct(
71+ OpenACCLoopConstructClass, OpenACCDirectiveKind::Loop,
72+ SourceLocation{}, SourceLocation{}, SourceLocation{},
73+ /* AssociatedStmt=*/ nullptr ) {
74+ std::uninitialized_value_construct (
75+ getTrailingObjects<const OpenACCClause *>(),
76+ getTrailingObjects<const OpenACCClause *>() + NumClauses);
77+ setClauseList (
78+ MutableArrayRef (getTrailingObjects<const OpenACCClause *>(), NumClauses));
79+ }
80+
81+ OpenACCLoopConstruct::OpenACCLoopConstruct (
82+ SourceLocation Start, SourceLocation DirLoc, SourceLocation End,
83+ ArrayRef<const OpenACCClause *> Clauses, Stmt *Loop)
84+ : OpenACCAssociatedStmtConstruct(OpenACCLoopConstructClass,
85+ OpenACCDirectiveKind::Loop, Start, DirLoc,
86+ End, Loop) {
87+ // accept 'nullptr' for the loop. This is diagnosed somewhere, but this gives
88+ // us some level of AST fidelity in the error case.
89+ assert ((Loop == nullptr || isa<ForStmt, CXXForRangeStmt>(Loop)) &&
90+ " Associated Loop not a for loop?" );
91+ // Initialize the trailing storage.
92+ std::uninitialized_copy (Clauses.begin (), Clauses.end (),
93+ getTrailingObjects<const OpenACCClause *>());
94+
95+ setClauseList (MutableArrayRef (getTrailingObjects<const OpenACCClause *>(),
96+ Clauses.size ()));
97+ }
98+
99+ void OpenACCLoopConstruct::setLoop (Stmt *Loop) {
100+ assert ((isa<ForStmt, CXXForRangeStmt>(Loop)) &&
101+ " Associated Loop not a for loop?" );
102+ setAssociatedStmt (Loop);
103+ }
104+
105+ OpenACCLoopConstruct *OpenACCLoopConstruct::CreateEmpty (const ASTContext &C,
106+ unsigned NumClauses) {
107+ void *Mem =
108+ C.Allocate (OpenACCLoopConstruct::totalSizeToAlloc<const OpenACCClause *>(
109+ NumClauses));
110+ auto *Inst = new (Mem) OpenACCLoopConstruct (NumClauses);
111+ return Inst;
112+ }
113+
114+ OpenACCLoopConstruct *
115+ OpenACCLoopConstruct::Create (const ASTContext &C, SourceLocation BeginLoc,
116+ SourceLocation DirLoc, SourceLocation EndLoc,
117+ ArrayRef<const OpenACCClause *> Clauses,
118+ Stmt *Loop) {
119+ void *Mem =
120+ C.Allocate (OpenACCLoopConstruct::totalSizeToAlloc<const OpenACCClause *>(
121+ Clauses.size ()));
122+ auto *Inst =
123+ new (Mem) OpenACCLoopConstruct (BeginLoc, DirLoc, EndLoc, Clauses, Loop);
35124 return Inst;
36125}
0 commit comments