mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 15:41:46 +00:00
Revert r120808, my previous implementation of caching for the linkage
and visibility of declarations, because it was extremely messy and it increased the size of NamedDecl. An improved implementation is forthcoming. llvm-svn: 121012
This commit is contained in:
parent
1321cbbd87
commit
027ba500ab
@ -99,25 +99,10 @@ class NamedDecl : public Decl {
|
||||
/// constructor, Objective-C selector, etc.)
|
||||
DeclarationName Name;
|
||||
|
||||
/// \brief Whether we have already cached linkage and visibility.
|
||||
mutable unsigned HasLinkageAndVisibilityCached : 1;
|
||||
|
||||
/// \brief The cached visibility, if \c HasLinkageAndVisibilityCached is
|
||||
/// non-zero.
|
||||
mutable unsigned CachedVisibility : 2;
|
||||
|
||||
/// \brief Whether the cached visibility was explicitly placed on this
|
||||
/// declaration.
|
||||
mutable unsigned CachedVisibilityIsExplicit : 1;
|
||||
|
||||
/// \brief The cached linkage, if \c HasLinkageAndVisibilityCached is
|
||||
/// non-zero.
|
||||
mutable unsigned CachedLinkage : 2;
|
||||
|
||||
protected:
|
||||
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
|
||||
: Decl(DK, DC, L), Name(N), HasLinkageAndVisibilityCached(0) { }
|
||||
|
||||
: Decl(DK, DC, L), Name(N) { }
|
||||
|
||||
public:
|
||||
/// getIdentifier - Get the identifier that names this declaration,
|
||||
/// if there is one. This will return NULL if this declaration has
|
||||
@ -287,13 +272,6 @@ public:
|
||||
/// \brief Determines the linkage and visibility of this entity.
|
||||
LinkageInfo getLinkageAndVisibility() const;
|
||||
|
||||
/// \brief Clear the linkage and visibility cache in response to a change
|
||||
/// to the declaration.
|
||||
///
|
||||
/// \param Redeclarations When true, we also have to clear out the linkage
|
||||
/// and visibility cache for all redeclarations.
|
||||
void ClearLinkageAndVisibilityCache();
|
||||
|
||||
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
|
||||
/// the underlying named decl.
|
||||
NamedDecl *getUnderlyingDecl();
|
||||
@ -647,8 +625,6 @@ private:
|
||||
bool NRVOVariable : 1;
|
||||
|
||||
friend class StmtIteratorBase;
|
||||
friend class ASTDeclReader;
|
||||
|
||||
protected:
|
||||
VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
|
||||
QualType T, TypeSourceInfo *TInfo, StorageClass SC,
|
||||
@ -684,7 +660,10 @@ public:
|
||||
StorageClass getStorageClassAsWritten() const {
|
||||
return (StorageClass) SClassAsWritten;
|
||||
}
|
||||
void setStorageClass(StorageClass SC);
|
||||
void setStorageClass(StorageClass SC) {
|
||||
assert(isLegalForVariable(SC));
|
||||
SClass = SC;
|
||||
}
|
||||
void setStorageClassAsWritten(StorageClass SC) {
|
||||
assert(isLegalForVariable(SC));
|
||||
SClassAsWritten = SC;
|
||||
@ -1499,7 +1478,10 @@ public:
|
||||
}
|
||||
|
||||
StorageClass getStorageClass() const { return StorageClass(SClass); }
|
||||
void setStorageClass(StorageClass SC);
|
||||
void setStorageClass(StorageClass SC) {
|
||||
assert(isLegalForFunction(SC));
|
||||
SClass = SC;
|
||||
}
|
||||
|
||||
StorageClass getStorageClassAsWritten() const {
|
||||
return StorageClass(SClassAsWritten);
|
||||
@ -2576,63 +2558,6 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
return DB;
|
||||
}
|
||||
|
||||
template<typename decl_type>
|
||||
void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) {
|
||||
// Note: This routine is implemented here because we need both NamedDecl
|
||||
// and Redeclarable to be defined.
|
||||
decl_type *First;
|
||||
|
||||
if (PrevDecl) {
|
||||
// Point to previous. Make sure that this is actually the most recent
|
||||
// redeclaration, or we can build invalid chains. If the most recent
|
||||
// redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
|
||||
RedeclLink = PreviousDeclLink(llvm::cast<decl_type>(
|
||||
PrevDecl->getMostRecentDeclaration()));
|
||||
First = PrevDecl->getFirstDeclaration();
|
||||
assert(First->RedeclLink.NextIsLatest() && "Expected first");
|
||||
} else {
|
||||
// Make this first.
|
||||
First = static_cast<decl_type*>(this);
|
||||
}
|
||||
|
||||
// First one will point to this one as latest.
|
||||
First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
|
||||
|
||||
// If this declaration has a visibility attribute that differs from the
|
||||
// previous visibility attribute, or has private extern storage while the
|
||||
// previous declaration merely had extern storage, clear out the linkage and
|
||||
///visibility cache. This is required because declarations after the first
|
||||
// declaration can change the visibility for all previous and future
|
||||
// declarations.
|
||||
if (NamedDecl *ND = dyn_cast<NamedDecl>(static_cast<decl_type*>(this))) {
|
||||
bool MustClear = false;
|
||||
if (VisibilityAttr *Visibility = ND->getAttr<VisibilityAttr>()) {
|
||||
VisibilityAttr *PrevVisibility
|
||||
= PrevDecl->template getAttr<VisibilityAttr>();
|
||||
if (!PrevVisibility ||
|
||||
PrevVisibility->getVisibility() != Visibility->getVisibility())
|
||||
MustClear = true;
|
||||
}
|
||||
|
||||
if (!MustClear) {
|
||||
if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
|
||||
if (VD->getStorageClass() != cast<VarDecl>(PrevDecl)->getStorageClass())
|
||||
MustClear = true;
|
||||
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
|
||||
FunctionDecl *PrevFD = cast<FunctionDecl>(PrevDecl);
|
||||
if (FD->getStorageClass() != PrevFD->getStorageClass())
|
||||
MustClear = true;
|
||||
else if (FD->isInlineSpecified() && !PrevFD->isInlined())
|
||||
MustClear = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (MustClear)
|
||||
ND->ClearLinkageAndVisibilityCache();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -198,7 +198,7 @@ private:
|
||||
return DeclCtx.get<DeclContext*>();
|
||||
}
|
||||
|
||||
/// Loc - The location of this decl.
|
||||
/// Loc - The location that this decl.
|
||||
SourceLocation Loc;
|
||||
|
||||
/// DeclKind - This indicates which class this is.
|
||||
@ -316,7 +316,12 @@ public:
|
||||
void swapAttrs(Decl *D);
|
||||
void dropAttrs();
|
||||
|
||||
void addAttr(Attr *A);
|
||||
void addAttr(Attr *A) {
|
||||
if (hasAttrs())
|
||||
getAttrs().push_back(A);
|
||||
else
|
||||
setAttrs(AttrVec(1, A));
|
||||
}
|
||||
|
||||
typedef AttrVec::const_iterator attr_iterator;
|
||||
|
||||
|
@ -1241,8 +1241,6 @@ public:
|
||||
}
|
||||
|
||||
void setSpecializationKind(TemplateSpecializationKind TSK) {
|
||||
if (getSpecializationKind() != TSK)
|
||||
ClearLinkageAndVisibilityCache();
|
||||
SpecializationKind = TSK;
|
||||
}
|
||||
|
||||
|
@ -109,8 +109,26 @@ public:
|
||||
|
||||
/// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
|
||||
/// first and only declaration.
|
||||
void setPreviousDeclaration(decl_type *PrevDecl);
|
||||
|
||||
void setPreviousDeclaration(decl_type *PrevDecl) {
|
||||
decl_type *First;
|
||||
|
||||
if (PrevDecl) {
|
||||
// Point to previous. Make sure that this is actually the most recent
|
||||
// redeclaration, or we can build invalid chains. If the most recent
|
||||
// redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
|
||||
RedeclLink = PreviousDeclLink(llvm::cast<decl_type>(
|
||||
PrevDecl->getMostRecentDeclaration()));
|
||||
First = PrevDecl->getFirstDeclaration();
|
||||
assert(First->RedeclLink.NextIsLatest() && "Expected first");
|
||||
} else {
|
||||
// Make this first.
|
||||
First = static_cast<decl_type*>(this);
|
||||
}
|
||||
|
||||
// First one will point to this one as latest.
|
||||
First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
|
||||
}
|
||||
|
||||
/// \brief Iterates through all the redeclarations of the same decl.
|
||||
class redecl_iterator {
|
||||
/// Current - The current declaration.
|
||||
|
@ -526,57 +526,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
|
||||
}
|
||||
|
||||
LinkageInfo NamedDecl::getLinkageAndVisibility() const {
|
||||
// If we have already cached linkage and visibility, just return the
|
||||
// cached information.
|
||||
if (HasLinkageAndVisibilityCached) {
|
||||
#ifndef NDEBUG
|
||||
LinkageInfo LI = getLVForDecl(this, LVFlags());
|
||||
assert(LI.visibility() == Visibility(CachedVisibility));
|
||||
assert(LI.visibilityExplicit() == CachedVisibilityIsExplicit);
|
||||
assert(LI.linkage() == Linkage(CachedLinkage));
|
||||
#endif
|
||||
return LinkageInfo(Linkage(CachedLinkage), Visibility(CachedVisibility),
|
||||
CachedVisibilityIsExplicit);
|
||||
}
|
||||
|
||||
LinkageInfo LI = getLVForDecl(this, LVFlags());
|
||||
HasLinkageAndVisibilityCached = 1;
|
||||
CachedVisibility = LI.visibility();
|
||||
CachedVisibilityIsExplicit = LI.visibilityExplicit();
|
||||
CachedLinkage = LI.linkage();
|
||||
return LI;
|
||||
}
|
||||
|
||||
void NamedDecl::ClearLinkageAndVisibilityCache() {
|
||||
HasLinkageAndVisibilityCached = 0;
|
||||
|
||||
if (VarDecl *VD = dyn_cast<VarDecl>(this)) {
|
||||
for (VarDecl::redecl_iterator R = VD->redecls_begin(),
|
||||
REnd = VD->redecls_end();
|
||||
R != REnd; ++R)
|
||||
R->HasLinkageAndVisibilityCached = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) {
|
||||
for (FunctionDecl::redecl_iterator R = FD->redecls_begin(),
|
||||
REnd = FD->redecls_end();
|
||||
R != REnd; ++R)
|
||||
R->HasLinkageAndVisibilityCached = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Changing the linkage or visibility of a C++ class affect the linkage and
|
||||
// visibility of all of its members. Clear their caches, too.
|
||||
if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(this)) {
|
||||
for (DeclContext::decl_iterator D = RD->decls_begin(),
|
||||
DEnd = RD->decls_end();
|
||||
D != DEnd; ++D)
|
||||
if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
|
||||
ND->ClearLinkageAndVisibilityCache();
|
||||
}
|
||||
return getLVForDecl(this, LVFlags());
|
||||
}
|
||||
|
||||
static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
|
||||
@ -928,14 +878,6 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
|
||||
return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S, SCAsWritten);
|
||||
}
|
||||
|
||||
void VarDecl::setStorageClass(StorageClass SC) {
|
||||
assert(isLegalForVariable(SC));
|
||||
if (getStorageClass() != SC)
|
||||
ClearLinkageAndVisibilityCache();
|
||||
|
||||
SClass = SC;
|
||||
}
|
||||
|
||||
SourceLocation VarDecl::getInnerLocStart() const {
|
||||
SourceLocation Start = getTypeSpecStartLoc();
|
||||
if (Start.isInvalid())
|
||||
@ -1154,7 +1096,6 @@ void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
|
||||
PointOfInstantiation.isValid() &&
|
||||
MSI->getPointOfInstantiation().isInvalid())
|
||||
MSI->setPointOfInstantiation(PointOfInstantiation);
|
||||
ClearLinkageAndVisibilityCache();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1254,10 +1195,8 @@ Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
|
||||
|
||||
void FunctionDecl::setBody(Stmt *B) {
|
||||
Body = B;
|
||||
if (B) {
|
||||
if (B)
|
||||
EndRangeLoc = B->getLocEnd();
|
||||
ClearLinkageAndVisibilityCache();
|
||||
}
|
||||
}
|
||||
|
||||
void FunctionDecl::setPure(bool P) {
|
||||
@ -1338,14 +1277,6 @@ FunctionDecl *FunctionDecl::getCanonicalDecl() {
|
||||
return getFirstDeclaration();
|
||||
}
|
||||
|
||||
void FunctionDecl::setStorageClass(StorageClass SC) {
|
||||
assert(isLegalForFunction(SC));
|
||||
if (getStorageClass() != SC)
|
||||
ClearLinkageAndVisibilityCache();
|
||||
|
||||
SClass = SC;
|
||||
}
|
||||
|
||||
/// \brief Returns a value indicating whether this function
|
||||
/// corresponds to a builtin function.
|
||||
///
|
||||
@ -1778,7 +1709,6 @@ FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
|
||||
MSInfo->setPointOfInstantiation(PointOfInstantiation);
|
||||
} else
|
||||
assert(false && "Function cannot have a template specialization kind");
|
||||
ClearLinkageAndVisibilityCache();
|
||||
}
|
||||
|
||||
SourceLocation FunctionDecl::getPointOfInstantiation() const {
|
||||
@ -1857,7 +1787,6 @@ void TagDecl::setTypedefForAnonDecl(TypedefDecl *TDD) {
|
||||
TypedefDeclOrQualifier = TDD;
|
||||
if (TypeForDecl)
|
||||
TypeForDecl->ClearLinkageCache();
|
||||
ClearLinkageAndVisibilityCache();
|
||||
}
|
||||
|
||||
void TagDecl::startDefinition() {
|
||||
|
@ -337,38 +337,6 @@ void Decl::dropAttrs() {
|
||||
getASTContext().eraseDeclAttrs(this);
|
||||
}
|
||||
|
||||
void Decl::addAttr(Attr *A) {
|
||||
if (NamedDecl *ND = dyn_cast<NamedDecl>(this))
|
||||
if (VisibilityAttr *Visibility = dyn_cast<VisibilityAttr>(A)) {
|
||||
bool ClearVisibility = true;
|
||||
if (VarDecl *VD = dyn_cast<VarDecl>(this)) {
|
||||
if (VD->getPreviousDeclaration()) {
|
||||
VisibilityAttr *PrevVisibility
|
||||
= VD->getPreviousDeclaration()->getAttr<VisibilityAttr>();
|
||||
if (PrevVisibility &&
|
||||
PrevVisibility->getVisibility() == Visibility->getVisibility())
|
||||
ClearVisibility = false;
|
||||
}
|
||||
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) {
|
||||
if (FD->getPreviousDeclaration()) {
|
||||
VisibilityAttr *PrevVisibility
|
||||
= FD->getPreviousDeclaration()->getAttr<VisibilityAttr>();
|
||||
if (PrevVisibility &&
|
||||
PrevVisibility->getVisibility() == Visibility->getVisibility())
|
||||
ClearVisibility = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ClearVisibility)
|
||||
ND->ClearLinkageAndVisibilityCache();
|
||||
}
|
||||
|
||||
if (hasAttrs())
|
||||
getAttrs().push_back(A);
|
||||
else
|
||||
setAttrs(AttrVec(1, A));
|
||||
}
|
||||
|
||||
const AttrVec &Decl::getAttrs() const {
|
||||
assert(HasAttrs && "No attrs to get!");
|
||||
return getASTContext().getDeclAttrs(this);
|
||||
|
@ -792,8 +792,6 @@ CXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
|
||||
}
|
||||
|
||||
if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
|
||||
if (MSInfo->getTemplateSpecializationKind() != TSK)
|
||||
ClearLinkageAndVisibilityCache();
|
||||
MSInfo->setTemplateSpecializationKind(TSK);
|
||||
return;
|
||||
}
|
||||
|
@ -384,7 +384,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
|
||||
// FunctionDecl's body is handled last at ASTDeclReader::Visit,
|
||||
// after everything else is read.
|
||||
|
||||
FD->SClass = (StorageClass)Record[Idx++];
|
||||
FD->setStorageClass((StorageClass)Record[Idx++]);
|
||||
FD->setStorageClassAsWritten((StorageClass)Record[Idx++]);
|
||||
FD->setInlineSpecified(Record[Idx++]);
|
||||
FD->setVirtualAsWritten(Record[Idx++]);
|
||||
@ -651,7 +651,7 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
|
||||
void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
|
||||
VisitDeclaratorDecl(VD);
|
||||
VisitRedeclarable(VD);
|
||||
VD->SClass = (StorageClass)Record[Idx++];
|
||||
VD->setStorageClass((StorageClass)Record[Idx++]);
|
||||
VD->setStorageClassAsWritten((StorageClass)Record[Idx++]);
|
||||
VD->setThreadSpecified(Record[Idx++]);
|
||||
VD->setCXXDirectInitializer(Record[Idx++]);
|
||||
|
Loading…
Reference in New Issue
Block a user