Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions clang/include/clang/AST/ASTImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,13 @@ class TypeSourceInfo;
/// 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);
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ class TemplateArgumentList final

/// Create a new template argument list that copies the given set of
/// template arguments.
static TemplateArgumentList *CreateCopy(ASTContext &Context,
static TemplateArgumentList *CreateCopy(const ASTContext &Context,
ArrayRef<TemplateArgument> Args);

/// Retrieve the template argument at a given index.
Expand Down
38 changes: 25 additions & 13 deletions clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,8 @@ class DeclRefExpr final
/// 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;
Expand All @@ -1298,7 +1300,8 @@ class DeclRefExpr final
SourceLocation TemplateKWLoc, ValueDecl *D,
bool RefersToEnclosingVariableOrCapture,
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.
Expand All @@ -1317,6 +1320,7 @@ class DeclRefExpr final
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 *
Expand All @@ -1326,6 +1330,7 @@ class DeclRefExpr final
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.
Expand Down Expand Up @@ -1433,6 +1438,8 @@ class DeclRefExpr final
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 {
Expand Down Expand Up @@ -3248,6 +3255,8 @@ class MemberExpr final
/// 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;
Expand Down Expand Up @@ -3277,21 +3286,21 @@ class MemberExpr final
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
ValueDecl *MemberDecl, DeclAccessPair FoundDecl,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs, QualType T,
ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR);
const TemplateArgumentListInfo *TemplateArgs,
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.
Expand All @@ -3302,7 +3311,8 @@ class MemberExpr final
return Create(C, Base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(),
SourceLocation(), MemberDecl,
DeclAccessPair::make(MemberDecl, MemberDecl->getAccess()),
DeclarationNameInfo(), nullptr, T, VK, OK, NOUR_None);
DeclarationNameInfo(), nullptr, /*Deduced=*/{}, T, VK, OK,
NOUR_None);
}

static MemberExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier,
Expand All @@ -3328,6 +3338,8 @@ class MemberExpr final
return *getTrailingObjects<DeclAccessPair>();
}

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.
Expand Down
8 changes: 5 additions & 3 deletions clang/include/clang/Sema/Initialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,7 @@ class InitializationSequence {
bool HadMultipleCandidates;
FunctionDecl *Function;
DeclAccessPair FoundDecl;
const TemplateArgumentList *ConvertedArgs;
};

union {
Expand Down Expand Up @@ -1262,9 +1263,10 @@ class InitializationSequence {
///
/// \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.
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Sema/Overload.h
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,9 @@ class Sema;
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 {
Expand Down
45 changes: 28 additions & 17 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -6856,7 +6856,8 @@ class Sema final : public SemaBase {
const CXXScopeSpec *SS = nullptr,
NamedDecl *FoundD = nullptr,
SourceLocation TemplateKWLoc = SourceLocation(),
const TemplateArgumentListInfo *TemplateArgs = nullptr);
const TemplateArgumentListInfo *TemplateArgs = nullptr,
const TemplateArgumentList *ConvertArgs = nullptr);

/// BuildDeclRefExpr - Build an expression that references a
/// declaration that does not require a closure capture.
Expand All @@ -6865,7 +6866,8 @@ class Sema final : public SemaBase {
const DeclarationNameInfo &NameInfo,
NestedNameSpecifierLoc NNS, NamedDecl *FoundD = nullptr,
SourceLocation TemplateKWLoc = SourceLocation(),
const TemplateArgumentListInfo *TemplateArgs = nullptr);
const TemplateArgumentListInfo *TemplateArgs = nullptr,
const TemplateArgumentList *ConvertArgs = nullptr);

bool UseArgumentDependentLookup(const CXXScopeSpec &SS, const LookupResult &R,
bool HasTrailingLParen);
Expand All @@ -6887,6 +6889,7 @@ class Sema final : public SemaBase {
const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D,
NamedDecl *FoundD = nullptr,
const TemplateArgumentListInfo *TemplateArgs = nullptr,
const TemplateArgumentList *ConvertedArgs = nullptr,
bool AcceptInvalidDecl = false);

// ExpandFunctionLocalPredefinedMacros - Returns a new vector of Tokens,
Expand Down Expand Up @@ -8700,14 +8703,13 @@ class Sema final : public SemaBase {
SourceLocation TemplateKWLoc,
UnqualifiedId &Member, Decl *ObjCImpDecl);

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,
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);

