mizvekov updated this revision to Diff 464434.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D134115/new/
https://reviews.llvm.org/D134115
Files:
clang/include/clang/AST/ASTImporter.h
clang/include/clang/AST/Expr.h
clang/include/clang/Sema/Initialization.h
clang/include/clang/Sema/Overload.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/Expr.cpp
clang/lib/Analysis/BodyFarm.cpp
clang/lib/CodeGen/CGExpr.cpp
clang/lib/Sema/SemaCUDA.cpp
clang/lib/Sema/SemaCast.cpp
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaExprMember.cpp
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/SemaTemplateDeduction.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterDecl.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -621,7 +621,8 @@
if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
(E->getDecl() == E->getFoundDecl()) &&
nk == DeclarationName::Identifier &&
- !E->refersToEnclosingVariableOrCapture() && !E->isNonOdrUse()) {
+ !E->refersToEnclosingVariableOrCapture() && !E->isNonOdrUse() &&
+ !E->getConvertedArgs()) {
AbbrevToUse = Writer.getDeclRefExprAbbrev();
}
@@ -636,6 +637,10 @@
E->getTrailingObjects<TemplateArgumentLoc>());
Record.AddDeclRef(E->getDecl());
+ if (E->ConvertedArgs)
+ Record.AddTemplateArgumentList(E->ConvertedArgs);
+ else
+ Record.push_back(0);
Record.AddSourceLocation(E->getLocation());
Record.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName());
Code = serialization::EXPR_DECL_REF;
@@ -911,6 +916,10 @@
Record.push_back(E->hadMultipleCandidates());
Record.push_back(E->isNonOdrUse());
Record.AddSourceLocation(E->getOperatorLoc());
+ if (E->Deduced)
+ Record.AddTemplateArgumentList(E->Deduced);
+ else
+ Record.push_back(0);
if (HasFoundDecl) {
DeclAccessPair FoundDecl = E->getFoundDecl();
Index: clang/lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTWriterDecl.cpp
+++ clang/lib/Serialization/ASTWriterDecl.cpp
@@ -2311,6 +2311,7 @@
Abv->Add(BitCodeAbbrevOp(0)); // RefersToEnclosingVariableOrCapture
Abv->Add(BitCodeAbbrevOp(0)); // NonOdrUseReason
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ConvertedArgs
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -595,6 +595,7 @@
E->DeclRefExprBits.HadMultipleCandidates = Record.readInt();
E->DeclRefExprBits.RefersToEnclosingVariableOrCapture = Record.readInt();
E->DeclRefExprBits.NonOdrUseReason = Record.readInt();
+
unsigned NumTemplateArgs = 0;
if (E->hasTemplateKWAndArgsInfo())
NumTemplateArgs = Record.readInt();
@@ -612,6 +613,7 @@
E->getTrailingObjects<TemplateArgumentLoc>(), NumTemplateArgs);
E->D = readDeclAs<ValueDecl>();
+ E->ConvertedArgs = Record.readTemplateArgumentList();
E->setLocation(readSourceLocation());
E->DNLoc = Record.readDeclarationNameLoc(E->getDecl()->getDeclName());
}
@@ -1027,6 +1029,7 @@
E->MemberExprBits.HadMultipleCandidates = Record.readInt();
E->MemberExprBits.NonOdrUseReason = Record.readInt();
E->MemberExprBits.OperatorLoc = Record.readSourceLocation();
+ E->Deduced = Record.readTemplateArgumentList();
if (HasQualifier || HasFoundDecl) {
DeclAccessPair FoundDecl;
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -8844,6 +8844,15 @@
TemplArgs.push_back(readTemplateArgument(Canonicalize));
}
+const TemplateArgumentList *
+ASTRecordReader::readTemplateArgumentList(bool Canonicalize) {
+ SmallVector<TemplateArgument, 8> Args;
+ readTemplateArgumentList(Args, Canonicalize);
+ if (Args.size() == 0)
+ return nullptr;
+ return TemplateArgumentList::CreateCopy(getContext(), Args);
+}
+
/// Read a UnresolvedSet structure.
void ASTRecordReader::readUnresolvedSet(LazyASTUnresolvedSet &Set) {
unsigned NumDecls = readInt();
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -563,6 +563,9 @@
NamedDecl *FirstQualifierInScope = nullptr,
bool AllowInjectedClassName = false);
+ Optional<TemplateArgument>
+ TransformTemplateArgument(const TemplateArgument &Arg);
+
/// Transform the given template argument.
///
/// By default, this operation transforms the type, expression, or
@@ -2496,11 +2499,12 @@
ValueDecl *VD,
const DeclarationNameInfo &NameInfo,
NamedDecl *Found,
- TemplateArgumentListInfo *TemplateArgs) {
+ TemplateArgumentListInfo *TemplateArgs,
+ const TemplateArgumentList *ConvertedArgs) {
CXXScopeSpec SS;
SS.Adopt(QualifierLoc);
return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
- TemplateArgs);
+ TemplateArgs, ConvertedArgs);
}
/// Build a new expression in parentheses.
@@ -4373,6 +4377,76 @@
llvm_unreachable("overloaded function decl survived to here");
}
+template <typename Derived>
+Optional<TemplateArgument>
+TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
+ switch (auto Kind = Arg.getKind()) {
+ case TemplateArgument::Null:
+ llvm_unreachable("Unexpected TemplateArgument Null");
+ case TemplateArgument::Expression:
+ llvm_unreachable("Unexpected TemplateArgument Expr");
+
+ case TemplateArgument::Pack: {
+ SmallVector<TemplateArgument, 4> Args(Arg.getPackAsArray());
+ for (auto &I : Args) {
+ const auto Arg = getDerived().TransformTemplateArgument(I);
+ if (!Arg)
+ return None;
+ I = *Arg;
+ }
+ return TemplateArgument(
+ TemplateArgumentList::CreateCopy(getSema().Context, Args)->asArray());
+ }
+
+ case TemplateArgument::Integral:
+ case TemplateArgument::NullPtr:
+ case TemplateArgument::Declaration: {
+ QualType T = Arg.getNonTypeTemplateArgumentType();
+ QualType NewT = getDerived().TransformType(T);
+ if (NewT.isNull())
+ return None;
+
+ ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
+ ? Arg.getAsDecl()
+ : nullptr;
+ ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
+ getDerived().getBaseLocation(), D))
+ : nullptr;
+ if (D && !NewD)
+ return None;
+ if (NewT == T && D == NewD)
+ return Arg;
+ if (Kind == TemplateArgument::Integral)
+ return TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT);
+ if (Kind == TemplateArgument::NullPtr)
+ return TemplateArgument(NewT, /*IsNullPtr=*/true);
+ assert(Kind == TemplateArgument::Declaration);
+ return TemplateArgument(NewD, NewT);
+ }
+ case TemplateArgument::Type:
+ if (QualType T = getDerived().TransformType(Arg.getAsType()); !T.isNull())
+ return TemplateArgument(T);
+ return None;
+ case TemplateArgument::Template: {
+ CXXScopeSpec SS;
+ if (TemplateName Template = getDerived().TransformTemplateName(
+ SS, Arg.getAsTemplate(), SourceLocation());
+ !Template.isNull())
+ return TemplateArgument(Template);
+ return None;
+ }
+ case TemplateArgument::TemplateExpansion: {
+ CXXScopeSpec SS;
+ if (TemplateName Template = getDerived().TransformTemplateName(
+ SS, Arg.getAsTemplateOrTemplatePattern(), SourceLocation());
+ !Template.isNull())
+ return TemplateArgument(Template, Arg.getNumTemplateExpansions());
+ return None;
+ }
+ }
+ llvm_unreachable("Unexpected Template Kind");
+}
+
template<typename Derived>
void TreeTransform<Derived>::InventTemplateArgumentLoc(
const TemplateArgument &Arg,
@@ -4393,39 +4467,15 @@
case TemplateArgument::Integral:
case TemplateArgument::NullPtr:
- case TemplateArgument::Declaration: {
+ case TemplateArgument::Declaration:
// Transform a resolved template argument straight to a resolved template
// argument. We get here when substituting into an already-substituted
// template type argument during concept satisfaction checking.
- QualType T = Arg.getNonTypeTemplateArgumentType();
- QualType NewT = getDerived().TransformType(T);
- if (NewT.isNull())
- return true;
-
- ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
- ? Arg.getAsDecl()
- : nullptr;
- ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
- getDerived().getBaseLocation(), D))
- : nullptr;
- if (D && !NewD)
- return true;
-
- if (NewT == T && D == NewD)
- Output = Input;
- else if (Arg.getKind() == TemplateArgument::Integral)
- Output = TemplateArgumentLoc(
- TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
- TemplateArgumentLocInfo());
- else if (Arg.getKind() == TemplateArgument::NullPtr)
- Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
- TemplateArgumentLocInfo());
- else
- Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
- TemplateArgumentLocInfo());
-
- return false;
- }
+ if (const auto Out = getDerived().TransformTemplateArgument(Arg)) {
+ Output = TemplateArgumentLoc(*Out, TemplateArgumentLocInfo());
+ return false;
+ }
+ return true;
case TemplateArgument::Type: {
TypeSourceInfo *DI = Input.getTypeSourceInfo();
@@ -6690,6 +6740,7 @@
ArgIterator(*this, ConvertedArgs.begin()),
ArgIterator(*this, ConvertedArgs.end()), NewTemplateArgs))
return QualType();
+ assert(NewTemplateArgs.size() != 0);
} else {
using ArgIterator =
TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>;
@@ -10581,9 +10632,22 @@
TransArgs))
return ExprError();
}
+ const TemplateArgumentList *NewConvertedArgs = nullptr;
+ if (const TemplateArgumentList *OldConvertedArgs = E->getConvertedArgs()) {
+ assert(OldConvertedArgs->size() != 0);
+ SmallVector<TemplateArgument, 4> NewArgs(OldConvertedArgs->asArray());
+ for (auto I : NewArgs) {
+ const auto Arg = getDerived().TransformTemplateArgument(I);
+ if (!Arg)
+ return ExprError();
+ I = *Arg;
+ }
+ NewConvertedArgs =
+ TemplateArgumentList::CreateCopy(getSema().Context, NewArgs);
+ }
- return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
- Found, TemplateArgs);
+ return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo, Found,
+ TemplateArgs, NewConvertedArgs);
}
template<typename Derived>
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3687,7 +3687,8 @@
/// Gets the type of a function for template-argument-deducton
/// purposes when it's considered as part of an overload set.
static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R,
- FunctionDecl *Fn) {
+ FunctionDecl *Fn,
+ ArrayRef<TemplateArgument> Args) {
// We may need to deduce the return type of the function now.
if (S.getLangOpts().CPlusPlus14 && Fn->getReturnType()->isUndeducedType() &&
S.DeduceReturnType(Fn, R.Expression->getExprLoc(), /*Diagnose*/ false))
@@ -3728,6 +3729,11 @@
if (R.IsAddressOfOperand)
TDF |= TDF_IgnoreQualifiers;
+ // Gather the explicit template arguments, if any.
+ TemplateArgumentListInfo ExplicitTemplateArgs;
+ if (Ovl->hasExplicitTemplateArgs())
+ Ovl->copyTemplateArgumentsInto(ExplicitTemplateArgs);
+
// C++0x [temp.deduct.call]p6:
// When P is a function type, pointer to function type, or pointer
// to member function type:
@@ -3737,28 +3743,27 @@
!ParamType->isMemberFunctionPointerType()) {
if (Ovl->hasExplicitTemplateArgs()) {
// But we can still look for an explicit specialization.
- if (FunctionDecl *ExplicitSpec
- = S.ResolveSingleFunctionTemplateSpecialization(Ovl))
- return GetTypeOfFunction(S, R, ExplicitSpec);
+ const TemplateArgumentList *ConvertedArgs;
+ if (FunctionDecl *ExplicitSpec =
+ S.ResolveSingleFunctionTemplateSpecialization(
+ Ovl, ExplicitTemplateArgs, ConvertedArgs))
+ return GetTypeOfFunction(S, R, ExplicitSpec, ConvertedArgs->asArray());
}
DeclAccessPair DAP;
if (FunctionDecl *Viable =
S.resolveAddressOfSingleOverloadCandidate(Arg, DAP))
- return GetTypeOfFunction(S, R, Viable);
+ return GetTypeOfFunction(S, R, Viable, None);
return {};
}
- // Gather the explicit template arguments, if any.
- TemplateArgumentListInfo ExplicitTemplateArgs;
- if (Ovl->hasExplicitTemplateArgs())
- Ovl->copyTemplateArgumentsInto(ExplicitTemplateArgs);
QualType Match;
for (UnresolvedSetIterator I = Ovl->decls_begin(),
E = Ovl->decls_end(); I != E; ++I) {
NamedDecl *D = (*I)->getUnderlyingDecl();
+ const TemplateArgumentList *ConvertedArgs = nullptr;
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) {
// - If the argument is an overload set containing one or more
// function templates, the parameter is treated as a
@@ -3774,10 +3779,12 @@
continue;
D = Specialization;
+ ConvertedArgs = Info.takeSugared();
}
FunctionDecl *Fn = cast<FunctionDecl>(D);
- QualType ArgType = GetTypeOfFunction(S, R, Fn);
+ QualType ArgType = GetTypeOfFunction(
+ S, R, Fn, ConvertedArgs ? ConvertedArgs->asArray() : None);
if (ArgType.isNull()) continue;
// Function-to-pointer conversion.
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -4583,14 +4583,15 @@
/// a given template-id.
struct PartialSpecMatchResult {
VarTemplatePartialSpecializationDecl *Partial;
- TemplateArgumentList *Args;
+ TemplateArgumentList *CanonicalArgs, *SugaredArgs;
};
} // end anonymous namespace
DeclResult
Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
SourceLocation TemplateNameLoc,
- const TemplateArgumentListInfo &TemplateArgs) {
+ const TemplateArgumentListInfo &TemplateArgs,
+ const TemplateArgumentList *&ConvertedArgs) {
assert(Template && "A variable template id without template?");
// Check that the template argument list is well-formed for this template.
@@ -4608,6 +4609,8 @@
TemplateArgs, CanonicalConverted))
return DeclResult();
+ ConvertedArgs = TemplateArgumentList::CreateCopy(Context, SugaredConverted);
+
// Find the variable template specialization declaration that
// corresponds to these arguments.
void *InsertPos = nullptr;
@@ -4623,9 +4626,11 @@
// the set of specializations, based on the closest partial specialization
// that it represents. That is,
VarDecl *InstantiationPattern = Template->getTemplatedDecl();
- TemplateArgumentList TemplateArgList(TemplateArgumentList::OnStack,
- CanonicalConverted);
- TemplateArgumentList *InstantiationArgs = &TemplateArgList;
+ TemplateArgumentList SugaredArgList(TemplateArgumentList::OnStack,
+ SugaredConverted);
+ TemplateArgumentList CanonicalArgList(TemplateArgumentList::OnStack,
+ CanonicalConverted);
+ TemplateArgumentList *InstantiationArgs = &CanonicalArgList;
bool AmbiguousPartialSpec = false;
typedef PartialSpecMatchResult MatchResult;
SmallVector<MatchResult, 4> Matched;
@@ -4646,7 +4651,7 @@
TemplateDeductionInfo Info(FailedCandidates.getLocation());
if (TemplateDeductionResult Result =
- DeduceTemplateArguments(Partial, TemplateArgList, Info)) {
+ DeduceTemplateArguments(Partial, SugaredArgList, Info)) {
// Store the failed-deduction information for use in diagnostics, later.
// TODO: Actually use the failed-deduction info?
FailedCandidates.addCandidate().set(
@@ -4656,7 +4661,8 @@
} else {
Matched.push_back(PartialSpecMatchResult());
Matched.back().Partial = Partial;
- Matched.back().Args = Info.takeCanonical();
+ Matched.back().SugaredArgs = Info.takeSugared();
+ Matched.back().CanonicalArgs = Info.takeCanonical();
}
}
@@ -4699,7 +4705,7 @@
// Instantiate using the best variable template partial specialization.
InstantiationPattern = Best->Partial;
- InstantiationArgs = Best->Args;
+ InstantiationArgs = Best->CanonicalArgs;
} else {
// -- If no match is found, the instantiation is generated
// from the primary template.
@@ -4724,9 +4730,10 @@
// Print the matching partial specializations.
for (MatchResult P : Matched)
+ // FIXME: Use SugaredArgs here.
Diag(P.Partial->getLocation(), diag::note_partial_spec_match)
<< getTemplateArgumentBindingsText(P.Partial->getTemplateParameters(),
- *P.Args);
+ *P.CanonicalArgs);
return true;
}
@@ -4745,9 +4752,9 @@
const DeclarationNameInfo &NameInfo,
VarTemplateDecl *Template, SourceLocation TemplateLoc,
const TemplateArgumentListInfo *TemplateArgs) {
-
+ const TemplateArgumentList *ConvertedArgs;
DeclResult Decl = CheckVarTemplateId(Template, TemplateLoc, NameInfo.getLoc(),
- *TemplateArgs);
+ *TemplateArgs, ConvertedArgs);
if (Decl.isInvalid())
return ExprError();
@@ -4761,7 +4768,8 @@
// Build an ordinary singleton decl ref.
return BuildDeclarationNameExpr(SS, NameInfo, Var,
- /*FoundD=*/nullptr, TemplateArgs);
+ /*FoundD=*/nullptr, TemplateArgs,
+ ConvertedArgs);
}
void Sema::diagnoseMissingTemplateArguments(TemplateName Name,
@@ -7438,13 +7446,14 @@
->isFunctionType())) {
if (Arg->getType() == Context.OverloadTy) {
- if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg, ParamType,
- true,
- FoundResult)) {
+ const TemplateArgumentList *ConvertedArgs;
+ if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(
+ Arg, ParamType, true, FoundResult, ConvertedArgs)) {
if (DiagnoseUseOfDecl(Fn, Arg->getBeginLoc()))
return ExprError();
- Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
+ Arg =
+ FixOverloadedFunctionReference(Arg, FoundResult, Fn, ConvertedArgs);
ArgType = Arg->getType();
} else
return ExprError();
@@ -7489,14 +7498,15 @@
"Only object references allowed here");
if (Arg->getType() == Context.OverloadTy) {
- if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg,
- ParamRefType->getPointeeType(),
- true,
- FoundResult)) {
+ const TemplateArgumentList *ConvertedArgs;
+ if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(
+ Arg, ParamRefType->getPointeeType(), true, FoundResult,
+ ConvertedArgs)) {
if (DiagnoseUseOfDecl(Fn, Arg->getBeginLoc()))
return ExprError();
- Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
+ Arg =
+ FixOverloadedFunctionReference(Arg, FoundResult, Fn, ConvertedArgs);
ArgType = Arg->getType();
} else
return ExprError();
@@ -10276,8 +10286,10 @@
TemplateArgumentListInfo TemplateArgs =
makeTemplateArgumentListInfo(*this, *D.getName().TemplateId);
- DeclResult Res = CheckVarTemplateId(PrevTemplate, TemplateLoc,
- D.getIdentifierLoc(), TemplateArgs);
+ const TemplateArgumentList *ConvertedArgs;
+ DeclResult Res =
+ CheckVarTemplateId(PrevTemplate, TemplateLoc, D.getIdentifierLoc(),
+ TemplateArgs, ConvertedArgs);
if (Res.isInvalid())
return true;
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -1720,9 +1720,9 @@
if (FromType == S.Context.OverloadTy) {
DeclAccessPair AccessPair;
- if (FunctionDecl *Fn
- = S.ResolveAddressOfOverloadedFunction(From, ToType, false,
- AccessPair)) {
+ const TemplateArgumentList *ConvertedArgs;
+ if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(
+ From, ToType, false, AccessPair, ConvertedArgs)) {
// We were able to resolve the address of the overloaded function,
// so we can convert to the type of that function.
FromType = Fn->getType();
@@ -4757,8 +4757,9 @@
// type of the resulting function.
if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) {
DeclAccessPair Found;
- if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Init, DeclType,
- false, Found))
+ const TemplateArgumentList *ConvertedArgs;
+ if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(
+ Init, DeclType, false, Found, ConvertedArgs))
T2 = Fn->getType();
}
@@ -5234,8 +5235,9 @@
// type of the resulting function.
if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) {
DeclAccessPair Found;
+ const TemplateArgumentList *ConvertedArgs;
if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(
- Init, ToType, false, Found))
+ Init, ToType, false, Found, ConvertedArgs))
T2 = Fn->getType();
}
@@ -6332,7 +6334,7 @@
OverloadCandidateSet &CandidateSet, bool SuppressUserConversions,
bool PartialOverloading, bool AllowExplicit, bool AllowExplicitConversions,
ADLCallKind IsADLCandidate, ConversionSequenceList EarlyConversions,
- OverloadCandidateParamOrder PO) {
+ OverloadCandidateParamOrder PO, const TemplateArgumentList *Deduced) {
const FunctionProtoType *Proto
= dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>());
assert(Proto && "Functions without a prototype cannot be overloaded");
@@ -6351,7 +6353,7 @@
AddMethodCandidate(Method, FoundDecl, Method->getParent(), QualType(),
Expr::Classification::makeSimpleLValue(), Args,
CandidateSet, SuppressUserConversions,
- PartialOverloading, EarlyConversions, PO);
+ PartialOverloading, EarlyConversions, PO, Deduced);
return;
}
// We treat a constructor like a non-member function, since its object
@@ -6396,6 +6398,7 @@
Candidate.IsADLCandidate = IsADLCandidate;
Candidate.IgnoreObjectArgument = false;
Candidate.ExplicitCallArguments = Args.size();
+ Candidate.Deduced = Deduced;
// Explicit functions are not actually candidates at all if we're not
// allowing them in this context, but keep them around so we can point
@@ -6930,16 +6933,13 @@
/// both @c a1 and @c a2. If @p SuppressUserConversions, then don't
/// allow user-defined conversions via constructors or conversion
/// operators.
-void
-Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext, QualType ObjectType,
- Expr::Classification ObjectClassification,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet &CandidateSet,
- bool SuppressUserConversions,
- bool PartialOverloading,
- ConversionSequenceList EarlyConversions,
- OverloadCandidateParamOrder PO) {
+void Sema::AddMethodCandidate(
+ CXXMethodDecl *Method, DeclAccessPair FoundDecl,
+ CXXRecordDecl *ActingContext, QualType ObjectType,
+ Expr::Classification ObjectClassification, ArrayRef<Expr *> Args,
+ OverloadCandidateSet &CandidateSet, bool SuppressUserConversions,
+ bool PartialOverloading, ConversionSequenceList EarlyConversions,
+ OverloadCandidateParamOrder PO, const TemplateArgumentList *Deduced) {
const FunctionProtoType *Proto
= dyn_cast<FunctionProtoType>(Method->getType()->getAs<FunctionType>());
assert(Proto && "Methods without a prototype cannot be overloaded");
@@ -6970,6 +6970,7 @@
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.ExplicitCallArguments = Args.size();
+ Candidate.Deduced = Deduced;
unsigned NumParams = Proto->getNumParams();
@@ -7146,7 +7147,7 @@
AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl,
ActingContext, ObjectType, ObjectClassification, Args,
CandidateSet, SuppressUserConversions, PartialOverloading,
- Conversions, PO);
+ Conversions, PO, Info.takeSugared());
}
/// Determine whether a given function template has a simple explicit specifier
@@ -7226,10 +7227,11 @@
// Add the function template specialization produced by template argument
// deduction as a candidate.
assert(Specialization && "Missing function template specialization?");
- AddOverloadCandidate(
- Specialization, FoundDecl, Args, CandidateSet, SuppressUserConversions,
- PartialOverloading, AllowExplicit,
- /*AllowExplicitConversions*/ false, IsADLCandidate, Conversions, PO);
+ AddOverloadCandidate(Specialization, FoundDecl, Args, CandidateSet,
+ SuppressUserConversions, PartialOverloading,
+ AllowExplicit,
+ /*AllowExplicitConversions*/ false, IsADLCandidate,
+ Conversions, PO, Info.takeSugared());
}
/// Check that implicit conversion sequences can be formed for each argument
@@ -12057,7 +12059,10 @@
OverloadExpr::FindResult OvlExprInfo;
OverloadExpr *OvlExpr;
TemplateArgumentListInfo OvlExplicitTemplateArgs;
- SmallVector<std::pair<DeclAccessPair, FunctionDecl*>, 4> Matches;
+ SmallVector<
+ std::tuple<DeclAccessPair, FunctionDecl *, const TemplateArgumentList *>,
+ 4>
+ Matches;
TemplateSpecCandidateSet FailedCandidates;
public:
@@ -12075,15 +12080,22 @@
FailedCandidates(OvlExpr->getNameLoc(), /*ForTakingAddress=*/true) {
ExtractUnqualifiedFunctionTypeFromTargetType();
+ if (OvlExpr->hasExplicitTemplateArgs())
+ OvlExpr->copyTemplateArgumentsInto(OvlExplicitTemplateArgs);
+
+ const TemplateArgumentList *ConvertedArgs;
if (TargetFunctionType->isFunctionType()) {
if (UnresolvedMemberExpr *UME = dyn_cast<UnresolvedMemberExpr>(OvlExpr))
if (!UME->isImplicitAccess() &&
- !S.ResolveSingleFunctionTemplateSpecialization(UME))
+ (!OvlExpr->hasExplicitTemplateArgs() ||
+ !S.ResolveSingleFunctionTemplateSpecialization(
+ UME, OvlExplicitTemplateArgs, ConvertedArgs)))
StaticMemberFunctionFromBoundPointer = true;
} else if (OvlExpr->hasExplicitTemplateArgs()) {
DeclAccessPair dap;
if (FunctionDecl *Fn = S.ResolveSingleFunctionTemplateSpecialization(
- OvlExpr, false, &dap)) {
+ OvlExpr, OvlExplicitTemplateArgs, ConvertedArgs,
+ /*Complain=*/false, &dap)) {
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn))
if (!Method->isStatic()) {
// If the target type is a non-function type and the function found
@@ -12097,14 +12109,11 @@
return;
}
- Matches.push_back(std::make_pair(dap, Fn));
+ Matches.push_back({dap, Fn, ConvertedArgs});
}
return;
}
- if (OvlExpr->hasExplicitTemplateArgs())
- OvlExpr->copyTemplateArgumentsInto(OvlExplicitTemplateArgs);
-
if (FindAllFunctionsThatMatchTargetTypeExactly()) {
// C++ [over.over]p4:
// If more than one function is selected, [...]
@@ -12146,15 +12155,17 @@
// Same algorithm as overload resolution -- one pass to pick the "best",
// another pass to be sure that nothing is better than the best.
auto Best = Matches.begin();
- for (auto I = Matches.begin()+1, E = Matches.end(); I != E; ++I)
- if (isBetterCandidate(I->second, Best->second))
+ for (auto I = Matches.begin() + 1, E = Matches.end(); I != E; ++I)
+ if (isBetterCandidate(std::get<1>(*I), std::get<1>(*Best)))
Best = I;
- const FunctionDecl *BestFn = Best->second;
- auto IsBestOrInferiorToBest = [this, BestFn](
- const std::pair<DeclAccessPair, FunctionDecl *> &Pair) {
- return BestFn == Pair.second || isBetterCandidate(BestFn, Pair.second);
- };
+ const FunctionDecl *BestFn = std::get<1>(*Best);
+ auto IsBestOrInferiorToBest =
+ [this, BestFn](const std::tuple<DeclAccessPair, FunctionDecl *,
+ const TemplateArgumentList *> &Tuple) {
+ return BestFn == std::get<1>(Tuple) ||
+ isBetterCandidate(BestFn, std::get<1>(Tuple));
+ };
// Note: We explicitly leave Matches unmodified if there isn't a clear best
// option, so we can potentially give the user a better error
@@ -12221,7 +12232,7 @@
if (!S.checkAddressOfFunctionIsAvailable(Specialization))
return false;
- Matches.push_back(std::make_pair(CurAccessFunPair, Specialization));
+ Matches.push_back({CurAccessFunPair, Specialization, Info.takeSugared()});
return true;
}
@@ -12261,8 +12272,9 @@
// If we're in C, we need to support types that aren't exactly identical.
if (!S.getLangOpts().CPlusPlus ||
candidateHasExactlyCorrectType(FunDecl)) {
- Matches.push_back(std::make_pair(
- CurAccessFunPair, cast<FunctionDecl>(FunDecl->getCanonicalDecl())));
+ Matches.push_back({CurAccessFunPair,
+ cast<FunctionDecl>(FunDecl->getCanonicalDecl()),
+ nullptr});
FoundNonTemplateFunction = true;
return true;
}
@@ -12319,7 +12331,8 @@
UnresolvedSet<4> MatchesCopy; // TODO: avoid!
for (unsigned I = 0, E = Matches.size(); I != E; ++I)
- MatchesCopy.addDecl(Matches[I].second, Matches[I].first.getAccess());
+ MatchesCopy.addDecl(std::get<1>(Matches[I]),
+ std::get<0>(Matches[I]).getAccess());
// TODO: It looks like FailedCandidates does not serve much purpose
// here, since the no_viable diagnostic has index 0.
@@ -12327,15 +12340,16 @@
MatchesCopy.begin(), MatchesCopy.end(), FailedCandidates,
SourceExpr->getBeginLoc(), S.PDiag(),
S.PDiag(diag::err_addr_ovl_ambiguous)
- << Matches[0].second->getDeclName(),
+ << std::get<1>(Matches[0])->getDeclName(),
S.PDiag(diag::note_ovl_candidate)
<< (unsigned)oc_function << (unsigned)ocs_described_template,
Complain, TargetFunctionType);
if (Result != MatchesCopy.end()) {
// Make it the first and only element
- Matches[0].first = Matches[Result - MatchesCopy.begin()].first;
- Matches[0].second = cast<FunctionDecl>(*Result);
+ const auto &Old = Matches[Result - MatchesCopy.begin()];
+ Matches[0] = {std::get<0>(Old), cast<FunctionDecl>(*Result),
+ std::get<2>(Old)};
Matches.resize(1);
} else
HasComplained |= Complain;
@@ -12345,7 +12359,7 @@
// [...] any function template specializations in the set are
// eliminated if the set also contains a non-template function, [...]
for (unsigned I = 0, N = Matches.size(); I != N; ) {
- if (Matches[I].second->getPrimaryTemplate() == nullptr)
+ if (std::get<1>(Matches[I])->getPrimaryTemplate() == nullptr)
++I;
else {
Matches[I] = Matches[--N];
@@ -12426,12 +12440,18 @@
FunctionDecl* getMatchingFunctionDecl() const {
if (Matches.size() != 1) return nullptr;
- return Matches[0].second;
+ return std::get<1>(Matches[0]);
}
const DeclAccessPair* getMatchingFunctionAccessPair() const {
if (Matches.size() != 1) return nullptr;
- return &Matches[0].first;
+ return &std::get<0>(Matches[0]);
+ }
+
+ const TemplateArgumentList *getMatchingFunctionConvertedArgs() const {
+ if (Matches.size() != 1)
+ return nullptr;
+ return std::get<2>(Matches[0]);
}
};
}
@@ -12451,12 +12471,10 @@
/// This routine returns the resulting FunctionDecl if it could be
/// resolved, and NULL otherwise. When @p Complain is true, this
/// routine will emit diagnostics if there is an error.
-FunctionDecl *
-Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr,
- QualType TargetType,
- bool Complain,
- DeclAccessPair &FoundResult,
- bool *pHadMultipleCandidates) {
+FunctionDecl *Sema::ResolveAddressOfOverloadedFunction(
+ Expr *AddressOfExpr, QualType TargetType, bool Complain,
+ DeclAccessPair &FoundResult, const TemplateArgumentList *&ConvertedArgs,
+ bool *pHadMultipleCandidates) {
assert(AddressOfExpr->getType() == Context.OverloadTy);
AddressOfFunctionResolver Resolver(*this, AddressOfExpr, TargetType,
@@ -12478,6 +12496,7 @@
if (auto *FPT = Fn->getType()->getAs<FunctionProtoType>())
ResolveExceptionSpec(AddressOfExpr->getExprLoc(), FPT);
FoundResult = *Resolver.getMatchingFunctionAccessPair();
+ ConvertedArgs = Resolver.getMatchingFunctionConvertedArgs();
if (Complain) {
if (Resolver.IsStaticMemberFunctionFromBoundPointer())
Resolver.ComplainIsStaticMemberFunctionFromBoundPointer();
@@ -12590,7 +12609,7 @@
// for both.
DiagnoseUseOfDecl(Found, E->getExprLoc());
CheckAddressOfMemberAccess(E, DAP);
- Expr *Fixed = FixOverloadedFunctionReference(E, DAP, Found);
+ Expr *Fixed = FixOverloadedFunctionReference(E, DAP, Found, nullptr);
if (DoFunctionPointerConversion && Fixed->getType()->isFunctionType())
SrcExpr = DefaultFunctionArrayConversion(Fixed, /*Diagnose=*/false);
else
@@ -12608,10 +12627,10 @@
///
/// If no template-ids are found, no diagnostics are emitted and NULL is
/// returned.
-FunctionDecl *
-Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
- bool Complain,
- DeclAccessPair *FoundResult) {
+FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(
+ OverloadExpr *ovl, TemplateArgumentListInfo &ExplicitTemplateArgs,
+ const TemplateArgumentList *&ConvertedArgs, bool Complain,
+ DeclAccessPair *FoundResult) {
// C++ [over.over]p1:
// [...] [Note: any redundant set of parentheses surrounding the
// overloaded function name is ignored (5.1). ]
@@ -12619,12 +12638,9 @@
// [...] The overloaded function name can be preceded by the &
// operator.
- // If we didn't actually find any template-ids, we're done.
- if (!ovl->hasExplicitTemplateArgs())
- return nullptr;
+ // Specializations must have template args.
+ assert(ovl->hasExplicitTemplateArgs());
- TemplateArgumentListInfo ExplicitTemplateArgs;
- ovl->copyTemplateArgumentsInto(ExplicitTemplateArgs);
TemplateSpecCandidateSet FailedCandidates(ovl->getNameLoc());
// Look through all of the overloaded functions, searching for one
@@ -12675,6 +12691,7 @@
Matched = Specialization;
if (FoundResult) *FoundResult = I.getPair();
+ ConvertedArgs = Info.takeSugared();
}
if (Matched &&
@@ -12699,50 +12716,55 @@
assert(SrcExpr.get()->getType() == Context.OverloadTy);
OverloadExpr::FindResult ovl = OverloadExpr::find(SrcExpr.get());
-
- DeclAccessPair found;
ExprResult SingleFunctionExpression;
- if (FunctionDecl *fn = ResolveSingleFunctionTemplateSpecialization(
- ovl.Expression, /*complain*/ false, &found)) {
- if (DiagnoseUseOfDecl(fn, SrcExpr.get()->getBeginLoc())) {
- SrcExpr = ExprError();
- return true;
- }
+ if (ovl.Expression->hasExplicitTemplateArgs()) {
+ TemplateArgumentListInfo ExplicitTemplateArgs;
+ ovl.Expression->copyTemplateArgumentsInto(ExplicitTemplateArgs);
+
+ const TemplateArgumentList *ConvertedArgs;
+ DeclAccessPair found;
+ if (FunctionDecl *fn = ResolveSingleFunctionTemplateSpecialization(
+ ovl.Expression, ExplicitTemplateArgs, ConvertedArgs,
+ /*Complain=*/false, &found)) {
+ if (DiagnoseUseOfDecl(fn, SrcExpr.get()->getBeginLoc())) {
+ SrcExpr = ExprError();
+ return true;
+ }
- // It is only correct to resolve to an instance method if we're
- // resolving a form that's permitted to be a pointer to member.
- // Otherwise we'll end up making a bound member expression, which
- // is illegal in all the contexts we resolve like this.
- if (!ovl.HasFormOfMemberPointer &&
- isa<CXXMethodDecl>(fn) &&
- cast<CXXMethodDecl>(fn)->isInstance()) {
- if (!complain) return false;
-
- Diag(ovl.Expression->getExprLoc(),
- diag::err_bound_member_function)
- << 0 << ovl.Expression->getSourceRange();
-
- // TODO: I believe we only end up here if there's a mix of
- // static and non-static candidates (otherwise the expression
- // would have 'bound member' type, not 'overload' type).
- // Ideally we would note which candidate was chosen and why
- // the static candidates were rejected.
- SrcExpr = ExprError();
- return true;
- }
+ // It is only correct to resolve to an instance method if we're
+ // resolving a form that's permitted to be a pointer to member.
+ // Otherwise we'll end up making a bound member expression, which
+ // is illegal in all the contexts we resolve like this.
+ if (!ovl.HasFormOfMemberPointer && isa<CXXMethodDecl>(fn) &&
+ cast<CXXMethodDecl>(fn)->isInstance()) {
+ if (!complain)
+ return false;
- // Fix the expression to refer to 'fn'.
- SingleFunctionExpression =
- FixOverloadedFunctionReference(SrcExpr.get(), found, fn);
+ Diag(ovl.Expression->getExprLoc(), diag::err_bound_member_function)
+ << 0 << ovl.Expression->getSourceRange();
- // If desired, do function-to-pointer decay.
- if (doFunctionPointerConversion) {
- SingleFunctionExpression =
- DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.get());
- if (SingleFunctionExpression.isInvalid()) {
+ // TODO: I believe we only end up here if there's a mix of
+ // static and non-static candidates (otherwise the expression
+ // would have 'bound member' type, not 'overload' type).
+ // Ideally we would note which candidate was chosen and why
+ // the static candidates were rejected.
SrcExpr = ExprError();
return true;
}
+
+ // Fix the expression to refer to 'fn'.
+ SingleFunctionExpression = FixOverloadedFunctionReference(
+ SrcExpr.get(), found, fn, ConvertedArgs);
+
+ // If desired, do function-to-pointer decay.
+ if (doFunctionPointerConversion) {
+ SingleFunctionExpression = DefaultFunctionArrayLvalueConversion(
+ SingleFunctionExpression.get());
+ if (SingleFunctionExpression.isInvalid()) {
+ SrcExpr = ExprError();
+ return true;
+ }
+ }
}
}
@@ -13255,7 +13277,8 @@
SemaRef.CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl);
if (SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc()))
return ExprError();
- Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
+ Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl,
+ (*Best)->Deduced);
return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, RParenLoc,
ExecConfig, /*IsExecConfig=*/false,
(*Best)->IsADLCandidate);
@@ -13313,7 +13336,8 @@
// We emitted an error for the unavailable/deleted function call but keep
// the call in the AST.
FunctionDecl *FDecl = (*Best)->Function;
- Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
+ Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl,
+ (*Best)->Deduced);
return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, RParenLoc,
ExecConfig, /*IsExecConfig=*/false,
(*Best)->IsADLCandidate);
@@ -14581,7 +14605,8 @@
if (!Succeeded)
return BuildRecoveryExpr(chooseRecoveryType(CandidateSet, &Best));
- MemExprE = FixOverloadedFunctionReference(MemExprE, FoundDecl, Method);
+ MemExprE = FixOverloadedFunctionReference(MemExprE, FoundDecl, Method,
+ Best->Deduced);
// If overload resolution picked a static member, build a
// non-member call based on that function.
@@ -15196,11 +15221,13 @@
/// perhaps a '&' around it). We have resolved the overloaded function
/// to the function declaration Fn, so patch up the expression E to
/// refer (possibly indirectly) to Fn. Returns the new expr.
-Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
- FunctionDecl *Fn) {
+Expr *
+Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
+ FunctionDecl *Fn,
+ const TemplateArgumentList *Deduced) {
if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
- Expr *SubExpr = FixOverloadedFunctionReference(PE->getSubExpr(),
- Found, Fn);
+ Expr *SubExpr =
+ FixOverloadedFunctionReference(PE->getSubExpr(), Found, Fn, Deduced);
if (SubExpr == PE->getSubExpr())
return PE;
@@ -15208,8 +15235,8 @@
}
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
- Expr *SubExpr = FixOverloadedFunctionReference(ICE->getSubExpr(),
- Found, Fn);
+ Expr *SubExpr =
+ FixOverloadedFunctionReference(ICE->getSubExpr(), Found, Fn, Deduced);
assert(Context.hasSameType(ICE->getSubExpr()->getType(),
SubExpr->getType()) &&
"Implicit cast type cannot be determined from overload");
@@ -15224,8 +15251,8 @@
if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) {
if (!GSE->isResultDependent()) {
- Expr *SubExpr =
- FixOverloadedFunctionReference(GSE->getResultExpr(), Found, Fn);
+ Expr *SubExpr = FixOverloadedFunctionReference(GSE->getResultExpr(),
+ Found, Fn, Deduced);
if (SubExpr == GSE->getResultExpr())
return GSE;
@@ -15259,7 +15286,7 @@
// UnresolvedLookupExpr holding an overloaded member function
// or template.
Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(),
- Found, Fn);
+ Found, Fn, Deduced);
if (SubExpr == UnOp->getSubExpr())
return UnOp;
@@ -15284,8 +15311,8 @@
UnOp->getOperatorLoc(), false, CurFPFeatureOverrides());
}
}
- Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(),
- Found, Fn);
+ Expr *SubExpr =
+ FixOverloadedFunctionReference(UnOp->getSubExpr(), Found, Fn, Deduced);
if (SubExpr == UnOp->getSubExpr())
return UnOp;
@@ -15315,7 +15342,7 @@
DeclRefExpr *DRE = BuildDeclRefExpr(
Fn, Type, ValueKind, ULE->getNameInfo(), ULE->getQualifierLoc(),
- Found.getDecl(), ULE->getTemplateKeywordLoc(), TemplateArgs);
+ Found.getDecl(), ULE->getTemplateKeywordLoc(), TemplateArgs, Deduced);
DRE->setHadMultipleCandidates(ULE->getNumDecls() > 1);
return DRE;
}
@@ -15337,7 +15364,7 @@
DeclRefExpr *DRE = BuildDeclRefExpr(
Fn, Fn->getType(), VK_LValue, MemExpr->getNameInfo(),
MemExpr->getQualifierLoc(), Found.getDecl(),
- MemExpr->getTemplateKeywordLoc(), TemplateArgs);
+ MemExpr->getTemplateKeywordLoc(), TemplateArgs, Deduced);
DRE->setHadMultipleCandidates(MemExpr->getNumDecls() > 1);
return DRE;
} else {
@@ -15370,10 +15397,11 @@
llvm_unreachable("Invalid reference to overloaded function");
}
-ExprResult Sema::FixOverloadedFunctionReference(ExprResult E,
- DeclAccessPair Found,
- FunctionDecl *Fn) {
- return FixOverloadedFunctionReference(E.get(), Found, Fn);
+ExprResult
+Sema::FixOverloadedFunctionReference(ExprResult E, DeclAccessPair Found,
+ FunctionDecl *Fn,
+ const TemplateArgumentList *Deduced) {
+ return FixOverloadedFunctionReference(E.get(), Found, Fn, Deduced);
}
bool clang::shouldEnforceArgLimit(bool PartialOverloading,
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -3594,17 +3594,16 @@
return !Steps.empty() && Steps.back().Kind == SK_ConstructorInitialization;
}
-void
-InitializationSequence
-::AddAddressOverloadResolutionStep(FunctionDecl *Function,
- DeclAccessPair Found,
- bool HadMultipleCandidates) {
+void InitializationSequence ::AddAddressOverloadResolutionStep(
+ FunctionDecl *Function, DeclAccessPair Found,
+ const TemplateArgumentList *ConvertedArgs, bool HadMultipleCandidates) {
Step S;
S.Kind = SK_ResolveAddressOfOverloadedFunction;
S.Type = Function->getType();
S.Function.HadMultipleCandidates = HadMultipleCandidates;
S.Function.Function = Function;
S.Function.FoundDecl = Found;
+ S.Function.ConvertedArgs = ConvertedArgs;
Steps.push_back(S);
}
@@ -4255,13 +4254,12 @@
if (S.Context.getCanonicalType(UnqualifiedSourceType) ==
S.Context.OverloadTy) {
DeclAccessPair Found;
+ const TemplateArgumentList *ConvertedArgs;
bool HadMultipleCandidates = false;
- if (FunctionDecl *Fn
- = S.ResolveAddressOfOverloadedFunction(Initializer,
- UnqualifiedTargetType,
- false, Found,
- &HadMultipleCandidates)) {
- Sequence.AddAddressOverloadResolutionStep(Fn, Found,
+ if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(
+ Initializer, UnqualifiedTargetType, false, Found, ConvertedArgs,
+ &HadMultipleCandidates)) {
+ Sequence.AddAddressOverloadResolutionStep(Fn, Found, ConvertedArgs,
HadMultipleCandidates);
SourceType = Fn->getType();
UnqualifiedSourceType = SourceType.getUnqualifiedType();
@@ -6083,11 +6081,12 @@
AddPassByIndirectCopyRestoreStep(DestType, ShouldCopy);
} else if (ICS.isBad()) {
DeclAccessPair dap;
+ const TemplateArgumentList *ConvertedArgs;
if (isLibstdcxxPointerReturnFalseHack(S, Entity, Initializer)) {
AddZeroInitializationStep(Entity.getType());
} else if (Initializer->getType() == Context.OverloadTy &&
!S.ResolveAddressOfOverloadedFunction(Initializer, DestType,
- false, dap))
+ false, dap, ConvertedArgs))
SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
else if (Initializer->getType()->isFunctionType() &&
isExprAnUnaddressableFunction(S, Initializer))
@@ -8261,9 +8260,9 @@
S.CheckAddressOfMemberAccess(CurInit.get(), Step->Function.FoundDecl);
if (S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation()))
return ExprError();
- CurInit = S.FixOverloadedFunctionReference(CurInit,
- Step->Function.FoundDecl,
- Step->Function.Function);
+ CurInit = S.FixOverloadedFunctionReference(
+ CurInit, Step->Function.FoundDecl, Step->Function.Function,
+ Step->Function.ConvertedArgs);
// We might get back another placeholder expression if we resolved to a
// builtin.
if (!CurInit.isInvalid())
@@ -9136,10 +9135,9 @@
case FK_AddressOfOverloadFailed: {
DeclAccessPair Found;
- S.ResolveAddressOfOverloadedFunction(OnlyArg,
- DestType.getNonReferenceType(),
- true,
- Found);
+ const TemplateArgumentList *ConvertedArgs;
+ S.ResolveAddressOfOverloadedFunction(
+ OnlyArg, DestType.getNonReferenceType(), true, Found, ConvertedArgs);
break;
}
Index: clang/lib/Sema/SemaExprMember.cpp
===================================================================
--- clang/lib/Sema/SemaExprMember.cpp
+++ clang/lib/Sema/SemaExprMember.cpp
@@ -897,12 +897,13 @@
SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl,
bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo,
QualType Ty, ExprValueKind VK, ExprObjectKind OK,
- const TemplateArgumentListInfo *TemplateArgs) {
+ const TemplateArgumentListInfo *TemplateArgs,
+ const TemplateArgumentList *Deduced) {
NestedNameSpecifierLoc NNS =
SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc();
return BuildMemberExpr(Base, IsArrow, OpLoc, NNS, TemplateKWLoc, Member,
FoundDecl, HadMultipleCandidates, MemberNameInfo, Ty,
- VK, OK, TemplateArgs);
+ VK, OK, TemplateArgs, Deduced);
}
MemberExpr *Sema::BuildMemberExpr(
@@ -910,13 +911,14 @@
SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl,
bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo,
QualType Ty, ExprValueKind VK, ExprObjectKind OK,
- const TemplateArgumentListInfo *TemplateArgs) {
+ const TemplateArgumentListInfo *TemplateArgs,
+ const TemplateArgumentList *Deduced) {
assert((!IsArrow || Base->isPRValue()) &&
"-> base must be a pointer prvalue");
- MemberExpr *E =
- MemberExpr::Create(Context, Base, IsArrow, OpLoc, NNS, TemplateKWLoc,
- Member, FoundDecl, MemberNameInfo, TemplateArgs, Ty,
- VK, OK, getNonOdrUseReasonInCurrentContext(Member));
+ MemberExpr *E = MemberExpr::Create(
+ Context, Base, IsArrow, OpLoc, NNS, TemplateKWLoc, Member, FoundDecl,
+ MemberNameInfo, TemplateArgs, Deduced, Ty, VK, OK,
+ getNonOdrUseReasonInCurrentContext(Member));
E->setHadMultipleCandidates(HadMultipleCandidates);
MarkMemberReferenced(E);
@@ -1146,8 +1148,10 @@
return ExprError();
}
- DeclResult VDecl = CheckVarTemplateId(VarTempl, TemplateKWLoc,
- MemberNameInfo.getLoc(), *TemplateArgs);
+ const TemplateArgumentList *ConvertedArgs;
+ DeclResult VDecl =
+ CheckVarTemplateId(VarTempl, TemplateKWLoc, MemberNameInfo.getLoc(),
+ *TemplateArgs, ConvertedArgs);
if (VDecl.isInvalid())
return ExprError();
@@ -1164,7 +1168,7 @@
return BuildMemberExpr(BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc, Var,
FoundDecl, /*HadMultipleCandidates=*/false,
MemberNameInfo, Var->getType().getNonReferenceType(),
- VK_LValue, OK_Ordinary, TemplateArgs);
+ VK_LValue, OK_Ordinary, TemplateArgs, ConvertedArgs);
}
// We found something that we didn't expect. Complain.
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -2774,7 +2774,10 @@
FoundDelete.suppressDiagnostics();
- SmallVector<std::pair<DeclAccessPair,FunctionDecl*>, 2> Matches;
+ SmallVector<
+ std::tuple<DeclAccessPair, FunctionDecl *, const TemplateArgumentList *>,
+ 2>
+ Matches;
// Whether we're looking for a placement operator delete is dictated
// by whether we selected a placement operator new, not by whether
@@ -2824,6 +2827,7 @@
DEnd = FoundDelete.end();
D != DEnd; ++D) {
FunctionDecl *Fn = nullptr;
+ const TemplateArgumentList *ConvertedArgs = nullptr;
if (FunctionTemplateDecl *FnTmpl =
dyn_cast<FunctionTemplateDecl>((*D)->getUnderlyingDecl())) {
// Perform template argument deduction to try to match the
@@ -2832,14 +2836,15 @@
if (DeduceTemplateArguments(FnTmpl, nullptr, ExpectedFunctionType, Fn,
Info))
continue;
+ ConvertedArgs = Info.takeSugared();
} else
Fn = cast<FunctionDecl>((*D)->getUnderlyingDecl());
if (Context.hasSameType(adjustCCAndNoReturn(Fn->getType(),
ExpectedFunctionType,
- /*AdjustExcpetionSpec*/true),
+ /*AdjustExcpetionSpec=*/true),
ExpectedFunctionType))
- Matches.push_back(std::make_pair(D.getPair(), Fn));
+ Matches.push_back({D.getPair(), Fn, ConvertedArgs});
}
if (getLangOpts().CUDA)
@@ -2859,12 +2864,12 @@
/*WantAlign*/ hasNewExtendedAlignment(*this, AllocElemType),
&BestDeallocFns);
if (Selected)
- Matches.push_back(std::make_pair(Selected.Found, Selected.FD));
+ Matches.push_back({Selected.Found, Selected.FD, nullptr});
else {
// If we failed to select an operator, all remaining functions are viable
// but ambiguous.
for (auto Fn : BestDeallocFns)
- Matches.push_back(std::make_pair(Fn.Found, Fn.FD));
+ Matches.push_back({Fn.Found, Fn.FD, nullptr});
}
}
@@ -2873,7 +2878,7 @@
// function, that function will be called; otherwise, no
// deallocation function will be called.
if (Matches.size() == 1) {
- OperatorDelete = Matches[0].second;
+ OperatorDelete = std::get<1>(Matches[0]);
// C++1z [expr.new]p23:
// If the lookup finds a usual deallocation function (3.7.4.2)
@@ -2912,7 +2917,7 @@
}
CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(),
- Matches[0].first);
+ std::get<0>(Matches[0]));
} else if (!Matches.empty()) {
// We found multiple suitable operators. Per [expr.new]p20, that means we
// call no 'operator delete' function, but we should at least warn the user.
@@ -2921,8 +2926,8 @@
<< DeleteName << AllocElemType;
for (auto &Match : Matches)
- Diag(Match.second->getLocation(),
- diag::note_member_declared_here) << DeleteName;
+ Diag(std::get<1>(Match)->getLocation(), diag::note_member_declared_here)
+ << DeleteName;
}
return false;
@@ -4242,15 +4247,16 @@
// Resolve overloaded function references.
if (Context.hasSameType(FromType, Context.OverloadTy)) {
DeclAccessPair Found;
- FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(From, ToType,
- true, Found);
+ const TemplateArgumentList *ConvertedArgs;
+ FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(From, ToType, true,
+ Found, ConvertedArgs);
if (!Fn)
return ExprError();
if (DiagnoseUseOfDecl(Fn, From->getBeginLoc()))
return ExprError();
- From = FixOverloadedFunctionReference(From, Found, Fn);
+ From = FixOverloadedFunctionReference(From, Found, Fn, ConvertedArgs);
// We might get back another placeholder expression if we resolved to a
// builtin.
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -2007,11 +2007,12 @@
const DeclarationNameInfo &NameInfo,
const CXXScopeSpec *SS, NamedDecl *FoundD,
SourceLocation TemplateKWLoc,
- const TemplateArgumentListInfo *TemplateArgs) {
+ const TemplateArgumentListInfo *TemplateArgs,
+ const TemplateArgumentList *ConvertedArgs) {
NestedNameSpecifierLoc NNS =
SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc();
return BuildDeclRefExpr(D, Ty, VK, NameInfo, NNS, FoundD, TemplateKWLoc,
- TemplateArgs);
+ TemplateArgs, ConvertedArgs);
}
// CUDA/HIP: Check whether a captured reference variable is referencing a
@@ -2078,13 +2079,16 @@
const DeclarationNameInfo &NameInfo,
NestedNameSpecifierLoc NNS, NamedDecl *FoundD,
SourceLocation TemplateKWLoc,
- const TemplateArgumentListInfo *TemplateArgs) {
+ const TemplateArgumentListInfo *TemplateArgs,
+ const TemplateArgumentList *ConvertedArgs) {
bool RefersToCapturedVariable = isa<VarDecl, BindingDecl>(D) &&
NeedToCaptureVariable(D, NameInfo.getLoc());
- DeclRefExpr *E = DeclRefExpr::Create(
- Context, NNS, TemplateKWLoc, D, RefersToCapturedVariable, NameInfo, Ty,
- VK, FoundD, TemplateArgs, getNonOdrUseReasonInCurrentContext(D));
+ assert(!TemplateArgs || ConvertedArgs);
+ DeclRefExpr *E = DeclRefExpr::Create(Context, NNS, TemplateKWLoc, D,
+ RefersToCapturedVariable, NameInfo, Ty,
+ VK, FoundD, TemplateArgs, ConvertedArgs,
+ getNonOdrUseReasonInCurrentContext(D));
MarkDeclRefReferenced(E);
// C++ [except.spec]p17:
@@ -3223,7 +3227,7 @@
!R.getAsSingle<FunctionTemplateDecl>() &&
!ShouldLookupResultBeMultiVersionOverload(R))
return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), R.getFoundDecl(),
- R.getRepresentativeDecl(), nullptr,
+ R.getRepresentativeDecl(), nullptr, nullptr,
AcceptInvalidDecl);
// We only need to check the declaration if there's exactly one
@@ -3256,10 +3260,11 @@
ExprResult Sema::BuildDeclarationNameExpr(
const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D,
NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs,
- bool AcceptInvalidDecl) {
+ const TemplateArgumentList *ConvertedArgs, bool AcceptInvalidDecl) {
assert(D && "Cannot refer to a NULL declaration");
assert(!isa<FunctionTemplateDecl>(D) &&
"Cannot refer unambiguously to a function template");
+ assert(!TemplateArgs || ConvertedArgs);
SourceLocation Loc = NameInfo.getLoc();
if (CheckDeclInExpr(*this, Loc, D)) {
@@ -3496,7 +3501,7 @@
return BuildDeclRefExpr(VD, type, valueKind, NameInfo, &SS, FoundD,
/*FIXME: TemplateKWLoc*/ SourceLocation(),
- TemplateArgs);
+ TemplateArgs, ConvertedArgs);
}
static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,
@@ -6748,7 +6753,7 @@
Fn = DeclRefExpr::Create(
Context, FDecl->getQualifierLoc(), SourceLocation(), FDecl, false,
SourceLocation(), FDecl->getType(), Fn->getValueKind(), FDecl,
- nullptr, DRE->isNonOdrUse());
+ nullptr, nullptr, DRE->isNonOdrUse());
}
}
} else if (isa<MemberExpr>(NakedFn))
@@ -9964,9 +9969,10 @@
// As a set of extensions to C, we support overloading on functions. These
// functions need to be resolved here.
DeclAccessPair DAP;
+ const TemplateArgumentList *ConvertedArgs;
if (FunctionDecl *FD = ResolveAddressOfOverloadedFunction(
- RHS.get(), LHSType, /*Complain=*/false, DAP))
- RHS = FixOverloadedFunctionReference(RHS.get(), DAP, FD);
+ RHS.get(), LHSType, /*Complain=*/false, DAP, ConvertedArgs))
+ RHS = FixOverloadedFunctionReference(RHS.get(), DAP, FD, ConvertedArgs);
else
return Incompatible;
}
@@ -14257,14 +14263,19 @@
}
OverloadExpr *Ovl = cast<OverloadExpr>(E);
- if (isa<UnresolvedMemberExpr>(Ovl))
- if (!ResolveSingleFunctionTemplateSpecialization(Ovl)) {
- Diag(OpLoc, diag::err_invalid_form_pointer_member_function)
- << OrigOp.get()->getSourceRange();
- return QualType();
- }
-
- return Context.OverloadTy;
+ if (!isa<UnresolvedMemberExpr>(Ovl))
+ return Context.OverloadTy;
+ if (Ovl->hasExplicitTemplateArgs()) {
+ TemplateArgumentListInfo ExplicitTemplateArgs;
+ Ovl->copyTemplateArgumentsInto(ExplicitTemplateArgs);
+ const TemplateArgumentList *ConvertedArgs;
+ if (ResolveSingleFunctionTemplateSpecialization(
+ Ovl, ExplicitTemplateArgs, ConvertedArgs))
+ return Context.OverloadTy;
+ }
+ Diag(OpLoc, diag::err_invalid_form_pointer_member_function)
+ << OrigOp.get()->getSourceRange();
+ return QualType();
}
if (PTy->getKind() == BuiltinType::UnknownAny)
@@ -19140,7 +19151,8 @@
S.Context, DRE->getQualifierLoc(), DRE->getTemplateKeywordLoc(),
DRE->getDecl(), DRE->refersToEnclosingVariableOrCapture(),
DRE->getNameInfo(), DRE->getType(), DRE->getValueKind(),
- DRE->getFoundDecl(), CopiedTemplateArgs(DRE), NOUR);
+ DRE->getFoundDecl(), CopiedTemplateArgs(DRE), DRE->getConvertedArgs(),
+ NOUR);
}
case Expr::FunctionParmPackExprClass: {
@@ -19186,8 +19198,8 @@
S.Context, Base.get(), ME->isArrow(), ME->getOperatorLoc(),
ME->getQualifierLoc(), ME->getTemplateKeywordLoc(),
ME->getMemberDecl(), ME->getFoundDecl(), ME->getMemberNameInfo(),
- CopiedTemplateArgs(ME), ME->getType(), ME->getValueKind(),
- ME->getObjectKind(), ME->isNonOdrUse());
+ CopiedTemplateArgs(ME), ME->getDeduced(), ME->getType(),
+ ME->getValueKind(), ME->getObjectKind(), ME->isNonOdrUse());
}
if (ME->getMemberDecl()->isCXXInstanceMember())
@@ -19204,7 +19216,8 @@
S.Context, ME->getBase(), ME->isArrow(), ME->getOperatorLoc(),
ME->getQualifierLoc(), ME->getTemplateKeywordLoc(), ME->getMemberDecl(),
ME->getFoundDecl(), ME->getMemberNameInfo(), CopiedTemplateArgs(ME),
- ME->getType(), ME->getValueKind(), ME->getObjectKind(), NOUR);
+ ME->getDeduced(), ME->getType(), ME->getValueKind(),
+ ME->getObjectKind(), NOUR);
}
case Expr::BinaryOperatorClass: {
@@ -20748,7 +20761,8 @@
FD, FD->getType(), VK_LValue, DRE->getNameInfo(),
DRE->hasQualifier() ? &SS : nullptr, DRE->getFoundDecl(),
DRE->getTemplateKeywordLoc(),
- DRE->hasExplicitTemplateArgs() ? &TemplateArgs : nullptr);
+ DRE->hasExplicitTemplateArgs() ? &TemplateArgs : nullptr,
+ DRE->getConvertedArgs());
}
}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -3599,9 +3599,14 @@
return;
}
} else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
- if (ULE->hasExplicitTemplateArgs())
+ if (ULE->hasExplicitTemplateArgs()) {
S.Diag(Loc, diag::warn_cleanup_ext);
- FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
+ TemplateArgumentListInfo ExplicitTemplateArgs;
+ const TemplateArgumentList *ConvertedArgs;
+ ULE->copyTemplateArgumentsInto(ExplicitTemplateArgs);
+ FD = S.ResolveSingleFunctionTemplateSpecialization(
+ ULE, ExplicitTemplateArgs, ConvertedArgs, /*Complain=*/true);
+ }
NI = ULE->getNameInfo();
if (!FD) {
S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -6899,7 +6899,7 @@
DeclRefExpr *NewDRE = DeclRefExpr::Create(
Context, DRE->getQualifierLoc(), SourceLocation(), NewBuiltinDecl,
/*enclosing*/ false, DRE->getLocation(), Context.BuiltinFnTy,
- DRE->getValueKind(), nullptr, nullptr, DRE->isNonOdrUse());
+ DRE->getValueKind(), nullptr, nullptr, nullptr, DRE->isNonOdrUse());
// Set the callee in the CallExpr.
// FIXME: This loses syntactic information.
Index: clang/lib/Sema/SemaCast.cpp
===================================================================
--- clang/lib/Sema/SemaCast.cpp
+++ clang/lib/Sema/SemaCast.cpp
@@ -1720,9 +1720,9 @@
bool WasOverloadedFunction = false;
DeclAccessPair FoundOverload;
if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
- if (FunctionDecl *Fn
- = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), DestType, false,
- FoundOverload)) {
+ const TemplateArgumentList *ConvertedArgs;
+ if (FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(
+ SrcExpr.get(), DestType, false, FoundOverload, ConvertedArgs)) {
CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);
SrcType = Self.Context.getMemberPointerType(Fn->getType(),
Self.Context.getTypeDeclType(M->getParent()).getTypePtr());
@@ -1799,16 +1799,16 @@
if (WasOverloadedFunction) {
// Resolve the address of the overloaded function again, this time
// allowing complaints if something goes wrong.
- FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),
- DestType,
- true,
- FoundOverload);
+ const TemplateArgumentList *ConvertedArgs;
+ FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(
+ SrcExpr.get(), DestType, true, FoundOverload, ConvertedArgs);
if (!Fn) {
msg = 0;
return TC_Failed;
}
- SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn);
+ SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn,
+ ConvertedArgs);
if (!SrcExpr.isUsable()) {
msg = 0;
return TC_Failed;
@@ -2773,10 +2773,10 @@
if (tcr != TC_Success && msg != 0) {
if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
DeclAccessPair Found;
- FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),
- DestType,
- /*Complain*/ true,
- Found);
+ const TemplateArgumentList *ConvertedArgs;
+ FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(
+ SrcExpr.get(), DestType,
+ /*Complain*/ true, Found, ConvertedArgs);
if (Fn) {
// If DestType is a function type (not to be confused with the function
// pointer type), it will be possible to resolve the function address,
@@ -2882,10 +2882,12 @@
// Overloads are allowed with C extensions, so we need to support them.
if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
+ const TemplateArgumentList *ConvertedArgs;
DeclAccessPair DAP;
if (FunctionDecl *FD = Self.ResolveAddressOfOverloadedFunction(
- SrcExpr.get(), DestType, /*Complain=*/true, DAP))
- SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr.get(), DAP, FD);
+ SrcExpr.get(), DestType, /*Complain=*/true, DAP, ConvertedArgs))
+ SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr.get(), DAP, FD,
+ ConvertedArgs);
else
return;
assert(SrcExpr.isUsable());
Index: clang/lib/Sema/SemaCUDA.cpp
===================================================================
--- clang/lib/Sema/SemaCUDA.cpp
+++ clang/lib/Sema/SemaCUDA.cpp
@@ -271,25 +271,28 @@
void Sema::EraseUnwantedCUDAMatches(
const FunctionDecl *Caller,
- SmallVectorImpl<std::pair<DeclAccessPair, FunctionDecl *>> &Matches) {
+ SmallVectorImpl<std::tuple<DeclAccessPair, FunctionDecl *,
+ const TemplateArgumentList *>> &Matches) {
if (Matches.size() <= 1)
return;
- using Pair = std::pair<DeclAccessPair, FunctionDecl*>;
+ using Tuple =
+ std::tuple<DeclAccessPair, FunctionDecl *, const TemplateArgumentList *>;
// Gets the CUDA function preference for a call from Caller to Match.
- auto GetCFP = [&](const Pair &Match) {
- return IdentifyCUDAPreference(Caller, Match.second);
+ auto GetCFP = [&](const Tuple &Match) {
+ return IdentifyCUDAPreference(Caller, std::get<1>(Match));
};
// Find the best call preference among the functions in Matches.
CUDAFunctionPreference BestCFP = GetCFP(*std::max_element(
- Matches.begin(), Matches.end(),
- [&](const Pair &M1, const Pair &M2) { return GetCFP(M1) < GetCFP(M2); }));
+ Matches.begin(), Matches.end(), [&](const Tuple &M1, const Tuple &M2) {
+ return GetCFP(M1) < GetCFP(M2);
+ }));
// Erase all functions with lower priority.
llvm::erase_if(Matches,
- [&](const Pair &Match) { return GetCFP(Match) < BestCFP; });
+ [&](const Tuple &Match) { return GetCFP(Match) < BestCFP; });
}
/// When an implicitly-declared special member has to invoke more than one
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -1603,7 +1603,8 @@
return DeclRefExpr::Create(
CGF.getContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
/*RefersToEnclosingVariableOrCapture=*/false, ME->getExprLoc(),
- ME->getType(), ME->getValueKind(), nullptr, nullptr, ME->isNonOdrUse());
+ ME->getType(), ME->getValueKind(), nullptr, nullptr, nullptr,
+ ME->isNonOdrUse());
}
return nullptr;
}
Index: clang/lib/Analysis/BodyFarm.cpp
===================================================================
--- clang/lib/Analysis/BodyFarm.cpp
+++ clang/lib/Analysis/BodyFarm.cpp
@@ -230,8 +230,8 @@
C, base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(),
SourceLocation(), MemberDecl, FoundDecl,
DeclarationNameInfo(MemberDecl->getDeclName(), SourceLocation()),
- /* TemplateArgumentListInfo=*/ nullptr, MemberDecl->getType(), ValueKind,
- OK_Ordinary, NOUR_None);
+ /* TemplateArgumentListInfo=*/nullptr, /*Deduced=*/nullptr,
+ MemberDecl->getType(), ValueKind, OK_Ordinary, NOUR_None);
}
ValueDecl *ASTMaker::findMemberField(const RecordDecl *RD, StringRef Name) {
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -401,7 +401,8 @@
ExprValueKind VK, SourceLocation L,
const DeclarationNameLoc &LocInfo,
NonOdrUseReason NOUR)
- : Expr(DeclRefExprClass, T, VK, OK_Ordinary), D(D), DNLoc(LocInfo) {
+ : Expr(DeclRefExprClass, T, VK, OK_Ordinary), D(D), ConvertedArgs(nullptr),
+ DNLoc(LocInfo) {
DeclRefExprBits.HasQualifier = false;
DeclRefExprBits.HasTemplateKWAndArgsInfo = false;
DeclRefExprBits.HasFoundDecl = false;
@@ -419,9 +420,12 @@
bool RefersToEnclosingVariableOrCapture,
const DeclarationNameInfo &NameInfo, NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
- QualType T, ExprValueKind VK, NonOdrUseReason NOUR)
+ const TemplateArgumentList *ConvertedArgs, QualType T,
+ ExprValueKind VK, NonOdrUseReason NOUR)
: Expr(DeclRefExprClass, T, VK, OK_Ordinary), D(D),
- DNLoc(NameInfo.getInfo()) {
+ ConvertedArgs(ConvertedArgs), DNLoc(NameInfo.getInfo()) {
+ assert(!TemplateArgs || ConvertedArgs);
+ assert(!ConvertedArgs || ConvertedArgs->size() != 0);
DeclRefExprBits.Loc = NameInfo.getLoc();
DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
if (QualifierLoc)
@@ -457,22 +461,21 @@
SourceLocation NameLoc, QualType T,
ExprValueKind VK, NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
+ const TemplateArgumentList *ConvertedArgs,
NonOdrUseReason NOUR) {
return Create(Context, QualifierLoc, TemplateKWLoc, D,
RefersToEnclosingVariableOrCapture,
- DeclarationNameInfo(D->getDeclName(), NameLoc),
- T, VK, FoundD, TemplateArgs, NOUR);
+ DeclarationNameInfo(D->getDeclName(), NameLoc), T, VK, FoundD,
+ TemplateArgs, ConvertedArgs, NOUR);
}
-DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, ValueDecl *D,
- bool RefersToEnclosingVariableOrCapture,
- const DeclarationNameInfo &NameInfo,
- QualType T, ExprValueKind VK,
- NamedDecl *FoundD,
- const TemplateArgumentListInfo *TemplateArgs,
- NonOdrUseReason NOUR) {
+DeclRefExpr *DeclRefExpr::Create(
+ const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, ValueDecl *D,
+ bool RefersToEnclosingVariableOrCapture,
+ const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
+ NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs,
+ const TemplateArgumentList *ConvertedArgs, NonOdrUseReason NOUR) {
// Filter out cases where the found Decl is the same as the value refenenced.
if (D == FoundD)
FoundD = nullptr;
@@ -486,9 +489,10 @@
TemplateArgs ? TemplateArgs->size() : 0);
void *Mem = Context.Allocate(Size, alignof(DeclRefExpr));
- return new (Mem) DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D,
- RefersToEnclosingVariableOrCapture, NameInfo,
- FoundD, TemplateArgs, T, VK, NOUR);
+ return new (Mem)
+ DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D,
+ RefersToEnclosingVariableOrCapture, NameInfo, FoundD,
+ TemplateArgs, ConvertedArgs, T, VK, NOUR);
}
DeclRefExpr *DeclRefExpr::CreateEmpty(const ASTContext &Context,
@@ -1612,11 +1616,13 @@
MemberExpr::MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc,
ValueDecl *MemberDecl,
- const DeclarationNameInfo &NameInfo, QualType T,
+ const DeclarationNameInfo &NameInfo,
+ const TemplateArgumentList *Deduced, QualType T,
ExprValueKind VK, ExprObjectKind OK,
NonOdrUseReason NOUR)
: Expr(MemberExprClass, T, VK, OK), Base(Base), MemberDecl(MemberDecl),
- MemberDNLoc(NameInfo.getInfo()), MemberLoc(NameInfo.getLoc()) {
+ Deduced(Deduced), MemberDNLoc(NameInfo.getInfo()),
+ MemberLoc(NameInfo.getLoc()) {
assert(!NameInfo.getName() ||
MemberDecl->getDeclName() == NameInfo.getName());
MemberExprBits.IsArrow = IsArrow;
@@ -1633,7 +1639,8 @@
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
ValueDecl *MemberDecl, DeclAccessPair FoundDecl,
DeclarationNameInfo NameInfo, const TemplateArgumentListInfo *TemplateArgs,
- QualType T, ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR) {
+ const TemplateArgumentList *Deduced, QualType T, ExprValueKind VK,
+ ExprObjectKind OK, NonOdrUseReason NOUR) {
bool HasQualOrFound = QualifierLoc || FoundDecl.getDecl() != MemberDecl ||
FoundDecl.getAccess() != MemberDecl->getAccess();
bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid();
@@ -1645,7 +1652,7 @@
void *Mem = C.Allocate(Size, alignof(MemberExpr));
MemberExpr *E = new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, MemberDecl,
- NameInfo, T, VK, OK, NOUR);
+ NameInfo, Deduced, T, VK, OK, NOUR);
// FIXME: remove remaining dependence computation to computeDependence().
auto Deps = E->getDependence();
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -7041,6 +7041,7 @@
auto ToQualifierLoc = importChecked(Err, E->getQualifierLoc());
auto ToTemplateKeywordLoc = importChecked(Err, E->getTemplateKeywordLoc());
auto ToDecl = importChecked(Err, E->getDecl());
+ auto ToConvertedArgs = importChecked(Err, E->getConvertedArgs());
auto ToLocation = importChecked(Err, E->getLocation());
auto ToType = importChecked(Err, E->getType());
if (Err)
@@ -7067,7 +7068,8 @@
auto *ToE = DeclRefExpr::Create(
Importer.getToContext(), ToQualifierLoc, ToTemplateKeywordLoc, ToDecl,
E->refersToEnclosingVariableOrCapture(), ToLocation, ToType,
- E->getValueKind(), ToFoundD, ToResInfo, E->isNonOdrUse());
+ E->getValueKind(), ToFoundD, ToResInfo, ToConvertedArgs,
+ E->isNonOdrUse());
if (E->hadMultipleCandidates())
ToE->setHadMultipleCandidates(true);
return ToE;
@@ -7951,6 +7953,7 @@
auto ToQualifierLoc = importChecked(Err, E->getQualifierLoc());
auto ToTemplateKeywordLoc = importChecked(Err, E->getTemplateKeywordLoc());
auto ToMemberDecl = importChecked(Err, E->getMemberDecl());
+ auto ToDeduced = importChecked(Err, E->getDeduced());
auto ToType = importChecked(Err, E->getType());
auto ToDecl = importChecked(Err, E->getFoundDecl().getDecl());
auto ToName = importChecked(Err, E->getMemberNameInfo().getName());
@@ -7975,7 +7978,7 @@
return MemberExpr::Create(Importer.getToContext(), ToBase, E->isArrow(),
ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc,
ToMemberDecl, ToFoundDecl, ToMemberNameInfo,
- ResInfo, ToType, E->getValueKind(),
+ ResInfo, ToDeduced, ToType, E->getValueKind(),
E->getObjectKind(), E->isNonOdrUse());
}
@@ -9655,6 +9658,17 @@
return Importer.ImportAPValue(FromValue);
}
+llvm::Expected<TemplateArgumentList *>
+ASTImporter::Import(const TemplateArgumentList *ArgList) {
+ ASTNodeImporter Importer(*this);
+ if (!ArgList)
+ return nullptr;
+ SmallVector<TemplateArgument, 4> ToArgs(ArgList->size());
+ if (auto Res = Importer.ImportTemplateArguments(ArgList->asArray(), ToArgs))
+ return std::move(Res);
+ return TemplateArgumentList::CreateCopy(ToContext, ToArgs);
+}
+
Error ASTImporter::ImportDefinition(Decl *From) {
ExpectedDecl ToOrErr = Import(From);
if (!ToOrErr)
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -3885,7 +3885,8 @@
bool AllowExplicitConversion = false,
ADLCallKind IsADLCandidate = ADLCallKind::NotADL,
ConversionSequenceList EarlyConversions = None,
- OverloadCandidateParamOrder PO = {});
+ OverloadCandidateParamOrder PO = {},
+ const TemplateArgumentList *Deduced = nullptr);
void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
ArrayRef<Expr *> Args,
OverloadCandidateSet &CandidateSet,
@@ -3900,16 +3901,16 @@
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversion = false,
OverloadCandidateParamOrder PO = {});
- void AddMethodCandidate(CXXMethodDecl *Method,
- DeclAccessPair FoundDecl,
+ void AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext, QualType ObjectType,
Expr::Classification ObjectClassification,
ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
+ OverloadCandidateSet &CandidateSet,
bool SuppressUserConversions = false,
bool PartialOverloading = false,
ConversionSequenceList EarlyConversions = None,
- OverloadCandidateParamOrder PO = {});
+ OverloadCandidateParamOrder PO = {},
+ const TemplateArgumentList *Deduced = nullptr);
void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
@@ -4033,10 +4034,9 @@
QualType ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType);
FunctionDecl *
- ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr,
- QualType TargetType,
- bool Complain,
- DeclAccessPair &Found,
+ ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, QualType TargetType,
+ bool Complain, DeclAccessPair &Found,
+ const TemplateArgumentList *&ConvertedArgs,
bool *pHadMultipleCandidates = nullptr);
FunctionDecl *
@@ -4045,10 +4045,10 @@
bool resolveAndFixAddressOfSingleOverloadCandidate(
ExprResult &SrcExpr, bool DoFunctionPointerConversion = false);
- FunctionDecl *
- ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
- bool Complain = false,
- DeclAccessPair *Found = nullptr);
+ FunctionDecl *ResolveSingleFunctionTemplateSpecialization(
+ OverloadExpr *ovl, TemplateArgumentListInfo &ExplicitTemplateArgs,
+ const TemplateArgumentList *&ConvertedArgs, bool Complain = false,
+ DeclAccessPair *Found = nullptr);
bool ResolveAndFixSingleFunctionTemplateSpecialization(
ExprResult &SrcExpr, bool DoFunctionPointerConversion = false,
@@ -4056,12 +4056,13 @@
QualType DestTypeForComplaining = QualType(),
unsigned DiagIDForComplaining = 0);
- Expr *FixOverloadedFunctionReference(Expr *E,
- DeclAccessPair FoundDecl,
- FunctionDecl *Fn);
- ExprResult FixOverloadedFunctionReference(ExprResult,
- DeclAccessPair FoundDecl,
- FunctionDecl *Fn);
+ Expr *FixOverloadedFunctionReference(Expr *E, DeclAccessPair FoundDecl,
+ FunctionDecl *Fn,
+ const TemplateArgumentList *Deduced);
+ ExprResult
+ FixOverloadedFunctionReference(ExprResult, DeclAccessPair FoundDecl,
+ FunctionDecl *Fn,
+ const TemplateArgumentList *Deduced);
void AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
ArrayRef<Expr *> Args,
@@ -5472,14 +5473,15 @@
const CXXScopeSpec *SS = nullptr,
NamedDecl *FoundD = nullptr,
SourceLocation TemplateKWLoc = SourceLocation(),
- const TemplateArgumentListInfo *TemplateArgs = nullptr);
+ const TemplateArgumentListInfo *TemplateArgs = nullptr,
+ const TemplateArgumentList *ConvertedArgs = nullptr);
DeclRefExpr *
BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
const DeclarationNameInfo &NameInfo,
- NestedNameSpecifierLoc NNS,
- NamedDecl *FoundD = nullptr,
+ NestedNameSpecifierLoc NNS, NamedDecl *FoundD = nullptr,
SourceLocation TemplateKWLoc = SourceLocation(),
- const TemplateArgumentListInfo *TemplateArgs = nullptr);
+ const TemplateArgumentListInfo *TemplateArgs = nullptr,
+ const TemplateArgumentList *ConvertedArgs = nullptr);
ExprResult
BuildAnonymousStructUnionMemberReference(
@@ -5523,6 +5525,7 @@
const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D,
NamedDecl *FoundD = nullptr,
const TemplateArgumentListInfo *TemplateArgs = nullptr,
+ const TemplateArgumentList *ConvertedArgs = nullptr,
bool AcceptInvalidDecl = false);
ExprResult BuildLiteralOperatorCall(LookupResult &R,
@@ -5706,22 +5709,20 @@
UnqualifiedId &Member,
Decl *ObjCImpDecl);
- MemberExpr *
- BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc,
- const CXXScopeSpec *SS, SourceLocation TemplateKWLoc,
- ValueDecl *Member, DeclAccessPair FoundDecl,
- bool HadMultipleCandidates,
- const DeclarationNameInfo &MemberNameInfo, QualType Ty,
- ExprValueKind VK, ExprObjectKind OK,
- const TemplateArgumentListInfo *TemplateArgs = nullptr);
- MemberExpr *
- BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc,
- NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
- ValueDecl *Member, DeclAccessPair FoundDecl,
- bool HadMultipleCandidates,
- const DeclarationNameInfo &MemberNameInfo, QualType Ty,
- ExprValueKind VK, ExprObjectKind OK,
- const TemplateArgumentListInfo *TemplateArgs = nullptr);
+ MemberExpr *BuildMemberExpr(
+ Expr *Base, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec *SS,
+ SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl,
+ bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo,
+ QualType Ty, ExprValueKind VK, ExprObjectKind OK,
+ const TemplateArgumentListInfo *TemplateArgs = nullptr,
+ const TemplateArgumentList *Deduced = nullptr);
+ MemberExpr *BuildMemberExpr(
+ Expr *Base, bool IsArrow, SourceLocation OpLoc,
+ NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
+ ValueDecl *Member, DeclAccessPair FoundDecl, bool HadMultipleCandidates,
+ const DeclarationNameInfo &MemberNameInfo, QualType Ty, ExprValueKind VK,
+ ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs = nullptr,
+ const TemplateArgumentList *Deduced = nullptr);
void ActOnDefaultCtorInitializers(Decl *CDtorDecl);
bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
@@ -7992,7 +7993,8 @@
DeclResult CheckVarTemplateId(VarTemplateDecl *Template,
SourceLocation TemplateLoc,
SourceLocation TemplateNameLoc,
- const TemplateArgumentListInfo &TemplateArgs);
+ const TemplateArgumentListInfo &TemplateArgs,
+ const TemplateArgumentList *&ConvertedArgs);
/// Form a reference to the specialization of the given variable template
/// corresponding to the specified argument list, or a null-but-valid result
@@ -12799,7 +12801,8 @@
/// calling priority.
void EraseUnwantedCUDAMatches(
const FunctionDecl *Caller,
- SmallVectorImpl<std::pair<DeclAccessPair, FunctionDecl *>> &Matches);
+ SmallVectorImpl<std::tuple<DeclAccessPair, FunctionDecl *,
+ const TemplateArgumentList *>> &Matches);
/// Given a implicit special member, infer its CUDA target from the
/// calls it needs to make to underlying base/field special members.
Index: clang/include/clang/Sema/Overload.h
===================================================================
--- clang/include/clang/Sema/Overload.h
+++ clang/include/clang/Sema/Overload.h
@@ -885,6 +885,9 @@
StandardConversionSequence FinalConversion;
};
+ /// Deduced Arguments for Function Templates.
+ const TemplateArgumentList *Deduced;
+
/// Get RewriteKind value in OverloadCandidateRewriteKind type (This
/// function is to workaround the spurious GCC bitfield enum warning)
OverloadCandidateRewriteKind getRewriteKind() const {
Index: clang/include/clang/Sema/Initialization.h
===================================================================
--- clang/include/clang/Sema/Initialization.h
+++ clang/include/clang/Sema/Initialization.h
@@ -939,6 +939,7 @@
bool HadMultipleCandidates;
FunctionDecl *Function;
DeclAccessPair FoundDecl;
+ const TemplateArgumentList *ConvertedArgs;
};
union {
@@ -1237,9 +1238,10 @@
///
/// \param Function the function to which the overloaded function reference
/// resolves.
- void AddAddressOverloadResolutionStep(FunctionDecl *Function,
- DeclAccessPair Found,
- bool HadMultipleCandidates);
+ void
+ AddAddressOverloadResolutionStep(FunctionDecl *Function, DeclAccessPair Found,
+ const TemplateArgumentList *ConvertedArgs,
+ bool HadMultipleCandidates);
/// Add a new step in the initialization that performs a derived-to-
/// base cast.
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -1232,6 +1232,8 @@
/// The declaration that we are referencing.
ValueDecl *D;
+ const TemplateArgumentList *ConvertedArgs;
+
/// Provides source/type location info for the declaration name
/// embedded in D.
DeclarationNameLoc DNLoc;
@@ -1256,7 +1258,8 @@
SourceLocation TemplateKWLoc, ValueDecl *D,
bool RefersToEnlosingVariableOrCapture,
const DeclarationNameInfo &NameInfo, NamedDecl *FoundD,
- const TemplateArgumentListInfo *TemplateArgs, QualType T,
+ const TemplateArgumentListInfo *TemplateArgs,
+ const TemplateArgumentList *ConvertedArgs, QualType T,
ExprValueKind VK, NonOdrUseReason NOUR);
/// Construct an empty declaration reference expression.
@@ -1275,6 +1278,7 @@
bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc,
QualType T, ExprValueKind VK, NamedDecl *FoundD = nullptr,
const TemplateArgumentListInfo *TemplateArgs = nullptr,
+ const TemplateArgumentList *ConvertedArgs = nullptr,
NonOdrUseReason NOUR = NOUR_None);
static DeclRefExpr *
@@ -1284,6 +1288,7 @@
const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
NamedDecl *FoundD = nullptr,
const TemplateArgumentListInfo *TemplateArgs = nullptr,
+ const TemplateArgumentList *ConvertedArgs = nullptr,
NonOdrUseReason NOUR = NOUR_None);
/// Construct an empty declaration reference expression.
@@ -1391,6 +1396,8 @@
return getTrailingObjects<TemplateArgumentLoc>();
}
+ const TemplateArgumentList *getConvertedArgs() const { return ConvertedArgs; }
+
/// Retrieve the number of template arguments provided as part of this
/// template-id.
unsigned getNumTemplateArgs() const {
@@ -3175,6 +3182,8 @@
/// In X.F, this is the decl referenced by F.
ValueDecl *MemberDecl;
+ const TemplateArgumentList *Deduced;
+
/// MemberDNLoc - Provides source/type location info for the
/// declaration name embedded in MemberDecl.
DeclarationNameLoc MemberDNLoc;
@@ -3200,21 +3209,20 @@
MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc,
ValueDecl *MemberDecl, const DeclarationNameInfo &NameInfo,
- QualType T, ExprValueKind VK, ExprObjectKind OK,
- NonOdrUseReason NOUR);
+ const TemplateArgumentList *Deduced, QualType T, ExprValueKind VK,
+ ExprObjectKind OK, NonOdrUseReason NOUR);
MemberExpr(EmptyShell Empty)
: Expr(MemberExprClass, Empty), Base(), MemberDecl() {}
public:
- static MemberExpr *Create(const ASTContext &C, Expr *Base, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, ValueDecl *MemberDecl,
- DeclAccessPair FoundDecl,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- QualType T, ExprValueKind VK, ExprObjectKind OK,
- NonOdrUseReason NOUR);
+ static MemberExpr *
+ Create(const ASTContext &C, Expr *Base, bool IsArrow,
+ SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, ValueDecl *MemberDecl,
+ DeclAccessPair FoundDecl, DeclarationNameInfo MemberNameInfo,
+ const TemplateArgumentListInfo *TemplateArgs,
+ const TemplateArgumentList *Deduced, QualType T, ExprValueKind VK,
+ ExprObjectKind OK, NonOdrUseReason NOUR);
/// Create an implicit MemberExpr, with no location, qualifier, template
/// arguments, and so on. Suitable only for non-static member access.
@@ -3225,7 +3233,8 @@
return Create(C, Base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(),
SourceLocation(), MemberDecl,
DeclAccessPair::make(MemberDecl, MemberDecl->getAccess()),
- DeclarationNameInfo(), nullptr, T, VK, OK, NOUR_None);
+ DeclarationNameInfo(), nullptr, nullptr, T, VK, OK,
+ NOUR_None);
}
static MemberExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier,
@@ -3251,6 +3260,8 @@
return getTrailingObjects<MemberExprNameQualifier>()->FoundDecl;
}
+ const TemplateArgumentList *getDeduced() const { return Deduced; }
+
/// Determines whether this member expression actually had
/// a C++ nested-name-specifier prior to the name of the member, e.g.,
/// x->Base::foo.
Index: clang/include/clang/AST/ASTImporter.h
===================================================================
--- clang/include/clang/AST/ASTImporter.h
+++ clang/include/clang/AST/ASTImporter.h
@@ -480,6 +480,13 @@
/// error.
llvm::Expected<APValue> Import(const APValue &FromValue);
+ /// Import the given C++ TemplateArgumentList from the "from"
+ /// context into the "to" context.
+ ///
+ /// \returns The equivalent initializer in the "to" context, or the import
+ /// error.
+ llvm::Expected<TemplateArgumentList *> Import(const TemplateArgumentList *);
+
/// Import the definition of the given declaration, including all of
/// the declarations it contains.
[[nodiscard]] llvm::Error ImportDefinition(Decl *From);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits