summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-01-14 00:30:36 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-01-14 00:30:36 +0000
commit2f869a3f4f17d99f6b46274a5ddd67ddc2293140 (patch)
tree61739de067fe86971227996c0c4309845254bb4a /clang/lib
parent1b9c5f1188b05a19df9195ac7c7a17332103cbad (diff)
downloadbcm5719-llvm-2f869a3f4f17d99f6b46274a5ddd67ddc2293140.tar.gz
bcm5719-llvm-2f869a3f4f17d99f6b46274a5ddd67ddc2293140.zip
Remember if a type has its visibility set explicitly or implicitly.
With that, centralize the way we merge visibility, always preferring explicit over implicit and then picking the most restrictive one. Fixes pr10113 and pr11690. llvm-svn: 148163
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Decl.cpp58
-rw-r--r--clang/lib/AST/Type.cpp43
2 files changed, 53 insertions, 48 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 738414e0219..9132b0a1903 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -67,17 +67,6 @@ static llvm::Optional<Visibility> getVisibilityOf(const Decl *D) {
}
typedef NamedDecl::LinkageInfo LinkageInfo;
-typedef std::pair<Linkage,Visibility> LVPair;
-
-static LVPair merge(LVPair L, LVPair R) {
- return LVPair(minLinkage(L.first, R.first),
- minVisibility(L.second, R.second));
-}
-
-static LVPair merge(LVPair L, LinkageInfo R) {
- return LVPair(minLinkage(L.first, R.linkage()),
- minVisibility(L.second, R.visibility()));
-}
namespace {
/// Flags controlling the computation of linkage and visibility.
@@ -113,11 +102,16 @@ struct LVFlags {
};
} // end anonymous namespace
+static LinkageInfo getLVForType(QualType T) {
+ std::pair<Linkage,Visibility> P = T->getLinkageAndVisibility();
+ return LinkageInfo(P.first, P.second, T->isVisibilityExplicit());
+}
+
/// \brief Get the most restrictive linkage for the types in the given
/// template parameter list.
-static LVPair
+static LinkageInfo
getLVForTemplateParameterList(const TemplateParameterList *Params) {
- LVPair LV(ExternalLinkage, DefaultVisibility);
+ LinkageInfo LV(ExternalLinkage, DefaultVisibility, false);
for (TemplateParameterList::const_iterator P = Params->begin(),
PEnd = Params->end();
P != PEnd; ++P) {
@@ -126,20 +120,20 @@ getLVForTemplateParameterList(const TemplateParameterList *Params) {
for (unsigned I = 0, N = NTTP->getNumExpansionTypes(); I != N; ++I) {
QualType T = NTTP->getExpansionType(I);
if (!T->isDependentType())
- LV = merge(LV, T->getLinkageAndVisibility());
+ LV.merge(getLVForType(T));
}
continue;
}
if (!NTTP->getType()->isDependentType()) {
- LV = merge(LV, NTTP->getType()->getLinkageAndVisibility());
+ LV.merge(getLVForType(NTTP->getType()));
continue;
}
}
if (TemplateTemplateParmDecl *TTP
= dyn_cast<TemplateTemplateParmDecl>(*P)) {
- LV = merge(LV, getLVForTemplateParameterList(TTP->getTemplateParameters()));
+ LV.merge(getLVForTemplateParameterList(TTP->getTemplateParameters()));
}
}
@@ -151,10 +145,10 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags F);
/// \brief Get the most restrictive linkage for the types and
/// declarations in the given template argument list.
-static LVPair getLVForTemplateArgumentList(const TemplateArgument *Args,
- unsigned NumArgs,
- LVFlags &F) {
- LVPair LV(ExternalLinkage, DefaultVisibility);
+static LinkageInfo getLVForTemplateArgumentList(const TemplateArgument *Args,
+ unsigned NumArgs,
+ LVFlags &F) {
+ LinkageInfo LV(ExternalLinkage, DefaultVisibility, false);
for (unsigned I = 0; I != NumArgs; ++I) {
switch (Args[I].getKind()) {
@@ -164,7 +158,7 @@ static LVPair getLVForTemplateArgumentList(const TemplateArgument *Args,
break;
case TemplateArgument::Type:
- LV = merge(LV, Args[I].getAsType()->getLinkageAndVisibility());
+ LV.merge(getLVForType(Args[I].getAsType()));
break;
case TemplateArgument::Declaration:
@@ -180,13 +174,13 @@ static LVPair getLVForTemplateArgumentList(const TemplateArgument *Args,
case TemplateArgument::TemplateExpansion:
if (TemplateDecl *Template
= Args[I].getAsTemplateOrTemplatePattern().getAsTemplateDecl())
- LV = merge(LV, getLVForDecl(Template, F));
+ LV.merge(getLVForDecl(Template, F));
break;
case TemplateArgument::Pack:
- LV = merge(LV, getLVForTemplateArgumentList(Args[I].pack_begin(),
- Args[I].pack_size(),
- F));
+ LV.merge(getLVForTemplateArgumentList(Args[I].pack_begin(),
+ Args[I].pack_size(),
+ F));
break;
}
}
@@ -194,7 +188,7 @@ static LVPair getLVForTemplateArgumentList(const TemplateArgument *Args,
return LV;
}
-static LVPair
+static LinkageInfo
getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
LVFlags &F) {
return getLVForTemplateArgumentList(TArgs.data(), TArgs.size(), F);
@@ -337,11 +331,11 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
// Note that we don't want to make the variable non-external
// because of this, but unique-external linkage suits us.
if (Context.getLangOptions().CPlusPlus && !Var->isExternC()) {
- LVPair TypeLV = Var->getType()->getLinkageAndVisibility();
- if (TypeLV.first != ExternalLinkage)
+ LinkageInfo TypeLV = getLVForType(Var->getType());
+ if (TypeLV.linkage() != ExternalLinkage)
return LinkageInfo::uniqueExternal();
if (!LV.visibilityExplicit())
- LV.mergeVisibility(TypeLV.second);
+ LV.mergeVisibility(TypeLV.visibility(), TypeLV.visibilityExplicit());
}
if (Var->getStorageClass() == SC_PrivateExtern)
@@ -599,11 +593,11 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
} else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
// Modify the variable's linkage by its type, but ignore the
// type's visibility unless it's a definition.
- LVPair TypeLV = VD->getType()->getLinkageAndVisibility();
- if (TypeLV.first != ExternalLinkage)
+ LinkageInfo TypeLV = getLVForType(VD->getType());
+ if (TypeLV.linkage() != ExternalLinkage)
LV.mergeLinkage(UniqueExternalLinkage);
if (!LV.visibilityExplicit())
- LV.mergeVisibility(TypeLV.second);
+ LV.mergeVisibility(TypeLV.visibility(), TypeLV.visibilityExplicit());
}
F.ConsiderGlobalVisibility &= !LV.visibilityExplicit();
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 4584ca09d9a..99468b8f613 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -1990,21 +1990,22 @@ namespace {
/// \brief The cached properties of a type.
class CachedProperties {
- char linkage;
- char visibility;
+ NamedDecl::LinkageInfo LV;
bool local;
public:
- CachedProperties(Linkage linkage, Visibility visibility, bool local)
- : linkage(linkage), visibility(visibility), local(local) {}
+ CachedProperties(NamedDecl::LinkageInfo LV, bool local)
+ : LV(LV), local(local) {}
- Linkage getLinkage() const { return (Linkage) linkage; }
- Visibility getVisibility() const { return (Visibility) visibility; }
+ Linkage getLinkage() const { return LV.linkage(); }
+ Visibility getVisibility() const { return LV.visibility(); }
+ bool isVisibilityExplicit() const { return LV.visibilityExplicit(); }
bool hasLocalOrUnnamedType() const { return local; }
friend CachedProperties merge(CachedProperties L, CachedProperties R) {
- return CachedProperties(minLinkage(L.getLinkage(), R.getLinkage()),
- minVisibility(L.getVisibility(), R.getVisibility()),
+ NamedDecl::LinkageInfo MergedLV = L.LV;
+ MergedLV.merge(R.LV);
+ return CachedProperties(MergedLV,
L.hasLocalOrUnnamedType() | R.hasLocalOrUnnamedType());
}
};
@@ -2024,9 +2025,10 @@ public:
static CachedProperties get(const Type *T) {
ensure(T);
- return CachedProperties(T->TypeBits.getLinkage(),
- T->TypeBits.getVisibility(),
- T->TypeBits.hasLocalOrUnnamedType());
+ NamedDecl::LinkageInfo LV(T->TypeBits.getLinkage(),
+ T->TypeBits.getVisibility(),
+ T->TypeBits.isVisibilityExplicit());
+ return CachedProperties(LV, T->TypeBits.hasLocalOrUnnamedType());
}
static void ensure(const Type *T) {
@@ -2040,6 +2042,8 @@ public:
ensure(CT);
T->TypeBits.CacheValidAndVisibility =
CT->TypeBits.CacheValidAndVisibility;
+ T->TypeBits.CachedExplicitVisibility =
+ CT->TypeBits.CachedExplicitVisibility;
T->TypeBits.CachedLinkage = CT->TypeBits.CachedLinkage;
T->TypeBits.CachedLocalOrUnnamed = CT->TypeBits.CachedLocalOrUnnamed;
return;
@@ -2048,6 +2052,7 @@ public:
// Compute the cached properties and then set the cache.
CachedProperties Result = computeCachedProperties(T);
T->TypeBits.CacheValidAndVisibility = Result.getVisibility() + 1U;
+ T->TypeBits.CachedExplicitVisibility = Result.isVisibilityExplicit();
assert(T->TypeBits.isCacheValid() &&
T->TypeBits.getVisibility() == Result.getVisibility());
T->TypeBits.CachedLinkage = Result.getLinkage();
@@ -2075,13 +2080,13 @@ static CachedProperties computeCachedProperties(const Type *T) {
#include "clang/AST/TypeNodes.def"
// Treat instantiation-dependent types as external.
assert(T->isInstantiationDependentType());
- return CachedProperties(ExternalLinkage, DefaultVisibility, false);
+ return CachedProperties(NamedDecl::LinkageInfo(), false);
case Type::Builtin:
// C++ [basic.link]p8:
// A type is said to have linkage if and only if:
// - it is a fundamental type (3.9.1); or
- return CachedProperties(ExternalLinkage, DefaultVisibility, false);
+ return CachedProperties(NamedDecl::LinkageInfo(), false);
case Type::Record:
case Type::Enum: {
@@ -2095,7 +2100,7 @@ static CachedProperties computeCachedProperties(const Type *T) {
bool IsLocalOrUnnamed =
Tag->getDeclContext()->isFunctionOrMethod() ||
(!Tag->getIdentifier() && !Tag->getTypedefNameForAnonDecl());
- return CachedProperties(LV.linkage(), LV.visibility(), IsLocalOrUnnamed);
+ return CachedProperties(LV, IsLocalOrUnnamed);
}
// C++ [basic.link]p8:
@@ -2135,7 +2140,7 @@ static CachedProperties computeCachedProperties(const Type *T) {
case Type::ObjCInterface: {
NamedDecl::LinkageInfo LV =
cast<ObjCInterfaceType>(T)->getDecl()->getLinkageAndVisibility();
- return CachedProperties(LV.linkage(), LV.visibility(), false);
+ return CachedProperties(LV, false);
}
case Type::ObjCObject:
return Cache::get(cast<ObjCObjectType>(T)->getBaseType());
@@ -2149,7 +2154,8 @@ static CachedProperties computeCachedProperties(const Type *T) {
// C++ [basic.link]p8:
// Names not covered by these rules have no linkage.
- return CachedProperties(NoLinkage, DefaultVisibility, false);
+ NamedDecl::LinkageInfo LV(NoLinkage, DefaultVisibility, false);
+ return CachedProperties(LV, false);
}
/// \brief Determine the linkage of this type.
@@ -2164,6 +2170,11 @@ Visibility Type::getVisibility() const {
return TypeBits.getVisibility();
}
+bool Type::isVisibilityExplicit() const {
+ Cache::ensure(this);
+ return TypeBits.isVisibilityExplicit();
+}
+
bool Type::hasUnnamedOrLocalType() const {
Cache::ensure(this);
return TypeBits.hasLocalOrUnnamedType();
OpenPOWER on IntegriCloud