diff options
Diffstat (limited to 'lib/Sema')
-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 |
5 files changed, 47 insertions, 4 deletions
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() || |