summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-02-24 02:36:08 +0000
committerDouglas Gregor <dgregor@apple.com>2011-02-24 02:36:08 +0000
commit7b26ff912f49f787d25f4ea9677f88c2f512790f (patch)
tree3bad9490f7419343d705560bc4efbf6a1a510fa2 /clang/lib
parent8e74e79145a60e4d3a49d5b85de4a15ee443022e (diff)
downloadbcm5719-llvm-7b26ff912f49f787d25f4ea9677f88c2f512790f.tar.gz
bcm5719-llvm-7b26ff912f49f787d25f4ea9677f88c2f512790f.zip
Teach NestedNameSpecifier to keep track of namespace aliases the same
way it keeps track of namespaces. Previously, we would map from the namespace alias to its underlying namespace when building a nested-name-specifier, losing source information in the process. llvm-svn: 126358
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp10
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp3
-rw-r--r--clang/lib/AST/NestedNameSpecifier.cpp73
-rw-r--r--clang/lib/Frontend/DocumentXML.cpp5
-rw-r--r--clang/lib/Sema/DeclSpec.cpp9
-rw-r--r--clang/lib/Sema/SemaCXXScopeSpec.cpp9
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp1
-rw-r--r--clang/lib/Sema/SemaType.cpp1
-rw-r--r--clang/lib/Sema/TreeTransform.h31
-rw-r--r--clang/lib/Serialization/ASTReader.cpp7
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp4
11 files changed, 143 insertions, 10 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 0b3febd0bdb..9c2455034d6 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2981,7 +2981,15 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
case NestedNameSpecifier::Namespace:
// A namespace is canonical; build a nested-name-specifier with
// this namespace and no prefix.
- return NestedNameSpecifier::Create(*this, 0, NNS->getAsNamespace());
+ return NestedNameSpecifier::Create(*this, 0,
+ NNS->getAsNamespace()->getOriginalNamespace());
+
+ case NestedNameSpecifier::NamespaceAlias:
+ // A namespace is canonical; build a nested-name-specifier with
+ // this namespace and no prefix.
+ return NestedNameSpecifier::Create(*this, 0,
+ NNS->getAsNamespaceAlias()->getNamespace()
+ ->getOriginalNamespace());
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index e2dbb839838..939ca7a924a 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -606,6 +606,9 @@ void CXXNameMangler::mangleUnresolvedScope(NestedNameSpecifier *Qualifier) {
case NestedNameSpecifier::Namespace:
mangleName(Qualifier->getAsNamespace());
break;
+ case NestedNameSpecifier::NamespaceAlias:
+ mangleName(Qualifier->getAsNamespaceAlias()->getNamespace());
+ break;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
const Type *QTy = Qualifier->getAsType();
diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp
index 650321d76ee..1b477d85a94 100644
--- a/clang/lib/AST/NestedNameSpecifier.cpp
+++ b/clang/lib/AST/NestedNameSpecifier.cpp
@@ -14,6 +14,7 @@
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/Type.h"
#include "llvm/Support/raw_ostream.h"
@@ -46,7 +47,7 @@ NestedNameSpecifier::Create(const ASTContext &Context,
NestedNameSpecifier Mockup;
Mockup.Prefix.setPointer(Prefix);
- Mockup.Prefix.setInt(Identifier);
+ Mockup.Prefix.setInt(StoredIdentifier);
Mockup.Specifier = II;
return FindOrInsert(Context, Mockup);
}
@@ -60,19 +61,34 @@ NestedNameSpecifier::Create(const ASTContext &Context,
"Broken nested name specifier");
NestedNameSpecifier Mockup;
Mockup.Prefix.setPointer(Prefix);
- Mockup.Prefix.setInt(Namespace);
+ Mockup.Prefix.setInt(StoredNamespaceOrAlias);
Mockup.Specifier = NS;
return FindOrInsert(Context, Mockup);
}
NestedNameSpecifier *
NestedNameSpecifier::Create(const ASTContext &Context,
+ NestedNameSpecifier *Prefix,
+ NamespaceAliasDecl *Alias) {
+ assert(Alias && "Namespace alias cannot be NULL");
+ assert((!Prefix ||
+ (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) &&
+ "Broken nested name specifier");
+ NestedNameSpecifier Mockup;
+ Mockup.Prefix.setPointer(Prefix);
+ Mockup.Prefix.setInt(StoredNamespaceOrAlias);
+ Mockup.Specifier = Alias;
+ return FindOrInsert(Context, Mockup);
+}
+
+NestedNameSpecifier *
+NestedNameSpecifier::Create(const ASTContext &Context,
NestedNameSpecifier *Prefix,
bool Template, const Type *T) {
assert(T && "Type cannot be NULL");
NestedNameSpecifier Mockup;
Mockup.Prefix.setPointer(Prefix);
- Mockup.Prefix.setInt(Template? TypeSpecWithTemplate : TypeSpec);
+ Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
Mockup.Specifier = const_cast<Type*>(T);
return FindOrInsert(Context, Mockup);
}
@@ -82,7 +98,7 @@ NestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) {
assert(II && "Identifier cannot be NULL");
NestedNameSpecifier Mockup;
Mockup.Prefix.setPointer(0);
- Mockup.Prefix.setInt(Identifier);
+ Mockup.Prefix.setInt(StoredIdentifier);
Mockup.Specifier = II;
return FindOrInsert(Context, Mockup);
}
@@ -94,6 +110,47 @@ NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) {
return Context.GlobalNestedNameSpecifier;
}
+NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
+ if (Specifier == 0)
+ return Global;
+
+ switch (Prefix.getInt()) {
+ case StoredIdentifier:
+ return Identifier;
+
+ case StoredNamespaceOrAlias:
+ return isa<NamespaceDecl>(static_cast<NamedDecl *>(Specifier))? Namespace
+ : NamespaceAlias;
+
+ case StoredTypeSpec:
+ return TypeSpec;
+
+ case StoredTypeSpecWithTemplate:
+ return TypeSpecWithTemplate;
+ }
+
+ return Global;
+}
+
+/// \brief Retrieve the namespace stored in this nested name
+/// specifier.
+NamespaceDecl *NestedNameSpecifier::getAsNamespace() const {
+ if (Prefix.getInt() == StoredNamespaceOrAlias)
+ return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
+
+ return 0;
+}
+
+/// \brief Retrieve the namespace alias stored in this nested name
+/// specifier.
+NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const {
+ if (Prefix.getInt() == StoredNamespaceOrAlias)
+ return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
+
+ return 0;
+}
+
+
/// \brief Whether this nested name specifier refers to a dependent
/// type or not.
bool NestedNameSpecifier::isDependent() const {
@@ -103,6 +160,7 @@ bool NestedNameSpecifier::isDependent() const {
return true;
case Namespace:
+ case NamespaceAlias:
case Global:
return false;
@@ -121,6 +179,7 @@ bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
return getPrefix() && getPrefix()->containsUnexpandedParameterPack();
case Namespace:
+ case NamespaceAlias:
case Global:
return false;
@@ -147,7 +206,11 @@ NestedNameSpecifier::print(llvm::raw_ostream &OS,
break;
case Namespace:
- OS << getAsNamespace()->getIdentifier()->getName();
+ OS << getAsNamespace()->getName();
+ break;
+
+ case NamespaceAlias:
+ OS << getAsNamespaceAlias()->getName();
break;
case Global:
diff --git a/clang/lib/Frontend/DocumentXML.cpp b/clang/lib/Frontend/DocumentXML.cpp
index b24ece5119d..a09db0be473 100644
--- a/clang/lib/Frontend/DocumentXML.cpp
+++ b/clang/lib/Frontend/DocumentXML.cpp
@@ -14,6 +14,7 @@
#include "clang/Frontend/DocumentXML.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/StringExtras.h"
@@ -218,6 +219,10 @@ void DocumentXML::addPtrAttribute(const char* pAttributeName,
addPtrAttribute(pAttributeName, pNNS->getAsNamespace());
break;
}
+ case NestedNameSpecifier::NamespaceAlias: {
+ addPtrAttribute(pAttributeName, pNNS->getAsNamespaceAlias());
+ break;
+ }
case NestedNameSpecifier::TypeSpec: {
addPtrAttribute(pAttributeName, pNNS->getAsType());
break;
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 39984974bfd..f21d90f7c8c 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -74,6 +74,15 @@ void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
Range.setEnd(ColonColonLoc);
}
+void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
+ SourceLocation AliasLoc,
+ SourceLocation ColonColonLoc) {
+ ScopeRep = NestedNameSpecifier::Create(Context, ScopeRep, Alias);
+ if (Range.getBegin().isInvalid())
+ Range.setBegin(AliasLoc);
+ Range.setEnd(ColonColonLoc);
+}
+
void CXXScopeSpec::MakeGlobal(ASTContext &Context,
SourceLocation ColonColonLoc) {
assert(!ScopeRep && "Already have a nested-name-specifier!?");
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index 754c52cc4ac..9daec58d4ed 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -139,6 +139,9 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
case NestedNameSpecifier::Namespace:
return NNS->getAsNamespace();
+ case NestedNameSpecifier::NamespaceAlias:
+ return NNS->getAsNamespaceAlias()->getNamespace();
+
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
const TagType *Tag = NNS->getAsType()->getAs<TagType>();
@@ -532,11 +535,8 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
return false;
}
- // FIXME: It would be nice to maintain the namespace alias name, then
- // see through that alias when resolving the nested-name-specifier down to
- // a declaration context.
if (NamespaceAliasDecl *Alias = dyn_cast<NamespaceAliasDecl>(SD)) {
- SS.Extend(Context, Alias->getNamespace(), IdentifierLoc, CCLoc);
+ SS.Extend(Context, Alias, IdentifierLoc, CCLoc);
return false;
}
@@ -681,6 +681,7 @@ bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
switch (Qualifier->getKind()) {
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::NamespaceAlias:
// These are always namespace scopes. We never want to enter a
// namespace scope from anything but a file context.
return CurContext->getRedeclContext()->isFileContext();
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index ab6dde5eb18..d75a1f1503d 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2868,6 +2868,7 @@ bool UnnamedLocalNoLinkageFinder::VisitNestedNameSpecifier(
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
return false;
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index d30ed743106..ba80076003c 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1895,6 +1895,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
break;
case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
llvm_unreachable("Nested-name-specifier must name a type");
break;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 7a0754fc883..1b2822ead7b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -877,6 +877,16 @@ public:
NamespaceDecl *NS);
/// \brief Build a new nested-name-specifier given the prefix and the
+ /// namespace alias named in the next step in the nested-name-specifier.
+ ///
+ /// By default, performs semantic analysis when building the new
+ /// nested-name-specifier. Subclasses may override this routine to provide
+ /// different behavior.
+ NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+ SourceRange Range,
+ NamespaceAliasDecl *Alias);
+
+ /// \brief Build a new nested-name-specifier given the prefix and the
/// type named in the next step in the nested-name-specifier.
///
/// By default, performs semantic analysis when building the new
@@ -2450,6 +2460,19 @@ TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
}
+ case NestedNameSpecifier::NamespaceAlias: {
+ NamespaceAliasDecl *Alias
+ = cast_or_null<NamespaceAliasDecl>(
+ getDerived().TransformDecl(Range.getBegin(),
+ NNS->getAsNamespaceAlias()));
+ if (!getDerived().AlwaysRebuild() &&
+ Prefix == NNS->getPrefix() &&
+ Alias == NNS->getAsNamespaceAlias())
+ return NNS;
+
+ return getDerived().RebuildNestedNameSpecifier(Prefix, Range, Alias);
+ }
+
case NestedNameSpecifier::Global:
// There is no meaningful transformation that one could perform on the
// global scope.
@@ -7571,6 +7594,14 @@ template<typename Derived>
NestedNameSpecifier *
TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
SourceRange Range,
+ NamespaceAliasDecl *Alias) {
+ return NestedNameSpecifier::Create(SemaRef.Context, Prefix, Alias);
+}
+
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+ SourceRange Range,
bool TemplateKW,
QualType T) {
if (T->isDependentType() || T->isRecordType() ||
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 2e8e8ca67b1..6f8856cd8de 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -4730,6 +4730,13 @@ ASTReader::ReadNestedNameSpecifier(const RecordData &Record, unsigned &Idx) {
break;
}
+ case NestedNameSpecifier::NamespaceAlias: {
+ NamespaceAliasDecl *Alias
+ = cast<NamespaceAliasDecl>(GetDecl(Record[Idx++]));
+ NNS = NestedNameSpecifier::Create(*Context, Prev, Alias);
+ break;
+ }
+
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
const Type *T = GetType(Record[Idx++]).getTypePtrOrNull();
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index b1edf95b9f9..42ca293932b 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -3470,6 +3470,10 @@ void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS,
AddDeclRef(NNS->getAsNamespace(), Record);
break;
+ case NestedNameSpecifier::NamespaceAlias:
+ AddDeclRef(NNS->getAsNamespaceAlias(), Record);
+ break;
+
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
AddTypeRef(QualType(NNS->getAsType(), 0), Record);
OpenPOWER on IntegriCloud