Cleanup handling of UniqueExternalLinkage.

This patch renames getLinkage to getLinkageInternal. Only code that
needs to handle UniqueExternalLinkage specially should call this.

Linkage, as defined in the c++ standard, is provided by
getFormalLinkage. It maps UniqueExternalLinkage to ExternalLinkage.

Most places in the compiler actually want isExternallyVisible, which
handles UniqueExternalLinkage as internal.

llvm-svn: 181677
This commit is contained in:
Rafael Espindola 2013-05-13 00:12:11 +00:00
parent 0e4676e1f5
commit 3ae00052cd
26 changed files with 104 additions and 105 deletions

View File

@ -212,11 +212,26 @@ public:
bool isCXXInstanceMember() const;
/// \brief Determine what kind of linkage this entity has.
Linkage getLinkage() const;
/// This is not the linkage as defined by the standard or the codegen notion
/// of linkage. It is just an implementation detail that is used to compute
/// those.
Linkage getLinkageInternal() const;
/// \brief Get the linkage from a semantic point of view. Entities in
/// anonymous namespaces are external (in c++98).
Linkage getFormalLinkage() const {
Linkage L = getLinkageInternal();
if (L == UniqueExternalLinkage)
return ExternalLinkage;
return L;
}
/// \brief True if this decl has external linkage.
bool hasExternalLinkage() const {
return getLinkage() == ExternalLinkage;
bool hasExternalFormalLinkage() const {
return getFormalLinkage() == ExternalLinkage;
}
bool isExternallyVisible() const {
return getLinkageInternal() == ExternalLinkage;
}
/// \brief Determines the visibility of this entity.

View File

@ -62,11 +62,6 @@ enum GVALinkage {
GVA_ExplicitTemplateInstantiation
};
/// \brief Determine whether the given linkage is semantically external.
inline bool isExternalLinkage(Linkage L) {
return L == UniqueExternalLinkage || L == ExternalLinkage;
}
/// \brief Compute the minimum linkage given two linages.
inline Linkage minLinkage(Linkage L1, Linkage L2) {
return L1 < L2? L1 : L2;

View File

@ -216,7 +216,7 @@ class Sema {
// it will keep having external linkage. If it has internal linkage, we
// will not link it. Since it has no previous decls, it will remain
// with internal linkage.
return !Old->isHidden() || New->hasExternalLinkage();
return !Old->isHidden() || New->isExternallyVisible();
}
public:

View File

@ -148,7 +148,7 @@ private:
if (FD->getName() == "CFRetain" &&
FD->getNumParams() == 1 &&
FD->getParent()->isTranslationUnit() &&
FD->hasExternalLinkage()) {
FD->isExternallyVisible()) {
Expr *Arg = callE->getArg(0);
if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
const Expr *sub = ICE->getSubExpr();
@ -413,7 +413,7 @@ private:
FD = dyn_cast_or_null<FunctionDecl>(callE->getCalleeDecl()))
if (FD->getName() == "CFRetain" && FD->getNumParams() == 1 &&
FD->getParent()->isTranslationUnit() &&
FD->hasExternalLinkage())
FD->isExternallyVisible())
return true;
return false;

View File

@ -94,7 +94,7 @@ bool trans::isPlusOne(const Expr *E) {
if (FD->isGlobal() &&
FD->getIdentifier() &&
FD->getParent()->isTranslationUnit() &&
FD->hasExternalLinkage() &&
FD->isExternallyVisible() &&
ento::cocoa::isRefType(callE->getType(), "CF",
FD->getIdentifier()->getName())) {
StringRef fname = FD->getIdentifier()->getName();
@ -198,7 +198,7 @@ bool trans::isGlobalVar(Expr *E) {
E = E->IgnoreParenCasts();
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
return DRE->getDecl()->getDeclContext()->isFileContext() &&
DRE->getDecl()->hasExternalLinkage();
DRE->getDecl()->isExternallyVisible();
if (ConditionalOperator *condOp = dyn_cast<ConditionalOperator>(E))
return isGlobalVar(condOp->getTrueExpr()) &&
isGlobalVar(condOp->getFalseExpr());

View File

@ -7767,30 +7767,23 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
}
GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) {
GVALinkage External = GVA_StrongExternal;
Linkage L = FD->getLinkage();
switch (L) {
case NoLinkage:
case InternalLinkage:
case UniqueExternalLinkage:
if (!FD->isExternallyVisible())
return GVA_Internal;
case ExternalLinkage:
switch (FD->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
External = GVA_StrongExternal;
break;
case TSK_ExplicitInstantiationDefinition:
return GVA_ExplicitTemplateInstantiation;
GVALinkage External = GVA_StrongExternal;
switch (FD->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
External = GVA_StrongExternal;
break;
case TSK_ExplicitInstantiationDeclaration:
case TSK_ImplicitInstantiation:
External = GVA_TemplateInstantiation;
break;
}
case TSK_ExplicitInstantiationDefinition:
return GVA_ExplicitTemplateInstantiation;
case TSK_ExplicitInstantiationDeclaration:
case TSK_ImplicitInstantiation:
External = GVA_TemplateInstantiation;
break;
}
if (!FD->isInlined())
@ -7820,6 +7813,9 @@ GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) {
}
GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
if (!VD->isExternallyVisible())
return GVA_Internal;
// If this is a static data member, compute the kind of template
// specialization. Otherwise, this variable is not part of a
// template.
@ -7827,33 +7823,21 @@ GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
if (VD->isStaticDataMember())
TSK = VD->getTemplateSpecializationKind();
Linkage L = VD->getLinkage();
switch (TSK) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
return GVA_StrongExternal;
switch (L) {
case NoLinkage:
case InternalLinkage:
case UniqueExternalLinkage:
return GVA_Internal;
case TSK_ExplicitInstantiationDeclaration:
llvm_unreachable("Variable should not be instantiated");
// Fall through to treat this like any other instantiation.
case ExternalLinkage:
switch (TSK) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
return GVA_StrongExternal;
case TSK_ExplicitInstantiationDefinition:
return GVA_ExplicitTemplateInstantiation;
case TSK_ExplicitInstantiationDeclaration:
llvm_unreachable("Variable should not be instantiated");
// Fall through to treat this like any other instantiation.
case TSK_ExplicitInstantiationDefinition:
return GVA_ExplicitTemplateInstantiation;
case TSK_ImplicitInstantiation:
return GVA_TemplateInstantiation;
}
case TSK_ImplicitInstantiation:
return GVA_TemplateInstantiation;
}
llvm_unreachable("Invalid Linkage!");
}
bool ASTContext::DeclMustBeEmitted(const Decl *D) {
@ -7986,7 +7970,8 @@ size_t ASTContext::getSideTableAllocatedMemory() const {
void ASTContext::addUnnamedTag(const TagDecl *Tag) {
// FIXME: This mangling should be applied to function local classes too
if (!Tag->getName().empty() || Tag->getTypedefNameForAnonDecl() ||
!isa<CXXRecordDecl>(Tag->getParent()) || Tag->getLinkage() != ExternalLinkage)
!isa<CXXRecordDecl>(Tag->getParent()) ||
!Tag->isExternallyVisible())
return;
std::pair<llvm::DenseMap<const DeclContext *, unsigned>::iterator, bool> P =

View File

@ -2610,8 +2610,8 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
continue;
if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(FoundDecls[I])) {
if (isExternalLinkage(FoundFunction->getLinkage()) &&
isExternalLinkage(D->getLinkage())) {
if (FoundFunction->hasExternalFormalLinkage() &&
D->hasExternalFormalLinkage()) {
if (Importer.IsStructurallyEquivalent(D->getType(),
FoundFunction->getType())) {
// FIXME: Actually try to merge the body and other attributes.
@ -2995,8 +2995,8 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
if (VarDecl *FoundVar = dyn_cast<VarDecl>(FoundDecls[I])) {
// We have found a variable that we may need to merge with. Check it.
if (isExternalLinkage(FoundVar->getLinkage()) &&
isExternalLinkage(D->getLinkage())) {
if (FoundVar->hasExternalFormalLinkage() &&
D->hasExternalFormalLinkage()) {
if (Importer.IsStructurallyEquivalent(D->getType(),
FoundVar->getType())) {
MergeWithVar = FoundVar;

View File

@ -483,6 +483,10 @@ static bool isSingleLineExternC(const Decl &D) {
return false;
}
static bool isExternalLinkage(Linkage L) {
return L == UniqueExternalLinkage || L == ExternalLinkage;
}
static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
LVComputationKind computation) {
assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
@ -885,7 +889,7 @@ bool NamedDecl::isLinkageValid() const {
Linkage(CachedLinkage);
}
Linkage NamedDecl::getLinkage() const {
Linkage NamedDecl::getLinkageInternal() const {
if (HasCachedLinkage)
return Linkage(CachedLinkage);
@ -1289,7 +1293,7 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
}
bool NamedDecl::hasLinkage() const {
return getLinkage() != NoLinkage;
return getLinkageInternal() != NoLinkage;
}
NamedDecl *NamedDecl::getUnderlyingDeclImpl() {
@ -1513,7 +1517,7 @@ template<typename T>
static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
// C++ [dcl.link]p1: All function types, function names with external linkage,
// and variable names with external linkage have a language linkage.
if (!isExternalLinkage(D.getLinkage()))
if (!D.hasExternalFormalLinkage())
return NoLanguageLinkage;
// Language linkage is a C++ concept, but saying that everything else in C has

View File

@ -405,7 +405,7 @@ bool ItaniumMangleContext::shouldMangleDeclName(const NamedDecl *D) {
if (DC->isFunctionOrMethod() && D->hasLinkage())
while (!DC->isNamespace() && !DC->isTranslationUnit())
DC = getEffectiveParentContext(DC);
if (DC->isTranslationUnit() && D->getLinkage() != InternalLinkage)
if (DC->isTranslationUnit() && D->getFormalLinkage() != InternalLinkage)
return false;
}
@ -1053,7 +1053,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// static void foo();
// This naming convention is the same as that followed by GCC,
// though it shouldn't actually matter.
if (ND && ND->getLinkage() == InternalLinkage &&
if (ND && ND->getFormalLinkage() == InternalLinkage &&
getEffectiveDeclContext(ND)->isFileContext())
Out << 'L';

View File

@ -199,7 +199,7 @@ bool MicrosoftMangleContext::shouldMangleDeclName(const NamedDecl *D) {
// Variables at global scope with internal linkage are not mangled.
if (!FD) {
const DeclContext *DC = D->getDeclContext();
if (DC->isTranslationUnit() && D->getLinkage() == InternalLinkage)
if (DC->isTranslationUnit() && D->getFormalLinkage() == InternalLinkage)
return false;
}

View File

@ -2354,7 +2354,7 @@ static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,
// A class that is not externally visible doesn't have a key function. (Or
// at least, there's no point to assigning a key function to such a class;
// this doesn't affect the ABI.)
if (RD->getLinkage() != ExternalLinkage)
if (!RD->isExternallyVisible())
return 0;
// Template instantiations don't have key functions,see Itanium C++ ABI 5.2.6.

View File

@ -2124,7 +2124,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
Linkage L = Tag->getLinkage();
Linkage L = Tag->getLinkageInternal();
bool IsLocalOrUnnamed =
Tag->getDeclContext()->isFunctionOrMethod() ||
!Tag->hasNameForLinkage();
@ -2166,7 +2166,7 @@ static CachedProperties computeCachedProperties(const Type *T) {
return result;
}
case Type::ObjCInterface: {
Linkage L = cast<ObjCInterfaceType>(T)->getDecl()->getLinkage();
Linkage L = cast<ObjCInterfaceType>(T)->getDecl()->getLinkageInternal();
return CachedProperties(L, false);
}
case Type::ObjCObject:

View File

@ -719,7 +719,7 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
/// Note that we only call this at the end of the translation unit.
llvm::GlobalVariable::LinkageTypes
CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
if (RD->getLinkage() != ExternalLinkage)
if (!RD->isExternallyVisible())
return llvm::GlobalVariable::InternalLinkage;
// We're at the end of the translation unit, so the current key

View File

@ -1763,7 +1763,7 @@ void CodeGenModule::MaybeHandleStaticInExternC(const SomeDecl *D,
return;
// Must have internal linkage and an ordinary name.
if (!D->getIdentifier() || D->getLinkage() != InternalLinkage)
if (!D->getIdentifier() || D->getFormalLinkage() != InternalLinkage)
return;
// Must be in an extern "C" context. Entities declared directly within

View File

@ -162,8 +162,7 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) {
// on their mangled names, if they're external.
// TODO: Is there a way to get a program-wide unique name for a
// decl with local linkage or no linkage?
if (Features.CPlusPlus &&
ETy->getDecl()->getLinkage() != ExternalLinkage)
if (Features.CPlusPlus && !ETy->getDecl()->isExternallyVisible())
return MetadataCache[Ty] = getChar();
// TODO: This is using the RTTI name. Is there a better way to get

View File

@ -332,7 +332,7 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
if (D->getMostRecentDecl()->isUsed())
return true;
if (D->hasExternalLinkage())
if (D->isExternallyVisible())
return true;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
@ -402,13 +402,13 @@ void Sema::getUndefinedButUsed(
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
if (FD->isDefined())
continue;
if (FD->hasExternalLinkage() &&
if (FD->isExternallyVisible() &&
!FD->getMostRecentDecl()->isInlined())
continue;
} else {
if (cast<VarDecl>(ND)->hasDefinition() != VarDecl::DeclarationOnly)
continue;
if (ND->hasExternalLinkage())
if (ND->isExternallyVisible())
continue;
}
@ -435,7 +435,7 @@ static void checkUndefinedButUsed(Sema &S) {
I = Undefined.begin(), E = Undefined.end(); I != E; ++I) {
NamedDecl *ND = I->first;
if (ND->getLinkage() != ExternalLinkage) {
if (!ND->isExternallyVisible()) {
S.Diag(ND->getLocation(), diag::warn_undefined_internal)
<< isa<VarDecl>(ND) << ND;
} else {

View File

@ -1194,7 +1194,7 @@ bool Sema::mightHaveNonExternalLinkage(const DeclaratorDecl *D) {
DC = DC->getParent();
}
return !D->hasExternalLinkage();
return !D->isExternallyVisible();
}
bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
@ -1614,7 +1614,7 @@ static void filterNonConflictingPreviousDecls(ASTContext &context,
if (!old->isHidden())
continue;
if (old->getLinkage() != ExternalLinkage)
if (!old->isExternallyVisible())
filter.erase();
}
@ -2314,7 +2314,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) {
// storage classes.
if (!isa<CXXMethodDecl>(New) && !isa<CXXMethodDecl>(Old) &&
New->getStorageClass() == SC_Static &&
isExternalLinkage(Old->getLinkage()) &&
Old->hasExternalFormalLinkage() &&
!New->getTemplateSpecializationInfo() &&
!canRedefineFunction(Old, getLangOpts())) {
if (getLangOpts().MicrosoftExt) {
@ -2923,7 +2923,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous,
// [dcl.stc]p8: Check if we have a non-static decl followed by a static.
if (New->getStorageClass() == SC_Static &&
!New->isStaticDataMember() &&
isExternalLinkage(Old->getLinkage())) {
Old->hasExternalFormalLinkage()) {
Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
return New->setInvalidDecl();
@ -4625,13 +4625,13 @@ bool Sema::inferObjCARCLifetime(ValueDecl *decl) {
static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {
// 'weak' only applies to declarations with external linkage.
if (WeakAttr *Attr = ND.getAttr<WeakAttr>()) {
if (ND.getLinkage() != ExternalLinkage) {
if (!ND.isExternallyVisible()) {
S.Diag(Attr->getLocation(), diag::err_attribute_weak_static);
ND.dropAttr<WeakAttr>();
}
}
if (WeakRefAttr *Attr = ND.getAttr<WeakRefAttr>()) {
if (ND.hasExternalLinkage()) {
if (ND.isExternallyVisible()) {
S.Diag(Attr->getLocation(), diag::err_attribute_weakref_not_static);
ND.dropAttr<WeakRefAttr>();
}
@ -6579,7 +6579,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// If there's a #pragma GCC visibility in scope, and this isn't a class
// member, set the visibility of this function.
if (!DC->isRecord() && NewFD->hasExternalLinkage())
if (!DC->isRecord() && NewFD->isExternallyVisible())
AddPushedVisibilityAttribute(NewFD);
// If there's a #pragma clang arc_cf_code_audited in scope, consider
@ -7816,7 +7816,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl,
// declared with no linkage (C99 6.2.2p6), the type for the
// object shall be complete.
if (!Type->isDependentType() && Var->isLocalVarDecl() &&
!Var->getLinkage() && !Var->isInvalidDecl() &&
!Var->hasLinkage() && !Var->isInvalidDecl() &&
RequireCompleteType(Var->getLocation(), Type,
diag::err_typecheck_decl_incomplete_type))
Var->setInvalidDecl();
@ -8029,7 +8029,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
}
if (var->isThisDeclarationADefinition() &&
var->hasExternalLinkage() &&
var->isExternallyVisible() &&
getDiagnostics().getDiagnosticLevel(
diag::warn_missing_variable_declarations,
var->getLocation())) {
@ -8138,7 +8138,7 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
const DeclContext *DC = VD->getDeclContext();
// If there's a #pragma GCC visibility in scope, and this isn't a class
// member, set the visibility of this variable.
if (!DC->isRecord() && VD->hasExternalLinkage())
if (!DC->isRecord() && VD->isExternallyVisible())
AddPushedVisibilityAttribute(VD);
if (VD->isFileVarDecl())
@ -8904,7 +8904,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
// ODR use before the definition. Avoid the expensive map lookup if this
// is the first declaration.
if (FD->getPreviousDecl() != 0 && FD->getPreviousDecl()->isUsed()) {
if (FD->getLinkage() != ExternalLinkage)
if (!FD->isExternallyVisible())
UndefinedButUsed.erase(FD);
else if (FD->isInlined() &&
(LangOpts.CPlusPlus || !LangOpts.GNUInline) &&

View File

@ -11824,7 +11824,7 @@ bool Sema::DefineUsedVTables() {
Consumer.HandleVTable(Class, VTablesUsed[Canonical]);
// Optionally warn if we're emitting a weak vtable.
if (Class->hasExternalLinkage() &&
if (Class->isExternallyVisible() &&
Class->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
const FunctionDecl *KeyFunctionDef = 0;
if (!KeyFunction ||

View File

@ -197,11 +197,11 @@ static void diagnoseUseOfInternalDeclInInlineFunction(Sema &S,
return;
if (!Current->isInlined())
return;
if (Current->getLinkage() != ExternalLinkage)
if (!Current->isExternallyVisible())
return;
// Check if the decl has internal linkage.
if (D->getLinkage() != InternalLinkage)
if (D->getFormalLinkage() != InternalLinkage)
return;
// Downgrade from ExtWarn to Extension if
@ -11459,7 +11459,7 @@ static void MarkVarDeclODRUsed(Sema &SemaRef, VarDecl *Var,
// Keep track of used but undefined variables.
// FIXME: We shouldn't suppress this warning for static data members.
if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
Var->getLinkage() != ExternalLinkage &&
!Var->isExternallyVisible() &&
!(Var->isStaticDataMember() && Var->hasInit())) {
SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()];
if (old.isInvalid()) old = Loc;

View File

@ -3793,14 +3793,14 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
}
// Address / reference template args must have external linkage in C++98.
if (Entity->getLinkage() == InternalLinkage) {
if (Entity->getFormalLinkage() == InternalLinkage) {
S.Diag(Arg->getLocStart(), S.getLangOpts().CPlusPlus11 ?
diag::warn_cxx98_compat_template_arg_object_internal :
diag::ext_template_arg_object_internal)
<< !Func << Entity << Arg->getSourceRange();
S.Diag(Entity->getLocation(), diag::note_template_arg_internal_object)
<< !Func;
} else if (Entity->getLinkage() == NoLinkage) {
} else if (!Entity->hasLinkage()) {
S.Diag(Arg->getLocStart(), diag::err_template_arg_object_no_linkage)
<< !Func << Entity << Arg->getSourceRange();
S.Diag(Entity->getLocation(), diag::note_template_arg_internal_object)

View File

@ -1783,14 +1783,14 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
//prototyped/non-prototyped functions, etc.
if (FunctionDecl *FuncX = dyn_cast<FunctionDecl>(X)) {
FunctionDecl *FuncY = cast<FunctionDecl>(Y);
return (FuncX->getLinkage() == FuncY->getLinkage()) &&
return (FuncX->getLinkageInternal() == FuncY->getLinkageInternal()) &&
FuncX->getASTContext().hasSameType(FuncX->getType(), FuncY->getType());
}
// Variables with the same type and linkage match.
if (VarDecl *VarX = dyn_cast<VarDecl>(X)) {
VarDecl *VarY = cast<VarDecl>(Y);
return (VarX->getLinkage() == VarY->getLinkage()) &&
return (VarX->getLinkageInternal() == VarY->getLinkageInternal()) &&
VarX->getASTContext().hasSameType(VarX->getType(), VarY->getType());
}

View File

@ -334,7 +334,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Record.push_back(D->hasImplicitReturnZero());
Record.push_back(D->isConstexpr());
Record.push_back(D->HasSkippedBody);
Record.push_back(D->getLinkage());
Record.push_back(D->getLinkageInternal());
Writer.AddSourceLocation(D->getLocEnd(), Record);
Record.push_back(D->getTemplatedKind());
@ -694,7 +694,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
Record.push_back(D->isCXXForRangeDecl());
Record.push_back(D->isARCPseudoStrong());
Record.push_back(D->isConstexpr());
Record.push_back(D->getLinkage());
Record.push_back(D->getLinkageInternal());
if (D->getInit()) {
Record.push_back(!D->isInitKnownICE() ? 1 : (D->isInitICE() ? 3 : 2));

View File

@ -68,7 +68,7 @@ bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD,
// If this function is not externally visible, it is not a C library function.
// Note that we make an exception for inline functions, which may be
// declared in header files without external linkage.
if (!FD->isInlined() && FD->getLinkage() != ExternalLinkage)
if (!FD->isInlined() && !FD->isExternallyVisible())
return false;
if (Name.empty())

View File

@ -5681,7 +5681,7 @@ CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
const Decl *D = cxcursor::getCursorDecl(cursor);
if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
switch (ND->getLinkage()) {
switch (ND->getLinkageInternal()) {
case NoLinkage: return CXLinkage_NoLinkage;
case InternalLinkage: return CXLinkage_Internal;
case UniqueExternalLinkage: return CXLinkage_UniqueExternal;

View File

@ -151,7 +151,7 @@ bool USRGenerator::EmitDeclName(const NamedDecl *D) {
}
static inline bool ShouldGenerateLocation(const NamedDecl *D) {
return D->getLinkage() != ExternalLinkage;
return !D->isExternallyVisible();
}
void USRGenerator::VisitDeclContext(const DeclContext *DC) {

View File

@ -210,11 +210,12 @@ bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
return false;
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
switch (ND->getLinkage()) {
switch (ND->getFormalLinkage()) {
case NoLinkage:
case InternalLinkage:
return true;
case UniqueExternalLinkage:
llvm_unreachable("Not a sema linkage");
case ExternalLinkage:
return false;
}