diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index bbd3ef3a2059..569608a60bed 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -185,16 +185,9 @@ public: /// \brief Determine whether this declaration has linkage. bool hasLinkage() const; - /// \brief Whether this declaration was marked as being private to the - /// module in which it was defined. - bool isModulePrivate() const { return ModulePrivate; } - - /// \brief Specify whether this declaration was marked as being private - /// to the module in which it was defined. - void setModulePrivate(bool MP = true) { - ModulePrivate = MP; - } - + using Decl::isModulePrivate; + using Decl::setModulePrivate; + /// \brief Determine whether this declaration is hidden from name lookup. bool isHidden() const { return Hidden; } diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index c2303bcf51f8..f52f5ad334e4 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -180,12 +180,28 @@ public: OBJC_TQ_Oneway = 0x20 }; -private: - /// NextDeclInContext - The next declaration within the same lexical +protected: + // Enumeration values used in the bits stored in NextInContextAndBits. + enum { + /// \brief Whether this declaration is a top-level declaration (function, + /// global variable, etc.) that is lexically inside an objc container + /// definition. + TopLevelDeclInObjCContainerFlag = 0x01, + + /// \brief Whether this declaration is private to the module in which it was + /// defined. + ModulePrivateFlag = 0x02 + }; + + /// \brief The next declaration within the same lexical /// DeclContext. These pointers form the linked list that is /// traversed via DeclContext's decls_begin()/decls_end(). - Decl *NextDeclInContext; + /// + /// The extra two bits are used for the TopLevelDeclInObjCContainer and + /// ModulePrivate bits. + llvm::PointerIntPair NextInContextAndBits; +private: friend class DeclContext; struct MultipleDC { @@ -244,12 +260,6 @@ private: /// are regarded as "referenced" but not "used". unsigned Referenced : 1; - /// \brief Whether this declaration is a top-level declaration (function, - /// global variable, etc.) that is lexically inside an objc container - /// definition. - /// FIXME: Consider setting the lexical context to the objc container. - unsigned TopLevelDeclInObjCContainer : 1; - protected: /// Access - Used by C++ decls for the access specifier. // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum @@ -259,10 +269,6 @@ protected: /// \brief Whether this declaration was loaded from an AST file. unsigned FromASTFile : 1; - /// \brief Whether this declaration is private to the module in which it was - /// defined. - unsigned ModulePrivate : 1; - /// \brief Whether this declaration is hidden from normal name lookup, e.g., /// because it is was loaded from an AST file is either module-private or /// because its submodule has not been made visible. @@ -291,11 +297,10 @@ private: protected: Decl(Kind DK, DeclContext *DC, SourceLocation L) - : NextDeclInContext(0), DeclCtx(DC), + : NextInContextAndBits(), DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(0), HasAttrs(false), Implicit(false), Used(false), Referenced(false), - TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), - ModulePrivate(0), Hidden(0), + Access(AS_none), FromASTFile(0), Hidden(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), HasCachedLinkage(0) { @@ -303,10 +308,9 @@ protected: } Decl(Kind DK, EmptyShell Empty) - : NextDeclInContext(0), DeclKind(DK), InvalidDecl(0), + : NextInContextAndBits(), DeclKind(DK), InvalidDecl(0), HasAttrs(false), Implicit(false), Used(false), Referenced(false), - TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), - ModulePrivate(0), Hidden(0), + Access(AS_none), FromASTFile(0), Hidden(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), HasCachedLinkage(0) { @@ -342,8 +346,8 @@ public: Kind getKind() const { return static_cast(DeclKind); } const char *getDeclKindName() const; - Decl *getNextDeclInContext() { return NextDeclInContext; } - const Decl *getNextDeclInContext() const { return NextDeclInContext; } + Decl *getNextDeclInContext() { return NextInContextAndBits.getPointer(); } + const Decl *getNextDeclInContext() const {return NextInContextAndBits.getPointer();} DeclContext *getDeclContext() { if (isInSemaDC()) @@ -480,13 +484,38 @@ public: /// global variable, etc.) that is lexically inside an objc container /// definition. bool isTopLevelDeclInObjCContainer() const { - return TopLevelDeclInObjCContainer; + return NextInContextAndBits.getInt() & TopLevelDeclInObjCContainerFlag; } void setTopLevelDeclInObjCContainer(bool V = true) { - TopLevelDeclInObjCContainer = V; + unsigned Bits = NextInContextAndBits.getInt(); + if (V) + Bits |= TopLevelDeclInObjCContainerFlag; + else + Bits &= ~TopLevelDeclInObjCContainerFlag; + NextInContextAndBits.setInt(Bits); } +protected: + /// \brief Whether this declaration was marked as being private to the + /// module in which it was defined. + bool isModulePrivate() const { + return NextInContextAndBits.getInt() & ModulePrivateFlag; + } + + /// \brief Specify whether this declaration was marked as being private + /// to the module in which it was defined. + void setModulePrivate(bool MP = true) { + unsigned Bits = NextInContextAndBits.getInt(); + if (MP) + Bits |= ModulePrivateFlag; + else + Bits &= ~ModulePrivateFlag; + NextInContextAndBits.setInt(Bits); + } + +public: + /// \brief Determine the availability of the given declaration. /// /// This routine will determine the most restrictive availability of @@ -1396,7 +1425,8 @@ public: /// \brief Determine whether the given declaration is stored in the list of /// declarations lexically within this context. bool isDeclInLexicalTraversal(const Decl *D) const { - return D && (D->NextDeclInContext || D == FirstDecl || D == LastDecl); + return D && (D->NextInContextAndBits.getPointer() || D == FirstDecl || + D == LastDecl); } static bool classof(const Decl *D); diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 4dc5bb7e8507..3fc507ebdb90 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -853,7 +853,7 @@ DeclContext *DeclContext::getNextContext() { std::pair DeclContext::BuildDeclChain(const SmallVectorImpl &Decls, bool FieldsAlreadyLoaded) { - // Build up a chain of declarations via the Decl::NextDeclInContext field. + // Build up a chain of declarations via the Decl::NextInContextAndBits field. Decl *FirstNewDecl = 0; Decl *PrevDecl = 0; for (unsigned I = 0, N = Decls.size(); I != N; ++I) { @@ -862,7 +862,7 @@ DeclContext::BuildDeclChain(const SmallVectorImpl &Decls, Decl *D = Decls[I]; if (PrevDecl) - PrevDecl->NextDeclInContext = D; + PrevDecl->NextInContextAndBits.setPointer(D); else FirstNewDecl = D; @@ -908,7 +908,7 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const { Decl *ExternalFirst, *ExternalLast; llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls, FieldsAlreadyLoaded); - ExternalLast->NextDeclInContext = FirstDecl; + ExternalLast->NextInContextAndBits.setPointer(FirstDecl); FirstDecl = ExternalFirst; if (!LastDecl) LastDecl = ExternalLast; @@ -983,7 +983,7 @@ bool DeclContext::decls_empty() const { void DeclContext::removeDecl(Decl *D) { assert(D->getLexicalDeclContext() == this && "decl being removed from non-lexical context"); - assert((D->NextDeclInContext || D == LastDecl) && + assert((D->NextInContextAndBits.getPointer() || D == LastDecl) && "decl is not in decls list"); // Remove D from the decl chain. This is O(n) but hopefully rare. @@ -991,12 +991,12 @@ void DeclContext::removeDecl(Decl *D) { if (D == LastDecl) FirstDecl = LastDecl = 0; else - FirstDecl = D->NextDeclInContext; + FirstDecl = D->NextInContextAndBits.getPointer(); } else { - for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) { + for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) { assert(I && "decl not found in linked list"); - if (I->NextDeclInContext == D) { - I->NextDeclInContext = D->NextDeclInContext; + if (I->NextInContextAndBits.getPointer() == D) { + I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer()); if (D == LastDecl) LastDecl = I; break; } @@ -1004,7 +1004,7 @@ void DeclContext::removeDecl(Decl *D) { } // Mark that D is no longer in the decl chain. - D->NextDeclInContext = 0; + D->NextInContextAndBits.setPointer(0); // Remove D from the lookup table if necessary. if (isa(D)) { @@ -1030,7 +1030,7 @@ void DeclContext::addHiddenDecl(Decl *D) { "Decl already inserted into a DeclContext"); if (FirstDecl) { - LastDecl->NextDeclInContext = D; + LastDecl->NextInContextAndBits.setPointer(D); LastDecl = D; } else { FirstDecl = LastDecl = D; diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 6a88313f743c..51a275ad0703 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -360,17 +360,17 @@ void ASTDeclReader::VisitDecl(Decl *D) { D->setImplicit(Record[Idx++]); D->setUsed(Record[Idx++]); D->setReferenced(Record[Idx++]); - D->TopLevelDeclInObjCContainer = Record[Idx++]; + D->setTopLevelDeclInObjCContainer(Record[Idx++]); D->setAccess((AccessSpecifier)Record[Idx++]); D->FromASTFile = true; - D->ModulePrivate = Record[Idx++]; - D->Hidden = D->ModulePrivate; + D->setModulePrivate(Record[Idx++]); + D->Hidden = D->isModulePrivate(); // Determine whether this declaration is part of a (sub)module. If so, it // may not yet be visible. if (unsigned SubmoduleID = readSubmoduleID(Record, Idx)) { // Module-private declarations are never visible, so there is no work to do. - if (!D->ModulePrivate) { + if (!D->isModulePrivate()) { if (Module *Owner = Reader.getSubmodule(SubmoduleID)) { if (Owner->NameVisibility != Module::AllVisible) { // The owning module is not visible. Mark this declaration as hidden. diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 19d8372a91fa..7ff1d5aab06f 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -154,9 +154,9 @@ void ASTDeclWriter::VisitDecl(Decl *D) { Record.push_back(D->isImplicit()); Record.push_back(D->isUsed(false)); Record.push_back(D->isReferenced()); - Record.push_back(D->TopLevelDeclInObjCContainer); + Record.push_back(D->isTopLevelDeclInObjCContainer()); Record.push_back(D->getAccess()); - Record.push_back(D->ModulePrivate); + Record.push_back(D->isModulePrivate()); Record.push_back(Writer.inferSubmoduleIDFromLocation(D->getLocation())); }