diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenACC.cpp | 93 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmtAttr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 12 |
6 files changed, 102 insertions, 30 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index ef1be23..2990fd6 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -6926,13 +6926,13 @@ StringRef Sema::GetFormatStringTypeName(FormatStringType FST) { FormatStringType Sema::GetFormatStringType(StringRef Flavor) { return llvm::StringSwitch<FormatStringType>(Flavor) - .Cases("gnu_scanf", "scanf", FormatStringType::Scanf) - .Cases("gnu_printf", "printf", "printf0", "syslog", + .Cases({"gnu_scanf", "scanf"}, FormatStringType::Scanf) + .Cases({"gnu_printf", "printf", "printf0", "syslog"}, FormatStringType::Printf) - .Cases("NSString", "CFString", FormatStringType::NSString) - .Cases("gnu_strftime", "strftime", FormatStringType::Strftime) - .Cases("gnu_strfmon", "strfmon", FormatStringType::Strfmon) - .Cases("kprintf", "cmn_err", "vcmn_err", "zcmn_err", + .Cases({"NSString", "CFString"}, FormatStringType::NSString) + .Cases({"gnu_strftime", "strftime"}, FormatStringType::Strftime) + .Cases({"gnu_strfmon", "strfmon"}, FormatStringType::Strfmon) + .Cases({"kprintf", "cmn_err", "vcmn_err", "zcmn_err"}, FormatStringType::Kprintf) .Case("freebsd_kprintf", FormatStringType::FreeBSDKPrintf) .Case("os_trace", FormatStringType::OSLog) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index dca9d6e..a50c276 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -12811,7 +12811,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { if (CTSD->isInStdNamespace() && llvm::StringSwitch<bool>(CTSD->getName()) - .Cases("less", "less_equal", "greater", "greater_equal", true) + .Cases({"less", "less_equal", "greater", "greater_equal"}, true) .Default(false)) { if (RHSType->isNullPtrType()) RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index f7974eb..7debe33 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -672,11 +672,12 @@ ExprResult InitListChecker::PerformEmptyInit(SourceLocation Loc, IsInStd = true; } - if (IsInStd && llvm::StringSwitch<bool>(R->getName()) - .Cases("basic_string", "deque", "forward_list", true) - .Cases("list", "map", "multimap", "multiset", true) - .Cases("priority_queue", "queue", "set", "stack", true) - .Cases("unordered_map", "unordered_set", "vector", true) + if (IsInStd && + llvm::StringSwitch<bool>(R->getName()) + .Cases({"basic_string", "deque", "forward_list"}, true) + .Cases({"list", "map", "multimap", "multiset"}, true) + .Cases({"priority_queue", "queue", "set", "stack"}, true) + .Cases({"unordered_map", "unordered_set", "vector"}, true) .Default(false)) { InitSeq.InitializeFrom( SemaRef, Entity, diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index ca99834..3bb8080 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -2996,6 +2996,8 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( case OpenACCReductionOperator::Max: case OpenACCReductionOperator::Min: + BinOp = BinaryOperatorKind::BO_LT; + break; case OpenACCReductionOperator::And: case OpenACCReductionOperator::Or: // We just want a 'NYI' error in the backend, so leave an empty combiner @@ -3011,26 +3013,80 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( assert(!VarTy->isArrayType() && "Only 1 level of array allowed"); + enum class CombinerFailureKind { + None = 0, + BinOp = 1, + Conditional = 2, + Assignment = 3, + }; + + auto genCombiner = [&, this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE) + -> std::pair<ExprResult, CombinerFailureKind> { + ExprResult BinOpRes = + SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, BinOp, LHSDRE, RHSDRE, + /*ForFoldExpr=*/false); + switch (ReductionOperator) { + case OpenACCReductionOperator::Addition: + case OpenACCReductionOperator::Multiplication: + case OpenACCReductionOperator::BitwiseAnd: + case OpenACCReductionOperator::BitwiseOr: + case OpenACCReductionOperator::BitwiseXOr: + // These 5 are simple and are being done as compound operators, so we can + // immediately quit here. + return {BinOpRes, BinOpRes.isUsable() ? CombinerFailureKind::None + : CombinerFailureKind::BinOp}; + case OpenACCReductionOperator::Max: + case OpenACCReductionOperator::Min: { + // These are done as: + // LHS = (LHS < RHS) ? LHS : RHS; and LHS = (LHS < RHS) ? RHS : LHS; + // + // The BinOpRes should have been created with the less-than, so we just + // have to build the conditional and assignment. + if (!BinOpRes.isUsable()) + return {BinOpRes, CombinerFailureKind::BinOp}; + + // Create the correct conditional operator, swapping the results + // (true/false value) depending on min/max. + ExprResult CondRes; + if (ReductionOperator == OpenACCReductionOperator::Min) + CondRes = SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.get(), LHSDRE, + RHSDRE); + else + CondRes = SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.get(), RHSDRE, + LHSDRE); + + if (!CondRes.isUsable()) + return {CondRes, CombinerFailureKind::Conditional}; + + // Build assignment. + ExprResult Assignment = SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, + BinaryOperatorKind::BO_Assign, + LHSDRE, CondRes.get(), + /*ForFoldExpr=*/false); + return {Assignment, Assignment.isUsable() + ? CombinerFailureKind::None + : CombinerFailureKind::Assignment}; + } + case OpenACCReductionOperator::And: + case OpenACCReductionOperator::Or: + llvm_unreachable("And/Or not implemented, but should fail earlier"); + case OpenACCReductionOperator::Invalid: + llvm_unreachable("Invalid should have been caught above"); + } + }; + auto tryCombiner = [&, this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE, bool IncludeTrap) { - // TODO: OpenACC: we have to figure out based on the bin-op how to do the - // ones that we can't just use compound operators for. So &&, ||, max, and - // min aren't really clear what we could do here. if (IncludeTrap) { // Trap all of the errors here, we'll emit our own at the end. Sema::TentativeAnalysisScope Trap{SemaRef}; - - return SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, BinOp, LHSDRE, - RHSDRE, - /*ForFoldExpr=*/false); - } else { - return SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, BinOp, LHSDRE, - RHSDRE, - /*ForFoldExpr=*/false); + return genCombiner(LHSDRE, RHSDRE); } + return genCombiner(LHSDRE, RHSDRE); }; struct CombinerAttemptTy { + CombinerFailureKind FailKind; VarDecl *LHS; DeclRefExpr *LHSDRE; VarDecl *RHS; @@ -3058,9 +3114,11 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( RHSDecl->getBeginLoc()}, Ty, clang::VK_LValue, RHSDecl, nullptr, NOUR_None); - ExprResult BinOpResult = tryCombiner(LHSDRE, RHSDRE, /*IncludeTrap=*/true); + std::pair<ExprResult, CombinerFailureKind> BinOpResult = + tryCombiner(LHSDRE, RHSDRE, /*IncludeTrap=*/true); - return {LHSDecl, LHSDRE, RHSDecl, RHSDRE, BinOpResult.get()}; + return {BinOpResult.second, LHSDecl, LHSDRE, RHSDecl, RHSDRE, + BinOpResult.first.get()}; }; CombinerAttemptTy TopLevelCombinerInfo = formCombiner(VarTy); @@ -3081,12 +3139,20 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( } } + auto EmitFailureNote = [&](CombinerFailureKind CFK) { + if (CFK == CombinerFailureKind::BinOp) + return Diag(Loc, diag::note_acc_reduction_combiner_forming) + << CFK << BinaryOperator::getOpcodeStr(BinOp); + return Diag(Loc, diag::note_acc_reduction_combiner_forming) << CFK; + }; + // Since the 'root' level didn't fail, the only thing that could be successful // is a struct that we decompose on its individual fields. RecordDecl *RD = VarTy->getAsRecordDecl(); if (!RD) { Diag(Loc, diag::err_acc_reduction_recipe_no_op) << VarTy; + EmitFailureNote(TopLevelCombinerInfo.FailKind); tryCombiner(TopLevelCombinerInfo.LHSDRE, TopLevelCombinerInfo.RHSDRE, /*IncludeTrap=*/false); return true; @@ -3098,6 +3164,7 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( if (!FieldCombinerInfo.Op || FieldCombinerInfo.Op->containsErrors()) { Diag(Loc, diag::err_acc_reduction_recipe_no_op) << FD->getType(); Diag(FD->getBeginLoc(), diag::note_acc_reduction_recipe_noop_field) << RD; + EmitFailureNote(FieldCombinerInfo.FailKind); tryCombiner(FieldCombinerInfo.LHSDRE, FieldCombinerInfo.RHSDRE, /*IncludeTrap=*/false); return true; diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 50acc83..27fd556 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -81,7 +81,7 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A, StringRef PragmaName = llvm::StringSwitch<StringRef>( PragmaNameLoc->getIdentifierInfo()->getName()) - .Cases("unroll", "nounroll", "unroll_and_jam", "nounroll_and_jam", + .Cases({"unroll", "nounroll", "unroll_and_jam", "nounroll_and_jam"}, PragmaNameLoc->getIdentifierInfo()->getName()) .Default("clang loop"); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 29f0c30..0c8c1d1 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -16430,12 +16430,16 @@ ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr( AssociatedDecl == E->getAssociatedDecl()) return E; - auto getParamAndType = [Index = E->getIndex()](Decl *AssociatedDecl) + auto getParamAndType = [E](Decl *AssociatedDecl) -> std::tuple<NonTypeTemplateParmDecl *, QualType> { - auto [PDecl, Arg] = getReplacedTemplateParameter(AssociatedDecl, Index); + auto [PDecl, Arg] = + getReplacedTemplateParameter(AssociatedDecl, E->getIndex()); auto *Param = cast<NonTypeTemplateParmDecl>(PDecl); - return {Param, Arg.isNull() ? Param->getType() - : Arg.getNonTypeTemplateArgumentType()}; + if (Arg.isNull()) + return {Param, Param->getType()}; + if (UnsignedOrNone PackIndex = E->getPackIndex()) + Arg = Arg.getPackAsArray()[*PackIndex]; + return {Param, Arg.getNonTypeTemplateArgumentType()}; }; // If the replacement expression did not change, and the parameter type |