return None;
}
+static LinkageInfo
+getLVForType(const Type &T, LVComputationKind computation) {
+ if (computation == LVForLinkageOnly)
+ return LinkageInfo(T.getLinkage(), DefaultVisibility, true);
+ return T.getLinkageAndVisibility();
+}
+
/// \brief Get the most restrictive linkage for the types in the given
/// template parameter list. For visibility purposes, template
/// parameters are part of the signature of a template.
static LinkageInfo
-getLVForTemplateParameterList(const TemplateParameterList *params) {
+getLVForTemplateParameterList(const TemplateParameterList *params,
+ LVComputationKind computation) {
LinkageInfo LV;
for (TemplateParameterList::const_iterator P = params->begin(),
PEnd = params->end();
// Handle the non-pack case first.
if (!NTTP->isExpandedParameterPack()) {
if (!NTTP->getType()->isDependentType()) {
- LV.merge(NTTP->getType()->getLinkageAndVisibility());
+ LV.merge(getLVForType(*NTTP->getType(), computation));
}
continue;
}
// Handle the non-pack case first.
if (!TTP->isExpandedParameterPack()) {
- LV.merge(getLVForTemplateParameterList(TTP->getTemplateParameters()));
+ LV.merge(getLVForTemplateParameterList(TTP->getTemplateParameters(),
+ computation));
continue;
}
for (unsigned i = 0, n = TTP->getNumExpansionTemplateParameters();
i != n; ++i) {
LV.merge(getLVForTemplateParameterList(
- TTP->getExpansionTemplateParameters(i)));
+ TTP->getExpansionTemplateParameters(i), computation));
}
}
/// Note that we don't take an LVComputationKind because we always
/// want to honor the visibility of template arguments in the same way.
static LinkageInfo
-getLVForTemplateArgumentList(ArrayRef<TemplateArgument> args) {
+getLVForTemplateArgumentList(ArrayRef<TemplateArgument> args,
+ LVComputationKind computation) {
LinkageInfo LV;
for (unsigned i = 0, e = args.size(); i != e; ++i) {
continue;
case TemplateArgument::Type:
- LV.merge(arg.getAsType()->getLinkageAndVisibility());
+ LV.merge(getLVForType(*arg.getAsType(), computation));
continue;
case TemplateArgument::Declaration:
if (NamedDecl *ND = dyn_cast<NamedDecl>(arg.getAsDecl())) {
assert(!usesTypeVisibility(ND));
- LV.merge(getLVForDecl(ND, LVForValue));
+ LV.merge(getLVForDecl(ND, computation));
}
continue;
case TemplateArgument::TemplateExpansion:
if (TemplateDecl *Template
= arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl())
- LV.merge(getLVForDecl(Template, LVForValue));
+ LV.merge(getLVForDecl(Template, computation));
continue;
case TemplateArgument::Pack:
- LV.merge(getLVForTemplateArgumentList(arg.getPackAsArray()));
+ LV.merge(getLVForTemplateArgumentList(arg.getPackAsArray(), computation));
continue;
}
llvm_unreachable("bad template argument kind");
}
static LinkageInfo
-getLVForTemplateArgumentList(const TemplateArgumentList &TArgs) {
- return getLVForTemplateArgumentList(TArgs.asArray());
+getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
+ LVComputationKind computation) {
+ return getLVForTemplateArgumentList(TArgs.asArray(), computation);
}
static bool shouldConsiderTemplateVisibility(const FunctionDecl *fn,
/// \param[out] LV the computation to use for the parent
static void
mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
- const FunctionTemplateSpecializationInfo *specInfo) {
+ const FunctionTemplateSpecializationInfo *specInfo,
+ LVComputationKind computation) {
bool considerVisibility =
shouldConsiderTemplateVisibility(fn, specInfo);
// Merge information from the template parameters.
FunctionTemplateDecl *temp = specInfo->getTemplate();
LinkageInfo tempLV =
- getLVForTemplateParameterList(temp->getTemplateParameters());
+ getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
LV.mergeMaybeWithVisibility(tempLV, considerVisibility);
// Merge information from the template arguments.
const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;
- LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs);
+ LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
LV.mergeMaybeWithVisibility(argsLV, considerVisibility);
}
ClassTemplateDecl *temp = spec->getSpecializedTemplate();
LinkageInfo tempLV =
- getLVForTemplateParameterList(temp->getTemplateParameters());
+ getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
LV.mergeMaybeWithVisibility(tempLV,
considerVisibility && !hasExplicitVisibilityAlready(computation));
// template-argument visibility if we've got an explicit
// instantiation with a visibility attribute.
const TemplateArgumentList &templateArgs = spec->getTemplateArgs();
- LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs);
+ LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
LV.mergeMaybeWithVisibility(argsLV, considerVisibility);
}
!Var->getType().isVolatileQualified()) {
const VarDecl *PrevVar = Var->getPreviousDecl();
if (PrevVar)
- return PrevVar->getLinkageAndVisibility();
+ return getLVForDecl(PrevVar, computation);
if (Var->getStorageClass() != SC_Extern &&
Var->getStorageClass() != SC_PrivateExtern &&
// Note that we don't want to make the variable non-external
// because of this, but unique-external linkage suits us.
if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var)) {
- LinkageInfo TypeLV = Var->getType()->getLinkageAndVisibility();
+ LinkageInfo TypeLV = getLVForType(*Var->getType(), computation);
if (TypeLV.getLinkage() != ExternalLinkage)
return LinkageInfo::uniqueExternal();
if (!LV.isVisibilityExplicit())
// specializations.
if (FunctionTemplateSpecializationInfo *specInfo
= Function->getTemplateSpecializationInfo()) {
- mergeTemplateLV(LV, Function, specInfo);
+ mergeTemplateLV(LV, Function, specInfo, computation);
}
// - a named class (Clause 9), or an unnamed class defined in a
} else if (const TemplateDecl *temp = dyn_cast<TemplateDecl>(D)) {
bool considerVisibility = !hasExplicitVisibilityAlready(computation);
LinkageInfo tempLV =
- getLVForTemplateParameterList(temp->getTemplateParameters());
+ getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
LV.mergeMaybeWithVisibility(tempLV, considerVisibility);
// - a namespace (7.3), unless it is declared within an unnamed
// the template parameters and arguments.
if (FunctionTemplateSpecializationInfo *spec
= MD->getTemplateSpecializationInfo()) {
- mergeTemplateLV(LV, MD, spec);
+ mergeTemplateLV(LV, MD, spec, computation);
if (spec->isExplicitSpecialization()) {
explicitSpecSuppressor = MD;
} else if (isExplicitMemberSpecialization(spec->getTemplate())) {
} 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.
- LinkageInfo typeLV = VD->getType()->getLinkageAndVisibility();
+ LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
LV.mergeMaybeWithVisibility(typeLV,
!LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit());
!classLV.isVisibilityExplicit() &&
!hasExplicitVisibilityAlready(computation));
LinkageInfo tempLV =
- getLVForTemplateParameterList(temp->getTemplateParameters());
+ getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
LV.mergeMaybeWithVisibility(tempLV, considerVisibility);
if (const RedeclarableTemplateDecl *redeclTemp =
void NamedDecl::anchor() { }
+static LinkageInfo computeLVForDecl(const NamedDecl *D,
+ LVComputationKind computation);
+
bool NamedDecl::isLinkageValid() const {
if (!hasCachedLinkage())
return true;
- return getLVForDecl(this, LVForExplicitValue).getLinkage() ==
+ return computeLVForDecl(this, LVForLinkageOnly).getLinkage() ==
getCachedLinkage();
}