diff options
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 2 | ||||
-rw-r--r-- | include/clang/AST/TemplateBase.h | 92 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 9 | ||||
-rw-r--r-- | lib/AST/ASTDiagnostic.cpp | 4 | ||||
-rw-r--r-- | lib/AST/ASTImporter.cpp | 26 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 12 | ||||
-rw-r--r-- | lib/AST/DumpXML.cpp | 4 | ||||
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 102 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 4 | ||||
-rw-r--r-- | lib/AST/TemplateBase.cpp | 63 | ||||
-rw-r--r-- | lib/AST/TypeLoc.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 88 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 66 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 5 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 11 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 6 | ||||
-rw-r--r-- | test/CodeGenCXX/mangle-nullptr-arg.cpp | 3 | ||||
-rw-r--r-- | test/CodeGenCXX/mangle-template.cpp | 4 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 7 | ||||
-rw-r--r-- | tools/libclang/CIndexUSRs.cpp | 8 | ||||
-rw-r--r-- | tools/libclang/RecursiveASTVisitor.h | 2 |
23 files changed, 314 insertions, 217 deletions
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 22cd290858..f96e067978 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -721,6 +721,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument( case TemplateArgument::Null: case TemplateArgument::Declaration: case TemplateArgument::Integral: + case TemplateArgument::NullPtr: return true; case TemplateArgument::Type: @@ -753,6 +754,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc( case TemplateArgument::Null: case TemplateArgument::Declaration: case TemplateArgument::Integral: + case TemplateArgument::NullPtr: return true; case TemplateArgument::Type: { diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 5047028e5e..1c0abde5b7 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -28,11 +28,11 @@ namespace llvm { namespace clang { -class Decl; class DiagnosticBuilder; class Expr; struct PrintingPolicy; class TypeSourceInfo; +class ValueDecl; /// \brief Represents a template argument within a class template /// specialization. @@ -43,12 +43,14 @@ public: /// \brief Represents an empty template argument, e.g., one that has not /// been deduced. Null = 0, - /// The template argument is a type. Its value is stored in the - /// TypeOrValue field. + /// The template argument is a type. Type, - /// The template argument is a declaration that was provided for a pointer - /// or reference non-type template parameter. + /// The template argument is a declaration that was provided for a pointer, + /// reference, or pointer to member non-type template parameter. Declaration, + /// The template argument is a null pointer or null pointer to member that + /// was provided for a non-type template parameter. + NullPtr, /// The template argument is an integral value stored in an llvm::APSInt /// that was provided for an integral non-type template parameter. Integral, @@ -73,6 +75,10 @@ private: union { uintptr_t TypeOrValue; struct { + ValueDecl *D; + bool ForRefParam; + } DeclArg; + struct { // We store a decomposed APSInt with the data allocated by ASTContext if // BitWidth > 64. The memory may be shared between multiple // TemplateArgument instances. @@ -101,15 +107,18 @@ public: TemplateArgument() : Kind(Null), TypeOrValue(0) { } /// \brief Construct a template type argument. - TemplateArgument(QualType T) : Kind(Type) { + TemplateArgument(QualType T, bool isNullPtr = false) + : Kind(isNullPtr ? NullPtr : Type) { TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); } /// \brief Construct a template argument that refers to a /// declaration, which is either an external declaration or a /// template declaration. - TemplateArgument(Decl *D) : Kind(Declaration) { - TypeOrValue = reinterpret_cast<uintptr_t>(D); + TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) { + assert(D && "Expected decl"); + DeclArg.D = D; + DeclArg.ForRefParam = ForRefParam; } /// \brief Construct an integral constant template argument. The memory to @@ -177,6 +186,10 @@ public: this->Args.NumArgs = NumArgs; } + static TemplateArgument getEmptyPack() { + return TemplateArgument((TemplateArgument*)0, 0); + } + /// \brief Create a new template argument pack by copying the given set of /// template arguments. static TemplateArgument CreatePackCopy(ASTContext &Context, @@ -205,34 +218,43 @@ public: /// \brief Determine whether this template argument is a pack expansion. bool isPackExpansion() const; - /// \brief Retrieve the template argument as a type. + /// \brief Retrieve the type for a type template argument. QualType getAsType() const { - if (Kind != Type) - return QualType(); - + assert(Kind == Type && "Unexpected kind"); return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); } - /// \brief Retrieve the template argument as a declaration. - Decl *getAsDecl() const { - if (Kind != Declaration) - return 0; - return reinterpret_cast<Decl *>(TypeOrValue); + /// \brief Retrieve the declaration for a declaration non-type + /// template argument. + ValueDecl *getAsDecl() const { + assert(Kind == Declaration && "Unexpected kind"); + return DeclArg.D; + } + + /// \brief Retrieve whether a declaration is binding to a + /// reference parameter in a declaration non-type template argument. + bool isDeclForReferenceParam() const { + assert(Kind == Declaration && "Unexpected kind"); + return DeclArg.ForRefParam; } - /// \brief Retrieve the template argument as a template name. + /// \brief Retrieve the type for null non-type template argument. + QualType getNullPtrType() const { + assert(Kind == NullPtr && "Unexpected kind"); + return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); + } + + /// \brief Retrieve the template name for a template name argument. TemplateName getAsTemplate() const { - if (Kind != Template) - return TemplateName(); - + assert(Kind == Template && "Unexpected kind"); return TemplateName::getFromVoidPointer(TemplateArg.Name); } /// \brief Retrieve the template argument as a template name; if the argument /// is a pack expansion, return the pattern as a template name. TemplateName getAsTemplateOrTemplatePattern() const { - if (Kind != Template && Kind != TemplateExpansion) - return TemplateName(); + assert((Kind == Template || Kind == TemplateExpansion) && + "Unexpected kind"); return TemplateName::getFromVoidPointer(TemplateArg.Name); } @@ -244,6 +266,7 @@ public: /// \brief Retrieve the template argument as an integral value. // FIXME: Provide a way to read the integral data without copying the value. llvm::APSInt getAsIntegral() const { + assert(Kind == Integral && "Unexpected kind"); using namespace llvm; if (Integer.BitWidth <= 64) return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); @@ -255,23 +278,18 @@ public: /// \brief Retrieve the type of the integral value. QualType getIntegralType() const { - if (Kind != Integral) - return QualType(); - + assert(Kind == Integral && "Unexpected kind"); return QualType::getFromOpaquePtr(Integer.Type); } void setIntegralType(QualType T) { - assert(Kind == Integral && - "Cannot set the integral type of a non-integral template argument"); + assert(Kind == Integral && "Unexpected kind"); Integer.Type = T.getAsOpaquePtr(); } /// \brief Retrieve the template argument as an expression. Expr *getAsExpr() const { - if (Kind != Expression) - return 0; - + assert(Kind == Expression && "Unexpected kind"); return reinterpret_cast<Expr *>(TypeOrValue); } @@ -436,7 +454,17 @@ public: assert(Argument.getKind() == TemplateArgument::Declaration); return LocInfo.getAsExpr(); } - + + Expr *getSourceNullPtrExpression() const { + assert(Argument.getKind() == TemplateArgument::NullPtr); + return LocInfo.getAsExpr(); + } + + Expr *getSourceIntegralExpression() const { + assert(Argument.getKind() == TemplateArgument::Integral); + return LocInfo.getAsExpr(); + } + NestedNameSpecifierLoc getTemplateQualifierLoc() const { assert(Argument.getKind() == TemplateArgument::Template || Argument.getKind() == TemplateArgument::TemplateExpansion); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 9fd40b206d..f19a2aaaf7 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3684,11 +3684,14 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const { return Arg; case TemplateArgument::Declaration: { - if (Decl *D = Arg.getAsDecl()) - return TemplateArgument(D->getCanonicalDecl()); - return TemplateArgument((Decl*)0); + ValueDecl *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl()); + return TemplateArgument(D, Arg.isDeclForReferenceParam()); } + case TemplateArgument::NullPtr: + return TemplateArgument(getCanonicalType(Arg.getNullPtrType()), + /*isNullPtr*/true); + case TemplateArgument::Template: return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate())); diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp index a605f1a40c..411c337321 100644 --- a/lib/AST/ASTDiagnostic.cpp +++ b/lib/AST/ASTDiagnostic.cpp @@ -923,7 +923,9 @@ class TemplateDiff { bool isVariadic = DefaultTTPD->isParameterPack(); TemplateArgument TA = DefaultTTPD->getDefaultArgument().getArgument(); - TemplateDecl *DefaultTD = TA.getAsTemplate().getAsTemplateDecl(); + TemplateDecl *DefaultTD = 0; + if (TA.getKind() != TemplateArgument::Null) + DefaultTD = TA.getAsTemplate().getAsTemplateDecl(); if (!Iter.isEnd()) ArgDecl = Iter->getAsTemplate().getAsTemplateDecl(); diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 34e699496b..a90026072b 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -288,7 +288,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, case TemplateArgument::Type: return Context.IsStructurallyEquivalent(Arg1.getAsType(), Arg2.getAsType()); - + case TemplateArgument::Integral: if (!Context.IsStructurallyEquivalent(Arg1.getIntegralType(), Arg2.getIntegralType())) @@ -297,10 +297,11 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, return llvm::APSInt::isSameValue(Arg1.getAsIntegral(), Arg2.getAsIntegral()); case TemplateArgument::Declaration: - if (!Arg1.getAsDecl() || !Arg2.getAsDecl()) - return !Arg1.getAsDecl() && !Arg2.getAsDecl(); return Context.IsStructurallyEquivalent(Arg1.getAsDecl(), Arg2.getAsDecl()); - + + case TemplateArgument::NullPtr: + return true; // FIXME: Is this correct? + case TemplateArgument::Template: return IsStructurallyEquivalent(Context, Arg1.getAsTemplate(), @@ -1976,11 +1977,20 @@ ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) { return TemplateArgument(From, ToType); } - case TemplateArgument::Declaration: - if (Decl *To = Importer.Import(From.getAsDecl())) - return TemplateArgument(To); + case TemplateArgument::Declaration: { + ValueDecl *FromD = From.getAsDecl(); + if (ValueDecl *To = cast_or_null<ValueDecl>(Importer.Import(FromD))) + return TemplateArgument(To, From.isDeclForReferenceParam()); return TemplateArgument(); - + } + + case TemplateArgument::NullPtr: { + QualType ToType = Importer.Import(From.getNullPtrType()); + if (ToType.isNull()) + return TemplateArgument(); + return TemplateArgument(ToType, /*isNullPtr*/true); + } + case TemplateArgument::Template: { TemplateName ToTemplate = Importer.Import(From.getAsTemplate()); if (ToTemplate.isNull()) diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 13f931ae0b..8553e030e2 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -126,12 +126,12 @@ static LinkageInfo getLVForTemplateArgumentList(const TemplateArgument *Args, break; case TemplateArgument::Declaration: - // The decl can validly be null as the representation of nullptr - // arguments, valid only in C++0x. - if (Decl *D = Args[I].getAsDecl()) { - if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) - LV.mergeWithMin(getLVForDecl(ND, OnlyTemplate)); - } + if (NamedDecl *ND = dyn_cast<NamedDecl>(Args[I].getAsDecl())) + LV.mergeWithMin(getLVForDecl(ND, OnlyTemplate)); + break; + + case TemplateArgument::NullPtr: + LV.mergeWithMin(getLVForType(Args[I].getNullPtrType())); break; case TemplateArgument::Template: diff --git a/lib/AST/DumpXML.cpp b/lib/AST/DumpXML.cpp index 29d8c62c13..11e3b529a4 100644 --- a/lib/AST/DumpXML.cpp +++ b/lib/AST/DumpXML.cpp @@ -316,12 +316,12 @@ struct XMLDumper : public XMLDeclVisitor<XMLDumper>, } case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: + case TemplateArgument::NullPtr: // FIXME: Implement! break; case TemplateArgument::Declaration: { - if (Decl *D = A.getAsDecl()) - visitDeclRef(D); + visitDeclRef(A.getAsDecl()); break; } case TemplateArgument::Integral: { diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 3a168017d7..d8c6594d02 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -343,17 +343,10 @@ private: void mangleCXXDtorType(CXXDtorType T); void mangleTemplateArgs(const ASTTemplateArgumentListInfo &TemplateArgs); - void mangleTemplateArgs(TemplateName Template, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs); - void mangleTemplateArgs(const TemplateParameterList &PL, - const TemplateArgument *TemplateArgs, + void mangleTemplateArgs(const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs); - void mangleTemplateArgs(const TemplateParameterList &PL, - const TemplateArgumentList &AL); - void mangleTemplateArg(const NamedDecl *P, TemplateArgument A); - void mangleUnresolvedTemplateArgs(const TemplateArgument *args, - unsigned numArgs); + void mangleTemplateArgs(const TemplateArgumentList &AL); + void mangleTemplateArg(TemplateArgument A); void mangleTemplateParameter(unsigned Index); @@ -570,8 +563,7 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) { const TemplateArgumentList *TemplateArgs = 0; if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { mangleUnscopedTemplateName(TD); - TemplateParameterList *TemplateParameters = TD->getTemplateParameters(); - mangleTemplateArgs(*TemplateParameters, *TemplateArgs); + mangleTemplateArgs(*TemplateArgs); return; } @@ -593,8 +585,7 @@ void CXXNameMangler::mangleName(const TemplateDecl *TD, if (DC->isTranslationUnit() || isStdNamespace(DC)) { mangleUnscopedTemplateName(TD); - TemplateParameterList *TemplateParameters = TD->getTemplateParameters(); - mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs); + mangleTemplateArgs(TemplateArgs, NumTemplateArgs); } else { mangleNestedName(TD, TemplateArgs, NumTemplateArgs); } @@ -738,8 +729,7 @@ void CXXNameMangler::manglePrefix(QualType type) { // FIXME: GCC does not appear to mangle the template arguments when // the template in question is a dependent template name. Should we // emulate that badness? - mangleTemplateArgs(TST->getTemplateName(), TST->getArgs(), - TST->getNumArgs()); + mangleTemplateArgs(TST->getArgs(), TST->getNumArgs()); addSubstitution(QualType(TST, 0)); } } else if (const DependentTemplateSpecializationType *DTST @@ -752,7 +742,7 @@ void CXXNameMangler::manglePrefix(QualType type) { // FIXME: GCC does not appear to mangle the template arguments when // the template in question is a dependent template name. Should we // emulate that badness? - mangleTemplateArgs(Template, DTST->getArgs(), DTST->getNumArgs()); + mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs()); } else { // We use the QualType mangle type variant here because it handles // substitutions. @@ -943,7 +933,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, } } - mangleUnresolvedTemplateArgs(tst->getArgs(), tst->getNumArgs()); + mangleTemplateArgs(tst->getArgs(), tst->getNumArgs()); break; } @@ -960,7 +950,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, const DependentTemplateSpecializationType *tst = cast<DependentTemplateSpecializationType>(type); mangleSourceName(tst->getIdentifier()); - mangleUnresolvedTemplateArgs(tst->getArgs(), tst->getNumArgs()); + mangleTemplateArgs(tst->getArgs(), tst->getNumArgs()); break; } } @@ -1229,8 +1219,7 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND, const TemplateArgumentList *TemplateArgs = 0; if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { mangleTemplatePrefix(TD); - TemplateParameterList *TemplateParameters = TD->getTemplateParameters(); - mangleTemplateArgs(*TemplateParameters, *TemplateArgs); + mangleTemplateArgs(*TemplateArgs); } else { manglePrefix(DC, NoFunction); @@ -1247,8 +1236,7 @@ void CXXNameMangler::mangleNestedName(const TemplateDecl *TD, Out << 'N'; mangleTemplatePrefix(TD); - TemplateParameterList *TemplateParameters = TD->getTemplateParameters(); - mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs); + mangleTemplateArgs(TemplateArgs, NumTemplateArgs); Out << 'E'; } @@ -1421,8 +1409,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) { const TemplateArgumentList *TemplateArgs = 0; if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { mangleTemplatePrefix(TD); - TemplateParameterList *TemplateParameters = TD->getTemplateParameters(); - mangleTemplateArgs(*TemplateParameters, *TemplateArgs); + mangleTemplateArgs(*TemplateArgs); } else if(NoFunction && (isa<FunctionDecl>(ND) || isa<ObjCMethodDecl>(ND))) return; @@ -2172,7 +2159,7 @@ void CXXNameMangler::mangleType(const TemplateSpecializationType *T) { // FIXME: GCC does not appear to mangle the template arguments when // the template in question is a dependent template name. Should we // emulate that badness? - mangleTemplateArgs(T->getTemplateName(), T->getArgs(), T->getNumArgs()); + mangleTemplateArgs(T->getArgs(), T->getNumArgs()); addSubstitution(QualType(T, 0)); } } @@ -2198,7 +2185,7 @@ void CXXNameMangler::mangleType(const DependentTemplateSpecializationType *T) { // FIXME: GCC does not appear to mangle the template arguments when // the template in question is a dependent template name. Should we // emulate that badness? - mangleTemplateArgs(Prefix, T->getArgs(), T->getNumArgs()); + mangleTemplateArgs(T->getArgs(), T->getNumArgs()); Out << 'E'; } @@ -3053,50 +3040,28 @@ void CXXNameMangler::mangleTemplateArgs( // <template-args> ::= I <template-arg>+ E Out << 'I'; for (unsigned i = 0, e = TemplateArgs.NumTemplateArgs; i != e; ++i) - mangleTemplateArg(0, TemplateArgs.getTemplateArgs()[i].getArgument()); + mangleTemplateArg(TemplateArgs.getTemplateArgs()[i].getArgument()); Out << 'E'; } -void CXXNameMangler::mangleTemplateArgs(TemplateName Template, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs) { - if (TemplateDecl *TD = Template.getAsTemplateDecl()) - return mangleTemplateArgs(*TD->getTemplateParameters(), TemplateArgs, - NumTemplateArgs); - - mangleUnresolvedTemplateArgs(TemplateArgs, NumTemplateArgs); -} - -void CXXNameMangler::mangleUnresolvedTemplateArgs(const TemplateArgument *args, - unsigned numArgs) { - // <template-args> ::= I <template-arg>+ E - Out << 'I'; - for (unsigned i = 0; i != numArgs; ++i) - mangleTemplateArg(0, args[i]); - Out << 'E'; -} - -void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL, - const TemplateArgumentList &AL) { +void CXXNameMangler::mangleTemplateArgs(const TemplateArgumentList &AL) { // <template-args> ::= I <template-arg>+ E Out << 'I'; for (unsigned i = 0, e = AL.size(); i != e; ++i) - mangleTemplateArg(PL.getParam(i), AL[i]); + mangleTemplateArg(AL[i]); Out << 'E'; } -void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL, - const TemplateArgument *TemplateArgs, +void CXXNameMangler::mangleTemplateArgs(const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs) { // <template-args> ::= I <template-arg>+ E Out << 'I'; for (unsigned i = 0; i != NumTemplateArgs; ++i) - mangleTemplateArg(PL.getParam(i), TemplateArgs[i]); + mangleTemplateArg(TemplateArgs[i]); Out << 'E'; } -void CXXNameMangler::mangleTemplateArg(const NamedDecl *P, - TemplateArgument A) { +void CXXNameMangler::mangleTemplateArg(TemplateArgument A) { // <template-arg> ::= <type> # type or template // ::= X <expression> E # expression // ::= <expr-primary> # simple expressions @@ -3145,25 +3110,12 @@ void CXXNameMangler::mangleTemplateArg(const NamedDecl *P, mangleIntegerLiteral(A.getIntegralType(), A.getAsIntegral()); break; case TemplateArgument::Declaration: { - assert(P && "Missing template parameter for declaration argument"); // <expr-primary> ::= L <mangled-name> E # external name - // <expr-primary> ::= L <type> 0 E // Clang produces AST's where pointer-to-member-function expressions // and pointer-to-function expressions are represented as a declaration not // an expression. We compensate for it here to produce the correct mangling. - const NonTypeTemplateParmDecl *Parameter = cast<NonTypeTemplateParmDecl>(P); - - // Handle NULL pointer arguments. - if (!A.getAsDecl()) { - Out << "L"; - mangleType(Parameter->getType()); - Out << "0E"; - break; - } - - - NamedDecl *D = cast<NamedDecl>(A.getAsDecl()); - bool compensateMangling = !Parameter->getType()->isReferenceType(); + ValueDecl *D = A.getAsDecl(); + bool compensateMangling = !A.isDeclForReferenceParam(); if (compensateMangling) { Out << 'X'; mangleOperatorName(OO_Amp, 1); @@ -3186,14 +3138,20 @@ void CXXNameMangler::mangleTemplateArg(const NamedDecl *P, break; } - + case TemplateArgument::NullPtr: { + // <expr-primary> ::= L <type> 0 E + Out << 'L'; + mangleType(A.getNullPtrType()); + Out << "0E"; + break; + } case TemplateArgument::Pack: { // Note: proposal by Mike Herrick on 12/20/10 Out << 'J'; for (TemplateArgument::pack_iterator PA = A.pack_begin(), PAEnd = A.pack_end(); PA != PAEnd; ++PA) - mangleTemplateArg(P, *PA); + mangleTemplateArg(*PA); Out << 'E'; } } diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index 0c3186fec2..bfd3132506 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -1173,6 +1173,10 @@ void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) { VisitDecl(Arg.getAsDecl()); break; + case TemplateArgument::NullPtr: + VisitType(Arg.getNullPtrType()); + break; + case TemplateArgument::Integral: Arg.getAsIntegral().Profile(ID); VisitType(Arg.getIntegralType()); diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp index 95ff4edf1d..968a6be16e 100644 --- a/lib/AST/TemplateBase.cpp +++ b/lib/AST/TemplateBase.cpp @@ -77,7 +77,7 @@ TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context, const TemplateArgument *Args, unsigned NumArgs) { if (NumArgs == 0) - return TemplateArgument(0, 0); + return getEmptyPack(); TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs]; std::copy(Args, Args + NumArgs, Storage); @@ -99,12 +99,11 @@ bool TemplateArgument::isDependent() const { return true; case Declaration: - if (Decl *D = getAsDecl()) { - if (DeclContext *DC = dyn_cast<DeclContext>(D)) - return DC->isDependentContext(); - return D->getDeclContext()->isDependentContext(); - } - + if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) + return DC->isDependentContext(); + return getAsDecl()->getDeclContext()->isDependentContext(); + + case NullPtr: return false; case Integral: @@ -141,11 +140,11 @@ bool TemplateArgument::isInstantiationDependent() const { return true; case Declaration: - if (Decl *D = getAsDecl()) { - if (DeclContext *DC = dyn_cast<DeclContext>(D)) - return DC->isDependentContext(); - return D->getDeclContext()->isDependentContext(); - } + if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) + return DC->isDependentContext(); + return getAsDecl()->getDeclContext()->isDependentContext(); + + case NullPtr: return false; case Integral: @@ -174,6 +173,7 @@ bool TemplateArgument::isPackExpansion() const { case Integral: case Pack: case Template: + case NullPtr: return false; case TemplateExpansion: @@ -195,6 +195,7 @@ bool TemplateArgument::containsUnexpandedParameterPack() const { case Declaration: case Integral: case TemplateExpansion: + case NullPtr: break; case Type: @@ -286,12 +287,16 @@ bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { switch (getKind()) { case Null: case Type: - case Declaration: case Expression: case Template: case TemplateExpansion: + case NullPtr: return TypeOrValue == Other.TypeOrValue; + case Declaration: + return getAsDecl() == Other.getAsDecl() && + isDeclForReferenceParam() && Other.isDeclForReferenceParam(); + case Integral: return getIntegralType() == Other.getIntegralType() && getAsIntegral() == Other.getAsIntegral(); @@ -319,12 +324,13 @@ TemplateArgument TemplateArgument::getPackExpansionPattern() const { case TemplateExpansion: return TemplateArgument(getAsTemplateOrTemplatePattern()); - + case Declaration: case Integral: case Pack: case Null: case Template: + case NullPtr: return TemplateArgument(); } @@ -348,18 +354,20 @@ void TemplateArgument::print(const PrintingPolicy &Policy, } case Declaration: { - if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) { - if (ND->getDeclName()) { - Out << *ND; - } else { - Out << "<anonymous>"; - } + NamedDecl *ND = cast<NamedDecl>(getAsDecl()); + if (ND->getDeclName()) { + // FIXME: distinguish between pointer and reference args? + Out << *ND; } else { - Out << "nullptr"; + Out << "<anonymous>"; } break; } - + + case NullPtr: { + Out << "nullptr"; + } + case Template: getAsTemplate().print(Out, Policy); break; @@ -411,6 +419,9 @@ SourceRange TemplateArgumentLoc::getSourceRange() const { case TemplateArgument::Declaration: return getSourceDeclExpression()->getSourceRange(); + case TemplateArgument::NullPtr: + return getSourceNullPtrExpression()->getSourceRange(); + case TemplateArgument::Type: if (TypeSourceInfo *TSI = getTypeSourceInfo()) return TSI->getTypeLoc().getSourceRange(); @@ -430,6 +441,8 @@ SourceRange TemplateArgumentLoc::getSourceRange() const { return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc()); case TemplateArgument::Integral: + return getSourceIntegralExpression()->getSourceRange(); + case TemplateArgument::Pack: case TemplateArgument::Null: return SourceRange(); @@ -490,6 +503,7 @@ TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis, getTemplateNameLoc()); case TemplateArgument::Declaration: + case TemplateArgument::NullPtr: case TemplateArgument::Template: case TemplateArgument::Integral: case TemplateArgument::Pack: @@ -512,8 +526,9 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, return DB << Arg.getAsType(); case TemplateArgument::Declaration: - if (Decl *D = Arg.getAsDecl()) - return DB << D; + return DB << Arg.getAsDecl(); + + case TemplateArgument::NullPtr: return DB << "nullptr"; case TemplateArgument::Integral: diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index bd30a65259..945e783835 100644 --- a/lib/AST/TypeLoc.cpp +++ b/lib/AST/TypeLoc.cpp @@ -302,6 +302,9 @@ void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, case TemplateArgument::Declaration: case TemplateArgument::Integral: case TemplateArgument::Pack: + case TemplateArgument::NullPtr: + llvm_unreachable("Impossible TemplateArgument"); + case TemplateArgument::Expression: ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr()); break; @@ -311,7 +314,7 @@ void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, Context.getTrivialTypeSourceInfo(Args[i].getAsType(), Loc)); break; - + case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: { NestedNameSpecifierLocBuilder Builder; diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 8da6f8da9c..d5efd757c8 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -1798,6 +1798,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, case TemplateArgument::Declaration: case TemplateArgument::Integral: case TemplateArgument::Expression: |