@@ -835,19 +835,40 @@ class OpenACCClauseWithVarList : public OpenACCClauseWithExprs {
835835 ArrayRef<Expr *> getVarList () const { return getExprs (); }
836836};
837837
838+ // Represents all the data needed for recipe generation. The declaration and
839+ // init are stored separately, because in the case of subscripts, we do the
840+ // alloca at the level of the base, and the init at the element level.
841+ struct OpenACCPrivateRecipe {
842+ VarDecl *AllocaDecl;
843+ Expr *InitExpr;
844+
845+ OpenACCPrivateRecipe (VarDecl *A, Expr *I) : AllocaDecl(A), InitExpr(I) {
846+ assert (!AllocaDecl || AllocaDecl->getInit () == nullptr );
847+ }
848+
849+ bool isSet () const { return AllocaDecl; }
850+
851+ static OpenACCPrivateRecipe Empty () {
852+ return OpenACCPrivateRecipe (nullptr , nullptr );
853+ }
854+ };
855+
838856class OpenACCPrivateClause final
839857 : public OpenACCClauseWithVarList,
840- private llvm::TrailingObjects<OpenACCPrivateClause, Expr *, VarDecl *> {
858+ private llvm::TrailingObjects<OpenACCPrivateClause, Expr *,
859+ OpenACCPrivateRecipe> {
841860 friend TrailingObjects;
842861
843862 OpenACCPrivateClause (SourceLocation BeginLoc, SourceLocation LParenLoc,
844863 ArrayRef<Expr *> VarList,
845- ArrayRef<VarDecl *> InitRecipes, SourceLocation EndLoc)
864+ ArrayRef<OpenACCPrivateRecipe> InitRecipes,
865+ SourceLocation EndLoc)
846866 : OpenACCClauseWithVarList(OpenACCClauseKind::Private, BeginLoc,
847867 LParenLoc, EndLoc) {
848868 assert (VarList.size () == InitRecipes.size ());
849869 setExprs (getTrailingObjects<Expr *>(VarList.size ()), VarList);
850- llvm::uninitialized_copy (InitRecipes, getTrailingObjects<VarDecl *>());
870+ llvm::uninitialized_copy (InitRecipes,
871+ getTrailingObjects<OpenACCPrivateRecipe>());
851872 }
852873
853874public:
@@ -856,19 +877,19 @@ class OpenACCPrivateClause final
856877 }
857878 // Gets a list of 'made up' `VarDecl` objects that can be used by codegen to
858879 // ensure that we properly initialize each of these variables.
859- ArrayRef<VarDecl * > getInitRecipes () {
860- return ArrayRef<VarDecl *>{getTrailingObjects<VarDecl *>(),
861- getExprs ().size ()};
880+ ArrayRef<OpenACCPrivateRecipe > getInitRecipes () {
881+ return ArrayRef<OpenACCPrivateRecipe>{
882+ getTrailingObjects<OpenACCPrivateRecipe>(), getExprs ().size ()};
862883 }
863884
864- ArrayRef<VarDecl * > getInitRecipes () const {
865- return ArrayRef<VarDecl *>{getTrailingObjects<VarDecl *>(),
866- getExprs ().size ()};
885+ ArrayRef<OpenACCPrivateRecipe > getInitRecipes () const {
886+ return ArrayRef<OpenACCPrivateRecipe>{
887+ getTrailingObjects<OpenACCPrivateRecipe>(), getExprs ().size ()};
867888 }
868889
869890 static OpenACCPrivateClause *
870891 Create (const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc,
871- ArrayRef<Expr *> VarList, ArrayRef<VarDecl * > InitRecipes,
892+ ArrayRef<Expr *> VarList, ArrayRef<OpenACCPrivateRecipe > InitRecipes,
872893 SourceLocation EndLoc);
873894
874895 size_t numTrailingObjects (OverloadToken<Expr *>) const {
@@ -879,11 +900,20 @@ class OpenACCPrivateClause final
879900// A 'pair' to stand in for the recipe. RecipeDecl is the main declaration, and
880901// InitFromTemporary is the 'temp' declaration we put in to be 'copied from'.
881902struct OpenACCFirstPrivateRecipe {
882- VarDecl *RecipeDecl, *InitFromTemporary;
883- OpenACCFirstPrivateRecipe (VarDecl *R, VarDecl *T)
884- : RecipeDecl(R), InitFromTemporary(T) {}
885- OpenACCFirstPrivateRecipe (std::pair<VarDecl *, VarDecl *> p)
886- : RecipeDecl(p.first), InitFromTemporary(p.second) {}
903+ VarDecl *AllocaDecl;
904+ Expr *InitExpr;
905+ VarDecl *InitFromTemporary;
906+ OpenACCFirstPrivateRecipe (VarDecl *A, Expr *I, VarDecl *T)
907+ : AllocaDecl(A), InitExpr(I), InitFromTemporary(T) {
908+ assert (!AllocaDecl || AllocaDecl->getInit () == nullptr );
909+ assert (!InitFromTemporary || InitFromTemporary->getInit () == nullptr );
910+ }
911+
912+ bool isSet () const { return AllocaDecl; }
913+
914+ static OpenACCFirstPrivateRecipe Empty () {
915+ return OpenACCFirstPrivateRecipe (nullptr , nullptr , nullptr );
916+ }
887917};
888918
889919class OpenACCFirstPrivateClause final
@@ -1253,8 +1283,18 @@ class OpenACCCreateClause final
12531283// A structure to stand in for the recipe on a reduction. RecipeDecl is the
12541284// 'main' declaration used for initializaiton, which is fixed.
12551285struct OpenACCReductionRecipe {
1256- VarDecl *RecipeDecl;
1286+ VarDecl *AllocaDecl;
1287+ Expr *InitExpr;
12571288 // TODO: OpenACC: this should eventually have the operations here too.
1289+
1290+ OpenACCReductionRecipe (VarDecl *A, Expr *I) : AllocaDecl(A), InitExpr(I) {
1291+ assert (!AllocaDecl || AllocaDecl->getInit () == nullptr );
1292+ }
1293+
1294+ bool isSet () const { return AllocaDecl; }
1295+ static OpenACCReductionRecipe Empty () {
1296+ return OpenACCReductionRecipe (nullptr , nullptr );
1297+ }
12581298};
12591299
12601300class OpenACCReductionClause final
0 commit comments