diff options
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r-- | lib/AST/Decl.cpp | 346 |
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); } //===----------------------------------------------------------------------===// |