summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTContext.cpp33
-rw-r--r--clang/lib/AST/NestedNameSpecifier.cpp26
-rw-r--r--clang/lib/AST/TemplateName.cpp8
-rw-r--r--clang/lib/AST/Type.cpp9
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())
OpenPOWER on IntegriCloud