aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-11-17 05:59:44 +0000
committerJohn McCall <rjmccall@apple.com>2009-11-17 05:59:44 +0000
commit9488ea120e093068021f944176c3d610dd540914 (patch)
treeb25280b1967cb1edee70e5f7faceee121a9d897a /include/clang
parent049d3a06ea9f8fc03582488a2b7f24512565a335 (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.h11
-rw-r--r--include/clang/AST/DeclCXX.h106
-rw-r--r--include/clang/AST/DeclNodes.def1
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)