// Check whether the declarations we found through a nested-name
// specifier in a member expression are actually members of the base
Expand Down Expand Up @@ -10299,6 +10301,7 @@ class Sema final : public SemaBase {
ADLCallKind IsADLCandidate = ADLCallKind::NotADL,
ConversionSequenceList EarlyConversions = {},
OverloadCandidateParamOrder PO = {},
const TemplateArgumentList *Deduced = nullptr,
bool AggregateCandidateDeduction = false, bool StrictPackMatch = false);

/// Add all of the function declarations in the given function set to
Expand Down Expand Up @@ -10335,6 +10338,7 @@ class Sema final : public SemaBase {
bool PartialOverloading = false,
ConversionSequenceList EarlyConversions = {},
OverloadCandidateParamOrder PO = {},
const TemplateArgumentList *Deduced = nullptr,
bool StrictPackMatch = false);

/// Add a C++ member function template as a candidate to the candidate
Expand Down Expand Up @@ -10543,6 +10547,7 @@ class Sema final : public SemaBase {
FunctionDecl *
ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, QualType TargetType,
bool Complain, DeclAccessPair &Found,
const TemplateArgumentList *&ConvertedArgs,
bool *pHadMultipleCandidates = nullptr);

/// Given an expression that refers to an overloaded function, try to
Expand Down Expand Up @@ -10576,7 +10581,9 @@ class Sema final : public SemaBase {
/// If no template-ids are found, no diagnostics are emitted and NULL is
/// returned.
FunctionDecl *ResolveSingleFunctionTemplateSpecialization(
OverloadExpr *ovl, bool Complain = false, DeclAccessPair *Found = nullptr,
OverloadExpr *ovl, TemplateArgumentListInfo &ExplicitTemplateArgs,
const TemplateArgumentList *&ConvertedArgs, bool Complain = false,
DeclAccessPair *Found = nullptr,
TemplateSpecCandidateSet *FailedTSC = nullptr,
bool ForTypeDeduction = false);

Expand Down Expand Up @@ -10761,11 +10768,14 @@ class Sema final : public SemaBase {
/// 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.
ExprResult FixOverloadedFunctionReference(Expr *E, DeclAccessPair FoundDecl,
FunctionDecl *Fn);
ExprResult FixOverloadedFunctionReference(ExprResult,
DeclAccessPair FoundDecl,
FunctionDecl *Fn);
ExprResult
FixOverloadedFunctionReference(Expr *E, DeclAccessPair FoundDecl,
FunctionDecl *Fn,
const TemplateArgumentList *Deduced);
ExprResult
FixOverloadedFunctionReference(ExprResult, DeclAccessPair FoundDecl,
FunctionDecl *Fn,
const TemplateArgumentList *Deduced);

/// - Returns a selector which best matches given argument list or
/// nullptr if none could be found
Expand Down Expand Up @@ -11545,7 +11555,8 @@ class Sema final : public SemaBase {
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
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Sema/SemaCUDA.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ class SemaCUDA : public SemaBase {
/// calling priority.
void EraseUnwantedMatches(
const FunctionDecl *Caller,
llvm::SmallVectorImpl<std::pair<DeclAccessPair, FunctionDecl *>>
&Matches);
llvm::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.
Expand Down
18 changes: 16 additions & 2 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7493,6 +7493,7 @@ ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
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)
Expand All @@ -7519,7 +7520,8 @@ ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
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);
ToE->setIsImmediateEscalating(E->isImmediateEscalating());
Expand Down Expand Up @@ -8444,6 +8446,7 @@ ExpectedStmt ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
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());
Expand All @@ -8468,7 +8471,7 @@ ExpectedStmt ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
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());
}

Expand Down Expand Up @@ -10174,6 +10177,17 @@ llvm::Expected<APValue> ASTImporter::Import(const APValue &FromValue) {
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)
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/DeclTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,7 @@ TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
}

TemplateArgumentList *
TemplateArgumentList::CreateCopy(ASTContext &Context,
TemplateArgumentList::CreateCopy(const ASTContext &Context,
ArrayRef<TemplateArgument> Args) {
void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
return new (Mem) TemplateArgumentList(Args);
Expand Down
Loading
Loading