@@ -2604,31 +2604,120 @@ SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK, const Expr *VarExpr) {
2604
2604
QualType VarTy =
2605
2605
VarExpr->getType ().getNonReferenceType ().getUnqualifiedType ();
2606
2606
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
+
2607
2620
VarDecl *Recipe = VarDecl::Create (
2608
2621
getASTContext (), SemaRef.getCurContext (), VarExpr->getBeginLoc (),
2609
- VarExpr->getBeginLoc (),
2610
- &getASTContext ().Idents .get (" openacc.private.init" ), VarTy,
2622
+ VarExpr->getBeginLoc (), VarName, VarTy,
2611
2623
getASTContext ().getTrivialTypeSourceInfo (VarTy), SC_Auto);
2612
2624
2613
2625
ExprResult Init;
2614
2626
VarDecl *Temporary = nullptr ;
2615
-
2616
- if (CK == OpenACCClauseKind::Private) {
2627
+ {
2617
2628
// Trap errors so we don't get weird ones here. If we can't init, we'll just
2618
2629
// swallow the errors.
2619
2630
Sema::TentativeAnalysisScope Trap{SemaRef};
2620
2631
InitializedEntity Entity = InitializedEntity::InitializeVariable (Recipe);
2621
- InitializationKind Kind =
2622
- InitializationKind::CreateDefault (Recipe->getLocation ());
2623
2632
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
+ }
2632
2721
}
2633
2722
2634
2723
if (Init.get ()) {
0 commit comments