diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-09-26 02:36:12 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-09-26 02:36:12 +0000 |
commit | d7a6b1640e565487d163023a6a2e83f55476ae96 (patch) | |
tree | d5f4472454c04080fc1f329d70b8c71c91b24aa0 /lib | |
parent | 073819806ba2441e2a3e550107f1e756a6ee3ad0 (diff) |
Fix the AST representation for non-type template arguments to encode
enough information so we can mangle them correctly in cases involving
dependent parameter types. (This specifically impacts cases involving
null pointers and cases involving parameters of reference type.)
Fix the mangler to use this information instead of trying to scavenge
it out of the parameter declaration.
<rdar://problem/12296776>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164656 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-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 |
16 files changed, 234 insertions, 179 deletions
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: + case TemplateArgument::NullPtr: // [Note: non-type template arguments do not contribute to the set of // associated namespaces. ] break; diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index bc40cbb8c9..0efe710acc 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -2843,6 +2843,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, case TemplateArgument::Declaration: case TemplateArgument::Integral: + case TemplateArgument::NullPtr: // We've already checked this template argument, so just copy // it to the list of converted arguments. Converted.push_back(Arg.getArgument()); @@ -2977,6 +2978,8 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, llvm_unreachable("Declaration argument with template template parameter"); case TemplateArgument::Integral: llvm_unreachable("Integral argument with template template parameter"); + case TemplateArgument::NullPtr: + llvm_unreachable("Null pointer argument with template template parameter"); case TemplateArgument::Pack: llvm_unreachable("Caller must expand template argument packs"); @@ -3068,15 +3071,12 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, if (*Expansions == ArgumentPack.size()) { // We're done with this parameter pack. Pack up its arguments and add // them to the list. - if (ArgumentPack.empty()) - Converted.push_back(TemplateArgument(0, 0)); - else { - Converted.push_back( - TemplateArgument::CreatePackCopy(Context, - ArgumentPack.data(), - ArgumentPack.size())); - ArgumentPack.clear(); - } + Converted.push_back( + TemplateArgument::CreatePackCopy(Context, + ArgumentPack.data(), + ArgumentPack.size())); + ArgumentPack.clear(); + // This argument is assigned to the next parameter. ++Param; continue; @@ -3143,15 +3143,11 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // Push the argument pack onto the list of converted arguments. if (InFinalParameterPack) { - if (ArgumentPack.empty()) - Converted.push_back(TemplateArgument(0, 0)); - else { - Converted.push_back( - TemplateArgument::CreatePackCopy(Context, - ArgumentPack.data(), - ArgumentPack.size())); - ArgumentPack.clear(); - } + Converted.push_back( + TemplateArgument::CreatePackCopy(Context, + ArgumentPack.data(), + ArgumentPack.size())); + ArgumentPack.clear(); } else if (ExpansionIntoFixedList) { // We have expanded a pack into a fixed list. *ExpansionIntoFixedList = true; @@ -3185,14 +3181,10 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, if (Param + 1 != ParamEnd) return true; - if (ArgumentPack.empty()) - Converted.push_back(TemplateArgument(0, 0)); - else { - Converted.push_back(TemplateArgument::CreatePackCopy(Context, - ArgumentPack.data(), - ArgumentPack.size())); - ArgumentPack.clear(); - } + Converted.push_back(TemplateArgument::CreatePackCopy(Context, + ArgumentPack.data(), + ArgumentPack.size())); + ArgumentPack.clear(); ++Param; continue; @@ -3679,7 +3671,7 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, switch (isNullPointerValueTemplateArgument(S, Param, ParamType, Arg)) { case NPV_NullPointer: S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null); - Converted = TemplateArgument((Decl *)0); + Converted = TemplateArgument(ParamType, /*isNullPtr*/true); return false; case NPV_Error: @@ -3767,7 +3759,7 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, return true; } - NamedDecl *Entity = DRE->getDecl(); + ValueDecl *Entity = DRE->getDecl(); // Cannot refer to non-static data members if (FieldDecl *Field = dyn_cast<FieldDecl>(Entity)) { @@ -3955,7 +3947,8 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, } // Create the template argument. - Converted = TemplateArgument(Entity->getCanonicalDecl()); + Converted = TemplateArgument(cast<ValueDecl>(Entity->getCanonicalDecl()), + ParamType->isReferenceType()); S.MarkAnyDeclReferenced(Arg->getLocStart(), Entity); return false; } @@ -3976,7 +3969,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S, return true; case NPV_NullPointer: S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null); - Converted = TemplateArgument((Decl *)0); + Converted = TemplateArgument(ParamType, /*isNullPtr*/true); return false; case NPV_NotNullPointer: break; @@ -4045,10 +4038,12 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S, if (isa<NonTypeTemplateParmDecl>(VD) || (isa<VarDecl>(VD) && S.Context.getCanonicalType(VD->getType()).isConstQualified())) { - if (Arg->isTypeDependent() || Arg->isValueDependent()) + if (Arg->isTypeDependent() || Arg->isValueDependent()) { Converted = TemplateArgument(Arg); - else - Converted = TemplateArgument(VD->getCanonicalDecl()); + } else { + VD = cast<ValueDecl>(VD->getCanonicalDecl()); + Converted = TemplateArgument(VD, /*isReferenceParam*/false); + } return Invalid; } } @@ -4069,10 +4064,12 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S, // Okay: this is the address of a non-static member, and therefore // a member pointer constant. - if (Arg->isTypeDependent() || Arg->isValueDependent()) + if (Arg->isTypeDependent() || Arg->isValueDependent()) { Converted = TemplateArgument(Arg); - else - Converted = TemplateArgument(DRE->getDecl()->getCanonicalDecl()); + } else { + ValueDecl *D = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl()); + Converted = TemplateArgument(D, /*isReferenceParam*/false); + } return Invalid; } @@ -4425,7 +4422,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, case NPV_NullPointer: Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null); - Converted = TemplateArgument((Decl *)0); + Converted = TemplateArgument(ParamType, /*isNullPtr*/true); return Owned(Arg); } } @@ -4448,7 +4445,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param, const TemplateArgumentLoc &Arg, unsigned ArgumentPackIndex) { - TemplateName Name = Arg.getArgument().getAsTemplate(); + TemplateName Name = Arg.getArgument().getAsTemplateOrTemplatePattern(); TemplateDecl *Template = Name.getAsTemplateDecl(); if (!Template) { // Any dependent template name is fine. @@ -4497,12 +4494,9 @@ ExprResult Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc) { - assert(Arg.getKind() == TemplateArgument::Declaration && - "Only declaration template arguments permitted here"); - // For a NULL non-type template argument, return nullptr casted to the // parameter's type. - if (!Arg.getAsDecl()) { + if (Arg.getKind() == TemplateArgument::NullPtr) { return ImpCastExprToType( new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc), ParamType, @@ -4510,7 +4504,9 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, ? CK_NullToMemberPointer : CK_NullToPointer); } - + assert(Arg.getKind() == TemplateArgument::Declaration && + "Only declaration template arguments permitted here"); + ValueDecl *VD = cast<ValueDecl>(Arg.getAsDecl()); if (VD->getDeclContext()->isRecord() && @@ -5105,10 +5101,10 @@ static bool CheckNonTypeClassTemplatePartialSpecializationArgs(Sema &S, continue; } - Expr *ArgExpr = Args[I].getAsExpr(); - if (!ArgExpr) { + if (Args[I].getKind() != TemplateArgument::Expression) continue; - } + + Expr *ArgEx |