Index: clang/include/clang/AST/DeclCXX.h =================================================================== --- clang/include/clang/AST/DeclCXX.h +++ clang/include/clang/AST/DeclCXX.h @@ -69,6 +69,7 @@ class FunctionTemplateDecl; class IdentifierInfo; class MemberSpecializationInfo; +class ShadowIntroducingDecl; class TemplateDecl; class TemplateParameterList; class UsingDecl; @@ -3167,7 +3168,7 @@ /// } /// \endcode class UsingShadowDecl : public NamedDecl, public Redeclarable { - friend class UsingDecl; + friend class ShadowIntroducingDecl; /// The referenced declaration. NamedDecl *Underlying = nullptr; @@ -3194,7 +3195,7 @@ protected: UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC, SourceLocation Loc, - UsingDecl *Using, NamedDecl *Target); + ShadowIntroducingDecl *Introducer, NamedDecl *Target); UsingShadowDecl(Kind K, ASTContext &C, EmptyShell); public: @@ -3202,9 +3203,11 @@ friend class ASTDeclWriter; static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation Loc, UsingDecl *Using, + SourceLocation Loc, + ShadowIntroducingDecl *Introducer, NamedDecl *Target) { - return new (C, DC) UsingShadowDecl(UsingShadow, C, DC, Loc, Using, Target); + return new (C, DC) + UsingShadowDecl(UsingShadow, C, DC, Loc, Introducer, Target); } static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -3243,7 +3246,7 @@ } /// Gets the using declaration to which this declaration is tied. - UsingDecl *getUsingDecl() const; + ShadowIntroducingDecl *getShadowIntroducingDecl() const; /// The next using shadow declaration contained in the shadow decl /// chain of the using declaration which introduced this decl. @@ -3285,7 +3288,7 @@ unsigned IsVirtual : 1; ConstructorUsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc, - UsingDecl *Using, NamedDecl *Target, + ShadowIntroducingDecl *Using, NamedDecl *Target, bool TargetInVirtualBase) : UsingShadowDecl(ConstructorUsingShadow, C, DC, Loc, Using, Target->getUnderlyingDecl()), @@ -3367,72 +3370,36 @@ static bool classofKind(Kind K) { return K == ConstructorUsingShadow; } }; -/// Represents a C++ using-declaration. -/// -/// For example: -/// \code -/// using someNameSpace::someIdentifier; -/// \endcode -class UsingDecl : public NamedDecl, public Mergeable { - /// The source location of the 'using' keyword itself. - SourceLocation UsingLocation; - - /// The nested-name-specifier that precedes the name. - NestedNameSpecifierLoc QualifierLoc; - - /// Provides source/type location info for the declaration name - /// embedded in the ValueDecl base class. - DeclarationNameLoc DNLoc; +/// Represents a C++ declaration that introduces decls from somewhere else. It +/// provides a set of the shadow decls so introduced. +class ShadowIntroducingDecl : public NamedDecl { /// The first shadow declaration of the shadow decl chain associated /// with this using declaration. /// - /// The bool member of the pair store whether this decl has the \c typename - /// keyword. + /// The bool member of the pair is a bool flag a derived type may use + /// (UsingDecl makes use of it). llvm::PointerIntPair FirstUsingShadow; - UsingDecl(DeclContext *DC, SourceLocation UL, - NestedNameSpecifierLoc QualifierLoc, - const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword) - : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()), - UsingLocation(UL), QualifierLoc(QualifierLoc), - DNLoc(NameInfo.getInfo()), FirstUsingShadow(nullptr, HasTypenameKeyword) { - } +protected: + ShadowIntroducingDecl(Kind DK, DeclContext *DC, SourceLocation L, + DeclarationName N) + : NamedDecl(DK, DC, L, N), FirstUsingShadow(nullptr, 0) {} +private: void anchor() override; +protected: + /// A bool flag for use by a derived type + bool getShadowFlag() const { return FirstUsingShadow.getInt(); } + + /// A bool flag a derived type may set + void setShadowFlag(bool V) { FirstUsingShadow.setInt(V); } + public: friend class ASTDeclReader; friend class ASTDeclWriter; - /// Return the source location of the 'using' keyword. - SourceLocation getUsingLoc() const { return UsingLocation; } - - /// Set the source location of the 'using' keyword. - void setUsingLoc(SourceLocation L) { UsingLocation = L; } - - /// Retrieve the nested-name-specifier that qualifies the name, - /// with source-location information. - NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } - - /// Retrieve the nested-name-specifier that qualifies the name. - NestedNameSpecifier *getQualifier() const { - return QualifierLoc.getNestedNameSpecifier(); - } - - DeclarationNameInfo getNameInfo() const { - return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); - } - - /// Return true if it is a C++03 access declaration (no 'using'). - bool isAccessDeclaration() const { return UsingLocation.isInvalid(); } - - /// Return true if the using declaration has 'typename'. - bool hasTypename() const { return FirstUsingShadow.getInt(); } - - /// Sets whether the using declaration has 'typename'. - void setTypename(bool TN) { FirstUsingShadow.setInt(TN); } - /// Iterates through the using shadow declarations associated with /// this using declaration. class shadow_iterator { @@ -3492,6 +3459,70 @@ void addShadowDecl(UsingShadowDecl *S); void removeShadowDecl(UsingShadowDecl *S); + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Using; } +}; + +/// Represents a C++ using-declaration. +/// +/// For example: +/// \code +/// using someNameSpace::someIdentifier; +/// \endcode +class UsingDecl : public ShadowIntroducingDecl, public Mergeable { + /// The source location of the 'using' keyword itself. + SourceLocation UsingLocation; + + /// The nested-name-specifier that precedes the name. + NestedNameSpecifierLoc QualifierLoc; + + /// Provides source/type location info for the declaration name + /// embedded in the ValueDecl base class. + DeclarationNameLoc DNLoc; + + UsingDecl(DeclContext *DC, SourceLocation UL, + NestedNameSpecifierLoc QualifierLoc, + const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword) + : ShadowIntroducingDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()), + UsingLocation(UL), QualifierLoc(QualifierLoc), + DNLoc(NameInfo.getInfo()) { + setShadowFlag(HasTypenameKeyword); + } + + void anchor() override; + +public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + + /// Return the source location of the 'using' keyword. + SourceLocation getUsingLoc() const { return UsingLocation; } + + /// Set the source location of the 'using' keyword. + void setUsingLoc(SourceLocation L) { UsingLocation = L; } + + /// Retrieve the nested-name-specifier that qualifies the name, + /// with source-location information. + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + + /// Retrieve the nested-name-specifier that qualifies the name. + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); + } + + DeclarationNameInfo getNameInfo() const { + return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); + } + + /// Return true if it is a C++03 access declaration (no 'using'). + bool isAccessDeclaration() const { return UsingLocation.isInvalid(); } + + /// Return true if the using declaration has 'typename'. + bool hasTypename() const { return getShadowFlag(); } + + /// Sets whether the using declaration has 'typename'. + void setTypename(bool TN) { setShadowFlag(TN); } + static UsingDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation UsingL, NestedNameSpecifierLoc QualifierLoc, @@ -3503,8 +3534,12 @@ SourceRange getSourceRange() const override LLVM_READONLY; /// Retrieves the canonical declaration of this declaration. - UsingDecl *getCanonicalDecl() override { return getFirstDecl(); } - const UsingDecl *getCanonicalDecl() const { return getFirstDecl(); } + UsingDecl *getCanonicalDecl() override { + return cast(getFirstDecl()); + } + const UsingDecl *getCanonicalDecl() const { + return cast(getFirstDecl()); + } static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Using; } Index: clang/include/clang/Basic/DeclNodes.td =================================================================== --- clang/include/clang/Basic/DeclNodes.td +++ clang/include/clang/Basic/DeclNodes.td @@ -71,7 +71,8 @@ def TemplateTemplateParm : DeclNode