diff options
-rw-r--r-- | include/clang/AST/DeclCXX.h | 17 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 13 | ||||
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 31 | ||||
-rw-r--r-- | test/SemaCXX/using-directive.cpp | 10 |
5 files changed, 48 insertions, 25 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 2c43e96085..990403e7dc 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1514,9 +1514,9 @@ class UsingDirectiveDecl : public NamedDecl { SourceLocation IdentLoc; /// NominatedNamespace - Namespace nominated by using-directive. - NamespaceDecl *NominatedNamespace; + NamedDecl *NominatedNamespace; - /// Enclosing context containing both using-directive and nomintated + /// Enclosing context containing both using-directive and nominated /// namespace. DeclContext *CommonAncestor; @@ -1532,12 +1532,12 @@ class UsingDirectiveDecl : public NamedDecl { SourceRange QualifierRange, NestedNameSpecifier *Qualifier, SourceLocation IdentLoc, - NamespaceDecl *Nominated, + NamedDecl *Nominated, DeclContext *CommonAncestor) : NamedDecl(Decl::UsingDirective, DC, L, getName()), NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange), Qualifier(Qualifier), IdentLoc(IdentLoc), - NominatedNamespace(Nominated? Nominated->getOriginalNamespace() : 0), + NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { } @@ -1550,8 +1550,13 @@ public: /// name of the namespace. NestedNameSpecifier *getQualifier() const { return Qualifier; } + NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; } + const NamedDecl *getNominatedNamespaceAsWritten() const { + return NominatedNamespace; + } + /// getNominatedNamespace - Returns namespace nominated by using-directive. - NamespaceDecl *getNominatedNamespace() { return NominatedNamespace; } + NamespaceDecl *getNominatedNamespace(); const NamespaceDecl *getNominatedNamespace() const { return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace(); @@ -1574,7 +1579,7 @@ public: SourceRange QualifierRange, NestedNameSpecifier *Qualifier, SourceLocation IdentLoc, - NamespaceDecl *Nominated, + NamedDecl *Nominated, DeclContext *CommonAncestor); static bool classof(const Decl *D) { diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 94621aa1f6..4001988007 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -886,12 +886,21 @@ UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, SourceRange QualifierRange, NestedNameSpecifier *Qualifier, SourceLocation IdentLoc, - NamespaceDecl *Used, + NamedDecl *Used, DeclContext *CommonAncestor) { + if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used)) + Used = NS->getOriginalNamespace(); return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange, Qualifier, IdentLoc, Used, CommonAncestor); } +NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() { + if (NamespaceAliasDecl *NA = + dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace)) + return NA->getNamespace(); + return cast_or_null<NamespaceDecl>(NominatedNamespace); +} + NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, SourceLocation AliasLoc, @@ -900,6 +909,8 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, NestedNameSpecifier *Qualifier, SourceLocation IdentLoc, NamedDecl *Namespace) { + if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace)) + Namespace = NS->getOriginalNamespace(); return new (C) NamespaceAliasDecl(DC, L, AliasLoc, Alias, QualifierRange, Qualifier, IdentLoc, Namespace); } diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 864f1145a0..24d3da47a2 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -505,7 +505,7 @@ void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { Out << "using namespace "; if (D->getQualifier()) D->getQualifier()->print(Out, Policy); - Out << D->getNominatedNamespace()->getNameAsString(); + Out << D->getNominatedNamespaceAsWritten()->getNameAsString(); } void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 3ff9144cc2..58fe97a7e5 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2722,6 +2722,14 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope, return DeclPtrTy::make(Namespc); } +/// getNamespaceDecl - Returns the namespace a decl represents. If the decl +/// is a namespace alias, returns the namespace it points to. +static inline NamespaceDecl *getNamespaceDecl(NamedDecl *D) { + if (NamespaceAliasDecl *AD = dyn_cast_or_null<NamespaceAliasDecl>(D)) + return AD->getNamespace(); + return dyn_cast_or_null<NamespaceDecl>(D); +} + /// ActOnFinishNamespaceDef - This callback is called after a namespace is /// exited. Decl is the DeclTy returned by ActOnStartNamespaceDef. void Sema::ActOnFinishNamespaceDef(DeclPtrTy D, SourceLocation RBrace) { @@ -2753,9 +2761,9 @@ Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S, return DeclPtrTy(); if (!R.empty()) { - NamedDecl *NS = R.getFoundDecl(); - // FIXME: Namespace aliases! - assert(isa<NamespaceDecl>(NS) && "expected namespace decl"); + NamedDecl *Named = R.getFoundDecl(); + assert((isa<NamespaceDecl>(Named) || isa<NamespaceAliasDecl>(Named)) + && "expected namespace decl"); // C++ [namespace.udir]p1: // A using-directive specifies that the names in the nominated // namespace can be used in the scope in which the @@ -2768,18 +2776,15 @@ Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S, // Find enclosing context containing both using-directive and // nominated namespace. + NamespaceDecl *NS = getNamespaceDecl(Named); DeclContext *CommonAncestor = cast<DeclContext>(NS); while (CommonAncestor && !CommonAncestor->Encloses(CurContext)) CommonAncestor = CommonAncestor->getParent(); - UDir = UsingDirectiveDecl::Create(Context, - CurContext, UsingLoc, - NamespcLoc, + UDir = UsingDirectiveDecl::Create(Context, CurContext, UsingLoc, NamespcLoc, SS.getRange(), (NestedNameSpecifier *)SS.getScopeRep(), - IdentLoc, - cast<NamespaceDecl>(NS), - CommonAncestor); + IdentLoc, Named, CommonAncestor); PushUsingDirective(S, UDir); } else { Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange(); @@ -3006,14 +3011,6 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, return UD; } -/// getNamespaceDecl - Returns the namespace a decl represents. If the decl -/// is a namespace alias, returns the namespace it points to. -static inline NamespaceDecl *getNamespaceDecl(NamedDecl *D) { - if (NamespaceAliasDecl *AD = dyn_cast_or_null<NamespaceAliasDecl>(D)) - return AD->getNamespace(); - return dyn_cast_or_null<NamespaceDecl>(D); -} - Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc, SourceLocation AliasLoc, diff --git a/test/SemaCXX/using-directive.cpp b/test/SemaCXX/using-directive.cpp index 3b67c7a5b6..51f347dc7a 100644 --- a/test/SemaCXX/using-directive.cpp +++ b/test/SemaCXX/using-directive.cpp @@ -102,3 +102,13 @@ namespace FuncHidesTagAmbiguity { (void)X(); // expected-error{{reference to 'X' is ambiguous}} } } + +// PR5479 +namespace Aliased { + void inAliased(); +} +namespace Alias = Aliased; +using namespace Alias; +void testAlias() { + inAliased(); +} |