diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-04-06 22:40:38 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-04-06 22:40:38 +0000 |
commit | 31f55dced546449acde6de1fb892caa4f6fb4fd1 (patch) | |
tree | 8405327c4506ef1cacce6c021fd2d5752061f4ff /clang/lib/AST | |
parent | 4460e0f805c21bc23c157dda6329aa86abf9b6eb (diff) | |
download | bcm5719-llvm-31f55dced546449acde6de1fb892caa4f6fb4fd1.tar.gz bcm5719-llvm-31f55dced546449acde6de1fb892caa4f6fb4fd1.zip |
Implement support for null non-type template arguments for non-type
template parameters of pointer, pointer-to-member, or nullptr_t
type in C++11. Fixes PR9700 / <rdar://problem/11193097>.
llvm-svn: 154219
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 7 | ||||
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/DumpXML.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 14 | ||||
-rw-r--r-- | clang/lib/AST/TemplateBase.cpp | 35 | ||||
-rw-r--r-- | clang/lib/AST/TypePrinter.cpp | 5 |
7 files changed, 49 insertions, 23 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 15f85ba9c48..acf5e0bbc9a 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -3313,8 +3313,11 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const { case TemplateArgument::Expression: return Arg; - case TemplateArgument::Declaration: - return TemplateArgument(Arg.getAsDecl()->getCanonicalDecl()); + case TemplateArgument::Declaration: { + if (Decl *D = Arg.getAsDecl()) + return TemplateArgument(D->getCanonicalDecl()); + return TemplateArgument((Decl*)0); + } case TemplateArgument::Template: return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate())); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 621658c7f0a..3879907ec6d 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -325,6 +325,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, return 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::Template: diff --git a/clang/lib/AST/DumpXML.cpp b/clang/lib/AST/DumpXML.cpp index b180e808ab4..4c7cd8a6793 100644 --- a/clang/lib/AST/DumpXML.cpp +++ b/clang/lib/AST/DumpXML.cpp @@ -320,7 +320,8 @@ struct XMLDumper : public XMLDeclVisitor<XMLDumper>, break; case TemplateArgument::Declaration: { - visitDeclRef(A.getAsDecl()); + if (Decl *D = A.getAsDecl()) + visitDeclRef(D); break; } case TemplateArgument::Integral: { diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 0d8490e137d..4ef169d1899 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1743,8 +1743,10 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, // parameters are constant expressions even if they're non-const. // In C, such things can also be folded, although they are not ICEs. const VarDecl *VD = dyn_cast<VarDecl>(D); - if (const VarDecl *VDef = VD->getDefinition(Info.Ctx)) - VD = VDef; + if (VD) { + if (const VarDecl *VDef = VD->getDefinition(Info.Ctx)) + VD = VDef; + } if (!VD || VD->isInvalidDecl()) { Info.Diag(Conv); return false; diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 5457036920b..d7b63545401 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3118,12 +3118,22 @@ void CXXNameMangler::mangleTemplateArg(const NamedDecl *P, 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. - NamedDecl *D = cast<NamedDecl>(A.getAsDecl()); 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(); if (compensateMangling) { Out << 'X'; diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 7e6bae2b267..531e03e302b 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -80,9 +80,13 @@ bool TemplateArgument::isDependent() const { return true; case Declaration: - if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) - return DC->isDependentContext(); - return getAsDecl()->getDeclContext()->isDependentContext(); + if (Decl *D = getAsDecl()) { + if (DeclContext *DC = dyn_cast<DeclContext>(D)) + return DC->isDependentContext(); + return D->getDeclContext()->isDependentContext(); + } + + return false; case Integral: // Never dependent @@ -118,10 +122,13 @@ bool TemplateArgument::isInstantiationDependent() const { return true; case Declaration: - if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) - return DC->isDependentContext(); - return getAsDecl()->getDeclContext()->isDependentContext(); - + if (Decl *D = getAsDecl()) { + if (DeclContext *DC = dyn_cast<DeclContext>(D)) + return DC->isDependentContext(); + return D->getDeclContext()->isDependentContext(); + } + return false; + case Integral: // Never dependent return false; @@ -322,16 +329,14 @@ void TemplateArgument::print(const PrintingPolicy &Policy, } case Declaration: { - bool Unnamed = true; if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) { if (ND->getDeclName()) { - Unnamed = false; Out << *ND; + } else { + Out << "<anonymous>"; } - } - - if (Unnamed) { - Out << "<anonymous>"; + } else { + Out << "nullptr"; } break; } @@ -488,7 +493,9 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, return DB << Arg.getAsType(); case TemplateArgument::Declaration: - return DB << Arg.getAsDecl(); + if (Decl *D = Arg.getAsDecl()) + return DB << D; + return DB << "nullptr"; case TemplateArgument::Integral: return DB << Arg.getAsIntegral()->toString(10); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 664a658160e..3bf80e79724 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -264,8 +264,9 @@ void TypePrinter::printRValueReference(const RValueReferenceType *T, void TypePrinter::printMemberPointer(const MemberPointerType *T, std::string &S) { - std::string C; - print(QualType(T->getClass(), 0), C); + PrintingPolicy InnerPolicy(Policy); + Policy.SuppressTag = true; + std::string C = QualType(T->getClass(), 0).getAsString(InnerPolicy); C += "::*"; S = C + S; |