diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaCUDA.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 64 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 14 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 270 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 14 |
7 files changed, 206 insertions, 183 deletions
diff --git a/lib/Sema/SemaCUDA.cpp b/lib/Sema/SemaCUDA.cpp index 6f272ec839f53..282633bbc9e16 100644 --- a/lib/Sema/SemaCUDA.cpp +++ b/lib/Sema/SemaCUDA.cpp @@ -228,10 +228,8 @@ void Sema::EraseUnwantedCUDAMatches( [&](const Pair &M1, const Pair &M2) { return GetCFP(M1) < GetCFP(M2); })); // Erase all functions with lower priority. - Matches.erase( - llvm::remove_if( - Matches, [&](const Pair &Match) { return GetCFP(Match) < BestCFP; }), - Matches.end()); + llvm::erase_if(Matches, + [&](const Pair &Match) { return GetCFP(Match) < BestCFP; }); } /// When an implicitly-declared special member has to invoke more than one diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index d76bde5746774..3eef366b75b33 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -7471,6 +7471,23 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, } Results.ExitScope(); + + if (!AtParameterName && !SelIdents.empty() && + SelIdents.front()->getName().startswith("init")) { + for (const auto &M : PP.macros()) { + if (M.first->getName() != "NS_DESIGNATED_INITIALIZER") + continue; + Results.EnterNewScope(); + CodeCompletionBuilder Builder(Results.getAllocator(), + Results.getCodeCompletionTUInfo()); + Builder.AddTypedTextChunk( + Builder.getAllocator().CopyString(M.first->getName())); + Results.AddResult(CodeCompletionResult(Builder.TakeString(), CCP_Macro, + CXCursor_MacroDefinition)); + Results.ExitScope(); + } + } + HandleCodeCompleteResults(this, CodeCompleter, CodeCompletionContext::CCC_Other, Results.data(),Results.size()); diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 804aadc0ff77e..edceb537df75d 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -1700,7 +1700,8 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { case OMPD_teams_distribute_parallel_for_simd: case OMPD_teams_distribute_parallel_for: case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_parallel_for: { + case OMPD_target_teams_distribute_parallel_for: + case OMPD_target_teams_distribute_parallel_for_simd: { QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); @@ -2439,6 +2440,12 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( AllowedNameModifiers.push_back(OMPD_target); AllowedNameModifiers.push_back(OMPD_parallel); break; + case OMPD_target_teams_distribute_parallel_for_simd: + Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( + ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); + AllowedNameModifiers.push_back(OMPD_target); + AllowedNameModifiers.push_back(OMPD_parallel); + break; case OMPD_declare_target: case OMPD_end_declare_target: case OMPD_threadprivate: @@ -6375,6 +6382,52 @@ StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); } +StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { + if (!AStmt) + return StmtError(); + + CapturedStmt *CS = cast<CapturedStmt>(AStmt); + // 1.2.2 OpenMP Language Terminology + // Structured block - An executable statement with a single entry at the + // top and a single exit at the bottom. + // The point of exit cannot be a branch out of the structured block. + // longjmp() and throw() must not violate the entry/exit criteria. + CS->getCapturedDecl()->setNothrow(); + + OMPLoopDirective::HelperExprs B; + // In presence of clause 'collapse' with number of loops, it will + // define the nested loops number. + auto NestedLoopCount = CheckOpenMPLoop( + OMPD_target_teams_distribute_parallel_for_simd, + getCollapseNumberExpr(Clauses), + nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, + VarsWithImplicitDSA, B); + if (NestedLoopCount == 0) + return StmtError(); + + assert((CurContext->isDependentContext() || B.builtAll()) && + "omp target teams distribute parallel for simd loop exprs were not " + "built"); + + if (!CurContext->isDependentContext()) { + // Finalize the clauses that need pre-built expressions for CodeGen. + for (auto C : Clauses) { + if (auto *LC = dyn_cast<OMPLinearClause>(C)) + if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), + B.NumIterations, *this, CurScope, + DSAStack)) + return StmtError(); + } + } + + getCurFunction()->setHasBranchProtectedScope(); + return OMPTargetTeamsDistributeParallelForSimdDirective::Create( + Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); +} + OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -7397,7 +7450,8 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || CurrDir == OMPD_target_teams || CurrDir == OMPD_target_teams_distribute || - CurrDir == OMPD_target_teams_distribute_parallel_for) { + CurrDir == OMPD_target_teams_distribute_parallel_for || + CurrDir == OMPD_target_teams_distribute_parallel_for_simd) { OpenMPClauseKind ConflictKind; if (DSAStack->checkMappableExprComponentListsForDecl( VD, /*CurrentRegionOnly=*/true, @@ -7657,7 +7711,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || CurrDir == OMPD_target_teams || CurrDir == OMPD_target_teams_distribute || - CurrDir == OMPD_target_teams_distribute_parallel_for) { + CurrDir == OMPD_target_teams_distribute_parallel_for || + CurrDir == OMPD_target_teams_distribute_parallel_for_simd) { OpenMPClauseKind ConflictKind; if (DSAStack->checkMappableExprComponentListsForDecl( VD, /*CurrentRegionOnly=*/true, @@ -10175,7 +10230,8 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, // attribute clause on the same construct if ((DKind == OMPD_target || DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute || - DKind == OMPD_target_teams_distribute_parallel_for) && VD) { + DKind == OMPD_target_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for_simd) && VD) { auto DVar = DSAS->getTopDSA(VD, false); if (isOpenMPPrivate(DVar.CKind)) { SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 47e3df20d9111..b5c0e634fa504 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -8958,9 +8958,7 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, S.IdentifyCUDAPreference(Caller, Cand->Function) == Sema::CFP_WrongSide; }; - Candidates.erase(std::remove_if(Candidates.begin(), Candidates.end(), - IsWrongSideCandidate), - Candidates.end()); + llvm::erase_if(Candidates, IsWrongSideCandidate); } } diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index facc5d1b375bd..66a10ef7993e0 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -4244,7 +4244,7 @@ namespace { UnnamedLocalNoLinkageFinder(Sema &S, SourceRange SR) : S(S), SR(SR) { } bool Visit(QualType T) { - return inherited::Visit(T.getTypePtr()); + return T.isNull() ? false : inherited::Visit(T.getTypePtr()); } #define TYPE(Class, Parent) \ @@ -4497,17 +4497,7 @@ bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param, // // C++11 allows these, and even in C++03 we allow them as an extension with // a warning. - bool NeedsCheck; - if (LangOpts.CPlusPlus11) - NeedsCheck = - !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_unnamed_type, - SR.getBegin()) || - !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_local_type, - SR.getBegin()); - else - NeedsCheck = Arg->hasUnnamedOrLocalType(); - - if (NeedsCheck) { + if (LangOpts.CPlusPlus11 || Arg->hasUnnamedOrLocalType()) { UnnamedLocalNoLinkageFinder Finder(*this, SR); (void)Finder.Visit(Context.getCanonicalType(Arg)); } diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 0bc85a2f2635b..7f1fd91c46f05 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -288,19 +288,22 @@ checkDeducedTemplateArguments(ASTContext &Context, X.pack_size() != Y.pack_size()) return DeducedTemplateArgument(); + llvm::SmallVector<TemplateArgument, 8> NewPack; for (TemplateArgument::pack_iterator XA = X.pack_begin(), XAEnd = X.pack_end(), YA = Y.pack_begin(); XA != XAEnd; ++XA, ++YA) { - // FIXME: Do we need to merge the results together here? - if (checkDeducedTemplateArguments(Context, - DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()), - DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound())) - .isNull()) + TemplateArgument Merged = checkDeducedTemplateArguments( + Context, DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()), + DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound())); + if (Merged.isNull()) return DeducedTemplateArgument(); + NewPack.push_back(Merged); } - return X; + return DeducedTemplateArgument( + TemplateArgument::CreatePackCopy(Context, NewPack), + X.wasDeducedFromArrayBound() && Y.wasDeducedFromArrayBound()); } llvm_unreachable("Invalid TemplateArgument Kind!"); @@ -672,17 +675,20 @@ public: // for that pack, then clear out the deduced argument. for (auto &Pack : Packs) { DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index]; - if (!DeducedArg.isNull()) { + if (!Pack.New.empty() || !DeducedArg.isNull()) { + while (Pack.New.size() < PackElements) + Pack.New.push_back(DeducedTemplateArgument()); Pack.New.push_back(DeducedArg); DeducedArg = DeducedTemplateArgument(); } } + ++PackElements; } /// \brief Finish template argument deduction for a set of argument packs, /// producing the argument packs and checking for consistency with prior /// deductions. - Sema::TemplateDeductionResult finish(bool HasAnyArguments) { + Sema::TemplateDeductionResult finish() { // Build argument packs for each of the parameter packs expanded by this // pack expansion. for (auto &Pack : Packs) { @@ -691,7 +697,7 @@ public: // Build or find a new value for this pack. DeducedTemplateArgument NewPack; - if (HasAnyArguments && Pack.New.empty()) { + if (PackElements && Pack.New.empty()) { if (Pack.DeferredDeduction.isNull()) { // We were not able to deduce anything for this parameter pack // (because it only appeared in non-deduced contexts), so just @@ -758,6 +764,7 @@ private: TemplateParameterList *TemplateParams; SmallVectorImpl<DeducedTemplateArgument> &Deduced; TemplateDeductionInfo &Info; + unsigned PackElements = 0; SmallVector<DeducedPack, 2> Packs; }; @@ -861,10 +868,7 @@ DeduceTemplateArguments(Sema &S, QualType Pattern = Expansion->getPattern(); PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern); - bool HasAnyArguments = false; for (; ArgIdx < NumArgs; ++ArgIdx) { - HasAnyArguments = true; - // Deduce template arguments from the pattern. if (Sema::TemplateDeductionResult Result = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, Pattern, @@ -877,7 +881,7 @@ DeduceTemplateArguments(Sema &S, // Build argument packs for each of the parameter packs expanded by this // pack expansion. - if (auto Result = PackScope.finish(HasAnyArguments)) + if (auto Result = PackScope.finish()) return Result; } @@ -1935,10 +1939,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // Keep track of the deduced template arguments for each parameter pack // expanded by this pack expansion (the outer index) and for each // template argument (the inner SmallVectors). - bool HasAnyArguments = false; for (; hasTemplateArgumentForDeduction(Args, ArgIdx); ++ArgIdx) { - HasAnyArguments = true; - // Deduce template arguments from the pattern. if (Sema::TemplateDeductionResult Result = DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx], @@ -1950,7 +1951,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // Build argument packs for each of the parameter packs expanded by this // pack expansion. - if (auto Result = PackScope.finish(HasAnyArguments)) + if (auto Result = PackScope.finish()) return Result; } @@ -2145,6 +2146,16 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, InnerArg.setDeducedFromArrayBound(Arg.wasDeducedFromArrayBound()); assert(InnerArg.getKind() != TemplateArgument::Pack && "deduced nested pack"); + if (P.isNull()) { + // We deduced arguments for some elements of this pack, but not for + // all of them. This happens if we get a conditionally-non-deduced + // context in a pack expansion (such as an overload set in one of the + // arguments). + S.Diag(Param->getLocation(), + diag::err_template_arg_deduced_incomplete_pack) + << Arg << Param; + return true; + } if (ConvertArg(InnerArg, PackedArgsBuilder.size())) return true; @@ -3192,67 +3203,59 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentByListElement( /// \brief Attempt template argument deduction from an initializer list /// deemed to be an argument in a function call. -static bool +static Sema::TemplateDeductionResult DeduceFromInitializerList(Sema &S, TemplateParameterList *TemplateParams, QualType AdjustedParamType, InitListExpr *ILE, TemplateDeductionInfo &Info, SmallVectorImpl<DeducedTemplateArgument> &Deduced, - unsigned TDF, Sema::TemplateDeductionResult &Result) { - - // [temp.deduct.call] p1 (post CWG-1591) - // If removing references and cv-qualifiers from P gives - // std::initializer_list<P0> or P0[N] for some P0 and N and the argument is a - // non-empty initializer list (8.5.4), then deduction is performed instead for - // each element of the initializer list, taking P0 as a function template - // parameter type and the initializer element as its argument, and in the - // P0[N] case, if N is a non-type template parameter, N is deduced from the - // length of the initializer list. Otherwise, an initializer list argument - // causes the parameter to be considered a non-deduced context - - const bool IsConstSizedArray = AdjustedParamType->isConstantArrayType(); - - const bool IsDependentSizedArray = - !IsConstSizedArray && AdjustedParamType->isDependentSizedArrayType(); - - QualType ElTy; // The element type of the std::initializer_list or the array. - - const bool IsSTDList = !IsConstSizedArray && !IsDependentSizedArray && - S.isStdInitializerList(AdjustedParamType, &ElTy); - - if (!IsConstSizedArray && !IsDependentSizedArray && !IsSTDList) - return false; - - Result = Sema::TDK_Success; - // If we are not deducing against the 'T' in a std::initializer_list<T> then - // deduce against the 'T' in T[N]. - if (ElTy.isNull()) { - assert(!IsSTDList); - ElTy = S.Context.getAsArrayType(AdjustedParamType)->getElementType(); + unsigned TDF) { + // C++ [temp.deduct.call]p1: (CWG 1591) + // If removing references and cv-qualifiers from P gives + // std::initializer_list<P0> or P0[N] for some P0 and N and the argument is + // a non-empty initializer list, then deduction is performed instead for + // each element of the initializer list, taking P0 as a function template + // parameter type and the initializer element as its argument + // + // FIXME: Remove references and cv-qualifiers here? Consider + // std::initializer_list<std::initializer_list<T>&&> + QualType ElTy; + auto *ArrTy = S.Context.getAsArrayType(AdjustedParamType); + if (ArrTy) + ElTy = ArrTy->getElementType(); + else if (!S.isStdInitializerList(AdjustedParamType, &ElTy)) { + // Otherwise, an initializer list argument causes the parameter to be + // considered a non-deduced context + return Sema::TDK_Success; } + // Deduction only needs to be done for dependent types. if (ElTy->isDependentType()) { for (Expr *E : ILE->inits()) { - if ((Result = DeduceTemplateArgumentByListElement(S, TemplateParams, ElTy, - E, Info, Deduced, TDF))) - return true; + if (auto Result = DeduceTemplateArgumentByListElement( + S, TemplateParams, ElTy, E, Info, Deduced, TDF)) + return Result; } } - if (IsDependentSizedArray) { - const DependentSizedArrayType *ArrTy = - S.Context.getAsDependentSizedArrayType(AdjustedParamType); + + // in the P0[N] case, if N is a non-type template parameter, N is deduced + // from the length of the initializer list. + // FIXME: We're not supposed to get here if N would be deduced as 0. + if (auto *DependentArrTy = dyn_cast_or_null<DependentSizedArrayType>(ArrTy)) { // Determine the array bound is something we can deduce. if (NonTypeTemplateParmDecl *NTTP = - getDeducedParameterFromExpr(Info, ArrTy->getSizeExpr())) { + getDeducedParameterFromExpr(Info, DependentArrTy->getSizeExpr())) { // We can perform template argument deduction for the given non-type // template parameter. llvm::APInt Size(S.Context.getIntWidth(NTTP->getType()), ILE->getNumInits()); - Result = DeduceNonTypeTemplateArgument( - S, TemplateParams, NTTP, llvm::APSInt(Size), NTTP->getType(), - /*ArrayBound=*/true, Info, Deduced); + if (auto Result = DeduceNonTypeTemplateArgument( + S, TemplateParams, NTTP, llvm::APSInt(Size), NTTP->getType(), + /*ArrayBound=*/true, Info, Deduced)) + return Result; } } - return true; + + return Sema::TDK_Success; } /// \brief Perform template argument deduction by matching a parameter type @@ -3268,15 +3271,10 @@ DeduceTemplateArgumentByListElement(Sema &S, unsigned TDF) { // Handle the case where an init list contains another init list as the // element. - if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) { - Sema::TemplateDeductionResult Result; - if (!DeduceFromInitializerList(S, TemplateParams, - ParamType.getNonReferenceType(), ILE, Info, - Deduced, TDF, Result)) - return Sema::TDK_Success; // Just ignore this expression. - - return Result; - } + if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) + return DeduceFromInitializerList(S, TemplateParams, + ParamType.getNonReferenceType(), ILE, Info, + Deduced, TDF); // For all other cases, just match by type. QualType ArgType = Arg->getType(); @@ -3363,58 +3361,51 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( ParamTypes.push_back(Function->getParamDecl(I)->getType()); } - // Deduce template arguments from the function parameters. - Deduced.resize(TemplateParams->size()); - unsigned ArgIdx = 0; SmallVector<OriginalCallArg, 4> OriginalCallArgs; - for (unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(); - ParamIdx != NumParamTypes; ++ParamIdx) { - QualType OrigParamType = ParamTypes[ParamIdx]; - QualType ParamType = OrigParamType; - const PackExpansionType *ParamExpansion - = dyn_cast<PackExpansionType>(ParamType); - if (!ParamExpansion) { - // Simple case: matching a function parameter to a function argument. - if (ArgIdx >= CheckArgs) - break; + // Deduce an argument of type ParamType from an expression with index ArgIdx. + auto DeduceCallArgument = [&](QualType ParamType, unsigned ArgIdx) { + Expr *Arg = Args[ArgIdx]; + QualType ArgType = Arg->getType(); + QualType OrigParamType = ParamType; - Expr *Arg = Args[ArgIdx++]; - QualType ArgType = Arg->getType(); + unsigned TDF = 0; + if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams, + ParamType, ArgType, Arg, + TDF)) + return Sema::TDK_Success; - unsigned TDF = 0; - if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams, - ParamType, ArgType, Arg, - TDF)) - continue; + // If we have nothing to deduce, we're done. + if (!hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType)) + return Sema::TDK_Success; - // If we have nothing to deduce, we're done. - if (!hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType)) - continue; + // If the argument is an initializer list ... + if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) + return DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE, + Info, Deduced, TDF); - // If the argument is an initializer list ... - if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) { - TemplateDeductionResult Result; - // Removing references was already done. - if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE, - Info, Deduced, TDF, Result)) - continue; + // Keep track of the argument type and corresponding parameter index, + // so we can check for compatibility between the deduced A and A. + OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx, ArgType)); - if (Result) - return Result; - // Don't track the argument type, since an initializer list has none. - continue; - } + return DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, ParamType, + ArgType, Info, Deduced, TDF); + }; - // Keep track of the argument type and corresponding parameter index, - // so we can check for compatibility between the deduced A and A. - OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx-1, - ArgType)); + // Deduce template arguments from the function parameters. + Deduced.resize(TemplateParams->size()); + for (unsigned ParamIdx = 0, NumParamTypes = ParamTypes.size(), ArgIdx = 0; + ParamIdx != NumParamTypes; ++ParamIdx) { + QualType ParamType = ParamTypes[ParamIdx]; - if (TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, - ParamType, ArgType, - Info, Deduced, TDF)) + const PackExpansionType *ParamExpansion = + dyn_cast<PackExpansionType>(ParamType); + if (!ParamExpansion) { + // Simple case: matching a function parameter to a function argument. + if (ArgIdx >= CheckArgs) + break; + + if (auto Result = DeduceCallArgument(ParamType, ArgIdx++)) return Result; continue; @@ -3429,6 +3420,9 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // the function parameter pack. For a function parameter pack that does // not occur at the end of the parameter-declaration-list, the type of // the parameter pack is a non-deduced context. + // FIXME: This does not say that subsequent parameters are also non-deduced. + // See also DR1388 / DR1399, which effectively says we should keep deducing + // after the pack. if (ParamIdx + 1 < NumParamTypes) break; @@ -3436,57 +3430,13 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( PackDeductionScope PackScope(*this, TemplateParams, Deduced, Info, ParamPattern); - bool HasAnyArguments = false; - for (; ArgIdx < Args.size(); ++ArgIdx) { - HasAnyArguments = true; - - QualType OrigParamType = ParamPattern; - ParamType = OrigParamType; - Expr *Arg = Args[ArgIdx]; - QualType ArgType = Arg->getType(); - - unsigned TDF = 0; - if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams, - ParamType, ArgType, Arg, - TDF)) { - // We can't actually perform any deduction for this argument, so stop - // deduction at this point. - ++ArgIdx; - break; - } - - // As above, initializer lists need special handling. - if (InitListExpr *ILE = dyn_cast<InitListExpr>(Arg)) { - TemplateDeductionResult Result; - if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE, - Info, Deduced, TDF, Result)) { - ++ArgIdx; - break; - } - - if (Result) - return Result; - } else { - - // Keep track of the argument type and corresponding argument index, - // so we can check for compatibility between the deduced A and A. - if (hasDeducibleTemplateParameters(*this, FunctionTemplate, ParamType)) - OriginalCallArgs.push_back(OriginalCallArg(OrigParamType, ArgIdx, - ArgType)); - - if (TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, - ParamType, ArgType, Info, - Deduced, TDF)) - return Result; - } - - PackScope.nextPackElement(); - } + for (; ArgIdx < Args.size(); PackScope.nextPackElement(), ++ArgIdx) + if (auto Result = DeduceCallArgument(ParamPattern, ArgIdx)) + return Result; // Build argument packs for each of the parameter packs expanded by this // pack expansion. - if (auto Result = PackScope.finish(HasAnyArguments)) + if (auto Result = PackScope.finish()) return Result; // After we've matching against a parameter pack, we're done. diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 3ab6019f0ec31..66892936e5731 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -7766,6 +7766,20 @@ TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective( return Res; } +template <typename Derived> +StmtResult TreeTransform<Derived>:: + TransformOMPTargetTeamsDistributeParallelForSimdDirective( + OMPTargetTeamsDistributeParallelForSimdDirective *D) { + DeclarationNameInfo DirName; + getDerived().getSema().StartOpenMPDSABlock( + OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr, + D->getLocStart()); + auto Res = getDerived().TransformOMPExecutableDirective(D); + getDerived().getSema().EndOpenMPDSABlock(Res.get()); + return Res; +} + + //===----------------------------------------------------------------------===// // OpenMP clause transformation //===----------------------------------------------------------------------===// |