diff options
author | John McCall <rjmccall@apple.com> | 2009-11-17 05:59:44 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-11-17 05:59:44 +0000 |
commit | 9488ea120e093068021f944176c3d610dd540914 (patch) | |
tree | b25280b1967cb1edee70e5f7faceee121a9d897a /include/clang | |
parent | 049d3a06ea9f8fc03582488a2b7f24512565a335 (diff) |
Instead of hanging a using declaration's target decls directly off the using
decl, create shadow declarations and put them in scope like normal.
Work in progress.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89048 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/DeclBase.h | 11 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 106 | ||||
-rw-r--r-- | include/clang/AST/DeclNodes.def | 1 |
3 files changed, 89 insertions, 29 deletions
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 10db7030db..79f7663561 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -79,9 +79,11 @@ public: /// namespaces, labels, tags, members and ordinary /// identifiers. These are meant as bitmasks, so that searches in /// C++ can look into the "tag" namespace during ordinary lookup. We - /// use additional namespaces for Objective-C entities. We also - /// put C++ friend declarations (of previously-undeclared entities) in - /// shadow namespaces. + /// use additional namespaces for Objective-C entities. We also put + /// C++ friend declarations (of previously-undeclared entities) in + /// shadow namespaces, and 'using' declarations (as opposed to their + /// implicit shadow declarations) can be found in their own + /// namespace. enum IdentifierNamespace { IDNS_Label = 0x1, IDNS_Tag = 0x2, @@ -91,7 +93,8 @@ public: IDNS_ObjCImplementation = 0x20, IDNS_ObjCCategoryImpl = 0x40, IDNS_OrdinaryFriend = 0x80, - IDNS_TagFriend = 0x100 + IDNS_TagFriend = 0x100, + IDNS_Using = 0x200 }; /// ObjCDeclQualifier - Qualifier used on types in method declarations diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 17dbd61aec..4d8991a46f 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1644,6 +1644,56 @@ public: static bool classof(const NamespaceAliasDecl *D) { return true; } }; +/// UsingShadowDecl - Represents a shadow declaration introduced into +/// a scope by a (resolved) using declaration. For example, +/// +/// namespace A { +/// void foo(); +/// } +/// namespace B { +/// using A::foo(); // <- a UsingDecl +/// // Also creates a UsingShadowDecl for A::foo in B +/// } +/// +class UsingShadowDecl : public NamedDecl { + /// The referenced declaration. + NamedDecl *Underlying; + + /// The using declaration which introduced this decl. + UsingDecl *Using; + + UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using, + NamedDecl *Target) + : NamedDecl(UsingShadow, DC, Loc, Target->getDeclName()), + Underlying(Target), Using(Using) { + IdentifierNamespace = Target->getIdentifierNamespace(); + setImplicit(); + } + +public: + static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation Loc, UsingDecl *Using, + NamedDecl *Target) { + return new (C) UsingShadowDecl(DC, Loc, Using, Target); + } + + /// Gets the underlying declaration which has been brought into the + /// local scope. + NamedDecl *getTargetDecl() const { + return Underlying; + } + + /// Gets the using declaration to which this declaration is tied. + UsingDecl *getUsingDecl() const { + return Using; + } + + static bool classof(const Decl *D) { + return D->getKind() == Decl::UsingShadow; + } + static bool classof(const UsingShadowDecl *D) { return true; } +}; + /// UsingDecl - Represents a C++ using-declaration. For example: /// using someNameSpace::someIdentifier; class UsingDecl : public NamedDecl { @@ -1651,29 +1701,26 @@ class UsingDecl : public NamedDecl { /// preceding the declaration name. SourceRange NestedNameRange; - /// \brief The source location of the target declaration name. - SourceLocation TargetNameLocation; - /// \brief The source location of the "using" location itself. SourceLocation UsingLocation; - /// \brief Target declaration. - NamedDecl* TargetDecl; - /// \brief Target nested name specifier. - NestedNameSpecifier* TargetNestedNameDecl; + NestedNameSpecifier* TargetNestedName; + + /// \brief The collection of shadow declarations associated with + /// this using declaration. This set can change as a class is + /// processed. + llvm::SmallPtrSet<UsingShadowDecl*, 8> Shadows; // \brief Has 'typename' keyword. bool IsTypeName; UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR, - SourceLocation TargetNL, SourceLocation UL, NamedDecl* Target, - NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) - : NamedDecl(Decl::Using, DC, L, Target->getDeclName()), - NestedNameRange(NNR), TargetNameLocation(TargetNL), - UsingLocation(UL), TargetDecl(Target), - TargetNestedNameDecl(TargetNNS), IsTypeName(IsTypeNameArg) { - this->IdentifierNamespace = TargetDecl->getIdentifierNamespace(); + SourceLocation UL, NestedNameSpecifier* TargetNNS, + DeclarationName Name, bool IsTypeNameArg) + : NamedDecl(Decl::Using, DC, L, Name), + NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS), + IsTypeName(IsTypeNameArg) { } public: @@ -1681,28 +1728,37 @@ public: /// preceding the namespace name. SourceRange getNestedNameRange() { return NestedNameRange; } - /// \brief Returns the source location of the target declaration name. - SourceLocation getTargetNameLocation() { return TargetNameLocation; } - /// \brief Returns the source location of the "using" location itself. SourceLocation getUsingLocation() { return UsingLocation; } - /// \brief getTargetDecl - Returns target specified by using-decl. - NamedDecl *getTargetDecl() { return TargetDecl; } - const NamedDecl *getTargetDecl() const { return TargetDecl; } - /// \brief Get target nested name declaration. NestedNameSpecifier* getTargetNestedNameDecl() { - return TargetNestedNameDecl; + return TargetNestedName; } /// isTypeName - Return true if using decl has 'typename'. bool isTypeName() const { return IsTypeName; } + typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator; + shadow_iterator shadow_begin() const { return Shadows.begin(); } + shadow_iterator shadow_end() const { return Shadows.end(); } + + void addShadowDecl(UsingShadowDecl *S) { + assert(S->getUsingDecl() == this); + if (!Shadows.insert(S)) { + assert(false && "declaration already in set"); + } + } + void removeShadowDecl(UsingShadowDecl *S) { + assert(S->getUsingDecl() == this); + if (!Shadows.erase(S)) { + assert(false && "declaration not in set"); + } + } + static UsingDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, SourceRange NNR, SourceLocation TargetNL, - SourceLocation UL, NamedDecl* Target, - NestedNameSpecifier* TargetNNS, bool IsTypeNameArg); + SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL, + NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg); static bool classof(const Decl *D) { return D->getKind() == Decl::Using; diff --git a/include/clang/AST/DeclNodes.def b/include/clang/AST/DeclNodes.def index 3ef3cc3f09..f0238375cc 100644 --- a/include/clang/AST/DeclNodes.def +++ b/include/clang/AST/DeclNodes.def @@ -110,6 +110,7 @@ ABSTRACT_DECL(Named, Decl) DECL(TemplateTemplateParm, TemplateDecl) DECL(Using, NamedDecl) DECL(UnresolvedUsing, NamedDecl) + DECL(UsingShadow, NamedDecl) DECL(ObjCMethod, NamedDecl) DECL(ObjCContainer, NamedDecl) DECL(ObjCCategory, ObjCContainerDecl) |