================
@@ -2604,31 +2604,120 @@ SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK, 
const Expr *VarExpr) {
   QualType VarTy =
       VarExpr->getType().getNonReferenceType().getUnqualifiedType();
 
+  IdentifierInfo *VarName = [&]() {
+    switch (CK) {
+    case OpenACCClauseKind::Private:
+      return &getASTContext().Idents.get("openacc.private.init");
+    case OpenACCClauseKind::FirstPrivate:
+      return &getASTContext().Idents.get("openacc.firstprivate.init");
+    case OpenACCClauseKind::Reduction:
+      return &getASTContext().Idents.get("openacc.reduction.init");
+    default:
+      llvm_unreachable("Unknown clause kind?");
+    }
+  }();
+
   VarDecl *Recipe = VarDecl::Create(
       getASTContext(), SemaRef.getCurContext(), VarExpr->getBeginLoc(),
-      VarExpr->getBeginLoc(),
-      &getASTContext().Idents.get("openacc.private.init"), VarTy,
+      VarExpr->getBeginLoc(), VarName, VarTy,
       getASTContext().getTrivialTypeSourceInfo(VarTy), SC_Auto);
 
   ExprResult Init;
   VarDecl *Temporary = nullptr;
-
-  if (CK == OpenACCClauseKind::Private) {
+  {
     // Trap errors so we don't get weird ones here. If we can't init, we'll 
just
     // swallow the errors.
     Sema::TentativeAnalysisScope Trap{SemaRef};
     InitializedEntity Entity = InitializedEntity::InitializeVariable(Recipe);
-    InitializationKind Kind =
-        InitializationKind::CreateDefault(Recipe->getLocation());
 
-    InitializationSequence InitSeq(SemaRef.SemaRef, Entity, Kind, {});
-    Init = InitSeq.Perform(SemaRef.SemaRef, Entity, Kind, {});
-  } else if (CK == OpenACCClauseKind::FirstPrivate) {
-    // TODO: OpenACC: Implement this to do a 'copy' operation.
-  } else if (CK == OpenACCClauseKind::Reduction) {
-    // TODO: OpenACC: Implement this for whatever reduction needs.
-  } else {
-    llvm_unreachable("Unknown clause kind in CreateInitRecipe");
+    if (CK == OpenACCClauseKind::Private) {
+      InitializationKind Kind =
+          InitializationKind::CreateDefault(Recipe->getLocation());
+
+      InitializationSequence InitSeq(SemaRef.SemaRef, Entity, Kind, {});
+      Init = InitSeq.Perform(SemaRef.SemaRef, Entity, Kind, {});
+
+    } else if (CK == OpenACCClauseKind::FirstPrivate) {
+      // Create a VarDecl to be the 'copied-from' for the copy section of the
+      // recipe. This allows us to make the association so that we can use the
+      // standard 'generation' ability of the init.
+      Temporary = VarDecl::Create(
+          getASTContext(), SemaRef.getCurContext(), VarExpr->getBeginLoc(),
+          VarExpr->getBeginLoc(), &getASTContext().Idents.get("openacc.temp"),
+          VarTy, getASTContext().getTrivialTypeSourceInfo(VarTy), SC_Auto);
+      auto *TemporaryDRE = DeclRefExpr::Create(
+          getASTContext(), NestedNameSpecifierLoc{}, SourceLocation{},
+          Temporary,
+          /*ReferstoEnclosingVariableOrCapture=*/false,
+          DeclarationNameInfo{DeclarationName{Temporary->getDeclName()},
+                              VarExpr->getBeginLoc()},
+          VarTy, clang::VK_LValue, Temporary, nullptr, NOUR_None);
+
+      Expr *InitExpr = nullptr;
+
+      if (const auto *ArrTy = getASTContext().getAsConstantArrayType(VarTy)) {
+        // Arrays need to have each individual element initialized as there
+        // isn't a normal 'equals' feature in C/C++. This section sets these up
+        // as an init list after 'initializing' each individual element.
+        llvm::SmallVector<Expr *> Args;
+
+        // Decay to pointer for the array subscript expression.
+        auto *CastToPtr = ImplicitCastExpr::Create(
+            getASTContext(),
+            getASTContext().getPointerType(ArrTy->getElementType()),
+            CK_ArrayToPointerDecay, TemporaryDRE, /*BasePath=*/nullptr,
+            clang::VK_LValue, FPOptionsOverride{});
+
+        for (std::size_t I = 0; I < ArrTy->getLimitedSize(); ++I) {
+          // Each element needs to be some sort of copy initialization from an
+          // array-index of the original temporary (referenced via a
+          // DeclRefExpr).
+
+          auto *Idx = IntegerLiteral::Create(
+              getASTContext(), llvm::APInt(sizeof(std::size_t) * 8, I),
----------------
s-barannikov wrote:

Should it use the target size_t width?


https://github.com/llvm/llvm-project/pull/153622
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to