@@ -2604,31 +2604,120 @@ SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK, const Expr *VarExpr) {
26042604 QualType VarTy =
26052605 VarExpr->getType ().getNonReferenceType ().getUnqualifiedType ();
26062606
2607+ IdentifierInfo *VarName = [&]() {
2608+ switch (CK) {
2609+ case OpenACCClauseKind::Private:
2610+ return &getASTContext ().Idents .get (" openacc.private.init" );
2611+ case OpenACCClauseKind::FirstPrivate:
2612+ return &getASTContext ().Idents .get (" openacc.firstprivate.init" );
2613+ case OpenACCClauseKind::Reduction:
2614+ return &getASTContext ().Idents .get (" openacc.reduction.init" );
2615+ default :
2616+ llvm_unreachable (" Unknown clause kind?" );
2617+ }
2618+ }();
2619+
26072620 VarDecl *Recipe = VarDecl::Create (
26082621 getASTContext (), SemaRef.getCurContext (), VarExpr->getBeginLoc (),
2609- VarExpr->getBeginLoc (),
2610- &getASTContext ().Idents .get (" openacc.private.init" ), VarTy,
2622+ VarExpr->getBeginLoc (), VarName, VarTy,
26112623 getASTContext ().getTrivialTypeSourceInfo (VarTy), SC_Auto);
26122624
26132625 ExprResult Init;
26142626 VarDecl *Temporary = nullptr ;
2615-
2616- if (CK == OpenACCClauseKind::Private) {
2627+ {
26172628 // Trap errors so we don't get weird ones here. If we can't init, we'll just
26182629 // swallow the errors.
26192630 Sema::TentativeAnalysisScope Trap{SemaRef};
26202631 InitializedEntity Entity = InitializedEntity::InitializeVariable (Recipe);
2621- InitializationKind Kind =
2622- InitializationKind::CreateDefault (Recipe->getLocation ());
26232632
2624- InitializationSequence InitSeq (SemaRef.SemaRef , Entity, Kind, {});
2625- Init = InitSeq.Perform (SemaRef.SemaRef , Entity, Kind, {});
2626- } else if (CK == OpenACCClauseKind::FirstPrivate) {
2627- // TODO: OpenACC: Implement this to do a 'copy' operation.
2628- } else if (CK == OpenACCClauseKind::Reduction) {
2629- // TODO: OpenACC: Implement this for whatever reduction needs.
2630- } else {
2631- llvm_unreachable (" Unknown clause kind in CreateInitRecipe" );
2633+ if (CK == OpenACCClauseKind::Private) {
2634+ InitializationKind Kind =
2635+ InitializationKind::CreateDefault (Recipe->getLocation ());
2636+
2637+ InitializationSequence InitSeq (SemaRef.SemaRef , Entity, Kind, {});
2638+ Init = InitSeq.Perform (SemaRef.SemaRef , Entity, Kind, {});
2639+
2640+ } else if (CK == OpenACCClauseKind::FirstPrivate) {
2641+ // Create a VarDecl to be the 'copied-from' for the copy section of the
2642+ // recipe. This allows us to make the association so that we can use the
2643+ // standard 'generation' ability of the init.
2644+ Temporary = VarDecl::Create (
2645+ getASTContext (), SemaRef.getCurContext (), VarExpr->getBeginLoc (),
2646+ VarExpr->getBeginLoc (), &getASTContext ().Idents .get (" openacc.temp" ),
2647+ VarTy, getASTContext ().getTrivialTypeSourceInfo (VarTy), SC_Auto);
2648+ auto *TemporaryDRE = DeclRefExpr::Create (
2649+ getASTContext (), NestedNameSpecifierLoc{}, SourceLocation{},
2650+ Temporary,
2651+ /* ReferstoEnclosingVariableOrCapture=*/ false ,
2652+ DeclarationNameInfo{DeclarationName{Temporary->getDeclName ()},
2653+ VarExpr->getBeginLoc ()},
2654+ VarTy, clang::VK_LValue, Temporary, nullptr , NOUR_None);
2655+
2656+ Expr *InitExpr = nullptr ;
2657+
2658+ if (const auto *ArrTy = getASTContext ().getAsConstantArrayType (VarTy)) {
2659+ // Arrays need to have each individual element initialized as there
2660+ // isn't a normal 'equals' feature in C/C++. This section sets these up
2661+ // as an init list after 'initializing' each individual element.
2662+ llvm::SmallVector<Expr *> Args;
2663+
2664+ // Decay to pointer for the array subscript expression.
2665+ auto *CastToPtr = ImplicitCastExpr::Create (
2666+ getASTContext (),
2667+ getASTContext ().getPointerType (ArrTy->getElementType ()),
2668+ CK_ArrayToPointerDecay, TemporaryDRE, /* BasePath=*/ nullptr ,
2669+ clang::VK_LValue, FPOptionsOverride{});
2670+
2671+ for (std::size_t I = 0 ; I < ArrTy->getLimitedSize (); ++I) {
2672+ // Each element needs to be some sort of copy initialization from an
2673+ // array-index of the original temporary (referenced via a
2674+ // DeclRefExpr).
2675+
2676+ auto *Idx = IntegerLiteral::Create (
2677+ getASTContext (), llvm::APInt (sizeof (std::size_t ) * 8 , I),
2678+ getASTContext ().getSizeType (), VarExpr->getBeginLoc ());
2679+
2680+ Expr *Subscript = new (getASTContext ()) ArraySubscriptExpr (
2681+ CastToPtr, Idx, ArrTy->getElementType (), clang::VK_LValue,
2682+ OK_Ordinary, VarExpr->getBeginLoc ());
2683+
2684+ // Generate a simple copy from the result of the subscript. This will
2685+ // do a bitwise copy or a copy-constructor, as necessary.
2686+ InitializedEntity CopyEntity =
2687+ InitializedEntity::InitializeElement (getASTContext (), I, Entity);
2688+ InitializationKind CopyKind =
2689+ InitializationKind::CreateCopy (VarExpr->getBeginLoc (), {});
2690+ InitializationSequence CopySeq (SemaRef.SemaRef , CopyEntity, CopyKind,
2691+ Subscript,
2692+ /* TopLevelOfInitList=*/ true );
2693+
2694+ ExprResult ElemRes =
2695+ CopySeq.Perform (SemaRef.SemaRef , CopyEntity, CopyKind, Subscript);
2696+ Args.push_back (ElemRes.get ());
2697+ }
2698+
2699+ InitExpr = new (getASTContext ())
2700+ InitListExpr (getASTContext (), VarExpr->getBeginLoc (), Args,
2701+ VarExpr->getEndLoc ());
2702+ InitExpr->setType (VarTy);
2703+
2704+ } else {
2705+ // If this isn't an array, we can just do normal copy init from a simple
2706+ // variable reference, so set that up.
2707+ InitExpr = TemporaryDRE;
2708+ }
2709+
2710+ InitializationKind Kind = InitializationKind::CreateForInit (
2711+ Recipe->getLocation (), /* DirectInit=*/ true , InitExpr);
2712+ InitializationSequence InitSeq (SemaRef.SemaRef , Entity, Kind, InitExpr,
2713+ /* TopLevelOfInitList=*/ false ,
2714+ /* TreatUnavailableAsInvalid=*/ false );
2715+ Init = InitSeq.Perform (SemaRef.SemaRef , Entity, Kind, InitExpr, &VarTy);
2716+ } else if (CK == OpenACCClauseKind::Reduction) {
2717+ // TODO: OpenACC: Implement this for whatever reduction needs.
2718+ } else {
2719+ llvm_unreachable (" Unknown clause kind in CreateInitRecipe" );
2720+ }
26322721 }
26332722
26342723 if (Init.get ()) {
0 commit comments