diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 33 | ||||
-rw-r--r-- | clang/lib/AST/NestedNameSpecifier.cpp | 26 | ||||
-rw-r--r-- | clang/lib/AST/TemplateName.cpp | 8 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 9 |
4 files changed, 59 insertions, 17 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 422988d05d0..cede0e55639 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1454,6 +1454,39 @@ QualType ASTContext::getTypenameType(NestedNameSpecifier *NNS, return QualType(T, 0); } +QualType +ASTContext::getTypenameType(NestedNameSpecifier *NNS, + const TemplateSpecializationType *TemplateId, + QualType Canon) { + assert(NNS->isDependent() && "nested-name-specifier must be dependent"); + + if (Canon.isNull()) { + NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); + QualType CanonType = getCanonicalType(QualType(TemplateId, 0)); + if (CanonNNS != NNS || CanonType != QualType(TemplateId, 0)) { + const TemplateSpecializationType *CanonTemplateId + = CanonType->getAsTemplateSpecializationType(); + assert(CanonTemplateId && + "Canonical type must also be a template specialization type"); + Canon = getTypenameType(CanonNNS, CanonTemplateId); + } + } + + llvm::FoldingSetNodeID ID; + TypenameType::Profile(ID, NNS, TemplateId); + + void *InsertPos = 0; + TypenameType *T + = TypenameTypes.FindNodeOrInsertPos(ID, InsertPos); + if (T) + return QualType(T, 0); + + T = new (*this) TypenameType(NNS, TemplateId, Canon); + Types.push_back(T); + TypenameTypes.InsertNode(T, InsertPos); + return QualType(T, 0); +} + /// CmpProtocolNames - Comparison predicate for sorting protocols /// alphabetically. static bool CmpProtocolNames(const ObjCProtocolDecl *LHS, diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp index 2db8c763431..c94a4da7b61 100644 --- a/clang/lib/AST/NestedNameSpecifier.cpp +++ b/clang/lib/AST/NestedNameSpecifier.cpp @@ -30,7 +30,7 @@ NestedNameSpecifier::FindOrInsert(ASTContext &Context, NestedNameSpecifier *NNS = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos); if (!NNS) { - NNS = new (Context) NestedNameSpecifier(Mockup); + NNS = new (Context, 4) NestedNameSpecifier(Mockup); Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos); } @@ -44,9 +44,9 @@ NestedNameSpecifier::Create(ASTContext &Context, NestedNameSpecifier *Prefix, assert(Prefix && Prefix->isDependent() && "Prefix must be dependent"); NestedNameSpecifier Mockup; - Mockup.Prefix = Prefix; - Mockup.Specifier.setPointer(II); - Mockup.Specifier.setInt(Identifier); + Mockup.Prefix.setPointer(Prefix); + Mockup.Prefix.setInt(Identifier); + Mockup.Specifier = II; return FindOrInsert(Context, Mockup); } @@ -58,9 +58,9 @@ NestedNameSpecifier::Create(ASTContext &Context, NestedNameSpecifier *Prefix, (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) && "Broken nested name specifier"); NestedNameSpecifier Mockup; - Mockup.Prefix = Prefix; - Mockup.Specifier.setPointer(NS); - Mockup.Specifier.setInt(Namespace); + Mockup.Prefix.setPointer(Prefix); + Mockup.Prefix.setInt(Namespace); + Mockup.Specifier = NS; return FindOrInsert(Context, Mockup); } @@ -69,15 +69,15 @@ NestedNameSpecifier::Create(ASTContext &Context, NestedNameSpecifier *Prefix, bool Template, Type *T) { assert(T && "Type cannot be NULL"); NestedNameSpecifier Mockup; - Mockup.Prefix = Prefix; - Mockup.Specifier.setPointer(T); - Mockup.Specifier.setInt(Template? TypeSpecWithTemplate : TypeSpec); + Mockup.Prefix.setPointer(Prefix); + Mockup.Prefix.setInt(Template? TypeSpecWithTemplate : TypeSpec); + Mockup.Specifier = T; return FindOrInsert(Context, Mockup); } NestedNameSpecifier *NestedNameSpecifier::GlobalSpecifier(ASTContext &Context) { if (!Context.GlobalNestedNameSpecifier) - Context.GlobalNestedNameSpecifier = new (Context) NestedNameSpecifier(); + Context.GlobalNestedNameSpecifier = new (Context, 4) NestedNameSpecifier(); return Context.GlobalNestedNameSpecifier; } @@ -105,8 +105,8 @@ bool NestedNameSpecifier::isDependent() const { /// \brief Print this nested name specifier to the given output /// stream. void NestedNameSpecifier::print(llvm::raw_ostream &OS) const { - if (Prefix) - Prefix->print(OS); + if (getPrefix()) + getPrefix()->print(OS); switch (getKind()) { case Identifier: diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp index 659796d27b2..16b96a01cd9 100644 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -38,16 +38,18 @@ bool TemplateName::isDependent() const { return true; } -void TemplateName::print(llvm::raw_ostream &OS) const { +void TemplateName::print(llvm::raw_ostream &OS, bool SuppressNNS) const { if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>()) OS << Template->getIdentifier()->getName(); else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { - QTN->getQualifier()->print(OS); + if (!SuppressNNS) + QTN->getQualifier()->print(OS); if (QTN->hasTemplateKeyword()) OS << "template "; OS << QTN->getTemplateDecl()->getIdentifier()->getName(); } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) { - DTN->getQualifier()->print(OS); + if (!SuppressNNS) + DTN->getQualifier()->print(OS); OS << "template "; OS << DTN->getName()->getName(); } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 669eb7ce9c3..b9bd0bae046 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1450,7 +1450,14 @@ void TypenameType::getAsStringInternal(std::string &InnerString) const { llvm::raw_string_ostream OS(MyString); OS << "typename "; NNS->print(OS); - OS << Name->getName(); + + if (const IdentifierInfo *Ident = getIdentifier()) + OS << Ident->getName(); + else if (const TemplateSpecializationType *Spec = getTemplateId()) { + Spec->getTemplateName().print(OS, true); + OS << TemplateSpecializationType::PrintTemplateArgumentList( + Spec->getArgs(), Spec->getNumArgs()); + } } if (InnerString.empty()) |