Move LinkageInfo out of NamedDecl so that it can be used in Type.h.

Everything that cares about visibility also cares about linkage, so I just
moved it to Visibility.h instead of creating a new .h.

llvm-svn: 176155
This commit is contained in:
Rafael Espindola 2013-02-27 02:15:29 +00:00
parent 683f59b36c
commit a8fbdab850
5 changed files with 92 additions and 94 deletions

View File

@ -211,81 +211,6 @@ public:
/// a C++ class.
bool isCXXInstanceMember() const;
class LinkageInfo {
uint8_t linkage_ : 2;
uint8_t visibility_ : 2;
uint8_t explicit_ : 1;
void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; }
public:
LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility),
explicit_(false) {}
LinkageInfo(Linkage L, Visibility V, bool E)
: linkage_(L), visibility_(V), explicit_(E) {
assert(linkage() == L && visibility() == V && visibilityExplicit() == E &&
"Enum truncated!");
}
static LinkageInfo external() {
return LinkageInfo();
}
static LinkageInfo internal() {
return LinkageInfo(InternalLinkage, DefaultVisibility, false);
}
static LinkageInfo uniqueExternal() {
return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false);
}
static LinkageInfo none() {
return LinkageInfo(NoLinkage, DefaultVisibility, false);
}
Linkage linkage() const { return (Linkage)linkage_; }
Visibility visibility() const { return (Visibility)visibility_; }
bool visibilityExplicit() const { return explicit_; }
void setLinkage(Linkage L) { linkage_ = L; }
void mergeLinkage(Linkage L) {
setLinkage(minLinkage(linkage(), L));
}
void mergeLinkage(LinkageInfo other) {
mergeLinkage(other.linkage());
}
/// Merge in the visibility 'newVis'.
void mergeVisibility(Visibility newVis, bool newExplicit) {
Visibility oldVis = visibility();
// Never increase visibility.
if (oldVis < newVis)
return;
// If the new visibility is the same as the old and the new
// visibility isn't explicit, we have nothing to add.
if (oldVis == newVis && !newExplicit)
return;
// Otherwise, we're either decreasing visibility or making our
// existing visibility explicit.
setVisibility(newVis, newExplicit);
}
void mergeVisibility(LinkageInfo other) {
mergeVisibility(other.visibility(), other.visibilityExplicit());
}
/// Merge both linkage and visibility.
void merge(LinkageInfo other) {
mergeLinkage(other);
mergeVisibility(other);
}
/// Merge linkage and conditionally merge visibility.
void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) {
mergeLinkage(other);
if (withVis) mergeVisibility(other);
}
};
/// \brief Determine what kind of linkage this entity has.
Linkage getLinkage() const;

View File

@ -15,6 +15,8 @@
#ifndef LLVM_CLANG_BASIC_VISIBILITY_H
#define LLVM_CLANG_BASIC_VISIBILITY_H
#include "clang/Basic/Linkage.h"
namespace clang {
/// \brief Describes the different kinds of visibility that a declaration
@ -46,6 +48,80 @@ inline Visibility minVisibility(Visibility L, Visibility R) {
return L < R ? L : R;
}
class LinkageInfo {
uint8_t linkage_ : 2;
uint8_t visibility_ : 2;
uint8_t explicit_ : 1;
void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; }
public:
LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility),
explicit_(false) {}
LinkageInfo(Linkage L, Visibility V, bool E)
: linkage_(L), visibility_(V), explicit_(E) {
assert(linkage() == L && visibility() == V && visibilityExplicit() == E &&
"Enum truncated!");
}
static LinkageInfo external() {
return LinkageInfo();
}
static LinkageInfo internal() {
return LinkageInfo(InternalLinkage, DefaultVisibility, false);
}
static LinkageInfo uniqueExternal() {
return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false);
}
static LinkageInfo none() {
return LinkageInfo(NoLinkage, DefaultVisibility, false);
}
Linkage linkage() const { return (Linkage)linkage_; }
Visibility visibility() const { return (Visibility)visibility_; }
bool visibilityExplicit() const { return explicit_; }
void setLinkage(Linkage L) { linkage_ = L; }
void mergeLinkage(Linkage L) {
setLinkage(minLinkage(linkage(), L));
}
void mergeLinkage(LinkageInfo other) {
mergeLinkage(other.linkage());
}
/// Merge in the visibility 'newVis'.
void mergeVisibility(Visibility newVis, bool newExplicit) {
Visibility oldVis = visibility();
// Never increase visibility.
if (oldVis < newVis)
return;
// If the new visibility is the same as the old and the new
// visibility isn't explicit, we have nothing to add.
if (oldVis == newVis && !newExplicit)
return;
// Otherwise, we're either decreasing visibility or making our
// existing visibility explicit.
setVisibility(newVis, newExplicit);
}
void mergeVisibility(LinkageInfo other) {
mergeVisibility(other.visibility(), other.visibilityExplicit());
}
/// Merge both linkage and visibility.
void merge(LinkageInfo other) {
mergeLinkage(other);
mergeVisibility(other);
}
/// Merge linkage and conditionally merge visibility.
void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) {
mergeLinkage(other);
if (withVis) mergeVisibility(other);
}
};
}
#endif // LLVM_CLANG_BASIC_VISIBILITY_H

View File

@ -138,8 +138,6 @@ static Optional<Visibility> getExplicitVisibility(const NamedDecl *D,
return D->getExplicitVisibility((NamedDecl::ExplicitVisibilityKind) kind);
}
typedef NamedDecl::LinkageInfo LinkageInfo;
/// Is the given declaration a "type" or a "value" for the purposes of
/// visibility computation?
static bool usesTypeVisibility(const NamedDecl *D) {

View File

@ -2002,20 +2002,19 @@ namespace {
/// \brief The cached properties of a type.
class CachedProperties {
NamedDecl::LinkageInfo LV;
LinkageInfo LV;
bool local;
public:
CachedProperties(NamedDecl::LinkageInfo LV, bool local)
: LV(LV), local(local) {}
CachedProperties(LinkageInfo LV, bool local) : LV(LV), local(local) {}
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) {
NamedDecl::LinkageInfo MergedLV = L.LV;
LinkageInfo MergedLV = L.LV;
MergedLV.merge(R.LV);
return CachedProperties(MergedLV,
L.hasLocalOrUnnamedType() | R.hasLocalOrUnnamedType());
@ -2037,9 +2036,9 @@ public:
static CachedProperties get(const Type *T) {
ensure(T);
NamedDecl::LinkageInfo LV(T->TypeBits.getLinkage(),
T->TypeBits.getVisibility(),
T->TypeBits.isVisibilityExplicit());
LinkageInfo LV(T->TypeBits.getLinkage(),
T->TypeBits.getVisibility(),
T->TypeBits.isVisibilityExplicit());
return CachedProperties(LV, T->TypeBits.hasLocalOrUnnamedType());
}
@ -2092,13 +2091,13 @@ static CachedProperties computeCachedProperties(const Type *T) {
#include "clang/AST/TypeNodes.def"
// Treat instantiation-dependent types as external.
assert(T->isInstantiationDependentType());
return CachedProperties(NamedDecl::LinkageInfo(), false);
return CachedProperties(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(NamedDecl::LinkageInfo(), false);
return CachedProperties(LinkageInfo(), false);
case Type::Record:
case Type::Enum: {
@ -2108,7 +2107,7 @@ static CachedProperties computeCachedProperties(const Type *T) {
// - it is a class or enumeration type that is named (or has a name
// for linkage purposes (7.1.3)) and the name has linkage; or
// - it is a specialization of a class template (14); or
NamedDecl::LinkageInfo LV = Tag->getLinkageAndVisibility();
LinkageInfo LV = Tag->getLinkageAndVisibility();
bool IsLocalOrUnnamed =
Tag->getDeclContext()->isFunctionOrMethod() ||
(!Tag->getIdentifier() && !Tag->getTypedefNameForAnonDecl());
@ -2150,7 +2149,7 @@ static CachedProperties computeCachedProperties(const Type *T) {
return result;
}
case Type::ObjCInterface: {
NamedDecl::LinkageInfo LV =
LinkageInfo LV =
cast<ObjCInterfaceType>(T)->getDecl()->getLinkageAndVisibility();
return CachedProperties(LV, false);
}

View File

@ -276,7 +276,7 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
}
// Set visibility for definitions.
NamedDecl::LinkageInfo LV = D->getLinkageAndVisibility();
LinkageInfo LV = D->getLinkageAndVisibility();
if (LV.visibilityExplicit() || !GV->hasAvailableExternallyLinkage())
GV->setVisibility(GetLLVMVisibility(LV.visibility()));
}
@ -693,7 +693,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
} else {
F->setLinkage(llvm::Function::ExternalLinkage);
NamedDecl::LinkageInfo LV = FD->getLinkageAndVisibility();
LinkageInfo LV = FD->getLinkageAndVisibility();
if (LV.linkage() == ExternalLinkage && LV.visibilityExplicit()) {
F->setVisibility(GetLLVMVisibility(LV.visibility()));
}
@ -1433,7 +1433,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
GV->setConstant(isTypeConstant(D->getType(), false));
// Set linkage and visibility in case we never see a definition.
NamedDecl::LinkageInfo LV = D->getLinkageAndVisibility();
LinkageInfo LV = D->getLinkageAndVisibility();
if (LV.linkage() != ExternalLinkage) {
// Don't set internal linkage on declarations.
} else {