summaryrefslogtreecommitdiffstats
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp346
1 files changed, 193 insertions, 153 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 53032bc..d5b0be3 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -66,32 +66,6 @@ static llvm::Optional<Visibility> getVisibilityOf(const Decl *D) {
typedef NamedDecl::LinkageInfo LinkageInfo;
-namespace {
-/// Flags controlling the computation of linkage and visibility.
-struct LVFlags {
- const bool ConsiderGlobalVisibility;
- const bool ConsiderVisibilityAttributes;
- const bool ConsiderTemplateParameterTypes;
-
- LVFlags() : ConsiderGlobalVisibility(true),
- ConsiderVisibilityAttributes(true),
- ConsiderTemplateParameterTypes(true) {
- }
-
- LVFlags(bool Global, bool Attributes, bool Parameters) :
- ConsiderGlobalVisibility(Global),
- ConsiderVisibilityAttributes(Attributes),
- ConsiderTemplateParameterTypes(Parameters) {
- }
-
- /// \brief Returns a set of flags that is only useful for computing the
- /// linkage, not the visibility, of a declaration.
- static LVFlags CreateOnlyDeclLinkage() {
- return LVFlags(false, false, false);
- }
-};
-} // end anonymous namespace
-
static LinkageInfo getLVForType(QualType T) {
std::pair<Linkage,Visibility> P = T->getLinkageAndVisibility();
return LinkageInfo(P.first, P.second, T->isVisibilityExplicit());
@@ -131,13 +105,13 @@ getLVForTemplateParameterList(const TemplateParameterList *Params) {
}
/// getLVForDecl - Get the linkage and visibility for the given declaration.
-static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags F);
+static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate);
/// \brief Get the most restrictive linkage for the types and
/// declarations in the given template argument list.
static LinkageInfo getLVForTemplateArgumentList(const TemplateArgument *Args,
unsigned NumArgs,
- LVFlags &F) {
+ bool OnlyTemplate) {
LinkageInfo LV(ExternalLinkage, DefaultVisibility, false);
for (unsigned I = 0; I != NumArgs; ++I) {
@@ -148,7 +122,7 @@ static LinkageInfo getLVForTemplateArgumentList(const TemplateArgument *Args,
break;
case TemplateArgument::Type:
- LV.merge(getLVForType(Args[I].getAsType()));
+ LV.mergeWithMin(getLVForType(Args[I].getAsType()));
break;
case TemplateArgument::Declaration:
@@ -156,7 +130,7 @@ static LinkageInfo getLVForTemplateArgumentList(const TemplateArgument *Args,
// arguments, valid only in C++0x.
if (Decl *D = Args[I].getAsDecl()) {
if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
- LV = merge(LV, getLVForDecl(ND, F));
+ LV.mergeWithMin(getLVForDecl(ND, OnlyTemplate));
}
break;
@@ -164,13 +138,13 @@ static LinkageInfo getLVForTemplateArgumentList(const TemplateArgument *Args,
case TemplateArgument::TemplateExpansion:
if (TemplateDecl *Template
= Args[I].getAsTemplateOrTemplatePattern().getAsTemplateDecl())
- LV.merge(getLVForDecl(Template, F));
+ LV.mergeWithMin(getLVForDecl(Template, OnlyTemplate));
break;
case TemplateArgument::Pack:
LV.mergeWithMin(getLVForTemplateArgumentList(Args[I].pack_begin(),
Args[I].pack_size(),
- F));
+ OnlyTemplate));
break;
}
}
@@ -180,21 +154,50 @@ static LinkageInfo getLVForTemplateArgumentList(const TemplateArgument *Args,
static LinkageInfo
getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
- LVFlags &F) {
- return getLVForTemplateArgumentList(TArgs.data(), TArgs.size(), F);
+ bool OnlyTemplate) {
+ return getLVForTemplateArgumentList(TArgs.data(), TArgs.size(), OnlyTemplate);
}
-static bool shouldConsiderTemplateLV(const FunctionDecl *fn,
+static bool shouldConsiderTemplateVis(const FunctionDecl *fn,
const FunctionTemplateSpecializationInfo *spec) {
- return !(spec->isExplicitSpecialization() &&
- fn->hasAttr<VisibilityAttr>());
+ return !fn->hasAttr<VisibilityAttr>() || spec->isExplicitSpecialization();
}
-static bool shouldConsiderTemplateLV(const ClassTemplateSpecializationDecl *d) {
- return !(d->isExplicitSpecialization() && d->hasAttr<VisibilityAttr>());
+static bool
+shouldConsiderTemplateVis(const ClassTemplateSpecializationDecl *d) {
+ return !d->hasAttr<VisibilityAttr>() || d->isExplicitSpecialization();
}
-static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
+static bool useInlineVisibilityHidden(const NamedDecl *D) {
+ // FIXME: we should warn if -fvisibility-inlines-hidden is used with c.
+ const LangOptions &Opts = D->getASTContext().getLangOpts();
+ if (!Opts.CPlusPlus || !Opts.InlineVisibilityHidden)
+ return false;
+
+ const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+ if (!FD)
+ return false;
+
+ TemplateSpecializationKind TSK = TSK_Undeclared;
+ if (FunctionTemplateSpecializationInfo *spec
+ = FD->getTemplateSpecializationInfo()) {
+ TSK = spec->getTemplateSpecializationKind();
+ } else if (MemberSpecializationInfo *MSI =
+ FD->getMemberSpecializationInfo()) {
+ TSK = MSI->getTemplateSpecializationKind();
+ }
+
+ const FunctionDecl *Def = 0;
+ // InlineVisibilityHidden only applies to definitions, and
+ // isInlined() only gives meaningful answers on definitions
+ // anyway.
+ return TSK != TSK_ExplicitInstantiationDeclaration &&
+ TSK != TSK_ExplicitInstantiationDefinition &&
+ FD->hasBody(Def) && Def->isInlined();
+}
+
+static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
+ bool OnlyTemplate) {
assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
"Not a name having namespace scope");
ASTContext &Context = D->getASTContext();
@@ -271,11 +274,10 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
// scope and no storage-class specifier, its linkage is
// external.
LinkageInfo LV;
- LV.mergeVisibility(Context.getLangOpts().getVisibilityMode());
- if (F.ConsiderVisibilityAttributes) {
+ if (!OnlyTemplate) {
if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) {
- LV.setVisibility(*Vis, true);
+ LV.mergeVisibility(*Vis, true);
} else {
// If we're declared in a namespace with a visibility attribute,
// use that namespace's visibility, but don't call it explicit.
@@ -285,13 +287,21 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
if (!ND) continue;
if (llvm::Optional<Visibility> Vis = ND->getExplicitVisibility()) {
- LV.setVisibility(*Vis, true);
+ LV.mergeVisibility(*Vis, true);
break;
}
}
}
}
+ if (!OnlyTemplate) {
+ LV.mergeVisibility(Context.getLangOpts().getVisibilityMode());
+ // If we're paying attention to global visibility, apply
+ // -finline-visibility-hidden if this is an inline method.
+ if (!LV.visibilityExplicit() && useInlineVisibilityHidden(D))
+ LV.mergeVisibility(HiddenVisibility, true);
+ }
+
// C++ [basic.link]p4:
// A name having namespace scope has external linkage if it is the
@@ -325,11 +335,11 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
LinkageInfo TypeLV = getLVForType(Var->getType());
if (TypeLV.linkage() != ExternalLinkage)
return LinkageInfo::uniqueExternal();
- LV.mergeVisibilityWithMin(TypeLV);
+ LV.mergeVisibility(TypeLV);
}
if (Var->getStorageClass() == SC_PrivateExtern)
- LV.setVisibility(HiddenVisibility, true);
+ LV.mergeVisibility(HiddenVisibility, true);
if (!Context.getLangOpts().CPlusPlus &&
(Var->getStorageClass() == SC_Extern ||
@@ -345,7 +355,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
// is visible, or if the prior declaration specifies no
// linkage, then the identifier has external linkage.
if (const VarDecl *PrevVar = Var->getPreviousDecl()) {
- LinkageInfo PrevLV = getLVForDecl(PrevVar, F);
+ LinkageInfo PrevLV = getLVForDecl(PrevVar, OnlyTemplate);
if (PrevLV.linkage()) LV.setLinkage(PrevLV.linkage());
LV.mergeVisibility(PrevLV);
}
@@ -359,7 +369,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
// just too painful to make work.
if (Function->getStorageClass() == SC_PrivateExtern)
- LV.setVisibility(HiddenVisibility, true);
+ LV.mergeVisibility(HiddenVisibility, true);
// C99 6.2.2p5:
// If the declaration of an identifier for a function has no
@@ -380,7 +390,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
// is visible, or if the prior declaration specifies no
// linkage, then the identifier has external linkage.
if (const FunctionDecl *PrevFunc = Function->getPreviousDecl()) {
- LinkageInfo PrevLV = getLVForDecl(PrevFunc, F);
+ LinkageInfo PrevLV = getLVForDecl(PrevFunc, OnlyTemplate);
if (PrevLV.linkage()) LV.setLinkage(PrevLV.linkage());
LV.mergeVisibility(PrevLV);
}
@@ -399,11 +409,16 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
// this is an explicit specialization with a visibility attribute.
if (FunctionTemplateSpecializationInfo *specInfo
= Function->getTemplateSpecializationInfo()) {
- if (shouldConsiderTemplateLV(Function, specInfo)) {
- LV.merge(getLVForDecl(specInfo->getTemplate(),
- LVFlags::CreateOnlyDeclLinkage()));
- const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;
- LV.mergeWithMin(getLVForTemplateArgumentList(templateArgs, F));
+ LinkageInfo TempLV = getLVForDecl(specInfo->getTemplate(), true);
+ const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;
+ LinkageInfo ArgsLV = getLVForTemplateArgumentList(templateArgs,
+ OnlyTemplate);
+ if (shouldConsiderTemplateVis(Function, specInfo)) {
+ LV.mergeWithMin(TempLV);
+ LV.mergeWithMin(ArgsLV);
+ } else {
+ LV.mergeLinkage(TempLV);
+ LV.mergeLinkage(ArgsLV);
}
}
@@ -422,20 +437,26 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
// linkage of the template and template arguments.
if (const ClassTemplateSpecializationDecl *spec
= dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
- if (shouldConsiderTemplateLV(spec)) {
- // From the template.
- LV.merge(getLVForDecl(spec->getSpecializedTemplate(),
- LVFlags::CreateOnlyDeclLinkage()));
-
- // The arguments at which the template was instantiated.
- const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs();
- LV.mergeWithMin(getLVForTemplateArgumentList(TemplateArgs, F));
+ // From the template.
+ LinkageInfo TempLV = getLVForDecl(spec->getSpecializedTemplate(), true);
+
+ // The arguments at which the template was instantiated.
+ const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs();
+ LinkageInfo ArgsLV = getLVForTemplateArgumentList(TemplateArgs,
+ OnlyTemplate);
+ if (shouldConsiderTemplateVis(spec)) {
+ LV.mergeWithMin(TempLV);
+ LV.mergeWithMin(ArgsLV);
+ } else {
+ LV.mergeLinkage(TempLV);
+ LV.mergeLinkage(ArgsLV);
}
}
// - an enumerator belonging to an enumeration with external linkage;
} else if (isa<EnumConstantDecl>(D)) {
- LinkageInfo EnumLV = getLVForDecl(cast<NamedDecl>(D->getDeclContext()), F);
+ LinkageInfo EnumLV = getLVForDecl(cast<NamedDecl>(D->getDeclContext()),
+ OnlyTemplate);
if (!isExternalLinkage(EnumLV.linkage()))
return LinkageInfo::none();
LV.merge(EnumLV);
@@ -443,9 +464,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
// - a template, unless it is a function template that has
// internal linkage (Clause 14);
} else if (const TemplateDecl *temp = dyn_cast<TemplateDecl>(D)) {
- if (F.ConsiderTemplateParameterTypes)
- LV.merge(getLVForTemplateParameterList(temp->getTemplateParameters()));
-
+ LV.merge(getLVForTemplateParameterList(temp->getTemplateParameters()));
// - a namespace (7.3), unless it is declared within an unnamed
// namespace.
} else if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace()) {
@@ -469,7 +488,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
return LV;
}
-static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
+static LinkageInfo getLVForClassMember(const NamedDecl *D, bool OnlyTemplate) {
// 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
@@ -482,53 +501,32 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
return LinkageInfo::none();
LinkageInfo LV;
- LV.mergeVisibility(D->getASTContext().getLangOpts().getVisibilityMode());
- bool DHasExplicitVisibility = false;
// If we have an explicit visibility attribute, merge that in.
- if (F.ConsiderVisibilityAttributes) {
- if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) {
+ if (!OnlyTemplate) {
+ if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility())
LV.mergeVisibility(*Vis, true);
-
- DHasExplicitVisibility = true;
- }
- }
- // Ignore both global visibility and attributes when computing our
- // parent's visibility if we already have an explicit one.
- LVFlags ClassF = DHasExplicitVisibility ?
- LVFlags::CreateOnlyDeclLinkage() : F;
-
- // If we're paying attention to global visibility, apply
- // -finline-visibility-hidden if this is an inline method.
- //
- // Note that we do this before merging information about
- // the class visibility.
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
- TemplateSpecializationKind TSK = TSK_Undeclared;
- if (FunctionTemplateSpecializationInfo *spec
- = MD->getTemplateSpecializationInfo()) {
- TSK = spec->getTemplateSpecializationKind();
- } else if (MemberSpecializationInfo *MSI =
- MD->getMemberSpecializationInfo()) {
- TSK = MSI->getTemplateSpecializationKind();
- }
-
- const FunctionDecl *Def = 0;
- // InlineVisibilityHidden only applies to definitions, and
- // isInlined() only gives meaningful answers on definitions
- // anyway.
- if (TSK != TSK_ExplicitInstantiationDeclaration &&
- TSK != TSK_ExplicitInstantiationDefinition &&
- F.ConsiderGlobalVisibility &&
- !LV.visibilityExplicit() &&
- MD->getASTContext().getLangOpts().InlineVisibilityHidden &&
- MD->hasBody(Def) && Def->isInlined())
+ // If we're paying attention to global visibility, apply
+ // -finline-visibility-hidden if this is an inline method.
+ //
+ // Note that we do this before merging information about
+ // the class visibility.
+ if (!LV.visibilityExplicit() && useInlineVisibilityHidden(D))
LV.mergeVisibility(HiddenVisibility, true);
}
- // Class members only have linkage if their class has external
- // linkage.
- LV.merge(getLVForDecl(cast<RecordDecl>(D->getDeclContext()), ClassF));
+ // If this class member has an explicit visibility attribute, the only
+ // thing that can change its visibility is the template arguments, so
+ // only look for them when processing the class.
+ bool ClassOnlyTemplate = LV.visibilityExplicit() ? true : OnlyTemplate;
+
+ // If this member has an visibility attribute, ClassF will exclude
+ // attributes on the class or command line options, keeping only information
+ // about the template instantiation. If the member has no visibility
+ // attributes, mergeWithMin behaves like merge, so in both cases mergeWithMin
+ // produces the desired result.
+ LV.mergeWithMin(getLVForDecl(cast<RecordDecl>(D->getDeclContext()),
+ ClassOnlyTemplate));
if (!isExternalLinkage(LV.linkage()))
return LinkageInfo::none();
@@ -536,6 +534,9 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
if (LV.linkage() == UniqueExternalLinkage)
return LinkageInfo::uniqueExternal();
+ if (!OnlyTemplate)
+ LV.mergeVisibility(D->getASTContext().getLangOpts().getVisibilityMode());
+
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
// If the type of the function uses a type with unique-external
// linkage, it's not legally usable from outside this translation unit.
@@ -546,12 +547,20 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
// the template parameters and arguments.
if (FunctionTemplateSpecializationInfo *spec
= MD->getTemplateSpecializationInfo()) {
- if (shouldConsiderTemplateLV(MD, spec)) {
- LV.mergeWithMin(getLVForTemplateArgumentList(*spec->TemplateArguments,
- F));
- if (F.ConsiderTemplateParameterTypes)
- LV.merge(getLVForTemplateParameterList(
- spec->getTemplate()->getTemplateParameters()));
+ const TemplateArgumentList &TemplateArgs = *spec->TemplateArguments;
+ LinkageInfo ArgsLV = getLVForTemplateArgumentList(TemplateArgs,
+ OnlyTemplate);
+ TemplateParameterList *TemplateParams =
+ spec->getTemplate()->getTemplateParameters();
+ LinkageInfo ParamsLV = getLVForTemplateParameterList(TemplateParams);
+ if (shouldConsiderTemplateVis(MD, spec)) {
+ LV.mergeWithMin(ArgsLV);
+ if (!OnlyTemplate)
+ LV.mergeWithMin(ParamsLV);
+ } else {
+ LV.mergeLinkage(ArgsLV);
+ if (!OnlyTemplate)
+ LV.mergeLinkage(ParamsLV);
}
}
@@ -561,14 +570,22 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
} else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
if (const ClassTemplateSpecializationDecl *spec
= dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
- if (shouldConsiderTemplateLV(spec)) {
- // Merge template argument/parameter information for member
- // class template specializations.
- LV.mergeWithMin(getLVForTemplateArgumentList(spec->getTemplateArgs(),
- F));
- if (F.ConsiderTemplateParameterTypes)
- LV.merge(getLVForTemplateParameterList(
- spec->getSpecializedTemplate()->getTemplateParameters()));
+ // Merge template argument/parameter information for member
+ // class template specializations.
+ const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs();
+ LinkageInfo ArgsLV = getLVForTemplateArgumentList(TemplateArgs,
+ OnlyTemplate);
+ TemplateParameterList *TemplateParams =
+ spec->getSpecializedTemplate()->getTemplateParameters();
+ LinkageInfo ParamsLV = getLVForTemplateParameterList(TemplateParams);
+ if (shouldConsiderTemplateVis(spec)) {
+ LV.mergeWithMin(ArgsLV);
+ if (!OnlyTemplate)
+ LV.mergeWithMin(ParamsLV);
+ } else {
+ LV.mergeLinkage(ArgsLV);
+ if (!OnlyTemplate)
+ LV.mergeLinkage(ParamsLV);
}
}
@@ -579,8 +596,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
LinkageInfo TypeLV = getLVForType(VD->getType());
if (TypeLV.linkage() != ExternalLinkage)
LV.mergeLinkage(UniqueExternalLinkage);
- if (!LV.visibilityExplicit())
- LV.mergeVisibility(TypeLV);
+ LV.mergeVisibility(TypeLV);
}
return LV;
@@ -636,18 +652,17 @@ void NamedDecl::ClearLinkageCache() {
Linkage NamedDecl::getLinkage() const {
if (HasCachedLinkage) {
assert(Linkage(CachedLinkage) ==
- getLVForDecl(this, LVFlags::CreateOnlyDeclLinkage()).linkage());
+ getLVForDecl(this, true).linkage());
return Linkage(CachedLinkage);
}
- CachedLinkage = getLVForDecl(this,
- LVFlags::CreateOnlyDeclLinkage()).linkage();
+ CachedLinkage = getLVForDecl(this, true).linkage();
HasCachedLinkage = 1;
return Linkage(CachedLinkage);
}
LinkageInfo NamedDecl::getLinkageAndVisibility() const {
- LinkageInfo LI = getLVForDecl(this, LVFlags());
+ LinkageInfo LI = getLVForDecl(this, false);
assert(!HasCachedLinkage || Linkage(CachedLinkage) == LI.linkage());
HasCachedLinkage = 1;
CachedLinkage = LI.linkage();
@@ -656,9 +671,19 @@ LinkageInfo NamedDecl::getLinkageAndVisibility() const {
llvm::Optional<Visibility> NamedDecl::getExplicitVisibility() const {
// Use the most recent declaration of a variable.
- if (const VarDecl *var = dyn_cast<VarDecl>(this))
- return getVisibilityOf(var->getMostRecentDecl());
+ if (const VarDecl *Var = dyn_cast<VarDecl>(this)) {
+ if (llvm::Optional<Visibility> V =
+ getVisibilityOf(Var->getMostRecentDecl()))
+ return V;
+
+ if (Var->isStaticDataMember()) {
+ VarDecl *InstantiatedFrom = Var->getInstantiatedFromStaticDataMember();
+ if (InstantiatedFrom)
+ return getVisibilityOf(InstantiatedFrom);
+ }
+ return llvm::Optional<Visibility>();
+ }
// Use the most recent declaration of a function, and also handle
// function template specializations.
if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(this)) {
@@ -685,6 +710,10 @@ llvm::Optional<Visibility> NamedDecl::getExplicitVisibility() const {
if (llvm::Optional<Visibility> V = getVisibilityOf(this))
return V;
+ // The visibility of a template is stored in the templated decl.
+ if (const TemplateDecl *TD = dyn_cast<TemplateDecl>(this))
+ return getVisibilityOf(TD->getTemplatedDecl());
+
// If there wasn't explicit visibility there, and this is a
// specialization of a class template, check for visibility
// on the pattern.
@@ -703,7 +732,7 @@ llvm::Optional<Visibility> NamedDecl::getExplicitVisibility() const {
return llvm::Optional<Visibility>();
}
-static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
+static LinkageInfo getLVForDecl(const NamedDecl *D, bool OnlyTemplate) {
// Objective-C: treat all Objective-C declarations as having external
// linkage.
switch (D->getKind()) {
@@ -738,11 +767,12 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
if (isa<ParmVarDecl>(ContextDecl))
DC = ContextDecl->getDeclContext()->getRedeclContext();
else
- return getLVForDecl(cast<NamedDecl>(ContextDecl), Flags);
+ return getLVForDecl(cast<NamedDecl>(ContextDecl),
+ OnlyTemplate);
}
if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC))
- return getLVForDecl(ND, Flags);
+ return getLVForDecl(ND, OnlyTemplate);
return LinkageInfo::external();
}
@@ -753,7 +783,7 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
// Handle linkage for namespace-scope names.
if (D->getDeclContext()->getRedeclContext()->isFileContext())
- return getLVForNamespaceScopeDecl(D, Flags);
+ return getLVForNamespaceScopeDecl(D, OnlyTemplate);
// C++ [basic.link]p5:
// In addition, a member function, static data member, a named
@@ -763,7 +793,7 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
// purposes (7.1.3), has external linkage if the name of the class
// has external linkage.
if (D->getDeclContext()->isRecord())
- return getLVForClassMember(D, Flags);
+ return getLVForClassMember(D, OnlyTemplate);
// C++ [basic.link]p6:
// The name of a function declared in block scope and the name of
@@ -783,13 +813,13 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
return LinkageInfo::uniqueExternal();
LinkageInfo LV;
- if (Flags.ConsiderVisibilityAttributes) {
+ if (!OnlyTemplate) {
if (llvm::Optional<Visibility> Vis = Function->getExplicitVisibility())
- LV.setVisibility(*Vis, true);
+ LV.mergeVisibility(*Vis, true);
}
if (const FunctionDecl *Prev = Function->getPreviousDecl()) {
- LinkageInfo PrevLV = getLVForDecl(Prev, Flags);
+ LinkageInfo PrevLV = getLVForDecl(Prev, OnlyTemplate);
if (PrevLV.linkage()) LV.setLinkage(PrevLV.linkage());
LV.mergeVisibility(PrevLV);
}
@@ -806,14 +836,14 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
LinkageInfo LV;
if (Var->getStorageClass() == SC_PrivateExtern)
- LV.setVisibility(HiddenVisibility, true);
- else if (Flags.ConsiderVisibilityAttributes) {
+ LV.mergeVisibility(HiddenVisibility, true);
+ else if (!OnlyTemplate) {
if (llvm::Optional<Visibility> Vis = Var->getExplicitVisibility())
- LV.setVisibility(*Vis, true);
+ LV.mergeVisibility(*Vis, true);
}
if (const VarDecl *Prev = Var->getPreviousDecl()) {
- LinkageInfo PrevLV = getLVForDecl(Prev, Flags);
+ LinkageInfo PrevLV = getLVForDecl(Prev, OnlyTemplate);
if (PrevLV.linkage()) LV.setLinkage(PrevLV.linkage());
LV.mergeVisibility(PrevLV);
}
@@ -881,9 +911,7 @@ std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
for (unsigned i = 0; i < NumParams; ++i) {
if (i)
OS << ", ";
- std::string Param;
- FD->getParamDecl(i)->getType().getAsStringInternal(Param, P);
- OS << Param;
+ OS << FD->getParamDecl(i)->getType().stream(P);
}
if (FT->isVariadic()) {
@@ -1672,6 +1700,13 @@ void FunctionDecl::setPure(bool P) {
Parent->markedVirtualFunctionPure();
}
+void FunctionDecl::setConstexpr(bool IC) {
+ IsConstexpr = IC;
+ CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(this);
+ if (IC && CD)
+ CD->getParent()->markedConstructorConstexpr(CD);
+}
+
bool FunctionDecl::isMain() const {
const TranslationUnitDecl *tunit =
dyn_cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext());
@@ -2446,15 +2481,15 @@ FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
- bool HasInit) {
+ InClassInitStyle InitStyle) {
return new (C) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
- BW, Mutable, HasInit);
+ BW, Mutable, InitStyle);
}
FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FieldDecl));
return new (Mem) FieldDecl(Field, 0, SourceLocation(), SourceLocation(),
- 0, QualType(), 0, 0, false, false);
+ 0, QualType(), 0, 0, false, ICIS_NoInit);
}
bool FieldDecl::isAnonymousStructOrUnion() const {
@@ -2483,15 +2518,15 @@ unsigned FieldDecl::getFieldIndex() const {
for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
I != E; ++I, ++Index) {
- (*I)->CachedFieldIndex = Index + 1;
+ I->CachedFieldIndex = Index + 1;
if (IsMsStruct) {
// Zero-length bitfields following non-bitfield members are ignored.
- if (getASTContext().ZeroBitfieldFollowsNonBitfield((*I), LastFD)) {
+ if (getASTContext().ZeroBitfieldFollowsNonBitfield(*I, LastFD)) {
--Index;
continue;
}
- LastFD = (*I);
+ LastFD = *I;
}
}
@@ -2505,11 +2540,16 @@ SourceRange FieldDecl::getSourceRange() const {
return DeclaratorDecl::getSourceRange();
}
+void FieldDecl::setBitWidth(Expr *Width) {
+ assert(!InitializerOrBitWidth.getPointer() && !hasInClassInitializer() &&
+ "bit width or initializer already set");
+ InitializerOrBitWidth.setPointer(Width);
+}
+
void FieldDecl::setInClassInitializer(Expr *Init) {
- assert(!InitializerOrBitWidth.getPointer() &&
+ assert(!InitializerOrBitWidth.getPointer() && hasInClassInitializer() &&
"bit width or initializer already set");
InitializerOrBitWidth.setPointer(Init);
- InitializerOrBitWidth.setInt(0);
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud