summaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaCUDA.cpp6
-rw-r--r--lib/Sema/SemaCodeComplete.cpp17
-rw-r--r--lib/Sema/SemaOpenMP.cpp64
-rw-r--r--lib/Sema/SemaOverload.cpp4
-rw-r--r--lib/Sema/SemaTemplate.cpp14
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp270
-rw-r--r--lib/Sema/TreeTransform.h14
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
//===----------------------------------------------------------------------===//