Stash Decl's TopLevelDeclInObjCContainer and ModulePrivate bits

into the two unused lower bits of the NextDeclInContext link, dropping
the number of bits in Decl down to 32, and saving 8 bytes per
declaration on x86-64.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147660 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2012-01-06 16:59:53 +00:00
Родитель b4e85ed519
Коммит 46cd2186bd
5 изменённых файлов: 73 добавлений и 50 удалений

Просмотреть файл

@ -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; }

Просмотреть файл

@ -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<Decl *, 2, unsigned> 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<Kind>(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);

Просмотреть файл

@ -853,7 +853,7 @@ DeclContext *DeclContext::getNextContext() {
std::pair<Decl *, Decl *>
DeclContext::BuildDeclChain(const SmallVectorImpl<Decl*> &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<Decl*> &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<NamedDecl>(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;

Просмотреть файл

@ -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.

Просмотреть файл

@ -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()));
}