[cfe-commits] r171053 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclBase.h include/clang/AST/Type.h lib/AST/Decl.cpp lib/AST/Type.cpp lib/Sema/SemaAttr.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGenCXX/visibility-inlines-hidden.cpp
Rafael Espindola
rafael.espindola at gmail.com
Mon Dec 24 23:31:49 PST 2012
Author: rafael
Date: Tue Dec 25 01:31:49 2012
New Revision: 171053
URL: http://llvm.org/viewvc/llvm-project?rev=171053&view=rev
Log:
Add 171048 back but invalidate the cache of all redeclarations when setting
the body of a functions. The problem was that hasBody looks at the entire chain
and causes problems to -fvisibility-inlines-hidden if the cache was not
invalidated.
Original message:
Cache visibility of decls.
This unifies the linkage and visibility caching. I first implemented this when
working on pr13844, but the previous fixes removed the performance advantage of
this one.
This is still a step in the right direction for making linkage and visibility
cheap to use.
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/Sema/SemaAttr.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=171053&r1=171052&r2=171053&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Tue Dec 25 01:31:49 2012
@@ -228,6 +228,12 @@
"Enum truncated!");
}
+ bool operator==(const LinkageInfo &Other) {
+ return linkage_ == Other.linkage_ &&
+ visibility_ == Other.visibility_ &&
+ explicit_ == Other.explicit_;
+ }
+
static LinkageInfo external() {
return LinkageInfo();
}
@@ -323,7 +329,7 @@
/// \brief Clear the linkage cache in response to a change
/// to the declaration.
- void ClearLinkageCache();
+ void ClearLVCache();
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
@@ -3319,7 +3325,7 @@
// First one will point to this one as latest.
First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
if (NamedDecl *ND = dyn_cast<NamedDecl>(static_cast<decl_type*>(this)))
- ND->ClearLinkageCache();
+ ND->ClearLVCache();
}
// Inline function definitions.
Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=171053&r1=171052&r2=171053&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Tue Dec 25 01:31:49 2012
@@ -241,7 +241,7 @@
SourceLocation Loc;
/// DeclKind - This indicates which class this is.
- unsigned DeclKind : 8;
+ unsigned DeclKind : 6;
/// InvalidDecl - This indicates a semantic error occurred.
unsigned InvalidDecl : 1;
@@ -283,15 +283,16 @@
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
unsigned IdentifierNamespace : 12;
- /// \brief Whether the \c CachedLinkage field is active.
- ///
- /// This field is only valid for NamedDecls subclasses.
- mutable unsigned HasCachedLinkage : 1;
-
- /// \brief If \c HasCachedLinkage, the linkage of this declaration.
+ /// These fields are only valid for NamedDecls subclasses.
///
- /// This field is only valid for NamedDecls subclasses.
+ /// \brief Nonzero if the cache (i.e. the bitfields here starting
+ /// with 'Cache') is valid. If so, then this is a
+ /// LangOptions::VisibilityMode+1.
+ mutable unsigned CacheValidAndVisibility : 2;
+ /// \brief the linkage of this declaration.
mutable unsigned CachedLinkage : 2;
+ /// \brief true if the visibility is explicit.
+ mutable unsigned CachedVisibilityExplicit : 1;
friend class ASTDeclWriter;
friend class ASTDeclReader;
@@ -308,7 +309,7 @@
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
Access(AS_none), FromASTFile(0), Hidden(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- HasCachedLinkage(0)
+ CacheValidAndVisibility(0)
{
if (StatisticsEnabled) add(DK);
}
@@ -318,7 +319,7 @@
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
Access(AS_none), FromASTFile(0), Hidden(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- HasCachedLinkage(0)
+ CacheValidAndVisibility(0)
{
if (StatisticsEnabled) add(DK);
}
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=171053&r1=171052&r2=171053&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Tue Dec 25 01:31:49 2012
@@ -1786,7 +1786,7 @@
std::pair<Linkage,Visibility> getLinkageAndVisibility() const;
/// \brief Note that the linkage is no longer known.
- void ClearLinkageCache();
+ void ClearLVCache();
const char *getTypeClassName() const;
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=171053&r1=171052&r2=171053&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Tue Dec 25 01:31:49 2012
@@ -104,8 +104,14 @@
return LV;
}
-/// getLVForDecl - Get the linkage and visibility for the given declaration.
-static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate);
+/// Compute the linkage and visibility for the given declaration.
+static LinkageInfo computeLVForDecl(const NamedDecl *D, bool OnlyTemplate);
+
+static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate) {
+ if (!OnlyTemplate)
+ return D->getLinkageAndVisibility();
+ return computeLVForDecl(D, OnlyTemplate);
+}
/// \brief Get the most restrictive linkage for the types and
/// declarations in the given template argument list.
@@ -569,18 +575,18 @@
i = record->decls_begin(), e = record->decls_end(); i != e; ++i) {
Decl *child = *i;
if (isa<NamedDecl>(child))
- cast<NamedDecl>(child)->ClearLinkageCache();
+ cast<NamedDecl>(child)->ClearLVCache();
}
}
void NamedDecl::anchor() { }
-void NamedDecl::ClearLinkageCache() {
+void NamedDecl::ClearLVCache() {
// Note that we can't skip clearing the linkage of children just
// because the parent doesn't have cached linkage: we don't cache
// when computing linkage for parent contexts.
- HasCachedLinkage = 0;
+ CacheValidAndVisibility = 0;
// If we're changing the linkage of a class, we need to reset the
// linkage of child declarations, too.
@@ -591,44 +597,44 @@
dyn_cast<ClassTemplateDecl>(const_cast<NamedDecl*>(this))) {
// Clear linkage for the template pattern.
CXXRecordDecl *record = temp->getTemplatedDecl();
- record->HasCachedLinkage = 0;
+ record->CacheValidAndVisibility = 0;
clearLinkageForClass(record);
// We need to clear linkage for specializations, too.
for (ClassTemplateDecl::spec_iterator
i = temp->spec_begin(), e = temp->spec_end(); i != e; ++i)
- i->ClearLinkageCache();
+ i->ClearLVCache();
}
// Clear cached linkage for function template decls, too.
if (FunctionTemplateDecl *temp =
dyn_cast<FunctionTemplateDecl>(const_cast<NamedDecl*>(this))) {
- temp->getTemplatedDecl()->ClearLinkageCache();
+ temp->getTemplatedDecl()->ClearLVCache();
for (FunctionTemplateDecl::spec_iterator
i = temp->spec_begin(), e = temp->spec_end(); i != e; ++i)
- i->ClearLinkageCache();
+ i->ClearLVCache();
}
}
Linkage NamedDecl::getLinkage() const {
- if (HasCachedLinkage) {
- assert(Linkage(CachedLinkage) ==
- getLVForDecl(this, true).linkage());
- return Linkage(CachedLinkage);
- }
-
- CachedLinkage = getLVForDecl(this, true).linkage();
- HasCachedLinkage = 1;
- return Linkage(CachedLinkage);
+ return getLinkageAndVisibility().linkage();
}
LinkageInfo NamedDecl::getLinkageAndVisibility() const {
- LinkageInfo LI = getLVForDecl(this, false);
- assert(!HasCachedLinkage || Linkage(CachedLinkage) == LI.linkage());
- HasCachedLinkage = 1;
- CachedLinkage = LI.linkage();
- return LI;
+ if (CacheValidAndVisibility) {
+ Linkage L = static_cast<Linkage>(CachedLinkage);
+ Visibility V = static_cast<Visibility>(CacheValidAndVisibility - 1);
+ bool Explicit = CachedVisibilityExplicit;
+ LinkageInfo LV(L, V, Explicit);
+ assert(LV == computeLVForDecl(this, false));
+ return LV;
+ }
+ LinkageInfo LV = computeLVForDecl(this, false);
+ CachedLinkage = LV.linkage();
+ CacheValidAndVisibility = LV.visibility() + 1;
+ CachedVisibilityExplicit = LV.visibilityExplicit();
+ return LV;
}
llvm::Optional<Visibility> NamedDecl::getExplicitVisibility() const {
@@ -692,7 +698,7 @@
return llvm::Optional<Visibility>();
}
-static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate) {
+static LinkageInfo computeLVForDecl(const NamedDecl *D, bool OnlyTemplate) {
// Objective-C: treat all Objective-C declarations as having external
// linkage.
switch (D->getKind()) {
@@ -1157,7 +1163,7 @@
void VarDecl::setStorageClass(StorageClass SC) {
assert(isLegalForVariable(SC));
if (getStorageClass() != SC)
- ClearLinkageCache();
+ ClearLVCache();
VarDeclBits.SClass = SC;
}
@@ -1653,6 +1659,9 @@
Body = B;
if (B)
EndRangeLoc = B->getLocEnd();
+ for (redecl_iterator R = redecls_begin(), REnd = redecls_end(); R != REnd;
+ ++R)
+ R->ClearLVCache();
}
void FunctionDecl::setPure(bool P) {
@@ -1757,7 +1766,7 @@
void FunctionDecl::setStorageClass(StorageClass SC) {
assert(isLegalForFunction(SC));
if (getStorageClass() != SC)
- ClearLinkageCache();
+ ClearLVCache();
SClass = SC;
}
@@ -2527,8 +2536,8 @@
void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
TypedefNameDeclOrQualifier = TDD;
if (TypeForDecl)
- const_cast<Type*>(TypeForDecl)->ClearLinkageCache();
- ClearLinkageCache();
+ const_cast<Type*>(TypeForDecl)->ClearLVCache();
+ ClearLVCache();
}
void TagDecl::startDefinition() {
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=171053&r1=171052&r2=171053&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Tue Dec 25 01:31:49 2012
@@ -2186,7 +2186,7 @@
return std::make_pair(TypeBits.getLinkage(), TypeBits.getVisibility());
}
-void Type::ClearLinkageCache() {
+void Type::ClearLVCache() {
TypeBits.CacheValidAndVisibility = 0;
if (QualType(this, 0) != CanonicalType)
CanonicalType->TypeBits.CacheValidAndVisibility = 0;
Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=171053&r1=171052&r2=171053&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Tue Dec 25 01:31:49 2012
@@ -309,7 +309,8 @@
if (!VisContext)
return;
- if (isa<NamedDecl>(D) && cast<NamedDecl>(D)->getExplicitVisibility())
+ NamedDecl *ND = dyn_cast<NamedDecl>(D);
+ if (ND && ND->getExplicitVisibility())
return;
VisStack *Stack = static_cast<VisStack*>(VisContext);
@@ -320,6 +321,7 @@
= (VisibilityAttr::VisibilityType) rawType;
SourceLocation loc = Stack->back().second;
+ ND->ClearLVCache();
D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
}
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=171053&r1=171052&r2=171053&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Dec 25 01:31:49 2012
@@ -1775,9 +1775,13 @@
AA->getIntroduced(), AA->getDeprecated(),
AA->getObsoleted(), AA->getUnavailable(),
AA->getMessage());
- else if (VisibilityAttr *VA = dyn_cast<VisibilityAttr>(Attr))
+ else if (VisibilityAttr *VA = dyn_cast<VisibilityAttr>(Attr)) {
NewAttr = mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility());
- else if (DLLImportAttr *ImportA = dyn_cast<DLLImportAttr>(Attr))
+ if (NewAttr) {
+ NamedDecl *ND = cast<NamedDecl>(D);
+ ND->ClearLVCache();
+ }
+ } else if (DLLImportAttr *ImportA = dyn_cast<DLLImportAttr>(Attr))
NewAttr = mergeDLLImportAttr(D, ImportA->getRange());
else if (DLLExportAttr *ExportA = dyn_cast<DLLExportAttr>(Attr))
NewAttr = mergeDLLExportAttr(D, ExportA->getRange());
@@ -6611,7 +6615,7 @@
}
VDecl->setTypeSourceInfo(DeducedType);
VDecl->setType(DeducedType->getType());
- VDecl->ClearLinkageCache();
+ VDecl->ClearLVCache();
// In ARC, infer lifetime.
if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=171053&r1=171052&r2=171053&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Dec 25 01:31:49 2012
@@ -2147,8 +2147,11 @@
Deprecated.Version,
Obsoleted.Version,
IsUnavailable, Str);
- if (NewAttr)
+ if (NewAttr) {
D->addAttr(NewAttr);
+ NamedDecl *ND = cast<NamedDecl>(D);
+ ND->ClearLVCache();
+ }
}
VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
@@ -2165,6 +2168,8 @@
Diag(ExistingAttr->getLocation(), diag::err_mismatched_visibility);
Diag(Range.getBegin(), diag::note_previous_attribute);
D->dropAttr<VisibilityAttr>();
+ NamedDecl *ND = cast<NamedDecl>(D);
+ ND->ClearLVCache();
}
return ::new (Context) VisibilityAttr(Range, Context, Vis);
}
@@ -2208,8 +2213,11 @@
}
VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type);
- if (NewAttr)
+ if (NewAttr) {
D->addAttr(NewAttr);
+ NamedDecl *ND = cast<NamedDecl>(D);
+ ND->ClearLVCache();
+ }
}
static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
Modified: cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp?rev=171053&r1=171052&r2=171053&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp Tue Dec 25 01:31:49 2012
@@ -135,3 +135,15 @@
}
// CHECK: define available_externally void @_ZN5test43fooE
}
+
+namespace test5 {
+ // just don't crash.
+ template <int> inline void Op();
+ class UnaryInstruction {
+ UnaryInstruction() {
+ Op<0>();
+ }
+ };
+ template <int Idx_nocapture> void Op() {
+ }
+}
More information about the cfe-commits
mailing list