зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
b4e85ed519
Коммит
46cd2186bd
|
@ -185,16 +185,9 @@ public:
|
||||||
/// \brief Determine whether this declaration has linkage.
|
/// \brief Determine whether this declaration has linkage.
|
||||||
bool hasLinkage() const;
|
bool hasLinkage() const;
|
||||||
|
|
||||||
/// \brief Whether this declaration was marked as being private to the
|
using Decl::isModulePrivate;
|
||||||
/// module in which it was defined.
|
using Decl::setModulePrivate;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Determine whether this declaration is hidden from name lookup.
|
/// \brief Determine whether this declaration is hidden from name lookup.
|
||||||
bool isHidden() const { return Hidden; }
|
bool isHidden() const { return Hidden; }
|
||||||
|
|
||||||
|
|
|
@ -180,12 +180,28 @@ public:
|
||||||
OBJC_TQ_Oneway = 0x20
|
OBJC_TQ_Oneway = 0x20
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
/// NextDeclInContext - The next declaration within the same lexical
|
// 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
|
/// DeclContext. These pointers form the linked list that is
|
||||||
/// traversed via DeclContext's decls_begin()/decls_end().
|
/// 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;
|
friend class DeclContext;
|
||||||
|
|
||||||
struct MultipleDC {
|
struct MultipleDC {
|
||||||
|
@ -244,12 +260,6 @@ private:
|
||||||
/// are regarded as "referenced" but not "used".
|
/// are regarded as "referenced" but not "used".
|
||||||
unsigned Referenced : 1;
|
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:
|
protected:
|
||||||
/// Access - Used by C++ decls for the access specifier.
|
/// Access - Used by C++ decls for the access specifier.
|
||||||
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
|
// 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.
|
/// \brief Whether this declaration was loaded from an AST file.
|
||||||
unsigned FromASTFile : 1;
|
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.,
|
/// \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 it is was loaded from an AST file is either module-private or
|
||||||
/// because its submodule has not been made visible.
|
/// because its submodule has not been made visible.
|
||||||
|
@ -291,11 +297,10 @@ private:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Decl(Kind DK, DeclContext *DC, SourceLocation L)
|
Decl(Kind DK, DeclContext *DC, SourceLocation L)
|
||||||
: NextDeclInContext(0), DeclCtx(DC),
|
: NextInContextAndBits(), DeclCtx(DC),
|
||||||
Loc(L), DeclKind(DK), InvalidDecl(0),
|
Loc(L), DeclKind(DK), InvalidDecl(0),
|
||||||
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
|
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
|
||||||
TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
|
Access(AS_none), FromASTFile(0), Hidden(0),
|
||||||
ModulePrivate(0), Hidden(0),
|
|
||||||
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
|
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
|
||||||
HasCachedLinkage(0)
|
HasCachedLinkage(0)
|
||||||
{
|
{
|
||||||
|
@ -303,10 +308,9 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
Decl(Kind DK, EmptyShell Empty)
|
Decl(Kind DK, EmptyShell Empty)
|
||||||
: NextDeclInContext(0), DeclKind(DK), InvalidDecl(0),
|
: NextInContextAndBits(), DeclKind(DK), InvalidDecl(0),
|
||||||
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
|
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
|
||||||
TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
|
Access(AS_none), FromASTFile(0), Hidden(0),
|
||||||
ModulePrivate(0), Hidden(0),
|
|
||||||
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
|
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
|
||||||
HasCachedLinkage(0)
|
HasCachedLinkage(0)
|
||||||
{
|
{
|
||||||
|
@ -342,8 +346,8 @@ public:
|
||||||
Kind getKind() const { return static_cast<Kind>(DeclKind); }
|
Kind getKind() const { return static_cast<Kind>(DeclKind); }
|
||||||
const char *getDeclKindName() const;
|
const char *getDeclKindName() const;
|
||||||
|
|
||||||
Decl *getNextDeclInContext() { return NextDeclInContext; }
|
Decl *getNextDeclInContext() { return NextInContextAndBits.getPointer(); }
|
||||||
const Decl *getNextDeclInContext() const { return NextDeclInContext; }
|
const Decl *getNextDeclInContext() const {return NextInContextAndBits.getPointer();}
|
||||||
|
|
||||||
DeclContext *getDeclContext() {
|
DeclContext *getDeclContext() {
|
||||||
if (isInSemaDC())
|
if (isInSemaDC())
|
||||||
|
@ -480,13 +484,38 @@ public:
|
||||||
/// global variable, etc.) that is lexically inside an objc container
|
/// global variable, etc.) that is lexically inside an objc container
|
||||||
/// definition.
|
/// definition.
|
||||||
bool isTopLevelDeclInObjCContainer() const {
|
bool isTopLevelDeclInObjCContainer() const {
|
||||||
return TopLevelDeclInObjCContainer;
|
return NextInContextAndBits.getInt() & TopLevelDeclInObjCContainerFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTopLevelDeclInObjCContainer(bool V = true) {
|
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.
|
/// \brief Determine the availability of the given declaration.
|
||||||
///
|
///
|
||||||
/// This routine will determine the most restrictive availability of
|
/// 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
|
/// \brief Determine whether the given declaration is stored in the list of
|
||||||
/// declarations lexically within this context.
|
/// declarations lexically within this context.
|
||||||
bool isDeclInLexicalTraversal(const Decl *D) const {
|
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);
|
static bool classof(const Decl *D);
|
||||||
|
|
|
@ -853,7 +853,7 @@ DeclContext *DeclContext::getNextContext() {
|
||||||
std::pair<Decl *, Decl *>
|
std::pair<Decl *, Decl *>
|
||||||
DeclContext::BuildDeclChain(const SmallVectorImpl<Decl*> &Decls,
|
DeclContext::BuildDeclChain(const SmallVectorImpl<Decl*> &Decls,
|
||||||
bool FieldsAlreadyLoaded) {
|
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 *FirstNewDecl = 0;
|
||||||
Decl *PrevDecl = 0;
|
Decl *PrevDecl = 0;
|
||||||
for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
|
for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
|
||||||
|
@ -862,7 +862,7 @@ DeclContext::BuildDeclChain(const SmallVectorImpl<Decl*> &Decls,
|
||||||
|
|
||||||
Decl *D = Decls[I];
|
Decl *D = Decls[I];
|
||||||
if (PrevDecl)
|
if (PrevDecl)
|
||||||
PrevDecl->NextDeclInContext = D;
|
PrevDecl->NextInContextAndBits.setPointer(D);
|
||||||
else
|
else
|
||||||
FirstNewDecl = D;
|
FirstNewDecl = D;
|
||||||
|
|
||||||
|
@ -908,7 +908,7 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const {
|
||||||
Decl *ExternalFirst, *ExternalLast;
|
Decl *ExternalFirst, *ExternalLast;
|
||||||
llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls,
|
llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls,
|
||||||
FieldsAlreadyLoaded);
|
FieldsAlreadyLoaded);
|
||||||
ExternalLast->NextDeclInContext = FirstDecl;
|
ExternalLast->NextInContextAndBits.setPointer(FirstDecl);
|
||||||
FirstDecl = ExternalFirst;
|
FirstDecl = ExternalFirst;
|
||||||
if (!LastDecl)
|
if (!LastDecl)
|
||||||
LastDecl = ExternalLast;
|
LastDecl = ExternalLast;
|
||||||
|
@ -983,7 +983,7 @@ bool DeclContext::decls_empty() const {
|
||||||
void DeclContext::removeDecl(Decl *D) {
|
void DeclContext::removeDecl(Decl *D) {
|
||||||
assert(D->getLexicalDeclContext() == this &&
|
assert(D->getLexicalDeclContext() == this &&
|
||||||
"decl being removed from non-lexical context");
|
"decl being removed from non-lexical context");
|
||||||
assert((D->NextDeclInContext || D == LastDecl) &&
|
assert((D->NextInContextAndBits.getPointer() || D == LastDecl) &&
|
||||||
"decl is not in decls list");
|
"decl is not in decls list");
|
||||||
|
|
||||||
// Remove D from the decl chain. This is O(n) but hopefully rare.
|
// 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)
|
if (D == LastDecl)
|
||||||
FirstDecl = LastDecl = 0;
|
FirstDecl = LastDecl = 0;
|
||||||
else
|
else
|
||||||
FirstDecl = D->NextDeclInContext;
|
FirstDecl = D->NextInContextAndBits.getPointer();
|
||||||
} else {
|
} 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");
|
assert(I && "decl not found in linked list");
|
||||||
if (I->NextDeclInContext == D) {
|
if (I->NextInContextAndBits.getPointer() == D) {
|
||||||
I->NextDeclInContext = D->NextDeclInContext;
|
I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer());
|
||||||
if (D == LastDecl) LastDecl = I;
|
if (D == LastDecl) LastDecl = I;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1004,7 @@ void DeclContext::removeDecl(Decl *D) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark that D is no longer in the decl chain.
|
// 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.
|
// Remove D from the lookup table if necessary.
|
||||||
if (isa<NamedDecl>(D)) {
|
if (isa<NamedDecl>(D)) {
|
||||||
|
@ -1030,7 +1030,7 @@ void DeclContext::addHiddenDecl(Decl *D) {
|
||||||
"Decl already inserted into a DeclContext");
|
"Decl already inserted into a DeclContext");
|
||||||
|
|
||||||
if (FirstDecl) {
|
if (FirstDecl) {
|
||||||
LastDecl->NextDeclInContext = D;
|
LastDecl->NextInContextAndBits.setPointer(D);
|
||||||
LastDecl = D;
|
LastDecl = D;
|
||||||
} else {
|
} else {
|
||||||
FirstDecl = LastDecl = D;
|
FirstDecl = LastDecl = D;
|
||||||
|
|
|
@ -360,17 +360,17 @@ void ASTDeclReader::VisitDecl(Decl *D) {
|
||||||
D->setImplicit(Record[Idx++]);
|
D->setImplicit(Record[Idx++]);
|
||||||
D->setUsed(Record[Idx++]);
|
D->setUsed(Record[Idx++]);
|
||||||
D->setReferenced(Record[Idx++]);
|
D->setReferenced(Record[Idx++]);
|
||||||
D->TopLevelDeclInObjCContainer = Record[Idx++];
|
D->setTopLevelDeclInObjCContainer(Record[Idx++]);
|
||||||
D->setAccess((AccessSpecifier)Record[Idx++]);
|
D->setAccess((AccessSpecifier)Record[Idx++]);
|
||||||
D->FromASTFile = true;
|
D->FromASTFile = true;
|
||||||
D->ModulePrivate = Record[Idx++];
|
D->setModulePrivate(Record[Idx++]);
|
||||||
D->Hidden = D->ModulePrivate;
|
D->Hidden = D->isModulePrivate();
|
||||||
|
|
||||||
// Determine whether this declaration is part of a (sub)module. If so, it
|
// Determine whether this declaration is part of a (sub)module. If so, it
|
||||||
// may not yet be visible.
|
// may not yet be visible.
|
||||||
if (unsigned SubmoduleID = readSubmoduleID(Record, Idx)) {
|
if (unsigned SubmoduleID = readSubmoduleID(Record, Idx)) {
|
||||||
// Module-private declarations are never visible, so there is no work to do.
|
// 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 (Module *Owner = Reader.getSubmodule(SubmoduleID)) {
|
||||||
if (Owner->NameVisibility != Module::AllVisible) {
|
if (Owner->NameVisibility != Module::AllVisible) {
|
||||||
// The owning module is not visible. Mark this declaration as hidden.
|
// 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->isImplicit());
|
||||||
Record.push_back(D->isUsed(false));
|
Record.push_back(D->isUsed(false));
|
||||||
Record.push_back(D->isReferenced());
|
Record.push_back(D->isReferenced());
|
||||||
Record.push_back(D->TopLevelDeclInObjCContainer);
|
Record.push_back(D->isTopLevelDeclInObjCContainer());
|
||||||
Record.push_back(D->getAccess());
|
Record.push_back(D->getAccess());
|
||||||
Record.push_back(D->ModulePrivate);
|
Record.push_back(D->isModulePrivate());
|
||||||
Record.push_back(Writer.inferSubmoduleIDFromLocation(D->getLocation()));
|
Record.push_back(Writer.inferSubmoduleIDFromLocation(D->getLocation()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче