[cfe-commits] r117147 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ lib/AST/ lib/CodeGen/ lib/Frontend/ lib/Serialization/ test/CodeGenCXX/ test/Index/
John McCall
rjmccall at apple.com
Fri Oct 22 14:05:15 PDT 2010
Author: rjmccall
Date: Fri Oct 22 16:05:15 2010
New Revision: 117147
URL: http://llvm.org/viewvc/llvm-project?rev=117147&view=rev
Log:
Substantially revise how clang computes the visibility of a declaration to
more closely parallel the computation of linkage. This gets us to a state
much closer to what gcc emits, modulo bugs, which will undoubtedly arise in
abundance.
Added:
cfe/trunk/include/clang/Basic/Visibility.h
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/Basic/LangOptions.h
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
cfe/trunk/lib/CodeGen/CGRTTI.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/test/CodeGenCXX/member-pointer-type-convert.cpp
cfe/trunk/test/CodeGenCXX/pointers-to-data-members.cpp
cfe/trunk/test/CodeGenCXX/visibility.cpp
cfe/trunk/test/Index/index-templates.cpp
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Oct 22 16:05:15 2010
@@ -197,7 +197,13 @@
bool isCXXInstanceMember() const;
/// \brief Determine what kind of linkage this entity has.
- Linkage getLinkage() const;
+ Linkage getLinkage() const { return getLinkageAndVisibility().first; }
+
+ /// \brief Determines the visibility of this entity.
+ Visibility getVisibility() const { return getLinkageAndVisibility().second; }
+
+ /// \brief Determines the linkage and visibility of this entity.
+ std::pair<Linkage,Visibility> getLinkageAndVisibility() const;
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Fri Oct 22 16:05:15 2010
@@ -18,6 +18,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Linkage.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/Visibility.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "llvm/Support/Casting.h"
@@ -800,9 +801,10 @@
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
unsigned VariablyModified : 1;
- /// \brief Whether the linkage of this type along with the presence of any
- /// local or unnamed types is already known.
- mutable unsigned LinkageKnown : 1;
+ /// \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 Linkage of this type.
mutable unsigned CachedLinkage : 2;
@@ -813,7 +815,21 @@
/// \brief FromAST - Whether this type comes from an AST file.
mutable unsigned FromAST : 1;
- unsigned SpareBit : 1;
+ bool isCacheValid() const {
+ return (CacheValidAndVisibility != 0);
+ }
+ Visibility getVisibility() const {
+ assert(isCacheValid() && "getting linkage from invalid cache");
+ return static_cast<Visibility>(CacheValidAndVisibility-1);
+ }
+ Linkage getLinkage() const {
+ assert(isCacheValid() && "getting linkage from invalid cache");
+ return static_cast<Linkage>(CachedLinkage);
+ }
+ bool hasLocalOrUnnamedType() const {
+ assert(isCacheValid() && "getting linkage from invalid cache");
+ return CachedLocalOrUnnamed;
+ }
};
enum { NumTypeBits = 16 };
@@ -938,10 +954,35 @@
TypeBits.FromAST = V;
}
+ void ensureCachedProperties() const;
+
protected:
- /// \brief Compute the linkage of this type along with the presence of
- /// any local or unnamed types.
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ /// \brief Compute the cached properties of this type.
+ class CachedProperties {
+ char linkage;
+ char visibility;
+ bool local;
+
+ public:
+ CachedProperties(Linkage linkage, Visibility visibility, bool local)
+ : linkage(linkage), visibility(visibility), local(local) {}
+
+ Linkage getLinkage() const { return (Linkage) linkage; }
+ Visibility getVisibility() const { return (Visibility) visibility; }
+ bool hasLocalOrUnnamedType() const { return local; }
+
+ friend CachedProperties merge(CachedProperties L, CachedProperties R) {
+ return CachedProperties(minLinkage(L.getLinkage(), R.getLinkage()),
+ minVisibility(L.getVisibility(), R.getVisibility()),
+ L.hasLocalOrUnnamedType() | R.hasLocalOrUnnamedType());
+ }
+ };
+
+ virtual CachedProperties getCachedProperties() const;
+ static CachedProperties getCachedProperties(QualType T) {
+ return getCachedProperties(T.getTypePtr());
+ }
+ static CachedProperties getCachedProperties(const Type *T);
// silence VC++ warning C4355: 'this' : used in base member initializer list
Type *this_() { return this; }
@@ -950,7 +991,7 @@
TypeBits.TC = tc;
TypeBits.Dependent = Dependent;
TypeBits.VariablyModified = VariablyModified;
- TypeBits.LinkageKnown = false;
+ TypeBits.CacheValidAndVisibility = 0;
TypeBits.CachedLocalOrUnnamed = false;
TypeBits.CachedLinkage = NoLinkage;
TypeBits.FromAST = false;
@@ -1191,6 +1232,12 @@
/// \brief Determine the linkage of this type.
Linkage getLinkage() const;
+
+ /// \brief Determine the visibility of this type.
+ Visibility getVisibility() const;
+
+ /// \brief Determine the linkage and visibility of this type.
+ std::pair<Linkage,Visibility> getLinkageAndVisibility() const;
/// \brief Note that the linkage is no longer known.
void ClearLinkageCache();
@@ -1278,7 +1325,7 @@
};
protected:
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
BuiltinType(Kind K)
@@ -1334,7 +1381,7 @@
friend class ASTContext; // ASTContext creates these.
protected:
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
QualType getElementType() const { return ElementType; }
@@ -1366,7 +1413,7 @@
friend class ASTContext; // ASTContext creates these.
protected:
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
@@ -1400,7 +1447,7 @@
friend class ASTContext; // ASTContext creates these.
protected:
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
@@ -1437,7 +1484,7 @@
ReferenceTypeBits.InnerRef = Referencee->isReferenceType();
}
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; }
@@ -1521,7 +1568,7 @@
friend class ASTContext; // ASTContext creates these.
protected:
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
QualType getPointeeType() const { return PointeeType; }
@@ -1590,7 +1637,7 @@
friend class ASTContext; // ASTContext creates these.
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
QualType getElementType() const { return ElementType; }
@@ -1893,7 +1940,7 @@
}
friend class ASTContext; // ASTContext creates these.
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
@@ -2123,7 +2170,7 @@
friend class ASTContext; // ASTContext creates these.
protected:
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
// No additional state past what FunctionType provides.
@@ -2179,7 +2226,7 @@
friend class ASTContext; // ASTContext creates these.
protected:
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
unsigned getNumArgs() const { return NumArgs; }
@@ -2421,7 +2468,7 @@
protected:
TagType(TypeClass TC, const TagDecl *D, QualType can);
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
TagDecl *getDecl() const;
@@ -3084,7 +3131,7 @@
}
protected:
- std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const; // key function
+ CachedProperties getCachedProperties() const; // key function
public:
/// getBaseType - Gets the base type of this object type. This is
@@ -3192,6 +3239,10 @@
: ObjCObjectType(Nonce_ObjCInterface),
Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
friend class ASTContext; // ASTContext creates these.
+
+protected:
+ virtual CachedProperties getCachedProperties() const;
+
public:
/// getDecl - Get the declaration of this interface.
ObjCInterfaceDecl *getDecl() const { return Decl; }
@@ -3242,7 +3293,7 @@
friend class ASTContext; // ASTContext creates these.
protected:
- virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
+ virtual CachedProperties getCachedProperties() const;
public:
/// getPointeeType - Gets the type pointed to by this ObjC pointer.
Modified: cfe/trunk/include/clang/Basic/LangOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.h?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.h (original)
+++ cfe/trunk/include/clang/Basic/LangOptions.h Fri Oct 22 16:05:15 2010
@@ -15,6 +15,7 @@
#define LLVM_CLANG_LANGOPTIONS_H
#include <string>
+#include "clang/Basic/Visibility.h"
namespace clang {
@@ -131,11 +132,6 @@
enum GCMode { NonGC, GCOnly, HybridGC };
enum StackProtectorMode { SSPOff, SSPOn, SSPReq };
- enum VisibilityMode {
- Default,
- Protected,
- Hidden
- };
enum SignedOverflowBehaviorTy {
SOB_Undefined, // Default C standard behavior.
@@ -161,7 +157,7 @@
HeinousExtensions = 0;
AltiVec = OpenCL = StackProtector = 0;
- SymbolVisibility = (unsigned) Default;
+ SymbolVisibility = (unsigned) DefaultVisibility;
ThreadsafeStatics = 1;
POSIXThreads = 0;
@@ -208,10 +204,10 @@
StackProtector = static_cast<unsigned>(m);
}
- VisibilityMode getVisibilityMode() const {
- return (VisibilityMode) SymbolVisibility;
+ Visibility getVisibilityMode() const {
+ return (Visibility) SymbolVisibility;
}
- void setVisibilityMode(VisibilityMode v) { SymbolVisibility = (unsigned) v; }
+ void setVisibilityMode(Visibility v) { SymbolVisibility = (unsigned) v; }
SignedOverflowBehaviorTy getSignedOverflowBehavior() const {
return (SignedOverflowBehaviorTy)SignedOverflowBehavior;
Added: cfe/trunk/include/clang/Basic/Visibility.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Visibility.h?rev=117147&view=auto
==============================================================================
--- cfe/trunk/include/clang/Basic/Visibility.h (added)
+++ cfe/trunk/include/clang/Basic/Visibility.h Fri Oct 22 16:05:15 2010
@@ -0,0 +1,48 @@
+//===--- Visibility.h - Visibility enumeration and utilities ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Visibility enumeration and various utility
+// functions.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_VISIBILITY_H
+#define LLVM_CLANG_BASIC_VISIBILITY_H
+
+namespace clang {
+
+/// \link Describes the different kinds of visibility that a
+/// declaration may have. Visibility determines how a declaration
+/// interacts with the dynamic linker. It may also affect whether the
+/// symbol can be found by runtime symbol lookup APIs.
+///
+/// Visibility is not described in any language standard and
+/// (nonetheless) sometimes has odd behavior. Not all platforms
+/// support all visibility kinds.
+enum Visibility {
+ /// Objects with "hidden" visibility are not seen by the dynamic
+ /// linker.
+ HiddenVisibility,
+
+ /// Objects with "protected" visibility are seen by the dynamic
+ /// linker but always dynamically resolve to an object within this
+ /// shared object.
+ ProtectedVisibility,
+
+ /// Objects with "default" visibility are seen by the dynamic linker
+ /// and act like normal objects.
+ DefaultVisibility
+};
+
+inline Visibility minVisibility(Visibility L, Visibility R) {
+ return L < R ? L : R;
+}
+
+}
+
+#endif // LLVM_CLANG_BASIC_VISIBILITY_H
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Fri Oct 22 16:05:15 2010
@@ -32,35 +32,53 @@
// NamedDecl Implementation
//===----------------------------------------------------------------------===//
+static Visibility GetVisibilityFromAttr(const VisibilityAttr *A) {
+ switch (A->getVisibility()) {
+ case VisibilityAttr::Default:
+ return DefaultVisibility;
+ case VisibilityAttr::Hidden:
+ return HiddenVisibility;
+ case VisibilityAttr::Protected:
+ return ProtectedVisibility;
+ }
+ return DefaultVisibility;
+}
+
+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));
+}
+
/// \brief Get the most restrictive linkage for the types in the given
/// template parameter list.
-static Linkage
-getLinkageForTemplateParameterList(const TemplateParameterList *Params) {
- Linkage L = ExternalLinkage;
+static LVPair
+getLVForTemplateParameterList(const TemplateParameterList *Params) {
+ LVPair LV(ExternalLinkage, DefaultVisibility);
for (TemplateParameterList::const_iterator P = Params->begin(),
PEnd = Params->end();
P != PEnd; ++P) {
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
if (!NTTP->getType()->isDependentType()) {
- L = minLinkage(L, NTTP->getType()->getLinkage());
+ LV = merge(LV, NTTP->getType()->getLinkageAndVisibility());
continue;
}
if (TemplateTemplateParmDecl *TTP
= dyn_cast<TemplateTemplateParmDecl>(*P)) {
- L = minLinkage(L,
- getLinkageForTemplateParameterList(TTP->getTemplateParameters()));
+ LV =
+ merge(LV, getLVForTemplateParameterList(TTP->getTemplateParameters()));
}
}
- return L;
+ return LV;
}
/// \brief Get the most restrictive linkage for the types and
/// declarations in the given template argument list.
-static Linkage getLinkageForTemplateArgumentList(const TemplateArgument *Args,
- unsigned NumArgs) {
- Linkage L = ExternalLinkage;
+static LVPair getLVForTemplateArgumentList(const TemplateArgument *Args,
+ unsigned NumArgs) {
+ LVPair LV(ExternalLinkage, DefaultVisibility);
for (unsigned I = 0; I != NumArgs; ++I) {
switch (Args[I].getKind()) {
@@ -70,40 +88,41 @@
break;
case TemplateArgument::Type:
- L = minLinkage(L, Args[I].getAsType()->getLinkage());
+ LV = merge(LV, Args[I].getAsType()->getLinkageAndVisibility());
break;
case TemplateArgument::Declaration:
- if (NamedDecl *ND = dyn_cast<NamedDecl>(Args[I].getAsDecl()))
- L = minLinkage(L, ND->getLinkage());
- if (ValueDecl *VD = dyn_cast<ValueDecl>(Args[I].getAsDecl()))
- L = minLinkage(L, VD->getType()->getLinkage());
+ // The decl can validly be null as the representation of nullptr
+ // arguments, valid only in C++0x.
+ if (Decl *D = Args[I].getAsDecl()) {
+ if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
+ LV = merge(LV, ND->getLinkageAndVisibility());
+ if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+ LV = merge(LV, VD->getType()->getLinkageAndVisibility());
+ }
break;
case TemplateArgument::Template:
- if (TemplateDecl *Template
- = Args[I].getAsTemplate().getAsTemplateDecl())
- L = minLinkage(L, Template->getLinkage());
+ if (TemplateDecl *Template = Args[I].getAsTemplate().getAsTemplateDecl())
+ LV = merge(LV, Template->getLinkageAndVisibility());
break;
case TemplateArgument::Pack:
- L = minLinkage(L,
- getLinkageForTemplateArgumentList(Args[I].pack_begin(),
- Args[I].pack_size()));
+ LV = merge(LV, getLVForTemplateArgumentList(Args[I].pack_begin(),
+ Args[I].pack_size()));
break;
}
}
- return L;
+ return LV;
}
-static Linkage
-getLinkageForTemplateArgumentList(const TemplateArgumentList &TArgs) {
- return getLinkageForTemplateArgumentList(TArgs.getFlatArgumentList(),
- TArgs.flat_size());
+static LVPair getLVForTemplateArgumentList(const TemplateArgumentList &TArgs) {
+ return getLVForTemplateArgumentList(TArgs.getFlatArgumentList(),
+ TArgs.flat_size());
}
-static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
+static LVPair getLVForNamespaceScopeDecl(const NamedDecl *D) {
assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
"Not a name having namespace scope");
ASTContext &Context = D->getASTContext();
@@ -117,7 +136,7 @@
if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
// Explicitly declared static.
if (Var->getStorageClass() == SC_Static)
- return InternalLinkage;
+ return LVPair(InternalLinkage, DefaultVisibility);
// - an object or reference that is explicitly declared const
// and neither explicitly declared extern nor previously
@@ -135,7 +154,7 @@
FoundExtern = true;
if (!FoundExtern)
- return InternalLinkage;
+ return LVPair(InternalLinkage, DefaultVisibility);
}
} else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) {
// C++ [temp]p4:
@@ -150,23 +169,63 @@
// Explicitly declared static.
if (Function->getStorageClass() == SC_Static)
- return InternalLinkage;
+ return LVPair(InternalLinkage, DefaultVisibility);
} else if (const FieldDecl *Field = dyn_cast<FieldDecl>(D)) {
// - a data member of an anonymous union.
if (cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion())
- return InternalLinkage;
+ return LVPair(InternalLinkage, DefaultVisibility);
}
+ if (D->isInAnonymousNamespace())
+ return LVPair(UniqueExternalLinkage, DefaultVisibility);
+
+ // Set up the defaults.
+
+ // C99 6.2.2p5:
+ // If the declaration of an identifier for an object has file
+ // scope and no storage-class specifier, its linkage is
+ // external.
+ LVPair LV(ExternalLinkage, DefaultVisibility);
+
+ // We ignore -fvisibility on non-definitions and explicit
+ // instantiation declarations.
+ bool ConsiderDashFVisibility = true;
+
// C++ [basic.link]p4:
-
+
// A name having namespace scope has external linkage if it is the
// name of
//
// - an object or reference, unless it has internal linkage; or
if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ // Modify the variable's LV by the LV of its type unless this is
+ // C or extern "C". This follows from [basic.link]p9:
+ // A type without linkage shall not be used as the type of a
+ // variable or function with external linkage unless
+ // - the entity has C language linkage, or
+ // - the entity is declared within an unnamed namespace, or
+ // - the entity is not used or is defined in the same
+ // translation unit.
+ // and [basic.link]p10:
+ // ...the types specified by all declarations referring to a
+ // given variable or function shall be identical...
+ // C does not have an equivalent rule.
+ //
+ // 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)
+ return LVPair(UniqueExternalLinkage, DefaultVisibility);
+ LV.second = minVisibility(LV.second, TypeLV.second);
+ }
+
if (!Context.getLangOptions().CPlusPlus &&
(Var->getStorageClass() == SC_Extern ||
Var->getStorageClass() == SC_PrivateExtern)) {
+ if (Var->getStorageClass() == SC_PrivateExtern)
+ LV.second = HiddenVisibility;
+
// C99 6.2.2p4:
// For an identifier declared with the storage-class specifier
// extern in a scope in which a prior declaration of that
@@ -177,23 +236,23 @@
// is visible, or if the prior declaration specifies no
// linkage, then the identifier has external linkage.
if (const VarDecl *PrevVar = Var->getPreviousDeclaration()) {
- if (Linkage L = PrevVar->getLinkage())
- return L;
+ LVPair PrevLV = PrevVar->getLinkageAndVisibility();
+ if (PrevLV.first) LV.first = PrevLV.first;
+ LV.second = minVisibility(LV.second, PrevLV.second);
}
}
- // C99 6.2.2p5:
- // If the declaration of an identifier for an object has file
- // scope and no storage-class specifier, its linkage is
- // external.
- if (Var->isInAnonymousNamespace())
- return UniqueExternalLinkage;
-
- return ExternalLinkage;
- }
-
// - a function, unless it has internal linkage; or
- if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+ } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+ // Modify the function's LV by the LV of its type unless this is
+ // C or extern "C". See the comment above about variables.
+ if (Context.getLangOptions().CPlusPlus && !Function->isExternC()) {
+ LVPair TypeLV = Function->getType()->getLinkageAndVisibility();
+ if (TypeLV.first != ExternalLinkage)
+ return LVPair(UniqueExternalLinkage, DefaultVisibility);
+ LV.second = minVisibility(LV.second, TypeLV.second);
+ }
+
// C99 6.2.2p5:
// If the declaration of an identifier for a function has no
// storage-class specifier, its linkage is determined exactly
@@ -213,24 +272,25 @@
// is visible, or if the prior declaration specifies no
// linkage, then the identifier has external linkage.
if (const FunctionDecl *PrevFunc = Function->getPreviousDeclaration()) {
- if (Linkage L = PrevFunc->getLinkage())
- return L;
+ LVPair PrevLV = PrevFunc->getLinkageAndVisibility();
+ if (PrevLV.first) LV.first = PrevLV.first;
+ LV.second = minVisibility(LV.second, PrevLV.second);
}
}
- if (Function->isInAnonymousNamespace())
- return UniqueExternalLinkage;
-
if (FunctionTemplateSpecializationInfo *SpecInfo
= Function->getTemplateSpecializationInfo()) {
- Linkage L = SpecInfo->getTemplate()->getLinkage();
+ LV = merge(LV, SpecInfo->getTemplate()->getLinkageAndVisibility());
const TemplateArgumentList &TemplateArgs = *SpecInfo->TemplateArguments;
- L = minLinkage(L, getLinkageForTemplateArgumentList(TemplateArgs));
- return L;
+ LV = merge(LV, getLVForTemplateArgumentList(TemplateArgs));
+
+ if (SpecInfo->getTemplateSpecializationKind()
+ == TSK_ExplicitInstantiationDeclaration)
+ ConsiderDashFVisibility = false;
}
- return ExternalLinkage;
- }
+ if (ConsiderDashFVisibility)
+ ConsiderDashFVisibility = Function->hasBody();
// - a named class (Clause 9), or an unnamed class defined in a
// typedef declaration in which the class has the typedef name
@@ -238,116 +298,180 @@
// - a named enumeration (7.2), or an unnamed enumeration
// defined in a typedef declaration in which the enumeration
// has the typedef name for linkage purposes (7.1.3); or
- if (const TagDecl *Tag = dyn_cast<TagDecl>(D))
- if (Tag->getDeclName() || Tag->getTypedefForAnonDecl()) {
- if (Tag->isInAnonymousNamespace())
- return UniqueExternalLinkage;
-
- // If this is a class template specialization, consider the
- // linkage of the template and template arguments.
- if (const ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
- const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- Linkage L = getLinkageForTemplateArgumentList(TemplateArgs);
- return minLinkage(L, Spec->getSpecializedTemplate()->getLinkage());
- }
+ } else if (const TagDecl *Tag = dyn_cast<TagDecl>(D)) {
+ // Unnamed tags have no linkage.
+ if (!Tag->getDeclName() && !Tag->getTypedefForAnonDecl())
+ return LVPair(NoLinkage, DefaultVisibility);
+
+ // If this is a class template specialization, consider the
+ // linkage of the template and template arguments.
+ if (const ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
+ // From the template. Note below the restrictions on how we
+ // compute template visibility.
+ LV = merge(LV, Spec->getSpecializedTemplate()->getLinkageAndVisibility());
- return ExternalLinkage;
+ // The arguments at which the template was instantiated.
+ const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+ LV = merge(LV, getLVForTemplateArgumentList(TemplateArgs));
+
+ if (Spec->getTemplateSpecializationKind()
+ == TSK_ExplicitInstantiationDeclaration)
+ ConsiderDashFVisibility = false;
}
+ if (ConsiderDashFVisibility)
+ ConsiderDashFVisibility = Tag->isDefinition();
+
// - an enumerator belonging to an enumeration with external linkage;
- if (isa<EnumConstantDecl>(D)) {
- Linkage L = cast<NamedDecl>(D->getDeclContext())->getLinkage();
- if (isExternalLinkage(L))
- return L;
- }
+ } else if (isa<EnumConstantDecl>(D)) {
+ LVPair EnumLV =
+ cast<NamedDecl>(D->getDeclContext())->getLinkageAndVisibility();
+ if (!isExternalLinkage(EnumLV.first))
+ return LVPair(NoLinkage, DefaultVisibility);
+ LV = merge(LV, EnumLV);
// - a template, unless it is a function template that has
// internal linkage (Clause 14);
- if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
- if (D->isInAnonymousNamespace())
- return UniqueExternalLinkage;
-
- return getLinkageForTemplateParameterList(
- Template->getTemplateParameters());
- }
+ } else if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
+ LV = merge(LV, getLVForTemplateParameterList(
+ Template->getTemplateParameters()));
+
+ // We do not want to consider attributes or global settings when
+ // computing template visibility.
+ return LV;
// - a namespace (7.3), unless it is declared within an unnamed
// namespace.
- if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace())
- return ExternalLinkage;
+ } else if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace()) {
+ return LV;
- return NoLinkage;
+ // By extension, we assign external linkage to Objective-C
+ // interfaces.
+ } else if (isa<ObjCInterfaceDecl>(D)) {
+ // fallout
+
+ // Everything not covered here has no linkage.
+ } else {
+ return LVPair(NoLinkage, DefaultVisibility);
+ }
+
+ // If we ended up with non-external linkage, visibility should
+ // always be default.
+ if (LV.first != ExternalLinkage)
+ return LVPair(LV.first, DefaultVisibility);
+
+ // If we didn't end up with hidden visibility, consider attributes
+ // and -fvisibility.
+ if (LV.second != HiddenVisibility) {
+ Visibility StandardV;
+
+ // If we have an explicit visibility attribute, merge that in.
+ const VisibilityAttr *VA = D->getAttr<VisibilityAttr>();
+ if (VA)
+ StandardV = GetVisibilityFromAttr(VA);
+ else if (ConsiderDashFVisibility)
+ StandardV = Context.getLangOptions().getVisibilityMode();
+ else
+ StandardV = DefaultVisibility; // no-op
+
+ LV.second = minVisibility(LV.second, StandardV);
+ }
+
+ return LV;
}
-static Linkage getLinkageForClassMember(const NamedDecl *D) {
+static LVPair getLVForClassMember(const NamedDecl *D) {
+ // Only certain class members have linkage. Note that fields don't
+ // really have linkage, but it's convenient to say they do for the
+ // purposes of calculating linkage of pointer-to-data-member
+ // template arguments.
if (!(isa<CXXMethodDecl>(D) ||
isa<VarDecl>(D) ||
+ isa<FieldDecl>(D) ||
(isa<TagDecl>(D) &&
(D->getDeclName() || cast<TagDecl>(D)->getTypedefForAnonDecl()))))
- return NoLinkage;
+ return LVPair(NoLinkage, DefaultVisibility);
// Class members only have linkage if their class has external linkage.
- Linkage L = cast<RecordDecl>(D->getDeclContext())->getLinkage();
- if (!isExternalLinkage(L)) return NoLinkage;
+ LVPair ClassLV =
+ cast<RecordDecl>(D->getDeclContext())->getLinkageAndVisibility();
+ if (!isExternalLinkage(ClassLV.first))
+ return LVPair(NoLinkage, DefaultVisibility);
// If the class already has unique-external linkage, we can't improve.
- if (L == UniqueExternalLinkage) return UniqueExternalLinkage;
+ if (ClassLV.first == UniqueExternalLinkage)
+ return LVPair(UniqueExternalLinkage, DefaultVisibility);
+
+ // Start with the class's linkage and visibility.
+ LVPair LV = ClassLV;
+
+ // If we have an explicit visibility attribute, merge that in.
+ const VisibilityAttr *VA = D->getAttr<VisibilityAttr>();
+ if (VA) LV.second = minVisibility(LV.second, GetVisibilityFromAttr(VA));
+
+ // If it's a value declaration, apply the LV from its type.
+ // See the comment about namespace-scope variable decls above.
+ if (isa<ValueDecl>(D)) {
+ LVPair TypeLV = cast<ValueDecl>(D)->getType()->getLinkageAndVisibility();
+ if (TypeLV.first != ExternalLinkage)
+ LV.first = minLinkage(LV.first, UniqueExternalLinkage);
+ LV.second = minVisibility(LV.second, TypeLV.second);
+ }
- // If this is a method template specialization, use the linkage for
- // the template parameters and arguments.
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
- if (FunctionTemplateSpecializationInfo *SpecInfo
+ // If this is a method template specialization, use the linkage for
+ // the template parameters and arguments.
+ if (FunctionTemplateSpecializationInfo *Spec
= MD->getTemplateSpecializationInfo()) {
- Linkage ArgLinkage =
- getLinkageForTemplateArgumentList(*SpecInfo->TemplateArguments);
- Linkage ParamLinkage =
- getLinkageForTemplateParameterList(
- SpecInfo->getTemplate()->getTemplateParameters());
- return minLinkage(ArgLinkage, ParamLinkage);
+ LV = merge(LV, getLVForTemplateArgumentList(*Spec->TemplateArguments));
+ LV = merge(LV, getLVForTemplateParameterList(
+ Spec->getTemplate()->getTemplateParameters()));
}
+ // If -fvisibility-inlines-hidden was provided, then inline C++
+ // member functions get "hidden" visibility if they don't have an
+ // explicit visibility attribute.
+ if (!VA && MD->isInlined() && LV.second > HiddenVisibility &&
+ D->getASTContext().getLangOptions().InlineVisibilityHidden)
+ LV.second = HiddenVisibility;
+
// Similarly for member class template specializations.
} else if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(D)) {
- Linkage ArgLinkage =
- getLinkageForTemplateArgumentList(Spec->getTemplateArgs());
- Linkage ParamLinkage =
- getLinkageForTemplateParameterList(
- Spec->getSpecializedTemplate()->getTemplateParameters());
- return minLinkage(ArgLinkage, ParamLinkage);
+ LV = merge(LV, getLVForTemplateArgumentList(Spec->getTemplateArgs()));
+ LV = merge(LV, getLVForTemplateParameterList(
+ Spec->getSpecializedTemplate()->getTemplateParameters()));
}
- return ExternalLinkage;
+ return LV;
}
-Linkage NamedDecl::getLinkage() const {
+LVPair NamedDecl::getLinkageAndVisibility() const {
// Objective-C: treat all Objective-C declarations as having external
// linkage.
switch (getKind()) {
default:
break;
+ case Decl::TemplateTemplateParm: // count these as external
+ case Decl::NonTypeTemplateParm:
case Decl::ObjCAtDefsField:
case Decl::ObjCCategory:
case Decl::ObjCCategoryImpl:
- case Decl::ObjCClass:
case Decl::ObjCCompatibleAlias:
case Decl::ObjCForwardProtocol:
case Decl::ObjCImplementation:
- case Decl::ObjCInterface:
- case Decl::ObjCIvar:
case Decl::ObjCMethod:
case Decl::ObjCProperty:
case Decl::ObjCPropertyImpl:
case Decl::ObjCProtocol:
- return ExternalLinkage;
+ return LVPair(ExternalLinkage, DefaultVisibility);
}
// Handle linkage for namespace-scope names.
if (getDeclContext()->getRedeclContext()->isFileContext())
- if (Linkage L = getLinkageForNamespaceScopeDecl(this))
- return L;
+ return getLVForNamespaceScopeDecl(this);
// C++ [basic.link]p5:
// In addition, a member function, static data member, a named
@@ -357,7 +481,7 @@
// purposes (7.1.3), has external linkage if the name of the class
// has external linkage.
if (getDeclContext()->isRecord())
- return getLinkageForClassMember(this);
+ return getLVForClassMember(this);
// C++ [basic.link]p6:
// The name of a function declared in block scope and the name of
@@ -372,34 +496,48 @@
// external linkage.
if (getLexicalDeclContext()->isFunctionOrMethod()) {
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) {
- if (Function->getPreviousDeclaration())
- if (Linkage L = Function->getPreviousDeclaration()->getLinkage())
- return L;
-
if (Function->isInAnonymousNamespace())
- return UniqueExternalLinkage;
+ return LVPair(UniqueExternalLinkage, DefaultVisibility);
+
+ LVPair LV(ExternalLinkage, DefaultVisibility);
+ if (const VisibilityAttr *VA = Function->getAttr<VisibilityAttr>())
+ LV.second = GetVisibilityFromAttr(VA);
+
+ if (const FunctionDecl *Prev = Function->getPreviousDeclaration()) {
+ LVPair PrevLV = Prev->getLinkageAndVisibility();
+ if (PrevLV.first) LV.first = PrevLV.first;
+ LV.second = minVisibility(LV.second, PrevLV.second);
+ }
- return ExternalLinkage;
+ return LV;
}
if (const VarDecl *Var = dyn_cast<VarDecl>(this))
if (Var->getStorageClass() == SC_Extern ||
Var->getStorageClass() == SC_PrivateExtern) {
- if (Var->getPreviousDeclaration())
- if (Linkage L = Var->getPreviousDeclaration()->getLinkage())
- return L;
-
if (Var->isInAnonymousNamespace())
- return UniqueExternalLinkage;
+ return LVPair(UniqueExternalLinkage, DefaultVisibility);
+
+ LVPair LV(ExternalLinkage, DefaultVisibility);
+ if (Var->getStorageClass() == SC_PrivateExtern)
+ LV.second = HiddenVisibility;
+ else if (const VisibilityAttr *VA = Var->getAttr<VisibilityAttr>())
+ LV.second = GetVisibilityFromAttr(VA);
+
+ if (const VarDecl *Prev = Var->getPreviousDeclaration()) {
+ LVPair PrevLV = Prev->getLinkageAndVisibility();
+ if (PrevLV.first) LV.first = PrevLV.first;
+ LV.second = minVisibility(LV.second, PrevLV.second);
+ }
- return ExternalLinkage;
+ return LV;
}
}
// C++ [basic.link]p6:
// Names not covered by these rules have no linkage.
- return NoLinkage;
- }
+ return LVPair(NoLinkage, DefaultVisibility);
+}
std::string NamedDecl::getQualifiedNameAsString() const {
return getQualifiedNameAsString(getASTContext().getLangOptions());
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Fri Oct 22 16:05:15 2010
@@ -1268,129 +1268,154 @@
Profile(ID, getBaseType(), qual_begin(), getNumProtocols());
}
+void Type::ensureCachedProperties() const {
+ if (!TypeBits.isCacheValid()) {
+ CachedProperties Result = getCachedProperties();
+ TypeBits.CacheValidAndVisibility = Result.getVisibility() + 1U;
+ assert(TypeBits.isCacheValid() &&
+ TypeBits.getVisibility() == Result.getVisibility());
+ TypeBits.CachedLinkage = Result.getLinkage();
+ TypeBits.CachedLocalOrUnnamed = Result.hasLocalOrUnnamedType();
+ }
+}
+
/// \brief Determine the linkage of this type.
Linkage Type::getLinkage() const {
if (this != CanonicalType.getTypePtr())
return CanonicalType->getLinkage();
-
- if (!TypeBits.LinkageKnown) {
- std::pair<Linkage, bool> Result = getLinkageUnnamedLocalImpl();
- TypeBits.CachedLinkage = Result.first;
- TypeBits.CachedLocalOrUnnamed = Result.second;
- TypeBits.LinkageKnown = true;
- }
-
- return static_cast<clang::Linkage>(TypeBits.CachedLinkage);
+
+ ensureCachedProperties();
+ return TypeBits.getLinkage();
+}
+
+/// \brief Determine the linkage of this type.
+Visibility Type::getVisibility() const {
+ if (this != CanonicalType.getTypePtr())
+ return CanonicalType->getVisibility();
+
+ ensureCachedProperties();
+ return TypeBits.getVisibility();
}
bool Type::hasUnnamedOrLocalType() const {
if (this != CanonicalType.getTypePtr())
return CanonicalType->hasUnnamedOrLocalType();
-
- if (!TypeBits.LinkageKnown) {
- std::pair<Linkage, bool> Result = getLinkageUnnamedLocalImpl();
- TypeBits.CachedLinkage = Result.first;
- TypeBits.CachedLocalOrUnnamed = Result.second;
- TypeBits.LinkageKnown = true;
- }
-
- return TypeBits.CachedLocalOrUnnamed;
+
+ ensureCachedProperties();
+ return TypeBits.hasLocalOrUnnamedType();
}
-std::pair<Linkage, bool> Type::getLinkageUnnamedLocalImpl() const {
- // C++ [basic.link]p8:
- // Names not covered by these rules have no linkage.
- return std::make_pair(NoLinkage, false);
+std::pair<Linkage,Visibility> Type::getLinkageAndVisibility() const {
+ if (this != CanonicalType.getTypePtr())
+ return CanonicalType->getLinkageAndVisibility();
+
+ ensureCachedProperties();
+ return std::make_pair(TypeBits.getLinkage(), TypeBits.getVisibility());
+}
+
+
+Type::CachedProperties Type::getCachedProperties(const Type *T) {
+ T = T->CanonicalType.getTypePtr();
+ T->ensureCachedProperties();
+ return CachedProperties(T->TypeBits.getLinkage(),
+ T->TypeBits.getVisibility(),
+ T->TypeBits.hasLocalOrUnnamedType());
}
void Type::ClearLinkageCache() {
if (this != CanonicalType.getTypePtr())
CanonicalType->ClearLinkageCache();
else
- TypeBits.LinkageKnown = false;
+ TypeBits.CacheValidAndVisibility = 0;
}
-std::pair<Linkage, bool> BuiltinType::getLinkageUnnamedLocalImpl() const {
+Type::CachedProperties Type::getCachedProperties() const {
+ // Treat dependent types as external.
+ if (isDependentType())
+ return CachedProperties(ExternalLinkage, DefaultVisibility, false);
+
+ // C++ [basic.link]p8:
+ // Names not covered by these rules have no linkage.
+ return CachedProperties(NoLinkage, DefaultVisibility, false);
+}
+
+Type::CachedProperties BuiltinType::getCachedProperties() const {
// 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 std::make_pair(ExternalLinkage, false);
+ return CachedProperties(ExternalLinkage, DefaultVisibility, false);
}
-std::pair<Linkage, bool> TagType::getLinkageUnnamedLocalImpl() const {
+Type::CachedProperties TagType::getCachedProperties() const {
// C++ [basic.link]p8:
// - 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
- return std::make_pair(getDecl()->getLinkage(),
- getDecl()->getDeclContext()->isFunctionOrMethod() ||
+
+ std::pair<Linkage,Visibility> LV = getDecl()->getLinkageAndVisibility();
+ bool IsLocalOrUnnamed =
+ getDecl()->getDeclContext()->isFunctionOrMethod() ||
(!getDecl()->getIdentifier() &&
- !getDecl()->getTypedefForAnonDecl()));
+ !getDecl()->getTypedefForAnonDecl());
+ return CachedProperties(LV.first, LV.second, IsLocalOrUnnamed);
}
// C++ [basic.link]p8:
// - it is a compound type (3.9.2) other than a class or enumeration,
// compounded exclusively from types that have linkage; or
-std::pair<Linkage, bool> ComplexType::getLinkageUnnamedLocalImpl() const {
- return std::make_pair(ElementType->getLinkage(),
- ElementType->hasUnnamedOrLocalType());
+Type::CachedProperties ComplexType::getCachedProperties() const {
+ return Type::getCachedProperties(ElementType);
}
-std::pair<Linkage, bool> PointerType::getLinkageUnnamedLocalImpl() const {
- return std::make_pair(PointeeType->getLinkage(),
- PointeeType->hasUnnamedOrLocalType());
+Type::CachedProperties PointerType::getCachedProperties() const {
+ return Type::getCachedProperties(PointeeType);
}
-std::pair<Linkage, bool> BlockPointerType::getLinkageUnnamedLocalImpl() const {
- return std::make_pair(PointeeType->getLinkage(),
- PointeeType->hasUnnamedOrLocalType());
+Type::CachedProperties BlockPointerType::getCachedProperties() const {
+ return Type::getCachedProperties(PointeeType);
}
-std::pair<Linkage, bool> ReferenceType::getLinkageUnnamedLocalImpl() const {
- return std::make_pair(PointeeType->getLinkage(),
- PointeeType->hasUnnamedOrLocalType());
+Type::CachedProperties ReferenceType::getCachedProperties() const {
+ return Type::getCachedProperties(PointeeType);
}
-std::pair<Linkage, bool> MemberPointerType::getLinkageUnnamedLocalImpl() const {
- return std::make_pair(minLinkage(Class->getLinkage(),
- PointeeType->getLinkage()),
- Class->hasUnnamedOrLocalType() ||
- PointeeType->hasUnnamedOrLocalType());
+Type::CachedProperties MemberPointerType::getCachedProperties() const {
+ return merge(Type::getCachedProperties(Class),
+ Type::getCachedProperties(PointeeType));
}
-std::pair<Linkage, bool> ArrayType::getLinkageUnnamedLocalImpl() const {
- return std::make_pair(ElementType->getLinkage(),
- ElementType->hasUnnamedOrLocalType());
+Type::CachedProperties ArrayType::getCachedProperties() const {
+ return Type::getCachedProperties(ElementType);
}
-std::pair<Linkage, bool> VectorType::getLinkageUnnamedLocalImpl() const {
- return std::make_pair(ElementType->getLinkage(),
- ElementType->hasUnnamedOrLocalType());
+Type::CachedProperties VectorType::getCachedProperties() const {
+ return Type::getCachedProperties(ElementType);
}
-std::pair<Linkage, bool>
-FunctionNoProtoType::getLinkageUnnamedLocalImpl() const {
- return std::make_pair(getResultType()->getLinkage(),
- getResultType()->hasUnnamedOrLocalType());
+Type::CachedProperties FunctionNoProtoType::getCachedProperties() const {
+ return Type::getCachedProperties(getResultType());
}
-std::pair<Linkage, bool> FunctionProtoType::getLinkageUnnamedLocalImpl() const {
- Linkage L = getResultType()->getLinkage();
- bool UnnamedOrLocal = getResultType()->hasUnnamedOrLocalType();
+Type::CachedProperties FunctionProtoType::getCachedProperties() const {
+ CachedProperties Cached = Type::getCachedProperties(getResultType());
for (arg_type_iterator A = arg_type_begin(), AEnd = arg_type_end();
A != AEnd; ++A) {
- L = minLinkage(L, (*A)->getLinkage());
- UnnamedOrLocal = UnnamedOrLocal || (*A)->hasUnnamedOrLocalType();
+ Cached = merge(Cached, Type::getCachedProperties(*A));
}
-
- return std::make_pair(L, UnnamedOrLocal);
+ return Cached;
+}
+
+Type::CachedProperties ObjCInterfaceType::getCachedProperties() const {
+ std::pair<Linkage,Visibility> LV = getDecl()->getLinkageAndVisibility();
+ return CachedProperties(LV.first, LV.second, false);
}
-std::pair<Linkage, bool> ObjCObjectType::getLinkageUnnamedLocalImpl() const {
- return std::make_pair(ExternalLinkage, false);
+Type::CachedProperties ObjCObjectType::getCachedProperties() const {
+ if (const ObjCInterfaceType *T = getBaseType()->getAs<ObjCInterfaceType>())
+ return Type::getCachedProperties(T);
+ return CachedProperties(ExternalLinkage, DefaultVisibility, false);
}
-std::pair<Linkage, bool>
-ObjCObjectPointerType::getLinkageUnnamedLocalImpl() const {
- return std::make_pair(ExternalLinkage, false);
+Type::CachedProperties ObjCObjectPointerType::getCachedProperties() const {
+ return Type::getCachedProperties(PointeeType);
}
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Fri Oct 22 16:05:15 2010
@@ -180,7 +180,7 @@
}
// Finally, set up the alias with its proper name and attributes.
- SetCommonAttributes(AliasDecl.getDecl(), Alias);
+ SetCommonAttributes(cast<NamedDecl>(AliasDecl.getDecl()), Alias);
return false;
}
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Fri Oct 22 16:05:15 2010
@@ -2197,7 +2197,7 @@
CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8;
// FIXME: Set CXX-structors flag.
- if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden)
+ if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
Flags |= eClassFlags_Hidden;
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
@@ -2282,7 +2282,7 @@
unsigned Flags = eClassFlags_Meta;
unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy);
- if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden)
+ if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
Flags |= eClassFlags_Hidden;
std::vector<llvm::Constant*> Values(12);
@@ -4968,7 +4968,7 @@
llvm::GlobalVariable *SuperClassGV, *IsAGV;
bool classIsHidden =
- CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden;
+ ID->getClassInterface()->getVisibility() == HiddenVisibility;
if (classIsHidden)
flags |= OBJC2_CLS_HIDDEN;
if (ID->getNumIvarInitializers())
@@ -5263,7 +5263,7 @@
// well (i.e., in ObjCIvarOffsetVariable).
if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
Ivar->getAccessControl() == ObjCIvarDecl::Package ||
- CGM.getDeclVisibilityMode(ID) == LangOptions::Hidden)
+ ID->getVisibility() == HiddenVisibility)
IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
else
IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
@@ -6237,7 +6237,7 @@
ID->getIdentifier()->getName()));
}
- if (CGM.getLangOptions().getVisibilityMode() == LangOptions::Hidden)
+ if (CGM.getLangOptions().getVisibilityMode() == HiddenVisibility)
Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
Entry->setAlignment(CGM.getTargetData().getABITypeAlignment(
ObjCTypes.EHTypeTy));
Modified: cfe/trunk/lib/CodeGen/CGRTTI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRTTI.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRTTI.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRTTI.cpp Fri Oct 22 16:05:15 2010
@@ -113,7 +113,7 @@
}
if (const RecordType *RT = Ty->getAs<RecordType>())
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
- return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
+ return RD->getVisibility() == HiddenVisibility;
return false;
}
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Oct 22 16:05:15 2010
@@ -164,81 +164,23 @@
getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg;
}
-LangOptions::VisibilityMode
-CodeGenModule::getDeclVisibilityMode(const Decl *D) const {
- if (const VarDecl *VD = dyn_cast<VarDecl>(D))
- if (VD->getStorageClass() == SC_PrivateExtern)
- return LangOptions::Hidden;
-
- if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) {
- switch (attr->getVisibility()) {
- default: assert(0 && "Unknown visibility!");
- case VisibilityAttr::Default:
- return LangOptions::Default;
- case VisibilityAttr::Hidden:
- return LangOptions::Hidden;
- case VisibilityAttr::Protected:
- return LangOptions::Protected;
- }
- }
-
- if (getLangOptions().CPlusPlus) {
- // Entities subject to an explicit instantiation declaration get default
- // visibility.
- if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
- if (Function->getTemplateSpecializationKind()
- == TSK_ExplicitInstantiationDeclaration)
- return LangOptions::Default;
- } else if (const ClassTemplateSpecializationDecl *ClassSpec
- = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
- if (ClassSpec->getSpecializationKind()
- == TSK_ExplicitInstantiationDeclaration)
- return LangOptions::Default;
- } else if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
- if (Record->getTemplateSpecializationKind()
- == TSK_ExplicitInstantiationDeclaration)
- return LangOptions::Default;
- } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
- if (Var->isStaticDataMember() &&
- (Var->getTemplateSpecializationKind()
- == TSK_ExplicitInstantiationDeclaration))
- return LangOptions::Default;
- }
-
- // If -fvisibility-inlines-hidden was provided, then inline C++ member
- // functions get "hidden" visibility by default.
- if (getLangOptions().InlineVisibilityHidden)
- if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
- if (Method->isInlined())
- return LangOptions::Hidden;
- }
-
- // If this decl is contained in a class, it should have the same visibility
- // as the parent class.
- if (const DeclContext *DC = D->getDeclContext())
- if (DC->isRecord())
- return getDeclVisibilityMode(cast<Decl>(DC));
-
- return getLangOptions().getVisibilityMode();
-}
-
void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
- const Decl *D) const {
+ const NamedDecl *D) const {
// Internal definitions always have default visibility.
if (GV->hasLocalLinkage()) {
GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
return;
}
- switch (getDeclVisibilityMode(D)) {
- default: assert(0 && "Unknown visibility!");
- case LangOptions::Default:
+ switch (D->getVisibility()) {
+ case DefaultVisibility:
return GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
- case LangOptions::Hidden:
+ case HiddenVisibility:
return GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
- case LangOptions::Protected:
+ case ProtectedVisibility:
return GV->setVisibility(llvm::GlobalValue::ProtectedVisibility);
}
+ llvm_unreachable("unknown visibility!");
}
/// Set the symbol visibility of type information (vtable and RTTI)
@@ -498,7 +440,10 @@
void CodeGenModule::SetCommonAttributes(const Decl *D,
llvm::GlobalValue *GV) {
- setGlobalVisibility(GV, D);
+ if (isa<NamedDecl>(D))
+ setGlobalVisibility(GV, cast<NamedDecl>(D));
+ else
+ GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
if (D->hasAttr<UsedAttr>())
AddUsedGlobal(GV);
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Oct 22 16:05:15 2010
@@ -257,12 +257,9 @@
static void DecorateInstruction(llvm::Instruction *Inst,
llvm::MDNode *TBAAInfo);
- /// getDeclVisibilityMode - Compute the visibility of the decl \arg D.
- LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const;
-
/// setGlobalVisibility - Set the visibility for the given LLVM
/// GlobalValue.
- void setGlobalVisibility(llvm::GlobalValue *GV, const Decl *D) const;
+ void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const;
/// setTypeVisibility - Set the visibility for the given global
/// value which holds information about a type.
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Oct 22 16:05:15 2010
@@ -624,12 +624,12 @@
Res.push_back("-fobjc-gc-only");
}
}
- if (Opts.getVisibilityMode() != LangOptions::Default) {
+ if (Opts.getVisibilityMode() != DefaultVisibility) {
Res.push_back("-fvisibility");
- if (Opts.getVisibilityMode() == LangOptions::Hidden) {
+ if (Opts.getVisibilityMode() == HiddenVisibility) {
Res.push_back("hidden");
} else {
- assert(Opts.getVisibilityMode() == LangOptions::Protected &&
+ assert(Opts.getVisibilityMode() == ProtectedVisibility &&
"Invalid visibility!");
Res.push_back("protected");
}
@@ -1304,11 +1304,11 @@
llvm::StringRef Vis = Args.getLastArgValue(OPT_fvisibility, "default");
if (Vis == "default")
- Opts.setVisibilityMode(LangOptions::Default);
+ Opts.setVisibilityMode(DefaultVisibility);
else if (Vis == "hidden")
- Opts.setVisibilityMode(LangOptions::Hidden);
+ Opts.setVisibilityMode(HiddenVisibility);
else if (Vis == "protected")
- Opts.setVisibilityMode(LangOptions::Protected);
+ Opts.setVisibilityMode(ProtectedVisibility);
else
Diags.Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Oct 22 16:05:15 2010
@@ -2526,7 +2526,7 @@
PARSE_LANGOPT(CharIsSigned);
PARSE_LANGOPT(ShortWChar);
LangOpts.setGCMode((LangOptions::GCMode)Record[Idx++]);
- LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx++]);
+ LangOpts.setVisibilityMode((Visibility)Record[Idx++]);
LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode)
Record[Idx++]);
PARSE_LANGOPT(InstantiationDepth);
Modified: cfe/trunk/test/CodeGenCXX/member-pointer-type-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/member-pointer-type-convert.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/member-pointer-type-convert.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/member-pointer-type-convert.cpp Fri Oct 22 16:05:15 2010
@@ -6,5 +6,6 @@
const char *name;
param_t par;
} *ptr;
+void test_ptr() { (void) ptr; } // forced use
// CHECK: type { i8*, {{i..}} }
Modified: cfe/trunk/test/CodeGenCXX/pointers-to-data-members.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/pointers-to-data-members.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/pointers-to-data-members.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/pointers-to-data-members.cpp Fri Oct 22 16:05:15 2010
@@ -18,23 +18,26 @@
// CHECK: @_ZN8ZeroInit1bE = global i64 -1,
int A::* b = 0;
- // CHECK: @_ZN8ZeroInit2saE = global %struct.anon { i64 -1 }
+ // CHECK: @_ZN8ZeroInit2saE = internal global %struct.anon { i64 -1 }
struct {
int A::*a;
} sa;
+ void test_sa() { (void) sa; } // force emission
- // CHECK: @_ZN8ZeroInit3ssaE =
+ // CHECK: @_ZN8ZeroInit3ssaE = internal
// CHECK: [2 x i64] [i64 -1, i64 -1]
struct {
int A::*aa[2];
} ssa[2];
+ void test_ssa() { (void) ssa; }
- // CHECK: @_ZN8ZeroInit2ssE = global %1 { %struct.anon { i64 -1 } }
+ // CHECK: @_ZN8ZeroInit2ssE = internal global %1 { %struct.anon { i64 -1 } }
struct {
struct {
int A::*pa;
} s;
} ss;
+ void test_ss() { (void) ss; }
struct A {
int A::*a;
Modified: cfe/trunk/test/CodeGenCXX/visibility.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/visibility.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/visibility.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/visibility.cpp Fri Oct 22 16:05:15 2010
@@ -1,11 +1,15 @@
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
#define HIDDEN __attribute__((visibility("hidden")))
#define PROTECTED __attribute__((visibility("protected")))
#define DEFAULT __attribute__((visibility("default")))
// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
+// CHECK: @_ZN5Test71aE = hidden global
+// CHECK: @_ZN5Test71bE = global
// CHECK: @_ZTVN5Test63fooE = weak_odr hidden constant
+
namespace Test1 {
// CHECK: define hidden void @_ZN5Test11fEv
void HIDDEN f() { }
@@ -82,3 +86,32 @@
barc::barc() {}
}
+
+namespace Test7 {
+ class HIDDEN A {};
+ A a; // top of file
+
+ template <A&> struct Aref {
+ static void foo() {}
+ };
+
+ class B : public A {};
+ B b; // top of file
+
+ // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
+ void test() {
+ Aref<a>::foo();
+ }
+}
+
+namespace Test8 {
+ void foo();
+ void bar() {}
+ // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv()
+ // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
+
+ void test() {
+ foo();
+ bar();
+ }
+}
Modified: cfe/trunk/test/Index/index-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/index-templates.cpp?rev=117147&r1=117146&r2=117147&view=diff
==============================================================================
--- cfe/trunk/test/Index/index-templates.cpp (original)
+++ cfe/trunk/test/Index/index-templates.cpp Fri Oct 22 16:05:15 2010
@@ -192,7 +192,7 @@
// CHECK-USRS: index-templates.cpp c:index-templates.cpp at 210 Extent=[8:19 - 8:20]
// CHECK-USRS: index-templates.cpp c:index-templates.cpp at 222 Extent=[8:31 - 8:36]
// CHECK-USRS: index-templates.cpp c:@CT>2#T#T at vector@F at clear# Extent=[10:8 - 10:15]
-// CHECK-USRS: index-templates.cpp c:index-templates.cpp at 280@CP>1#T at vector>#*t0.0#>@CT>1#T at allocator1S0_ Extent=[13:1 - 14:21]
+// CHECK-USRS: index-templates.cpp c:@CP>1#T at vector>#*t0.0#>@CT>1#T at allocator1S0_ Extent=[13:1 - 14:21]
// CHECK-USRS: index-templates.cpp c:index-templates.cpp at 298 Extent=[13:19 - 13:20]
// CHECK-USRS: index-templates.cpp c:@S at Z1 Extent=[16:1 - 16:14]
// CHECK-USRS: index-templates.cpp c:@C at vector>#$@S at Z1#$@C at allocator>#S0_ Extent=[18:1 - 18:22]
More information about the cfe-commits
mailing list