From e4b92761b43ced611c417ae478568610f1ad7b1e Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Fri, 27 Jan 2012 09:46:47 +0000 Subject: [PATCH] Added source location for the template keyword in AST template-id expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149127 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Expr.h | 191 ++++++++++------- include/clang/AST/ExprCXX.h | 306 +++++++++++++++------------- include/clang/AST/Stmt.h | 2 +- include/clang/AST/TemplateBase.h | 37 +++- include/clang/Parse/Parser.h | 7 +- include/clang/Sema/ParsedTemplate.h | 6 +- include/clang/Sema/Sema.h | 26 ++- lib/AST/ASTImporter.cpp | 1 + lib/AST/Expr.cpp | 57 ++++-- lib/AST/ExprCXX.cpp | 129 +++++++----- lib/AST/StmtPrinter.cpp | 21 +- lib/AST/TemplateBase.cpp | 39 +++- lib/Parse/ParseDecl.cpp | 2 + lib/Parse/ParseDeclCXX.cpp | 10 +- lib/Parse/ParseExpr.cpp | 15 +- lib/Parse/ParseExprCXX.cpp | 104 +++++----- lib/Parse/ParseStmt.cpp | 2 +- lib/Parse/ParseTemplate.cpp | 9 +- lib/Parse/Parser.cpp | 10 +- lib/Sema/SemaCXXScopeSpec.cpp | 8 +- lib/Sema/SemaChecking.cpp | 1 + lib/Sema/SemaCodeComplete.cpp | 4 +- lib/Sema/SemaDecl.cpp | 8 +- lib/Sema/SemaDeclAttr.cpp | 4 +- lib/Sema/SemaDeclCXX.cpp | 23 ++- lib/Sema/SemaExpr.cpp | 42 ++-- lib/Sema/SemaExprCXX.cpp | 9 +- lib/Sema/SemaExprMember.cpp | 42 ++-- lib/Sema/SemaOverload.cpp | 11 +- lib/Sema/SemaStmt.cpp | 4 +- lib/Sema/SemaTemplate.cpp | 23 ++- lib/Sema/SemaType.cpp | 7 +- lib/Sema/TreeTransform.h | 75 ++++--- lib/Serialization/ASTReaderStmt.cpp | 68 ++++--- lib/Serialization/ASTWriterStmt.cpp | 64 +++--- tools/libclang/CIndex.cpp | 2 +- 36 files changed, 833 insertions(+), 536 deletions(-) diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 0029f183a7..591640d30c 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -746,9 +746,9 @@ public: /// Specifies when this declaration reference expression has a record of /// a NamedDecl (different from the referenced ValueDecl) which was found /// during name lookup and/or overload resolution. -/// DeclRefExprBits.HasExplicitTemplateArgs: +/// DeclRefExprBits.HasTemplateKWAndArgsInfo: /// Specifies when this declaration reference expression has an explicit -/// C++ template argument list. +/// C++ template keyword and/or template argument list. class DeclRefExpr : public Expr { /// \brief The declaration that we are referencing. ValueDecl *D; @@ -791,6 +791,7 @@ class DeclRefExpr : public Expr { } DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, ValueDecl *D, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, @@ -810,7 +811,7 @@ public: : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false), D(D), Loc(L), DNLoc(LocInfo) { DeclRefExprBits.HasQualifier = 0; - DeclRefExprBits.HasExplicitTemplateArgs = 0; + DeclRefExprBits.HasTemplateKWAndArgsInfo = 0; DeclRefExprBits.HasFoundDecl = 0; DeclRefExprBits.HadMultipleCandidates = 0; computeDependence(); @@ -818,6 +819,7 @@ public: static DeclRefExpr *Create(ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, ValueDecl *D, SourceLocation NameLoc, QualType T, ExprValueKind VK, @@ -826,6 +828,7 @@ public: static DeclRefExpr *Create(ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, ValueDecl *D, const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK, @@ -836,7 +839,7 @@ public: static DeclRefExpr *CreateEmpty(ASTContext &Context, bool HasQualifier, bool HasFoundDecl, - bool HasExplicitTemplateArgs, + bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); ValueDecl *getDecl() { return D; } @@ -888,25 +891,65 @@ public: return hasFoundDecl() ? getInternalFoundDecl() : D; } - /// \brief Determines whether this declaration reference was followed by an - /// explict template argument list. - bool hasExplicitTemplateArgs() const { - return DeclRefExprBits.HasExplicitTemplateArgs; + bool hasTemplateKWAndArgsInfo() const { + return DeclRefExprBits.HasTemplateKWAndArgsInfo; } - /// \brief Retrieve the explicit template argument list that followed the - /// member template name. - ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { - assert(hasExplicitTemplateArgs()); + /// \brief Return the optional template keyword and arguments info. + ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { + if (!hasTemplateKWAndArgsInfo()) + return 0; + if (hasFoundDecl()) - return *reinterpret_cast( + return reinterpret_cast( &getInternalFoundDecl() + 1); if (hasQualifier()) - return *reinterpret_cast( + return reinterpret_cast( &getInternalQualifierLoc() + 1); - return *reinterpret_cast(this + 1); + return reinterpret_cast(this + 1); + } + + /// \brief Return the optional template keyword and arguments info. + const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { + return const_cast(this)->getTemplateKWAndArgsInfo(); + } + + /// \brief Retrieve the location of the template keyword preceding + /// this name, if any. + SourceLocation getTemplateKeywordLoc() const { + if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); + return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc(); + } + + /// \brief Retrieve the location of the left angle bracket starting the + /// explicit template argument list following the name, if any. + SourceLocation getLAngleLoc() const { + if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); + return getTemplateKWAndArgsInfo()->LAngleLoc; + } + + /// \brief Retrieve the location of the right angle bracket ending the + /// explicit template argument list following the name, if any. + SourceLocation getRAngleLoc() const { + if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); + return getTemplateKWAndArgsInfo()->RAngleLoc; + } + + /// \brief Determines whether the name in this declaration reference + /// was preceded by the template keyword. + bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } + + /// \brief Determines whether this declaration reference was followed by an + /// explicit template argument list. + bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } + + /// \brief Retrieve the explicit template argument list that followed the + /// member template name. + ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { + assert(hasExplicitTemplateArgs()); + return *getTemplateKWAndArgsInfo(); } /// \brief Retrieve the explicit template argument list that followed the @@ -918,7 +961,7 @@ public: /// \brief Retrieves the optional explicit template arguments. /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. - const ASTTemplateArgumentListInfo *getExplicitTemplateArgsOpt() const { + const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { if (!hasExplicitTemplateArgs()) return 0; return &getExplicitTemplateArgs(); } @@ -930,15 +973,6 @@ public: getExplicitTemplateArgs().copyInto(List); } - /// \brief Retrieve the location of the left angle bracket following the - /// member name ('<'), if any. - SourceLocation getLAngleLoc() const { - if (!hasExplicitTemplateArgs()) - return SourceLocation(); - - return getExplicitTemplateArgs().LAngleLoc; - } - /// \brief Retrieve the template arguments provided as part of this /// template-id. const TemplateArgumentLoc *getTemplateArgs() const { @@ -957,15 +991,6 @@ public: return getExplicitTemplateArgs().NumTemplateArgs; } - /// \brief Retrieve the location of the right angle bracket following the - /// template arguments ('>'). - SourceLocation getRAngleLoc() const { - if (!hasExplicitTemplateArgs()) - return SourceLocation(); - - return getExplicitTemplateArgs().RAngleLoc; - } - /// \brief Returns true if this expression refers to a function that /// was resolved from an overloaded set having size greater than 1. bool hadMultipleCandidates() const { @@ -2139,12 +2164,14 @@ class MemberExpr : public Expr { /// structure is allocated immediately after the MemberExpr. bool HasQualifierOrFoundDecl : 1; - /// \brief True if this member expression specified a template argument list - /// explicitly, e.g., x->f. When true, an ExplicitTemplateArgumentList - /// structure (and its TemplateArguments) are allocated immediately after - /// the MemberExpr or, if the member expression also has a qualifier, after - /// the MemberNameQualifier structure. - bool HasExplicitTemplateArgumentList : 1; + /// \brief True if this member expression specified a template keyword + /// and/or a template argument list explicitly, e.g., x->f, + /// x->template f, x->template f. + /// When true, an ASTTemplateKWAndArgsInfo structure and its + /// TemplateArguments (if any) are allocated immediately after + /// the MemberExpr or, if the member expression also has a qualifier, + /// after the MemberNameQualifier structure. + bool HasTemplateKWAndArgsInfo : 1; /// \brief True if this member expression refers to a method that /// was resolved from an overloaded set having size greater than 1. @@ -2172,7 +2199,7 @@ public: base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()), MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow), - HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false), + HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) { assert(memberdecl->getDeclName() == NameInfo.getName()); } @@ -2180,7 +2207,7 @@ public: // NOTE: this constructor should be used only when it is known that // the member name can not provide additional syntactic info // (i.e., source locations for C++ operator names or type source info - // for constructors, destructors and conversion oeprators). + // for constructors, destructors and conversion operators). MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl, SourceLocation l, QualType ty, ExprValueKind VK, ExprObjectKind OK) @@ -2190,11 +2217,12 @@ public: base->containsUnexpandedParameterPack()), Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(), IsArrow(isarrow), - HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false), + HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) {} static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, ValueDecl *memberdecl, DeclAccessPair founddecl, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *targs, @@ -2243,12 +2271,51 @@ public: return getMemberQualifier()->QualifierLoc; } - /// \brief Determines whether this member expression actually had a C++ - /// template argument list explicitly specified, e.g., x.f. - bool hasExplicitTemplateArgs() const { - return HasExplicitTemplateArgumentList; + /// \brief Return the optional template keyword and arguments info. + ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { + if (!HasTemplateKWAndArgsInfo) + return 0; + + if (!HasQualifierOrFoundDecl) + return reinterpret_cast(this + 1); + + return reinterpret_cast( + getMemberQualifier() + 1); + } + + /// \brief Return the optional template keyword and arguments info. + const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { + return const_cast(this)->getTemplateKWAndArgsInfo(); + } + + /// \brief Retrieve the location of the template keyword preceding + /// the member name, if any. + SourceLocation getTemplateKeywordLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc(); + } + + /// \brief Retrieve the location of the left angle bracket starting the + /// explicit template argument list following the member name, if any. + SourceLocation getLAngleLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->LAngleLoc; + } + + /// \brief Retrieve the location of the right angle bracket ending the + /// explicit template argument list following the member name, if any. + SourceLocation getRAngleLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->RAngleLoc; } + /// Determines whether the member name was preceded by the template keyword. + bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } + + /// \brief Determines whether the member name was followed by an + /// explicit template argument list. + bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } + /// \brief Copies the template arguments (if present) into the given /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { @@ -2260,12 +2327,8 @@ public: /// follow the member template name. This must only be called on an /// expression with explicit template arguments. ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { - assert(HasExplicitTemplateArgumentList); - if (!HasQualifierOrFoundDecl) - return *reinterpret_cast(this + 1); - - return *reinterpret_cast( - getMemberQualifier() + 1); + assert(hasExplicitTemplateArgs()); + return *getTemplateKWAndArgsInfo(); } /// \brief Retrieve the explicit template argument list that @@ -2283,19 +2346,10 @@ public: return &getExplicitTemplateArgs(); } - /// \brief Retrieve the location of the left angle bracket following the - /// member name ('<'), if any. - SourceLocation getLAngleLoc() const { - if (!HasExplicitTemplateArgumentList) - return SourceLocation(); - - return getExplicitTemplateArgs().LAngleLoc; - } - /// \brief Retrieve the template arguments provided as part of this /// template-id. const TemplateArgumentLoc *getTemplateArgs() const { - if (!HasExplicitTemplateArgumentList) + if (!hasExplicitTemplateArgs()) return 0; return getExplicitTemplateArgs().getTemplateArgs(); @@ -2304,21 +2358,12 @@ public: /// \brief Retrieve the number of template arguments provided as part of this /// template-id. unsigned getNumTemplateArgs() const { - if (!HasExplicitTemplateArgumentList) + if (!hasExplicitTemplateArgs()) return 0; return getExplicitTemplateArgs().NumTemplateArgs; } - /// \brief Retrieve the location of the right angle bracket following the - /// template arguments ('>'). - SourceLocation getRAngleLoc() const { - if (!HasExplicitTemplateArgumentList) - return SourceLocation(); - - return getExplicitTemplateArgs().RAngleLoc; - } - /// \brief Retrieve the member declaration name info. DeclarationNameInfo getMemberNameInfo() const { return DeclarationNameInfo(MemberDecl->getDeclName(), diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 9d07e051ad..fcc417ad1d 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1778,11 +1778,21 @@ class OverloadExpr : public Expr { NestedNameSpecifierLoc QualifierLoc; protected: - /// True if the name was a template-id. - bool HasExplicitTemplateArgs; + /// \brief Whether the name includes info for explicit template + /// keyword and arguments. + bool HasTemplateKWAndArgsInfo; + + /// \brief Return the optional template keyword and arguments info. + ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo(); // defined far below. + + /// \brief Return the optional template keyword and arguments info. + const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { + return const_cast(this)->getTemplateKWAndArgsInfo(); + } OverloadExpr(StmtClass K, ASTContext &C, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, @@ -1792,7 +1802,7 @@ protected: OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty), Results(0), NumResults(0), - QualifierLoc(), HasExplicitTemplateArgs(false) { } + QualifierLoc(), HasTemplateKWAndArgsInfo(false) { } void initializeResults(ASTContext &C, UnresolvedSetIterator Begin, @@ -1863,16 +1873,59 @@ public: /// one was given. NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } - /// \brief Determines whether this expression had an explicit - /// template argument list, e.g. f. - bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } + /// \brief Retrieve the location of the template keyword preceding + /// this name, if any. + SourceLocation getTemplateKeywordLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc(); + } + + /// \brief Retrieve the location of the left angle bracket starting the + /// explicit template argument list following the name, if any. + SourceLocation getLAngleLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->LAngleLoc; + } + + /// \brief Retrieve the location of the right angle bracket ending the + /// explicit template argument list following the name, if any. + SourceLocation getRAngleLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->RAngleLoc; + } - ASTTemplateArgumentListInfo &getExplicitTemplateArgs(); // defined far below + /// Determines whether the name was preceded by the template keyword. + bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } + + /// Determines whether this expression had explicit template arguments. + bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } + + // Note that, inconsistently with the explicit-template-argument AST + // nodes, users are *forbidden* from calling these methods on objects + // without explicit template arguments. + + ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { + assert(hasExplicitTemplateArgs()); + return *getTemplateKWAndArgsInfo(); + } const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { return const_cast(this)->getExplicitTemplateArgs(); } + TemplateArgumentLoc const *getTemplateArgs() const { + return getExplicitTemplateArgs().getTemplateArgs(); + } + + unsigned getNumTemplateArgs() const { + return getExplicitTemplateArgs().NumTemplateArgs; + } + + /// Copies the template arguments into the given structure. + void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { + getExplicitTemplateArgs().copyInto(List); + } + /// \brief Retrieves the optional explicit template arguments. /// This points to the same data as getExplicitTemplateArgs(), but /// returns null if there are no explicit template arguments. @@ -1925,13 +1978,14 @@ class UnresolvedLookupExpr : public OverloadExpr { UnresolvedLookupExpr(ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool StdIsAssociatedNamespace) - : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, NameInfo, - TemplateArgs, Begin, End, false, false, false), + : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc, + NameInfo, TemplateArgs, Begin, End, false, false, false), RequiresADL(RequiresADL), StdIsAssociatedNamespace(StdIsAssociatedNamespace), Overloaded(Overloaded), NamingClass(NamingClass) @@ -1956,7 +2010,8 @@ public: bool StdIsAssociatedNamespace = false) { assert((ADL || !StdIsAssociatedNamespace) && "std considered associated namespace when not performing ADL"); - return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, NameInfo, + return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, + SourceLocation(), NameInfo, ADL, Overloaded, 0, Begin, End, StdIsAssociatedNamespace); } @@ -1964,6 +2019,7 @@ public: static UnresolvedLookupExpr *Create(ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, bool ADL, const TemplateArgumentListInfo &Args, @@ -1971,7 +2027,7 @@ public: UnresolvedSetIterator End); static UnresolvedLookupExpr *CreateEmpty(ASTContext &C, - bool HasExplicitTemplateArgs, + bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); /// True if this declaration should be extended by @@ -1990,51 +2046,6 @@ public: /// that was looked in to find these results. CXXRecordDecl *getNamingClass() const { return NamingClass; } - // Note that, inconsistently with the explicit-template-argument AST - // nodes, users are *forbidden* from calling these methods on objects - // without explicit template arguments. - - ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { - assert(hasExplicitTemplateArgs()); - return *reinterpret_cast(this + 1); - } - - /// Gets a reference to the explicit template argument list. - const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { - assert(hasExplicitTemplateArgs()); - return *reinterpret_cast(this + 1); - } - - /// \brief Retrieves the optional explicit template arguments. - /// This points to the same data as getExplicitTemplateArgs(), but - /// returns null if there are no explicit template arguments. - const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() { - if (!hasExplicitTemplateArgs()) return 0; - return &getExplicitTemplateArgs(); - } - - /// \brief Copies the template arguments (if present) into the given - /// structure. - void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { - getExplicitTemplateArgs().copyInto(List); - } - - SourceLocation getLAngleLoc() const { - return getExplicitTemplateArgs().LAngleLoc; - } - - SourceLocation getRAngleLoc() const { - return getExplicitTemplateArgs().RAngleLoc; - } - - TemplateArgumentLoc const *getTemplateArgs() const { - return getExplicitTemplateArgs().getTemplateArgs(); - } - - unsigned getNumTemplateArgs() const { - return getExplicitTemplateArgs().NumTemplateArgs; - } - SourceRange getSourceRange() const { SourceRange Range(getNameInfo().getSourceRange()); if (getQualifierLoc()) @@ -2074,22 +2085,36 @@ class DependentScopeDeclRefExpr : public Expr { /// The name of the entity we will be referencing. DeclarationNameInfo NameInfo; - /// \brief Whether the name includes explicit template arguments. - bool HasExplicitTemplateArgs; + /// \brief Whether the name includes info for explicit template + /// keyword and arguments. + bool HasTemplateKWAndArgsInfo; + + /// \brief Return the optional template keyword and arguments info. + ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { + if (!HasTemplateKWAndArgsInfo) return 0; + return reinterpret_cast(this + 1); + } + /// \brief Return the optional template keyword and arguments info. + const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { + return const_cast(this) + ->getTemplateKWAndArgsInfo(); + } DependentScopeDeclRefExpr(QualType T, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *Args); public: static DependentScopeDeclRefExpr *Create(ASTContext &C, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, - const TemplateArgumentListInfo *TemplateArgs = 0); + const TemplateArgumentListInfo *TemplateArgs); static DependentScopeDeclRefExpr *CreateEmpty(ASTContext &C, - bool HasExplicitTemplateArgs, + bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); /// \brief Retrieve the name that this expression refers to. @@ -2112,8 +2137,32 @@ public: return QualifierLoc.getNestedNameSpecifier(); } + /// \brief Retrieve the location of the template keyword preceding + /// this name, if any. + SourceLocation getTemplateKeywordLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc(); + } + + /// \brief Retrieve the location of the left angle bracket starting the + /// explicit template argument list following the name, if any. + SourceLocation getLAngleLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->LAngleLoc; + } + + /// \brief Retrieve the location of the right angle bracket ending the + /// explicit template argument list following the name, if any. + SourceLocation getRAngleLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->RAngleLoc; + } + + /// Determines whether the name was preceded by the template keyword. + bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } + /// Determines whether this lookup had explicit template arguments. - bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } + bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } // Note that, inconsistently with the explicit-template-argument AST // nodes, users are *forbidden* from calling these methods on objects @@ -2144,14 +2193,6 @@ public: getExplicitTemplateArgs().copyInto(List); } - SourceLocation getLAngleLoc() const { - return getExplicitTemplateArgs().LAngleLoc; - } - - SourceLocation getRAngleLoc() const { - return getExplicitTemplateArgs().RAngleLoc; - } - TemplateArgumentLoc const *getTemplateArgs() const { return getExplicitTemplateArgs().getTemplateArgs(); } @@ -2387,9 +2428,9 @@ class CXXDependentScopeMemberExpr : public Expr { /// the '.' operator. bool IsArrow : 1; - /// \brief Whether this member expression has explicitly-specified template - /// arguments. - bool HasExplicitTemplateArgs : 1; + /// \brief Whether this member expression has info for explicit template + /// keyword and arguments. + bool HasTemplateKWAndArgsInfo : 1; /// \brief The location of the '->' or '.' operator. SourceLocation OperatorLoc; @@ -2411,10 +2452,22 @@ class CXXDependentScopeMemberExpr : public Expr { /// FIXME: could also be a template-id DeclarationNameInfo MemberNameInfo; + /// \brief Return the optional template keyword and arguments info. + ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { + if (!HasTemplateKWAndArgsInfo) return 0; + return reinterpret_cast(this + 1); + } + /// \brief Return the optional template keyword and arguments info. + const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { + return const_cast(this) + ->getTemplateKWAndArgsInfo(); + } + CXXDependentScopeMemberExpr(ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs); @@ -2433,12 +2486,13 @@ public: Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs); static CXXDependentScopeMemberExpr * - CreateEmpty(ASTContext &C, bool HasExplicitTemplateArgs, + CreateEmpty(ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); /// \brief True if this is an implicit access, i.e. one in which the @@ -2502,16 +2556,38 @@ public: // expression refers to. SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); } + /// \brief Retrieve the location of the template keyword preceding the + /// member name, if any. + SourceLocation getTemplateKeywordLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc(); + } + + /// \brief Retrieve the location of the left angle bracket starting the + /// explicit template argument list following the member name, if any. + SourceLocation getLAngleLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->LAngleLoc; + } + + /// \brief Retrieve the location of the right angle bracket ending the + /// explicit template argument list following the member name, if any. + SourceLocation getRAngleLoc() const { + if (!HasTemplateKWAndArgsInfo) return SourceLocation(); + return getTemplateKWAndArgsInfo()->RAngleLoc; + } + + /// Determines whether the member name was preceded by the template keyword. + bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } + /// \brief Determines whether this member expression actually had a C++ /// template argument list explicitly specified, e.g., x.f. - bool hasExplicitTemplateArgs() const { - return HasExplicitTemplateArgs; - } + bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } /// \brief Retrieve the explicit template argument list that followed the /// member template name, if any. ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { - assert(HasExplicitTemplateArgs); + assert(hasExplicitTemplateArgs()); return *reinterpret_cast(this + 1); } @@ -2541,12 +2617,6 @@ public: getExplicitTemplateArgs().initializeFrom(List); } - /// \brief Retrieve the location of the left angle bracket following the - /// member name ('<'), if any. - SourceLocation getLAngleLoc() const { - return getExplicitTemplateArgs().LAngleLoc; - } - /// \brief Retrieve the template arguments provided as part of this /// template-id. const TemplateArgumentLoc *getTemplateArgs() const { @@ -2559,12 +2629,6 @@ public: return getExplicitTemplateArgs().NumTemplateArgs; } - /// \brief Retrieve the location of the right angle bracket following the - /// template arguments ('>'). - SourceLocation getRAngleLoc() const { - return getExplicitTemplateArgs().RAngleLoc; - } - SourceRange getSourceRange() const { SourceRange Range; if (!isImplicitAccess()) @@ -2633,6 +2697,7 @@ class UnresolvedMemberExpr : public OverloadExpr { Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End); @@ -2649,12 +2714,13 @@ public: Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End); static UnresolvedMemberExpr * - CreateEmpty(ASTContext &C, bool HasExplicitTemplateArgs, + CreateEmpty(ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs); /// \brief True if this is an implicit access, i.e. one in which the @@ -2701,57 +2767,6 @@ public: // expression refers to. SourceLocation getMemberLoc() const { return getNameLoc(); } - /// \brief Retrieve the explicit template argument list that followed the - /// member template name. - ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { - assert(hasExplicitTemplateArgs()); - return *reinterpret_cast(this + 1); - } - - /// \brief Retrieve the explicit template argument list that followed the - /// member template name, if any. - const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { - assert(hasExplicitTemplateArgs()); - return *reinterpret_cast(this + 1); - } - - /// \brief Retrieves the optional explicit template arguments. - /// This points to the same data as getExplicitTemplateArgs(), but - /// returns null if there are no explicit template arguments. - const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() { - if (!hasExplicitTemplateArgs()) return 0; - return &getExplicitTemplateArgs(); - } - - /// \brief Copies the template arguments into the given structure. - void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { - getExplicitTemplateArgs().copyInto(List); - } - - /// \brief Retrieve the location of the left angle bracket following - /// the member name ('<'). - SourceLocation getLAngleLoc() const { - return getExplicitTemplateArgs().LAngleLoc; - } - - /// \brief Retrieve the template arguments provided as part of this - /// template-id. - const TemplateArgumentLoc *getTemplateArgs() const { - return getExplicitTemplateArgs().getTemplateArgs(); - } - - /// \brief Retrieve the number of template arguments provided as - /// part of this template-id. - unsigned getNumTemplateArgs() const { - return getExplicitTemplateArgs().NumTemplateArgs; - } - - /// \brief Retrieve the location of the right angle bracket - /// following the template arguments ('>'). - SourceLocation getRAngleLoc() const { - return getExplicitTemplateArgs().RAngleLoc; - } - SourceRange getSourceRange() const { SourceRange Range = getMemberNameInfo().getSourceRange(); if (!isImplicitAccess()) @@ -2896,11 +2911,14 @@ public: } }; -inline ASTTemplateArgumentListInfo &OverloadExpr::getExplicitTemplateArgs() { +inline ASTTemplateKWAndArgsInfo *OverloadExpr::getTemplateKWAndArgsInfo() { + if (!HasTemplateKWAndArgsInfo) return 0; if (isa(this)) - return cast(this)->getExplicitTemplateArgs(); + return reinterpret_cast + (cast(this) + 1); else - return cast(this)->getExplicitTemplateArgs(); + return reinterpret_cast + (cast(this) + 1); } /// \brief Represents an expression that computes the length of a parameter diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 1a1dc67550..3a300d1b10 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -165,7 +165,7 @@ protected: unsigned : NumExprBits; unsigned HasQualifier : 1; - unsigned HasExplicitTemplateArgs : 1; + unsigned HasTemplateKWAndArgsInfo : 1; unsigned HasFoundDecl : 1; unsigned HadMultipleCandidates : 1; }; diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 371c27a0d2..f56b8df307 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -589,7 +589,42 @@ struct ASTTemplateArgumentListInfo { bool &ContainsUnexpandedParameterPack); void copyInto(TemplateArgumentListInfo &List) const; static std::size_t sizeFor(unsigned NumTemplateArgs); - static std::size_t sizeFor(const TemplateArgumentListInfo &List); +}; + +/// \brief Extends ASTTemplateArgumentListInfo with the source location +/// information for the template keyword; this is used as part of the +/// representation of qualified identifiers, such as S::template apply. +struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo { + typedef ASTTemplateArgumentListInfo Base; + + // NOTE: the source location of the (optional) template keyword is + // stored after all template arguments. + + /// \brief Get the source location of the template keyword. + SourceLocation getTemplateKeywordLoc() const { + return *reinterpret_cast + (getTemplateArgs() + NumTemplateArgs); + } + + /// \brief Sets the source location of the template keyword. + void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) { + *reinterpret_cast + (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc; + } + + static const ASTTemplateKWAndArgsInfo* + Create(ASTContext &C, SourceLocation TemplateKWLoc, + const TemplateArgumentListInfo &List); + + void initializeFrom(SourceLocation TemplateKWLoc, + const TemplateArgumentListInfo &List); + void initializeFrom(SourceLocation TemplateKWLoc, + const TemplateArgumentListInfo &List, + bool &Dependent, bool &InstantiationDependent, + bool &ContainsUnexpandedParameterPack); + void initializeFrom(SourceLocation TemplateKWLoc); + + static std::size_t sizeFor(unsigned NumTemplateArgs); }; const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index ca71047fe4..6221cfb1d4 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -2065,13 +2065,13 @@ private: AccessSpecifier getAccessSpecifierIfPresent() const; bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, IdentifierInfo *Name, SourceLocation NameLoc, bool EnteringContext, ParsedType ObjectType, UnqualifiedId &Id, - bool AssumeTemplateId, - SourceLocation TemplateKWLoc); + bool AssumeTemplateId); bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, ParsedType ObjectType, UnqualifiedId &Result); @@ -2079,6 +2079,7 @@ private: bool AllowDestructorName, bool AllowConstructorName, ParsedType ObjectType, + SourceLocation& TemplateKWLoc, UnqualifiedId &Result); //===--------------------------------------------------------------------===// @@ -2124,8 +2125,8 @@ private: bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, UnqualifiedId &TemplateName, - SourceLocation TemplateKWLoc = SourceLocation(), bool AllowTypeAnnotation = true); void AnnotateTemplateIdTokenAsType(); bool IsTemplateArgumentList(unsigned Skip = 0); diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h index 735a26bd7b..3ff045954b 100644 --- a/include/clang/Sema/ParsedTemplate.h +++ b/include/clang/Sema/ParsedTemplate.h @@ -141,7 +141,11 @@ namespace clang { struct TemplateIdAnnotation { /// \brief The nested-name-specifier that precedes the template name. CXXScopeSpec SS; - + + /// TemplateKWLoc - The location of the template keyword within the + /// source. + SourceLocation TemplateKWLoc; + /// TemplateNameLoc - The location of the template name within the /// source. SourceLocation TemplateNameLoc; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 69f16d7456..e5e86772c5 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2292,7 +2292,9 @@ public: // Primary Expressions. SourceRange getExprRange(Expr *E) const; - ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, UnqualifiedId &Id, + ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, + UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, CorrectionCandidateCallback *CCC = 0); @@ -2311,6 +2313,7 @@ public: bool AllowBuiltinCreation=false); ExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, bool isAddressOfOperand, const TemplateArgumentListInfo *TemplateArgs); @@ -2330,9 +2333,11 @@ public: Expr *baseObjectExpr = 0, SourceLocation opLoc = SourceLocation()); ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs); ExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, bool IsDefiniteInstance); @@ -2341,8 +2346,10 @@ public: bool HasTrailingLParen); ExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo); ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs); @@ -2423,6 +2430,7 @@ public: ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs); @@ -2430,6 +2438,7 @@ public: ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, @@ -2449,6 +2458,7 @@ public: ExprResult ActOnDependentMemberExpr(Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs); @@ -2457,6 +2467,7 @@ public: SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl, bool HasTrailingLParen); @@ -3345,29 +3356,27 @@ public: /// /// \param S The scope in which this nested-name-specifier occurs. /// - /// \param TemplateLoc The location of the 'template' keyword, if any. - /// /// \param SS The nested-name-specifier, which is both an input /// parameter (the nested-name-specifier before this type) and an /// output parameter (containing the full nested-name-specifier, /// including this new type). /// - /// \param TemplateLoc the location of the 'template' keyword, if any. + /// \param TemplateKWLoc the location of the 'template' keyword, if any. /// \param TemplateName The template name. /// \param TemplateNameLoc The location of the template name. /// \param LAngleLoc The location of the opening angle bracket ('<'). /// \param TemplateArgs The template arguments. /// \param RAngleLoc The location of the closing angle bracket ('>'). /// \param CCLoc The location of the '::'. - + /// /// \param EnteringContext Whether we're entering the context of the /// nested-name-specifier. /// /// /// \returns true if an error occurred, false otherwise. bool ActOnCXXNestedNameSpecifier(Scope *S, - SourceLocation TemplateLoc, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, TemplateTy Template, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, @@ -3961,16 +3970,19 @@ public: ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, LookupResult &R, bool RequiresADL, const TemplateArgumentListInfo &TemplateArgs); + ExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo &TemplateArgs); TemplateNameKind ActOnDependentTemplateName(Scope *S, - SourceLocation TemplateKWLoc, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index d6139de3fc..4ac9f76586 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -3909,6 +3909,7 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(), Importer.Import(E->getQualifierLoc()), + Importer.Import(E->getTemplateKeywordLoc()), ToD, Importer.Import(E->getLocation()), T, E->getValueKind(), diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index a92dafb273..0ba7a056a4 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -258,6 +258,7 @@ void DeclRefExpr::computeDependence() { } DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, ValueDecl *D, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, @@ -270,16 +271,20 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0; if (FoundD) getInternalFoundDecl() = FoundD; - DeclRefExprBits.HasExplicitTemplateArgs = TemplateArgs ? 1 : 0; + DeclRefExprBits.HasTemplateKWAndArgsInfo + = (TemplateArgs || TemplateKWLoc.isValid()) ? 1 : 0; if (TemplateArgs) { bool Dependent = false; bool InstantiationDependent = false; bool ContainsUnexpandedParameterPack = false; - getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, - InstantiationDependent, - ContainsUnexpandedParameterPack); + getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs, + Dependent, + InstantiationDependent, + ContainsUnexpandedParameterPack); if (InstantiationDependent) setInstantiationDependent(true); + } else if (TemplateKWLoc.isValid()) { + getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); } DeclRefExprBits.HadMultipleCandidates = 0; @@ -288,19 +293,21 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, ValueDecl *D, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs) { - return Create(Context, QualifierLoc, D, + return Create(Context, QualifierLoc, TemplateKWLoc, D, DeclarationNameInfo(D->getDeclName(), NameLoc), T, VK, FoundD, TemplateArgs); } DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, ValueDecl *D, const DeclarationNameInfo &NameInfo, QualType T, @@ -317,25 +324,27 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, if (FoundD) Size += sizeof(NamedDecl *); if (TemplateArgs) - Size += ASTTemplateArgumentListInfo::sizeFor(*TemplateArgs); + Size += ASTTemplateKWAndArgsInfo::sizeFor(TemplateArgs->size()); + else if (TemplateKWLoc.isValid()) + Size += ASTTemplateKWAndArgsInfo::sizeFor(0); void *Mem = Context.Allocate(Size, llvm::alignOf()); - return new (Mem) DeclRefExpr(QualifierLoc, D, NameInfo, FoundD, TemplateArgs, - T, VK); + return new (Mem) DeclRefExpr(QualifierLoc, TemplateKWLoc, D, NameInfo, + FoundD, TemplateArgs, T, VK); } DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context, bool HasQualifier, bool HasFoundDecl, - bool HasExplicitTemplateArgs, + bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { std::size_t Size = sizeof(DeclRefExpr); if (HasQualifier) Size += sizeof(NestedNameSpecifierLoc); if (HasFoundDecl) Size += sizeof(NamedDecl *); - if (HasExplicitTemplateArgs) - Size += ASTTemplateArgumentListInfo::sizeFor(NumTemplateArgs); + if (HasTemplateKWAndArgsInfo) + Size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); void *Mem = Context.Allocate(Size, llvm::alignOf()); return new (Mem) DeclRefExpr(EmptyShell()); @@ -941,6 +950,7 @@ IdentifierInfo *OffsetOfExpr::OffsetOfNode::getFieldName() const { MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, ValueDecl *memberdecl, DeclAccessPair founddecl, DeclarationNameInfo nameinfo, @@ -957,7 +967,9 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, Size += sizeof(MemberNameQualifier); if (targs) - Size += ASTTemplateArgumentListInfo::sizeFor(*targs); + Size += ASTTemplateKWAndArgsInfo::sizeFor(targs->size()); + else if (TemplateKWLoc.isValid()) + Size += ASTTemplateKWAndArgsInfo::sizeFor(0); void *Mem = C.Allocate(Size, llvm::alignOf()); MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo, @@ -981,16 +993,20 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, NQ->FoundDecl = founddecl; } + E->HasTemplateKWAndArgsInfo = (targs || TemplateKWLoc.isValid()); + if (targs) { bool Dependent = false; bool InstantiationDependent = false; bool ContainsUnexpandedParameterPack = false; - E->HasExplicitTemplateArgumentList = true; - E->getExplicitTemplateArgs().initializeFrom(*targs, Dependent, - InstantiationDependent, - ContainsUnexpandedParameterPack); + E->getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *targs, + Dependent, + InstantiationDependent, + ContainsUnexpandedParameterPack); if (InstantiationDependent) E->setInstantiationDependent(true); + } else if (TemplateKWLoc.isValid()) { + E->getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); } return E; @@ -1010,11 +1026,10 @@ SourceRange MemberExpr::getSourceRange() const { if (StartLoc.isInvalid()) StartLoc = MemberLoc; } - - SourceLocation EndLoc = - HasExplicitTemplateArgumentList? getRAngleLoc() - : getMemberNameInfo().getEndLoc(); - + + SourceLocation EndLoc = hasExplicitTemplateArgs() + ? getRAngleLoc() : getMemberNameInfo().getEndLoc(); + return SourceRange(StartLoc, EndLoc); } diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 285d38cbdf..af8498daa7 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -197,34 +197,38 @@ UnresolvedLookupExpr * UnresolvedLookupExpr::Create(ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, bool ADL, const TemplateArgumentListInfo &Args, UnresolvedSetIterator Begin, UnresolvedSetIterator End) { - void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) + - ASTTemplateArgumentListInfo::sizeFor(Args)); - return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, NameInfo, + void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) + + ASTTemplateKWAndArgsInfo::sizeFor(Args.size())); + return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, + TemplateKWLoc, NameInfo, ADL, /*Overload*/ true, &Args, Begin, End, /*StdIsAssociated=*/false); } UnresolvedLookupExpr * -UnresolvedLookupExpr::CreateEmpty(ASTContext &C, bool HasExplicitTemplateArgs, +UnresolvedLookupExpr::CreateEmpty(ASTContext &C, + bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { std::size_t size = sizeof(UnresolvedLookupExpr); - if (HasExplicitTemplateArgs) - size += ASTTemplateArgumentListInfo::sizeFor(NumTemplateArgs); + if (HasTemplateKWAndArgsInfo) + size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); void *Mem = C.Allocate(size, llvm::alignOf()); UnresolvedLookupExpr *E = new (Mem) UnresolvedLookupExpr(EmptyShell()); - E->HasExplicitTemplateArgs = HasExplicitTemplateArgs; + E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; return E; } OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, @@ -243,8 +247,9 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, (QualifierLoc && QualifierLoc.getNestedNameSpecifier() ->containsUnexpandedParameterPack()))), - Results(0), NumResults(End - Begin), NameInfo(NameInfo), - QualifierLoc(QualifierLoc), HasExplicitTemplateArgs(TemplateArgs != 0) + Results(0), NumResults(End - Begin), NameInfo(NameInfo), + QualifierLoc(QualifierLoc), + HasTemplateKWAndArgsInfo(TemplateArgs != 0 || TemplateKWLoc.isValid()) { NumResults = End - Begin; if (NumResults) { @@ -271,9 +276,10 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, bool Dependent = false; bool InstantiationDependent = false; bool ContainsUnexpandedParameterPack = false; - getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, - InstantiationDependent, - ContainsUnexpandedParameterPack); + getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs, + Dependent, + InstantiationDependent, + ContainsUnexpandedParameterPack); if (Dependent) { ExprBits.TypeDependent = true; @@ -283,6 +289,8 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, ExprBits.InstantiationDependent = true; if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; + } else if (TemplateKWLoc.isValid()) { + getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); } if (isTypeDependent()) @@ -314,6 +322,7 @@ CXXRecordDecl *OverloadExpr::getNamingClass() const { // DependentScopeDeclRefExpr DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *Args) : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary, @@ -326,47 +335,52 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, QualifierLoc.getNestedNameSpecifier() ->containsUnexpandedParameterPack()))), QualifierLoc(QualifierLoc), NameInfo(NameInfo), - HasExplicitTemplateArgs(Args != 0) + HasTemplateKWAndArgsInfo(Args != 0 || TemplateKWLoc.isValid()) { if (Args) { bool Dependent = true; bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = ExprBits.ContainsUnexpandedParameterPack; - - reinterpret_cast(this+1) - ->initializeFrom(*Args, Dependent, InstantiationDependent, - ContainsUnexpandedParameterPack); - + getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *Args, + Dependent, + InstantiationDependent, + ContainsUnexpandedParameterPack); ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; + } else if (TemplateKWLoc.isValid()) { + getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); } } DependentScopeDeclRefExpr * DependentScopeDeclRefExpr::Create(ASTContext &C, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *Args) { std::size_t size = sizeof(DependentScopeDeclRefExpr); if (Args) - size += ASTTemplateArgumentListInfo::sizeFor(*Args); + size += ASTTemplateKWAndArgsInfo::sizeFor(Args->size()); + else if (TemplateKWLoc.isValid()) + size += ASTTemplateKWAndArgsInfo::sizeFor(0); void *Mem = C.Allocate(size); - return new (Mem) DependentScopeDeclRefExpr(C.DependentTy, QualifierLoc, - NameInfo, Args); + return new (Mem) DependentScopeDeclRefExpr(C.DependentTy, QualifierLoc, + TemplateKWLoc, NameInfo, Args); } DependentScopeDeclRefExpr * DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C, - bool HasExplicitTemplateArgs, + bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { std::size_t size = sizeof(DependentScopeDeclRefExpr); - if (HasExplicitTemplateArgs) - size += ASTTemplateArgumentListInfo::sizeFor(NumTemplateArgs); + if (HasTemplateKWAndArgsInfo) + size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); void *Mem = C.Allocate(size); - DependentScopeDeclRefExpr *E + DependentScopeDeclRefExpr *E = new (Mem) DependentScopeDeclRefExpr(QualType(), NestedNameSpecifierLoc(), + SourceLocation(), DeclarationNameInfo(), 0); - E->HasExplicitTemplateArgs = HasExplicitTemplateArgs; + E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; return E; } @@ -784,7 +798,8 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, - NestedNameSpecifierLoc QualifierLoc, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) @@ -796,7 +811,7 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, ->containsUnexpandedParameterPack()) || MemberNameInfo.containsUnexpandedParameterPack())), Base(Base), BaseType(BaseType), IsArrow(IsArrow), - HasExplicitTemplateArgs(TemplateArgs != 0), + HasTemplateKWAndArgsInfo(TemplateArgs != 0 || TemplateKWLoc.isValid()), OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc), FirstQualifierFoundInScope(FirstQualifierFoundInScope), MemberNameInfo(MemberNameInfo) { @@ -804,11 +819,14 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, bool Dependent = true; bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = false; - getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, - InstantiationDependent, - ContainsUnexpandedParameterPack); + getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc, *TemplateArgs, + Dependent, + InstantiationDependent, + ContainsUnexpandedParameterPack); if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; + } else if (TemplateKWLoc.isValid()) { + getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); } } @@ -827,8 +845,8 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, containsUnexpandedParameterPack()) || MemberNameInfo.containsUnexpandedParameterPack())), Base(Base), BaseType(BaseType), IsArrow(IsArrow), - HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc), - QualifierLoc(QualifierLoc), + HasTemplateKWAndArgsInfo(false), + OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc), FirstQualifierFoundInScope(FirstQualifierFoundInScope), MemberNameInfo(MemberNameInfo) { } @@ -837,47 +855,50 @@ CXXDependentScopeMemberExpr::Create(ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) { - if (!TemplateArgs) + if (!TemplateArgs && !TemplateKWLoc.isValid()) return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc, FirstQualifierFoundInScope, MemberNameInfo); - std::size_t size = sizeof(CXXDependentScopeMemberExpr); - if (TemplateArgs) - size += ASTTemplateArgumentListInfo::sizeFor(*TemplateArgs); + unsigned NumTemplateArgs = TemplateArgs ? TemplateArgs->size() : 0; + std::size_t size = sizeof(CXXDependentScopeMemberExpr) + + ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); void *Mem = C.Allocate(size, llvm::alignOf()); return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType, IsArrow, OperatorLoc, QualifierLoc, + TemplateKWLoc, FirstQualifierFoundInScope, MemberNameInfo, TemplateArgs); } CXXDependentScopeMemberExpr * CXXDependentScopeMemberExpr::CreateEmpty(ASTContext &C, - bool HasExplicitTemplateArgs, + bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { - if (!HasExplicitTemplateArgs) + if (!HasTemplateKWAndArgsInfo) return new (C) CXXDependentScopeMemberExpr(C, 0, QualType(), - 0, SourceLocation(), + 0, SourceLocation(), NestedNameSpecifierLoc(), 0, DeclarationNameInfo()); std::size_t size = sizeof(CXXDependentScopeMemberExpr) + - ASTTemplateArgumentListInfo::sizeFor(NumTemplateArgs); + ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); void *Mem = C.Allocate(size, llvm::alignOf()); CXXDependentScopeMemberExpr *E = new (Mem) CXXDependentScopeMemberExpr(C, 0, QualType(), - 0, SourceLocation(), - NestedNameSpecifierLoc(), 0, + 0, SourceLocation(), + NestedNameSpecifierLoc(), + SourceLocation(), 0, DeclarationNameInfo(), 0); - E->HasExplicitTemplateArgs = true; + E->HasTemplateKWAndArgsInfo = true; return E; } @@ -916,12 +937,13 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End) - : OverloadExpr(UnresolvedMemberExprClass, C, QualifierLoc, MemberNameInfo, - TemplateArgs, Begin, End, + : OverloadExpr(UnresolvedMemberExprClass, C, QualifierLoc, TemplateKWLoc, + MemberNameInfo, TemplateArgs, Begin, End, // Dependent ((Base && Base->isTypeDependent()) || BaseType->isDependentType()), @@ -952,31 +974,34 @@ UnresolvedMemberExpr::Create(ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End) { std::size_t size = sizeof(UnresolvedMemberExpr); if (TemplateArgs) - size += ASTTemplateArgumentListInfo::sizeFor(*TemplateArgs); + size += ASTTemplateKWAndArgsInfo::sizeFor(TemplateArgs->size()); + else if (TemplateKWLoc.isValid()) + size += ASTTemplateKWAndArgsInfo::sizeFor(0); void *Mem = C.Allocate(size, llvm::alignOf()); return new (Mem) UnresolvedMemberExpr(C, HasUnresolvedUsing, Base, BaseType, - IsArrow, OperatorLoc, QualifierLoc, + IsArrow, OperatorLoc, QualifierLoc, TemplateKWLoc, MemberNameInfo, TemplateArgs, Begin, End); } UnresolvedMemberExpr * -UnresolvedMemberExpr::CreateEmpty(ASTContext &C, bool HasExplicitTemplateArgs, +UnresolvedMemberExpr::CreateEmpty(ASTContext &C, bool HasTemplateKWAndArgsInfo, unsigned NumTemplateArgs) { std::size_t size = sizeof(UnresolvedMemberExpr); - if (HasExplicitTemplateArgs) - size += ASTTemplateArgumentListInfo::sizeFor(NumTemplateArgs); + if (HasTemplateKWAndArgsInfo) + size += ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs); void *Mem = C.Allocate(size, llvm::alignOf()); UnresolvedMemberExpr *E = new (Mem) UnresolvedMemberExpr(EmptyShell()); - E->HasExplicitTemplateArgs = HasExplicitTemplateArgs; + E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo; return E; } diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index ecf8ed751f..141cb2900f 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -544,6 +544,8 @@ void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) { void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { if (NestedNameSpecifier *Qualifier = Node->getQualifier()) Qualifier->print(OS, Policy); + if (Node->hasTemplateKeyword()) + OS << "template "; OS << Node->getNameInfo(); if (Node->hasExplicitTemplateArgs()) OS << TemplateSpecializationType::PrintTemplateArgumentList( @@ -556,6 +558,8 @@ void StmtPrinter::VisitDependentScopeDeclRefExpr( DependentScopeDeclRefExpr *Node) { if (NestedNameSpecifier *Qualifier = Node->getQualifier()) Qualifier->print(OS, Policy); + if (Node->hasTemplateKeyword()) + OS << "template "; OS << Node->getNameInfo(); if (Node->hasExplicitTemplateArgs()) OS << TemplateSpecializationType::PrintTemplateArgumentList( @@ -567,6 +571,8 @@ void StmtPrinter::VisitDependentScopeDeclRefExpr( void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { if (Node->getQualifier()) Node->getQualifier()->print(OS, Policy); + if (Node->hasTemplateKeyword()) + OS << "template "; OS << Node->getNameInfo(); if (Node->hasExplicitTemplateArgs()) OS << TemplateSpecializationType::PrintTemplateArgumentList( @@ -883,9 +889,9 @@ void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { OS << (Node->isArrow() ? "->" : "."); if (NestedNameSpecifier *Qualifier = Node->getQualifier()) Qualifier->print(OS, Policy); - + if (Node->hasTemplateKeyword()) + OS << "template "; OS << Node->getMemberNameInfo(); - if (Node->hasExplicitTemplateArgs()) OS << TemplateSpecializationType::PrintTemplateArgumentList( Node->getTemplateArgs(), @@ -1371,12 +1377,9 @@ void StmtPrinter::VisitCXXDependentScopeMemberExpr( } if (NestedNameSpecifier *Qualifier = Node->getQualifier()) Qualifier->print(OS, Policy); - else if (Node->hasExplicitTemplateArgs()) - // FIXME: Track use of "template" keyword explicitly? + if (Node->hasTemplateKeyword()) OS << "template "; - OS << Node->getMemberNameInfo(); - if (Node->hasExplicitTemplateArgs()) { OS << TemplateSpecializationType::PrintTemplateArgumentList( Node->getTemplateArgs(), @@ -1392,11 +1395,9 @@ void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { } if (NestedNameSpecifier *Qualifier = Node->getQualifier()) Qualifier->print(OS, Policy); - - // FIXME: this might originally have been written with 'template' - + if (Node->hasTemplateKeyword()) + OS << "template "; OS << Node->getMemberNameInfo(); - if (Node->hasExplicitTemplateArgs()) { OS << TemplateSpecializationType::PrintTemplateArgumentList( Node->getTemplateArgs(), diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp index 57df8a4dce..beb77d6774 100644 --- a/lib/AST/TemplateBase.cpp +++ b/lib/AST/TemplateBase.cpp @@ -531,7 +531,7 @@ const ASTTemplateArgumentListInfo * ASTTemplateArgumentListInfo::Create(ASTContext &C, const TemplateArgumentListInfo &List) { std::size_t size = sizeof(CXXDependentScopeMemberExpr) + - ASTTemplateArgumentListInfo::sizeFor(List); + ASTTemplateArgumentListInfo::sizeFor(List.size()); void *Mem = C.Allocate(size, llvm::alignOf()); ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo(); TAI->initializeFrom(List); @@ -584,7 +584,38 @@ std::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) { sizeof(TemplateArgumentLoc) * NumTemplateArgs; } -std::size_t ASTTemplateArgumentListInfo::sizeFor( - const TemplateArgumentListInfo &Info) { - return sizeFor(Info.size()); +void +ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc, + const TemplateArgumentListInfo &Info) { + Base::initializeFrom(Info); + setTemplateKeywordLoc(TemplateKWLoc); +} + +void +ASTTemplateKWAndArgsInfo +::initializeFrom(SourceLocation TemplateKWLoc, + const TemplateArgumentListInfo &Info, + bool &Dependent, + bool &InstantiationDependent, + bool &ContainsUnexpandedParameterPack) { + Base::initializeFrom(Info, Dependent, InstantiationDependent, + ContainsUnexpandedParameterPack); + setTemplateKeywordLoc(TemplateKWLoc); +} + +void +ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { + // No explicit template arguments, but template keyword loc is valid. + assert(TemplateKWLoc.isValid()); + LAngleLoc = SourceLocation(); + RAngleLoc = SourceLocation(); + NumTemplateArgs = 0; + setTemplateKeywordLoc(TemplateKWLoc); +} + +std::size_t +ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) { + // Add space for the template keyword location. + return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation); } + diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index f6c0ae21d1..87c392f4a3 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -3939,11 +3939,13 @@ void Parser::ParseDirectDeclarator(Declarator &D) { else AllowConstructorName = (D.getContext() == Declarator::MemberContext); + SourceLocation TemplateKWLoc; if (ParseUnqualifiedId(D.getCXXScopeSpec(), /*EnteringContext=*/true, /*AllowDestructorName=*/true, AllowConstructorName, ParsedType(), + TemplateKWLoc, D.getName()) || // Once we're past the identifier, if the scope was bad, mark the // whole declarator bad. diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 92a501a8c4..d102fb3158 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -461,12 +461,14 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context, // Parse the unqualified-id. We allow parsing of both constructor and // destructor names and allow the action module to diagnose any semantic // errors. + SourceLocation TemplateKWLoc; UnqualifiedId Name; if (ParseUnqualifiedId(SS, /*EnteringContext=*/false, /*AllowDestructorName=*/true, /*AllowConstructorName=*/true, ParsedType(), + TemplateKWLoc, Name)) { SkipUntil(tok::semi); return 0; @@ -835,8 +837,8 @@ Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, TemplateName.setIdentifier(Id, IdLoc); // Parse the full template-id, then turn it into a type. - if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, - SourceLocation(), true)) + if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), + TemplateName, true)) return true; if (TNK == TNK_Dependent_template_name) AnnotateTemplateIdTokenAsType(); @@ -1692,8 +1694,10 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, /*EnteringContext=*/false); // Try to parse an unqualified-id. + SourceLocation TemplateKWLoc; UnqualifiedId Name; - if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), Name)) { + if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), + TemplateKWLoc, Name)) { SkipUntil(tok::semi); return; } diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 22c5841e45..3f80309b3a 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -795,12 +795,13 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, // not. UnqualifiedId Name; CXXScopeSpec ScopeSpec; + SourceLocation TemplateKWLoc; CastExpressionIdValidator Validator(isTypeCast != NotTypeCast, isTypeCast != IsTypeCast); Name.setIdentifier(&II, ILoc); - Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, Name, - Tok.is(tok::l_paren), isAddressOfOperand, - &Validator); + Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc, + Name, Tok.is(tok::l_paren), + isAddressOfOperand, &Validator); break; } case tok::char_constant: // constant: character-constant @@ -1403,19 +1404,19 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { // names a real destructor. // Allow explicit constructor calls in Microsoft mode. // FIXME: Add support for explicit call of template constructor. + SourceLocation TemplateKWLoc; UnqualifiedId Name; if (ParseUnqualifiedId(SS, /*EnteringContext=*/false, /*AllowDestructorName=*/true, /*AllowConstructorName=*/ getLang().MicrosoftExt, - ObjectType, - Name)) + ObjectType, TemplateKWLoc, Name)) LHS = ExprError(); if (!LHS.isInvalid()) LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.take(), OpLoc, - OpKind, SS, Name, ObjCImpDecl, - Tok.is(tok::l_paren)); + OpKind, SS, TemplateKWLoc, Name, + ObjCImpDecl, Tok.is(tok::l_paren)); break; } case tok::plusplus: // postfix-expression: postfix-expression '++' diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index d35203e941..2f373830e2 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -264,15 +264,13 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, // Commit to parsing the template-id. TPA.Commit(); TemplateTy Template; - if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName(getCurScope(), - TemplateKWLoc, - SS, - TemplateName, - ObjectType, - EnteringContext, - Template)) { - if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, - TemplateKWLoc, false)) + if (TemplateNameKind TNK + = Actions.ActOnDependentTemplateName(getCurScope(), + SS, TemplateKWLoc, TemplateName, + ObjectType, EnteringContext, + Template)) { + if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc, + TemplateName, false)) return true; } else return true; @@ -307,8 +305,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, TemplateId->NumArgs); if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), - /*FIXME:*/SourceLocation(), - SS, + SS, + TemplateId->TemplateKWLoc, TemplateId->Template, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, @@ -404,8 +402,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, // specializations) still want to see the original template-id // token. ConsumeToken(); - if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, - SourceLocation(), false)) + if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), + TemplateName, false)) return true; continue; } @@ -426,14 +424,14 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName(getCurScope(), - Tok.getLocation(), SS, + SS, SourceLocation(), TemplateName, ObjectType, EnteringContext, Template)) { // Consume the identifier. ConsumeToken(); - if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, - SourceLocation(), false)) - return true; + if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), + TemplateName, false)) + return true; } else return true; @@ -505,13 +503,15 @@ ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { // CXXScopeSpec SS; ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); - + + SourceLocation TemplateKWLoc; UnqualifiedId Name; - if (ParseUnqualifiedId(SS, - /*EnteringContext=*/false, - /*AllowDestructorName=*/false, - /*AllowConstructorName=*/false, + if (ParseUnqualifiedId(SS, + /*EnteringContext=*/false, + /*AllowDestructorName=*/false, + /*AllowConstructorName=*/false, /*ObjectType=*/ ParsedType(), + TemplateKWLoc, Name)) return ExprError(); @@ -519,10 +519,9 @@ ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { // followed by a postfix-expression suffix. if (isAddressOfOperand && isPostfixExpressionSuffixStart()) isAddressOfOperand = false; - - return Actions.ActOnIdExpression(getCurScope(), SS, Name, Tok.is(tok::l_paren), - isAddressOfOperand); - + + return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name, + Tok.is(tok::l_paren), isAddressOfOperand); } /// ParseLambdaExpression - Parse a C++0x lambda expression. @@ -1030,6 +1029,8 @@ Parser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc, assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); CCLoc = ConsumeToken(); } else if (Tok.is(tok::annot_template_id)) { + // FIXME: retrieve TemplateKWLoc from template-id annotation and + // store it in the pseudo-dtor node (to be used when instantiating it). FirstTypeName.setTemplateId( (TemplateIdAnnotation *)Tok.getAnnotationValue()); ConsumeToken(); @@ -1067,9 +1068,10 @@ Parser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc, // If there is a '<', the second type name is a template-id. Parse // it as such. if (Tok.is(tok::less) && - ParseUnqualifiedIdTemplateId(SS, Name, NameLoc, false, ObjectType, - SecondTypeName, /*AssumeTemplateName=*/true, - /*TemplateKWLoc*/SourceLocation())) + ParseUnqualifiedIdTemplateId(SS, SourceLocation(), + Name, NameLoc, + false, ObjectType, SecondTypeName, + /*AssumeTemplateName=*/true)) return ExprError(); return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, @@ -1502,13 +1504,13 @@ bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { /// /// \returns true if a parse error occurred, false otherwise. bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, IdentifierInfo *Name, SourceLocation NameLoc, bool EnteringContext, ParsedType ObjectType, UnqualifiedId &Id, - bool AssumeTemplateId, - SourceLocation TemplateKWLoc) { + bool AssumeTemplateId) { assert((AssumeTemplateId || Tok.is(tok::less)) && "Expected '<' to finish parsing a template-id"); @@ -1519,7 +1521,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, case UnqualifiedId::IK_OperatorFunctionId: case UnqualifiedId::IK_LiteralOperatorId: if (AssumeTemplateId) { - TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc, SS, + TNK = Actions.ActOnDependentTemplateName(getCurScope(), SS, TemplateKWLoc, Id, ObjectType, EnteringContext, Template); if (TNK == TNK_Non_template) @@ -1550,9 +1552,10 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword) << Name << FixItHint::CreateInsertion(Id.StartLocation, "template "); - TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc, - SS, Id, ObjectType, - EnteringContext, Template); + TNK = Actions.ActOnDependentTemplateName(getCurScope(), + SS, TemplateKWLoc, Id, + ObjectType, EnteringContext, + Template); if (TNK == TNK_Non_template) return true; } @@ -1575,9 +1578,10 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, bool MemberOfUnknownSpecialization; TemplateName.setIdentifier(Name, NameLoc); if (ObjectType) { - TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc, SS, - TemplateName, ObjectType, - EnteringContext, Template); + TNK = Actions.ActOnDependentTemplateName(getCurScope(), + SS, TemplateKWLoc, TemplateName, + ObjectType, EnteringContext, + Template); if (TNK == TNK_Non_template) return true; } else { @@ -1880,12 +1884,12 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, ParsedType ObjectType, + SourceLocation& TemplateKWLoc, UnqualifiedId &Result) { // Handle 'A::template B'. This is for template-ids which have not // already been annotated by ParseOptionalCXXScopeSpecifier(). bool TemplateSpecified = false; - SourceLocation TemplateKWLoc; if (getLang().CPlusPlus && Tok.is(tok::kw_template) && (ObjectType || SS.isSet())) { TemplateSpecified = true; @@ -1923,9 +1927,9 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, // If the next token is a '<', we may have a template. if (TemplateSpecified || Tok.is(tok::less)) - return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext, - ObjectType, Result, - TemplateSpecified, TemplateKWLoc); + return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, Id, IdLoc, + EnteringContext, ObjectType, + Result, TemplateSpecified); return false; } @@ -1969,6 +1973,7 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, // We have already parsed a template-id; consume the annotation token as // our unqualified-id. Result.setTemplateId(TemplateId); + TemplateKWLoc = TemplateId->TemplateKWLoc; ConsumeToken(); return false; } @@ -1988,10 +1993,10 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId || Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) && (TemplateSpecified || Tok.is(tok::less))) - return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(), - EnteringContext, ObjectType, - Result, - TemplateSpecified, TemplateKWLoc); + return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, + 0, SourceLocation(), + EnteringContext, ObjectType, + Result, TemplateSpecified); return false; } @@ -2028,9 +2033,10 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, if (TemplateSpecified || Tok.is(tok::less)) { Result.setDestructorName(TildeLoc, ParsedType(), ClassNameLoc); - return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc, - EnteringContext, ObjectType, Result, - TemplateSpecified, TemplateKWLoc); + return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, + ClassName, ClassNameLoc, + EnteringContext, ObjectType, + Result, TemplateSpecified); } // Note that this is a destructor name. diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index cd467dd720..aa9ba06b67 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -171,7 +171,7 @@ Retry: if (AnnotateTemplateIdToken( TemplateTy::make(Classification.getTemplateName()), Classification.getTemplateNameKind(), - SS, Id, SourceLocation(), + SS, SourceLocation(), Id, /*AllowTypeAnnotation=*/false)) { // Handle errors here by skipping up to the next semicolon or '}', and // eat the semicolon if that's what stopped us. diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 4f2f49c804..04050c0edb 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -765,8 +765,8 @@ Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template, /// bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, CXXScopeSpec &SS, - UnqualifiedId &TemplateName, SourceLocation TemplateKWLoc, + UnqualifiedId &TemplateName, bool AllowTypeAnnotation) { assert(getLang().CPlusPlus && "Can only annotate template-ids in C++"); assert(Template && Tok.is(tok::less) && @@ -833,6 +833,7 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, TemplateId->Operator = TemplateName.OperatorFunctionId.Operator; } TemplateId->SS = SS; + TemplateId->TemplateKWLoc = TemplateKWLoc; TemplateId->Template = Template; TemplateId->Kind = TNK; TemplateId->LAngleLoc = LAngleLoc; @@ -927,7 +928,7 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { if (SS.isSet() && Tok.is(tok::kw_template)) { // Parse the optional 'template' keyword following the // nested-name-specifier. - SourceLocation TemplateLoc = ConsumeToken(); + SourceLocation TemplateKWLoc = ConsumeToken(); if (Tok.is(tok::identifier)) { // We appear to have a dependent template name. @@ -944,8 +945,8 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { // template argument. TemplateTy Template; if (isEndOfTemplateArgument(Tok) && - Actions.ActOnDependentTemplateName(getCurScope(), TemplateLoc, - SS, Name, + Actions.ActOnDependentTemplateName(getCurScope(), + SS, TemplateKWLoc, Name, /*ObjectType=*/ ParsedType(), /*EnteringContext=*/false, Template)) diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index da1424c6b1..5afb0fdf3c 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -1320,7 +1320,8 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) { Template, MemberOfUnknownSpecialization)) { // Consume the identifier. ConsumeToken(); - if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName)) { + if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), + TemplateName)) { // If an unrecoverable error occurred, we need to return true here, // because the token stream is in a damaged state. We may not return // a valid identifier. @@ -1514,9 +1515,10 @@ bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) { return true; } - // Parse the unqualified-id. - if (ParseUnqualifiedId(Result.SS, false, true, true, ParsedType(), - Result.Name)) { + // Parse the unqualified-id. + SourceLocation TemplateKWLoc; // FIXME: parsed, but unused. + if (ParseUnqualifiedId(Result.SS, false, true, true, ParsedType(), + TemplateKWLoc, Result.Name)) { T.skipToEnd(); return true; } diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 1ad50434db..1468e45ab3 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -739,8 +739,8 @@ bool Sema::IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS, } bool Sema::ActOnCXXNestedNameSpecifier(Scope *S, - SourceLocation TemplateLoc, - CXXScopeSpec &SS, + CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, TemplateTy Template, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, @@ -777,7 +777,7 @@ bool Sema::ActOnCXXNestedNameSpecifier(Scope *S, for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); - SS.Extend(Context, TemplateLoc, Builder.getTypeLocInContext(Context, T), + SS.Extend(Context, TemplateKWLoc, Builder.getTypeLocInContext(Context, T), CCLoc); return false; } @@ -823,7 +823,7 @@ bool Sema::ActOnCXXNestedNameSpecifier(Scope *S, SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); - SS.Extend(Context, TemplateLoc, Builder.getTypeLocInContext(Context, T), + SS.Extend(Context, TemplateKWLoc, Builder.getTypeLocInContext(Context, T), CCLoc); return false; } diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 7579a5d0ee..08af9b71ec 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -1003,6 +1003,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) { DeclRefExpr* NewDRE = DeclRefExpr::Create( Context, DRE->getQualifierLoc(), + SourceLocation(), NewBuiltinDecl, DRE->getLocation(), NewBuiltinDecl->getType(), diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 4fdbfdb836..e4c2bdd031 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -4999,9 +4999,11 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, } else { // Assume that "super" names some kind of value and parse that way. CXXScopeSpec SS; + SourceLocation TemplateKWLoc; UnqualifiedId id; id.setIdentifier(Super, SuperLoc); - ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false); + ExprResult SuperExpr = ActOnIdExpression(S, SS, TemplateKWLoc, id, + false, false); return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(), SelIdents, NumSelIdents, AtArgumentExpression); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a6e1e401b3..c20f9426fb 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -642,7 +642,7 @@ Corrected: Result.suppressDiagnostics(); return NameClassification::Unknown(); - case LookupResult::NotFoundInCurrentInstantiation: + case LookupResult::NotFoundInCurrentInstantiation: { // We performed name lookup into the current instantiation, and there were // dependent bases, so we treat this result the same way as any other // dependent nested-name-specifier. @@ -657,7 +657,9 @@ Corrected: // perform some heroics to see if we actually have a // template-argument-list, which would indicate a missing 'template' // keyword here. - return BuildDependentDeclRefExpr(SS, NameInfo, /*TemplateArgs=*/0); + return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(), + NameInfo, /*TemplateArgs=*/0); + } case LookupResult::Found: case LookupResult::FoundOverloaded: @@ -763,7 +765,7 @@ Corrected: } if (!Result.empty() && (*Result.begin())->isCXXClassMember()) - return BuildPossibleImplicitMemberExpr(SS, Result, 0); + return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, 0); bool ADL = UseArgumentDependentLookup(SS, Result, NextToken.is(tok::l_paren)); return BuildDeclarationNameExpr(SS, Result, ADL); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 948aff93fa..aa827a40c6 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -699,10 +699,12 @@ static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, // Special case where the argument is a template id. if (Attr.getParameterName()) { CXXScopeSpec SS; + SourceLocation TemplateKWLoc; UnqualifiedId id; id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); - ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false); + ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id, + false, false); if (Size.isInvalid()) return; diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 9221b89b1a..4852288ff4 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2385,7 +2385,8 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, SemaRef.MarkDeclarationReferenced(Constructor->getLocation(), Param); Expr *CopyCtorArg = - DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), Param, + DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), + SourceLocation(), Param, Constructor->getLocation(), ParamType, VK_LValue, 0); @@ -2460,7 +2461,8 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, return false; Expr *MemberExprBase = - DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), Param, + DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), + SourceLocation(), Param, Loc, ParamType, VK_LValue, 0); if (Moving) { @@ -2479,6 +2481,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, ParamType, Loc, /*IsArrow=*/false, SS, + /*TemplateKWLoc=*/SourceLocation(), /*FirstQualifierInScope=*/0, MemberLookup, /*TemplateArgs=*/0); @@ -7592,7 +7595,9 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, // Create the reference to operator=. ExprResult OpEqualRef = S.BuildMemberReferenceExpr(To, T, Loc, /*isArrow=*/false, SS, - /*FirstQualifierInScope=*/0, OpLookup, + /*TemplateKWLoc=*/SourceLocation(), + /*FirstQualifierInScope=*/0, + OpLookup, /*TemplateArgs=*/0, /*SuppressQualifierCheck=*/true); if (OpEqualRef.isInvalid()) @@ -8034,10 +8039,12 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, MemberLookup.resolveKind(); ExprResult From = BuildMemberReferenceExpr(OtherRef, OtherRefType, Loc, /*IsArrow=*/false, - SS, 0, MemberLookup, 0); + SS, SourceLocation(), 0, + MemberLookup, 0); ExprResult To = BuildMemberReferenceExpr(This, This->getType(), Loc, /*IsArrow=*/true, - SS, 0, MemberLookup, 0); + SS, SourceLocation(), 0, + MemberLookup, 0); assert(!From.isInvalid() && "Implicit field reference cannot fail"); assert(!To.isInvalid() && "Implicit field reference cannot fail"); @@ -8454,10 +8461,12 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation, MemberLookup.resolveKind(); ExprResult From = BuildMemberReferenceExpr(OtherRef, OtherRefType, Loc, /*IsArrow=*/false, - SS, 0, MemberLookup, 0); + SS, SourceLocation(), 0, + MemberLookup, 0); ExprResult To = BuildMemberReferenceExpr(This, This->getType(), Loc, /*IsArrow=*/true, - SS, 0, MemberLookup, 0); + SS, SourceLocation(), 0, + MemberLookup, 0); assert(!From.isInvalid() && "Implicit field reference cannot fail"); assert(!To.isInvalid() && "Implicit field reference cannot fail"); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 018aadf8b9..b79829b53f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -582,10 +582,12 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, << CT)) { // Turn this into a trap. CXXScopeSpec SS; + SourceLocation TemplateKWLoc; UnqualifiedId Name; Name.setIdentifier(PP.getIdentifierInfo("__builtin_trap"), E->getLocStart()); - ExprResult TrapFn = ActOnIdExpression(TUScope, SS, Name, true, false); + ExprResult TrapFn = ActOnIdExpression(TUScope, SS, TemplateKWLoc, Name, + true, false); if (TrapFn.isInvalid()) return ExprError(); @@ -1442,8 +1444,9 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, MarkDeclarationReferenced(NameInfo.getLoc(), D); Expr *E = DeclRefExpr::Create(Context, - SS? SS->getWithLocInContext(Context) - : NestedNameSpecifierLoc(), + SS ? SS->getWithLocInContext(Context) + : NestedNameSpecifierLoc(), + SourceLocation(), D, NameInfo, Ty, VK); // Just in case we're building an illegal pointer-to-member. @@ -1557,7 +1560,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, CXXDependentScopeMemberExpr *DepExpr = CXXDependentScopeMemberExpr::Create( Context, DepThis, DepThisType, true, SourceLocation(), - SS.getWithLocInContext(Context), NULL, + SS.getWithLocInContext(Context), + ULE->getTemplateKeywordLoc(), 0, R.getLookupNameInfo(), ULE->hasExplicitTemplateArgs() ? &TList : 0); CallsUndergoingInstantiation.back()->setCallee(DepExpr); @@ -1702,6 +1706,7 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, ExprResult Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, @@ -1748,8 +1753,8 @@ ExprResult Sema::ActOnIdExpression(Scope *S, } if (DependentID) - return ActOnDependentIdExpression(SS, NameInfo, IsAddressOfOperand, - TemplateArgs); + return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, + IsAddressOfOperand, TemplateArgs); // Perform the required lookup. LookupResult R(*this, NameInfo, @@ -1767,8 +1772,8 @@ ExprResult Sema::ActOnIdExpression(Scope *S, if (MemberOfUnknownSpecialization || (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation)) - return ActOnDependentIdExpression(SS, NameInfo, IsAddressOfOperand, - TemplateArgs); + return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, + IsAddressOfOperand, TemplateArgs); } else { bool IvarLookupFollowUp = II && !SS.isSet() && getCurMethodDecl(); LookupParsedName(R, S, &SS, !IvarLookupFollowUp); @@ -1776,9 +1781,9 @@ ExprResult Sema::ActOnIdExpression(Scope *S, // If the result might be in a dependent base class, this is a dependent // id-expression. if (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation) - return ActOnDependentIdExpression(SS, NameInfo, IsAddressOfOperand, - TemplateArgs); - + return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, + IsAddressOfOperand, TemplateArgs); + // If this reference is in an Objective-C method, then we need to do // some special Objective-C lookup, too. if (IvarLookupFollowUp) { @@ -1816,8 +1821,8 @@ ExprResult Sema::ActOnIdExpression(Scope *S, // to be able to search into type dependent base classes. if (getLangOptions().MicrosoftMode && CurContext->isDependentContext() && isa(CurContext)) - return ActOnDependentIdExpression(SS, NameInfo, IsAddressOfOperand, - TemplateArgs); + return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, + IsAddressOfOperand, TemplateArgs); CorrectionCandidateCallback DefaultValidator; if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator)) @@ -1883,11 +1888,12 @@ ExprResult Sema::ActOnIdExpression(Scope *S, isa(R.getFoundDecl()); if (MightBeImplicitMember) - return BuildPossibleImplicitMemberExpr(SS, R, TemplateArgs); + return BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, + R, TemplateArgs); } if (TemplateArgs) - return BuildTemplateIdExpr(SS, R, ADL, *TemplateArgs); + return BuildTemplateIdExpr(SS, TemplateKWLoc, R, ADL, *TemplateArgs); return BuildDeclarationNameExpr(SS, R, ADL); } @@ -1898,10 +1904,11 @@ ExprResult Sema::ActOnIdExpression(Scope *S, /// this path. ExprResult Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo) { DeclContext *DC; if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext()) - return BuildDependentDeclRefExpr(SS, NameInfo, 0); + return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, 0); if (RequireCompleteDeclContext(SS, DC)) return ExprError(); @@ -1986,7 +1993,8 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, SelfName.setIdentifier(&II, SourceLocation()); SelfName.setKind(UnqualifiedId::IK_ImplicitSelfParam); CXXScopeSpec SelfScopeSpec; - ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec, + SourceLocation TemplateKWLoc; + ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName, false, false); if (SelfExpr.isInvalid()) return ExprError(); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 63cc9fc55c..34827c4e1c 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2039,10 +2039,11 @@ ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, << ConditionVar->getSourceRange()); ExprResult Condition = - Owned(DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), - ConditionVar, - ConditionVar->getLocation(), - ConditionVar->getType().getNonReferenceType(), + Owned(DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), + SourceLocation(), + ConditionVar, + ConditionVar->getLocation(), + ConditionVar->getType().getNonReferenceType(), VK_LValue)); MarkDeclarationReferenced(ConditionVar->getLocation(), ConditionVar); diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index de35ce2bb3..8f96089c18 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -216,23 +216,24 @@ static void DiagnoseInstanceReference(Sema &SemaRef, /// Builds an expression which might be an implicit member expression. ExprResult Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs) { switch (ClassifyImplicitMemberAccess(*this, CurScope, R)) { case IMA_Instance: - return BuildImplicitMemberExpr(SS, R, TemplateArgs, true); + return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true); case IMA_Mixed: case IMA_Mixed_Unrelated: case IMA_Unresolved: - return BuildImplicitMemberExpr(SS, R, TemplateArgs, false); + return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, false); case IMA_Static: case IMA_Mixed_StaticContext: case IMA_Unresolved_StaticContext: case IMA_Field_Uneval_Context: if (TemplateArgs) - return BuildTemplateIdExpr(SS, R, false, *TemplateArgs); + return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, *TemplateArgs); return BuildDeclarationNameExpr(SS, R, false); case IMA_Error_StaticContext: @@ -407,6 +408,7 @@ ExprResult Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { @@ -439,6 +441,7 @@ Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType, return Owned(CXXDependentScopeMemberExpr::Create(Context, BaseExpr, BaseType, IsArrow, OpLoc, SS.getWithLocInContext(Context), + TemplateKWLoc, FirstQualifierInScope, NameInfo, TemplateArgs)); } @@ -603,6 +606,7 @@ ExprResult Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { @@ -610,7 +614,7 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, (SS.isSet() && isDependentScopeSpecifier(SS))) return ActOnDependentMemberExpr(Base, BaseType, IsArrow, OpLoc, - SS, FirstQualifierInScope, + SS, TemplateKWLoc, FirstQualifierInScope, NameInfo, TemplateArgs); LookupResult R(*this, NameInfo, LookupMemberName); @@ -648,8 +652,8 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, } return BuildMemberReferenceExpr(Base, BaseType, - OpLoc, IsArrow, SS, FirstQualifierInScope, - R, TemplateArgs); + OpLoc, IsArrow, SS, TemplateKWLoc, + FirstQualifierInScope, R, TemplateArgs); } static ExprResult @@ -773,7 +777,9 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, /// \brief Build a MemberExpr AST node. static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow, - const CXXScopeSpec &SS, ValueDecl *Member, + const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, + ValueDecl *Member, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo, QualType Ty, @@ -781,7 +787,7 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow, const TemplateArgumentListInfo *TemplateArgs = 0) { assert((!isArrow || Base->isRValue()) && "-> base must be a pointer rvalue"); return MemberExpr::Create(C, Base, isArrow, SS.getWithLocInContext(C), - Member, FoundDecl, MemberNameInfo, + TemplateKWLoc, Member, FoundDecl, MemberNameInfo, TemplateArgs, Ty, VK, OK); } @@ -789,6 +795,7 @@ ExprResult Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, SourceLocation OpLoc, bool IsArrow, const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, @@ -845,7 +852,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, BaseExpr, BaseExprType, IsArrow, OpLoc, SS.getWithLocInContext(Context), - MemberNameInfo, + TemplateKWLoc, MemberNameInfo, TemplateArgs, R.begin(), R.end()); return Owned(MemExpr); @@ -902,7 +909,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, if (VarDecl *Var = dyn_cast(MemberDecl)) { MarkDeclarationReferenced(MemberLoc, Var); - return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, + return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, TemplateKWLoc, Var, FoundDecl, MemberNameInfo, Var->getType().getNonReferenceType(), VK_LValue, OK_Ordinary)); @@ -920,7 +927,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, } MarkDeclarationReferenced(MemberLoc, MemberDecl); - return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, + return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, TemplateKWLoc, MemberFn, FoundDecl, MemberNameInfo, type, valueKind, OK_Ordinary)); } @@ -928,7 +935,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, if (EnumConstantDecl *Enum = dyn_cast(MemberDecl)) { MarkDeclarationReferenced(MemberLoc, MemberDecl); - return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, + return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, TemplateKWLoc, Enum, FoundDecl, MemberNameInfo, Enum->getType(), VK_RValue, OK_Ordinary)); } @@ -1411,6 +1418,7 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, UnqualifiedId &Id, Decl *ObjCImpDecl, bool HasTrailingLParen) { @@ -1447,7 +1455,7 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, isDependentScopeSpecifier(SS)) { Result = ActOnDependentMemberExpr(Base, Base->getType(), IsArrow, OpLoc, - SS, FirstQualifierInScope, + SS, TemplateKWLoc, FirstQualifierInScope, NameInfo, TemplateArgs); } else { LookupResult R(*this, NameInfo, LookupMemberName); @@ -1476,8 +1484,8 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, } Result = BuildMemberReferenceExpr(Base, Base->getType(), - OpLoc, IsArrow, SS, FirstQualifierInScope, - R, TemplateArgs); + OpLoc, IsArrow, SS, TemplateKWLoc, + FirstQualifierInScope, R, TemplateArgs); } return move(Result); @@ -1539,6 +1547,7 @@ BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow, if (Base.isInvalid()) return ExprError(); return S.Owned(BuildMemberExpr(S.Context, Base.take(), IsArrow, SS, + /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl, MemberNameInfo, MemberType, VK, OK)); } @@ -1549,6 +1558,7 @@ BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow, /// is from an appropriate type. ExprResult Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, bool IsKnownInstance) { @@ -1580,7 +1590,7 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS, return BuildMemberReferenceExpr(baseExpr, ThisTy, /*OpLoc*/ SourceLocation(), /*IsArrow*/ true, - SS, + SS, TemplateKWLoc, /*FirstQualifierInScope*/ 0, R, TemplateArgs); } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 1aa5944669..91630e8d74 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -9252,6 +9252,7 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, CXXScopeSpec SS; SS.Adopt(ULE->getQualifierLoc()); + SourceLocation TemplateKWLoc = ULE->getTemplateKeywordLoc(); TemplateArgumentListInfo TABuffer; TemplateArgumentListInfo *ExplicitTemplateArgs = 0; @@ -9280,10 +9281,11 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, // casts and such from the call, we don't really care. ExprResult NewFn = ExprError(); if ((*R.begin())->isCXXClassMember()) - NewFn = SemaRef.BuildPossibleImplicitMemberExpr(SS, R, - ExplicitTemplateArgs); + NewFn = SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, + R, ExplicitTemplateArgs); else if (ExplicitTemplateArgs) - NewFn = SemaRef.BuildTemplateIdExpr(SS, R, false, *ExplicitTemplateArgs); + NewFn = SemaRef.BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, + *ExplicitTemplateArgs); else NewFn = SemaRef.BuildDeclarationNameExpr(SS, R, false); @@ -10774,6 +10776,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, DeclRefExpr *DRE = DeclRefExpr::Create(Context, ULE->getQualifierLoc(), + ULE->getTemplateKeywordLoc(), Fn, ULE->getNameLoc(), Fn->getType(), @@ -10800,6 +10803,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, if (cast(Fn)->isStatic()) { DeclRefExpr *DRE = DeclRefExpr::Create(Context, MemExpr->getQualifierLoc(), + MemExpr->getTemplateKeywordLoc(), Fn, MemExpr->getMemberLoc(), Fn->getType(), @@ -10833,6 +10837,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, MemberExpr *ME = MemberExpr::Create(Context, Base, MemExpr->isArrow(), MemExpr->getQualifierLoc(), + MemExpr->getTemplateKeywordLoc(), Fn, Found, MemExpr->getMemberNameInfo(), diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index f847e2e2e0..00f71c7ee5 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1263,7 +1263,9 @@ static ExprResult BuildForRangeBeginEndCall(Sema &SemaRef, Scope *S, ExprResult MemberRef = SemaRef.BuildMemberReferenceExpr(Range, Range->getType(), Loc, /*IsPtr=*/false, CXXScopeSpec(), - /*Qualifier=*/0, MemberLookup, + /*TemplateKWLoc=*/SourceLocation(), + /*FirstQualifierInScope=*/0, + MemberLookup, /*TemplateArgs=*/0); if (MemberRef.isInvalid()) return ExprError(); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 3b1a03d9c5..5b7e4a72b7 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -390,6 +390,7 @@ void Sema::LookupTemplateName(LookupResult &Found, /// specifier naming a dependent type. ExprResult Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, bool isAddressOfOperand, const TemplateArgumentListInfo *TemplateArgs) { @@ -409,20 +410,23 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS, /*IsArrow*/ true, /*Op*/ SourceLocation(), SS.getWithLocInContext(Context), + TemplateKWLoc, FirstQualifierInScope, NameInfo, TemplateArgs)); } - return BuildDependentDeclRefExpr(SS, NameInfo, TemplateArgs); + return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs); } ExprResult Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { return Owned(DependentScopeDeclRefExpr::Create(Context, SS.getWithLocInContext(Context), + TemplateKWLoc, NameInfo, TemplateArgs)); } @@ -2196,6 +2200,7 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, } ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, LookupResult &R, bool RequiresADL, const TemplateArgumentListInfo &TemplateArgs) { @@ -2219,6 +2224,7 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, UnresolvedLookupExpr *ULE = UnresolvedLookupExpr::Create(Context, R.getNamingClass(), SS.getWithLocInContext(Context), + TemplateKWLoc, R.getLookupNameInfo(), RequiresADL, TemplateArgs, R.begin(), R.end()); @@ -2229,13 +2235,15 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, // We actually only call this from template instantiation. ExprResult Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo &TemplateArgs) { DeclContext *DC; if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext() || RequireCompleteDeclContext(SS, DC)) - return BuildDependentDeclRefExpr(SS, NameInfo, &TemplateArgs); + return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, + &TemplateArgs); bool MemberOfUnknownSpecialization; LookupResult R(*this, NameInfo, LookupOrdinaryName); @@ -2259,7 +2267,7 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, return ExprError(); } - return BuildTemplateIdExpr(SS, R, /* ADL */ false, TemplateArgs); + return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*ADL*/ false, TemplateArgs); } /// \brief Form a dependent template name. @@ -2270,8 +2278,8 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, /// SS will be "MetaFun::", \p TemplateKWLoc contains the location /// of the "template" keyword, and "apply" is the \p Name. TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, - SourceLocation TemplateKWLoc, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, @@ -2739,9 +2747,14 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, CXXScopeSpec SS; SS.Adopt(Arg.getTemplateQualifierLoc()); + // FIXME: the template-template arg was a DependentTemplateName, + // so it was provided with a template keyword. However, its source + // location is not stored in the template argument structure. + SourceLocation TemplateKWLoc; ExprResult E = Owned(DependentScopeDeclRefExpr::Create(Context, SS.getWithLocInContext(Context), - NameInfo)); + TemplateKWLoc, + NameInfo, 0)); // If we parsed the template argument as a pack expansion, create a // pack expansion expression. diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 866cd225db..280a60e5de 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -3795,11 +3795,12 @@ static void HandleExtVectorTypeAttr(QualType &CurType, // Special case where the argument is a template id. if (Attr.getParameterName()) { CXXScopeSpec SS; + SourceLocation TemplateKWLoc; UnqualifiedId id; id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); - - ExprResult Size = S.ActOnIdExpression(S.getCurScope(), SS, id, false, - false); + + ExprResult Size = S.ActOnIdExpression(S.getCurScope(), SS, TemplateKWLoc, + id, false, false); if (Size.isInvalid()) return; diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 284371b7de..a6777ec5d8 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -418,7 +418,7 @@ public: /// Subclasses may override this function to provide alternate behavior. TemplateName TransformTemplateName(CXXScopeSpec &SS, TemplateName Name, - SourceLocation NameLoc, + SourceLocation NameLoc, QualType ObjectType = QualType(), NamedDecl *FirstQualifierInScope = 0); @@ -1464,6 +1464,7 @@ public: ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc, bool isArrow, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, ValueDecl *Member, NamedDecl *FoundDecl, @@ -1508,7 +1509,8 @@ public: R.resolveKind(); return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow, - SS, FirstQualifierInScope, + SS, TemplateKWLoc, + FirstQualifierInScope, R, ExplicitTemplateArgs); } @@ -1572,7 +1574,8 @@ public: DeclarationNameInfo NameInfo(&Accessor, AccessorLoc); return getSema().BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, /*IsArrow*/ false, - SS, /*FirstQualifierInScope*/ 0, + SS, SourceLocation(), + /*FirstQualifierInScope*/ 0, NameInfo, /* TemplateArgs */ 0); } @@ -2023,16 +2026,18 @@ public: /// Subclasses may override this routine to provide different behavior. ExprResult RebuildDependentScopeDeclRefExpr( NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { CXXScopeSpec SS; SS.Adopt(QualifierLoc); if (TemplateArgs) - return getSema().BuildQualifiedTemplateIdExpr(SS, NameInfo, - *TemplateArgs); + return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, + NameInfo, *TemplateArgs); - return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo); + return getSema().BuildQualifiedDeclarationNameExpr(SS, TemplateKWLoc, + NameInfo); } /// \brief Build a new template-id expression. @@ -2040,10 +2045,12 @@ public: /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS, - LookupResult &R, - bool RequiresADL, + SourceLocation TemplateKWLoc, + LookupResult &R, + bool RequiresADL, const TemplateArgumentListInfo &TemplateArgs) { - return getSema().BuildTemplateIdExpr(SS, R, RequiresADL, TemplateArgs); + return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL, + TemplateArgs); } /// \brief Build a new object-construction expression. @@ -2108,6 +2115,7 @@ public: bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) { @@ -2116,7 +2124,8 @@ public: return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType, OperatorLoc, IsArrow, - SS, FirstQualifierInScope, + SS, TemplateKWLoc, + FirstQualifierInScope, MemberNameInfo, TemplateArgs); } @@ -2129,6 +2138,7 @@ public: SourceLocation OperatorLoc, bool IsArrow, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs) { @@ -2137,7 +2147,8 @@ public: return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType, OperatorLoc, IsArrow, - SS, FirstQualifierInScope, + SS, TemplateKWLoc, + FirstQualifierInScope, R, TemplateArgs); } @@ -2228,7 +2239,8 @@ public: return move(Result); return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(), - /*FIXME:*/IvarLoc, IsArrow, SS, + /*FIXME:*/IvarLoc, IsArrow, + SS, SourceLocation(), /*FirstQualifierInScope=*/0, R, /*TemplateArgs=*/0); @@ -2257,7 +2269,7 @@ public: return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(), /*FIXME:*/PropertyLoc, IsArrow, - SS, + SS, SourceLocation(), /*FirstQualifierInScope=*/0, R, /*TemplateArgs=*/0); @@ -2299,7 +2311,8 @@ public: return move(Result); return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(), - /*FIXME:*/IsaLoc, IsArrow, SS, + /*FIXME:*/IsaLoc, IsArrow, + SS, SourceLocation(), /*FirstQualifierInScope=*/0, R, /*TemplateArgs=*/0); @@ -6244,6 +6257,7 @@ TreeTransform::TransformMemberExpr(MemberExpr *E) { if (!QualifierLoc) return ExprError(); } + SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); ValueDecl *Member = cast_or_null(getDerived().TransformDecl(E->getMemberLoc(), @@ -6297,6 +6311,7 @@ TreeTransform::TransformMemberExpr(MemberExpr *E) { return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc, E->isArrow(), QualifierLoc, + TemplateKWLoc, E->getMemberNameInfo(), Member, FoundDecl, @@ -7334,6 +7349,8 @@ TreeTransform::TransformUnresolvedLookupExpr( R.setNamingClass(NamingClass); } + SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); + // If we have no template arguments, it's a normal declaration name. if (!Old->hasExplicitTemplateArgs()) return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL()); @@ -7346,8 +7363,8 @@ TreeTransform::TransformUnresolvedLookupExpr( TransArgs)) return ExprError(); - return getDerived().RebuildTemplateIdExpr(SS, R, Old->requiresADL(), - TransArgs); + return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R, + Old->requiresADL(), TransArgs); } template @@ -7443,6 +7460,7 @@ TreeTransform::TransformDependentScopeDeclRefExpr( = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); if (!QualifierLoc) return ExprError(); + SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); // TODO: If this is a conversion-function-id, verify that the // destination type name (if present) resolves the same way after @@ -7462,6 +7480,7 @@ TreeTransform::TransformDependentScopeDeclRefExpr( return SemaRef.Owned(E); return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc, + TemplateKWLoc, NameInfo, /*TemplateArgs*/ 0); } @@ -7473,6 +7492,7 @@ TreeTransform::TransformDependentScopeDeclRefExpr( return ExprError(); return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc, + TemplateKWLoc, NameInfo, &TransArgs); } @@ -7660,6 +7680,8 @@ TreeTransform::TransformCXXDependentScopeMemberExpr( return ExprError(); } + SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); + // TODO: If this is a conversion-function-id, verify that the // destination type name (if present) resolves the same way after // instantiation as it did in the local scope. @@ -7685,6 +7707,7 @@ TreeTransform::TransformCXXDependentScopeMemberExpr( E->isArrow(), E->getOperatorLoc(), QualifierLoc, + TemplateKWLoc, FirstQualifierInScope, NameInfo, /*TemplateArgs*/ 0); @@ -7701,6 +7724,7 @@ TreeTransform::TransformCXXDependentScopeMemberExpr( E->isArrow(), E->getOperatorLoc(), QualifierLoc, + TemplateKWLoc, FirstQualifierInScope, NameInfo, &TransArgs); @@ -7733,6 +7757,8 @@ TreeTransform::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) return ExprError(); } + SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); + LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName); @@ -7800,6 +7826,7 @@ TreeTransform::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) Old->getOperatorLoc(), Old->isArrow(), QualifierLoc, + TemplateKWLoc, FirstQualifierInScope, R, (Old->hasExplicitTemplateArgs() @@ -8499,10 +8526,9 @@ TreeTransform::RebuildTemplateName(CXXScopeSpec &SS, UnqualifiedId TemplateName; TemplateName.setIdentifier(&Name, NameLoc); Sema::TemplateTy Template; + SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. getSema().ActOnDependentTemplateName(/*Scope=*/0, - /*FIXME:*/SourceLocation(), - SS, - TemplateName, + SS, TemplateKWLoc, TemplateName, ParsedType::make(ObjectType), /*EnteringContext=*/false, Template); @@ -8517,13 +8543,12 @@ TreeTransform::RebuildTemplateName(CXXScopeSpec &SS, QualType ObjectType) { UnqualifiedId Name; // FIXME: Bogus location information. - SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc }; + SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc }; Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations); + SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. Sema::TemplateTy Template; getSema().ActOnDependentTemplateName(/*Scope=*/0, - /*FIXME:*/SourceLocation(), - SS, - Name, + SS, TemplateKWLoc, Name, ParsedType::make(ObjectType), /*EnteringContext=*/false, Template); @@ -8660,9 +8685,11 @@ TreeTransform::RebuildCXXPseudoDestructorExpr(Expr *Base, // FIXME: the ScopeType should be tacked onto SS. + SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. return getSema().BuildMemberReferenceExpr(Base, BaseType, OperatorLoc, isArrow, - SS, /*FIXME: FirstQualifier*/ 0, + SS, TemplateKWLoc, + /*FIXME: FirstQualifier*/ 0, NameInfo, /*TemplateArgs*/ 0); } diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index a7dfa1b19f..623ee1ffc0 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -78,7 +78,10 @@ namespace clang { /// \brief The number of record fields required for the Expr class /// itself. static const unsigned NumExprFields = NumStmtFields + 7; - + + /// \brief Read and initialize a ExplicitTemplateArgumentList structure. + void ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, + unsigned NumTemplateArgs); /// \brief Read and initialize a ExplicitTemplateArgumentList structure. void ReadExplicitTemplateArgumentList(ASTTemplateArgumentListInfo &ArgList, unsigned NumTemplateArgs); @@ -91,15 +94,16 @@ namespace clang { } void ASTStmtReader:: -ReadExplicitTemplateArgumentList(ASTTemplateArgumentListInfo &ArgList, - unsigned NumTemplateArgs) { +ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, + unsigned NumTemplateArgs) { + SourceLocation TemplateKWLoc = ReadSourceLocation(Record, Idx); TemplateArgumentListInfo ArgInfo; ArgInfo.setLAngleLoc(ReadSourceLocation(Record, Idx)); ArgInfo.setRAngleLoc(ReadSourceLocation(Record, Idx)); for (unsigned i = 0; i != NumTemplateArgs; ++i) ArgInfo.addArgument( Reader.ReadTemplateArgumentLoc(F, Record, Idx)); - ArgList.initializeFrom(ArgInfo); + Args.initializeFrom(TemplateKWLoc, ArgInfo); } void ASTStmtReader::VisitStmt(Stmt *S) { @@ -326,10 +330,10 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { E->DeclRefExprBits.HasQualifier = Record[Idx++]; E->DeclRefExprBits.HasFoundDecl = Record[Idx++]; - E->DeclRefExprBits.HasExplicitTemplateArgs = Record[Idx++]; + E->DeclRefExprBits.HasTemplateKWAndArgsInfo = Record[Idx++]; E->DeclRefExprBits.HadMultipleCandidates = Record[Idx++]; unsigned NumTemplateArgs = 0; - if (E->hasExplicitTemplateArgs()) + if (E->hasTemplateKWAndArgsInfo()) NumTemplateArgs = Record[Idx++]; if (E->hasQualifier()) @@ -339,9 +343,9 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { if (E->hasFoundDecl()) E->getInternalFoundDecl() = ReadDeclAs(Record, Idx); - if (E->hasExplicitTemplateArgs()) - ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), - NumTemplateArgs); + if (E->hasTemplateKWAndArgsInfo()) + ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), + NumTemplateArgs); E->setDecl(ReadDeclAs(Record, Idx)); E->setLocation(ReadSourceLocation(Record, Idx)); @@ -1204,10 +1208,10 @@ void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) { void ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ VisitExpr(E); - - if (Record[Idx++]) - ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), - Record[Idx++]); + + if (Record[Idx++]) // HasTemplateKWAndArgsInfo + ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), + /*NumTemplateArgs=*/Record[Idx++]); E->Base = Reader.ReadSubExpr(); E->BaseType = Reader.readType(F, Record, Idx); @@ -1221,10 +1225,10 @@ ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ void ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { VisitExpr(E); - - if (Record[Idx++]) - ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), - Record[Idx++]); + + if (Record[Idx++]) // HasTemplateKWAndArgsInfo + ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), + /*NumTemplateArgs=*/Record[Idx++]); E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); ReadDeclarationNameInfo(E->NameInfo, Record, Idx); @@ -1244,11 +1248,10 @@ ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) { VisitExpr(E); - - // Read the explicit template argument list, if available. - if (Record[Idx++]) - ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), - Record[Idx++]); + + if (Record[Idx++]) // HasTemplateKWAndArgsInfo + ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(), + /*NumTemplateArgs=*/Record[Idx++]); unsigned NumDecls = Record[Idx++]; UnresolvedSet<8> Decls; @@ -1605,7 +1608,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, /*HasQualifier=*/Record[ASTStmtReader::NumExprFields], /*HasFoundDecl=*/Record[ASTStmtReader::NumExprFields + 1], - /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 2], + /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 2], /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 2] ? Record[ASTStmtReader::NumExprFields + 4] : 0); break; @@ -1672,9 +1675,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx); } + SourceLocation TemplateKWLoc; TemplateArgumentListInfo ArgInfo; - bool HasExplicitTemplateArgs = Record[Idx++]; - if (HasExplicitTemplateArgs) { + bool HasTemplateKWAndArgsInfo = Record[Idx++]; + if (HasTemplateKWAndArgsInfo) { + TemplateKWLoc = ReadSourceLocation(F, Record, Idx); unsigned NumTemplateArgs = Record[Idx++]; ArgInfo.setLAngleLoc(ReadSourceLocation(F, Record, Idx)); ArgInfo.setRAngleLoc(ReadSourceLocation(F, Record, Idx)); @@ -1698,8 +1703,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { bool IsArrow = Record[Idx++]; S = MemberExpr::Create(Context, Base, IsArrow, QualifierLoc, - MemberD, FoundDecl, MemberNameInfo, - HasExplicitTemplateArgs ? &ArgInfo : 0, T, VK, OK); + TemplateKWLoc, MemberD, FoundDecl, MemberNameInfo, + HasTemplateKWAndArgsInfo ? &ArgInfo : 0, + T, VK, OK); ReadDeclarationNameLoc(F, cast(S)->MemberDNLoc, MemberD->getDeclName(), Record, Idx); if (HadMultipleCandidates) @@ -1975,7 +1981,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case EXPR_CXX_DEPENDENT_SCOPE_MEMBER: S = CXXDependentScopeMemberExpr::CreateEmpty(Context, - /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields], + /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] ? Record[ASTStmtReader::NumExprFields + 1] : 0); @@ -1983,7 +1989,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF: S = DependentScopeDeclRefExpr::CreateEmpty(Context, - /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields], + /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] ? Record[ASTStmtReader::NumExprFields + 1] : 0); @@ -1996,7 +2002,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case EXPR_CXX_UNRESOLVED_MEMBER: S = UnresolvedMemberExpr::CreateEmpty(Context, - /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields], + /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] ? Record[ASTStmtReader::NumExprFields + 1] : 0); @@ -2004,7 +2010,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case EXPR_CXX_UNRESOLVED_LOOKUP: S = UnresolvedLookupExpr::CreateEmpty(Context, - /*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields], + /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] ? Record[ASTStmtReader::NumExprFields + 1] : 0); diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index e3202a7830..3cfab776d0 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -34,9 +34,8 @@ namespace clang { ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record) : Writer(Writer), Record(Record) { } - - void - AddExplicitTemplateArgumentList(const ASTTemplateArgumentListInfo &Args); + + void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args); void VisitStmt(Stmt *S); #define STMT(Type, Base) \ @@ -46,7 +45,8 @@ namespace clang { } void ASTStmtWriter:: -AddExplicitTemplateArgumentList(const ASTTemplateArgumentListInfo &Args) { +AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args) { + Writer.AddSourceLocation(Args.getTemplateKeywordLoc(), Record); Writer.AddSourceLocation(Args.LAngleLoc, Record); Writer.AddSourceLocation(Args.RAngleLoc, Record); for (unsigned i=0; i != Args.NumTemplateArgs; ++i) @@ -264,17 +264,17 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { Record.push_back(E->hasQualifier()); Record.push_back(E->getDecl() != E->getFoundDecl()); - Record.push_back(E->hasExplicitTemplateArgs()); + Record.push_back(E->hasTemplateKWAndArgsInfo()); Record.push_back(E->hadMultipleCandidates()); - if (E->hasExplicitTemplateArgs()) { + if (E->hasTemplateKWAndArgsInfo()) { unsigned NumTemplateArgs = E->getNumTemplateArgs(); Record.push_back(NumTemplateArgs); } DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind()); - if ((!E->hasExplicitTemplateArgs()) && (!E->hasQualifier()) && + if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) && (E->getDecl() == E->getFoundDecl()) && nk == DeclarationName::Identifier) { AbbrevToUse = Writer.getDeclRefExprAbbrev(); @@ -286,8 +286,8 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { if (E->getDecl() != E->getFoundDecl()) Writer.AddDeclRef(E->getFoundDecl(), Record); - if (E->hasExplicitTemplateArgs()) - AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs()); + if (E->hasTemplateKWAndArgsInfo()) + AddTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo()); Writer.AddDeclRef(E->getDecl(), Record); Writer.AddSourceLocation(E->getLocation(), Record); @@ -449,8 +449,9 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { if (E->hasQualifier()) Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); - Record.push_back(E->hasExplicitTemplateArgs()); - if (E->hasExplicitTemplateArgs()) { + Record.push_back(E->HasTemplateKWAndArgsInfo); + if (E->HasTemplateKWAndArgsInfo) { + Writer.AddSourceLocation(E->getTemplateKeywordLoc(), Record); unsigned NumTemplateArgs = E->getNumTemplateArgs(); Record.push_back(NumTemplateArgs); Writer.AddSourceLocation(E->getLAngleLoc(), Record); @@ -1194,17 +1195,17 @@ void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) { void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ VisitExpr(E); - - // Don't emit anything here, hasExplicitTemplateArgs() must be + + // Don't emit anything here, HasTemplateKWAndArgsInfo must be // emitted first. - Record.push_back(E->hasExplicitTemplateArgs()); - if (E->hasExplicitTemplateArgs()) { - const ASTTemplateArgumentListInfo &Args = E->getExplicitTemplateArgs(); + Record.push_back(E->HasTemplateKWAndArgsInfo); + if (E->HasTemplateKWAndArgsInfo) { + const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo(); Record.push_back(Args.NumTemplateArgs); - AddExplicitTemplateArgumentList(Args); + AddTemplateKWAndArgsInfo(Args); } - + if (!E->isImplicitAccess()) Writer.AddStmt(E->getBase()); else @@ -1221,14 +1222,15 @@ ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ void ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { VisitExpr(E); - - // Don't emit anything here, hasExplicitTemplateArgs() must be + + // Don't emit anything here, HasTemplateKWAndArgsInfo must be // emitted first. - Record.push_back(E->hasExplicitTemplateArgs()); - if (E->hasExplicitTemplateArgs()) { - const ASTTemplateArgumentListInfo &Args = E->getExplicitTemplateArgs(); + + Record.push_back(E->HasTemplateKWAndArgsInfo); + if (E->HasTemplateKWAndArgsInfo) { + const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo(); Record.push_back(Args.NumTemplateArgs); - AddExplicitTemplateArgumentList(Args); + AddTemplateKWAndArgsInfo(Args); } Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); @@ -1251,13 +1253,15 @@ ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) { VisitExpr(E); - - // Don't emit anything here, hasExplicitTemplateArgs() must be emitted first. - Record.push_back(E->hasExplicitTemplateArgs()); - if (E->hasExplicitTemplateArgs()) { - const ASTTemplateArgumentListInfo &Args = E->getExplicitTemplateArgs(); + + // Don't emit anything here, HasTemplateKWAndArgsInfo must be + // emitted first. + + Record.push_back(E->HasTemplateKWAndArgsInfo); + if (E->HasTemplateKWAndArgsInfo) { + const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo(); Record.push_back(Args.NumTemplateArgs); - AddExplicitTemplateArgumentList(Args); + AddTemplateKWAndArgsInfo(Args); } Record.push_back(E->getNumDecls()); diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index f49d6f6ccc..a2c0fb0bdf 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -4269,7 +4269,7 @@ CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags, if (DeclRefExpr *E = dyn_cast(getCursorExpr(C))) Pieces = buildPieces(NameFlags, false, E->getNameInfo(), E->getQualifierLoc().getSourceRange(), - E->getExplicitTemplateArgsOpt()); + E->getOptionalExplicitTemplateArgs()); break; case CXCursor_CallExpr: -- 2.40.0