diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 10 | ||||
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 3 | ||||
-rw-r--r-- | lib/AST/NestedNameSpecifier.cpp | 73 | ||||
-rw-r--r-- | lib/Frontend/DocumentXML.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 31 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 7 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 4 |
11 files changed, 143 insertions, 10 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 0b3febd0bd..9c2455034d 100644 --- a/lib/AST/ASTContext.cpp +++ b/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/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index e2dbb83983..939ca7a924 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/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/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp index 650321d76e..1b477d85a9 100644 --- a/lib/AST/NestedNameSpecifier.cpp +++ b/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/lib/Frontend/DocumentXML.cpp b/lib/Frontend/DocumentXML.cpp index b24ece5119..a09db0be47 100644 --- a/lib/Frontend/DocumentXML.cpp +++ b/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/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index 39984974bf..f21d90f7c8 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/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/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 754c52cc4a..9daec58d4e 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/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/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index ab6dde5eb1..d75a1f1503 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/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/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index d30ed74310..ba80076003 100644 --- a/lib/Sema/SemaType.cpp +++ b/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/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 7a0754fc88..1b2822ead7 100644 --- a/lib/Sema/TreeTransform.h +++ b/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/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 2e8e8ca67b..6f8856cd8d 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/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/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index b1edf95b9f..42ca293932 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/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); |