diff options
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 81 |
1 files changed, 30 insertions, 51 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 64010666299..e8201fc4ea2 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -610,18 +610,6 @@ static LinkageInfo getExternalLinkageFor(const NamedDecl *D) { return LinkageInfo::external(); } -static StorageClass getStorageClass(const Decl *D) { - if (auto *TD = dyn_cast<TemplateDecl>(D)) - D = TD->getTemplatedDecl(); - if (D) { - if (auto *VD = dyn_cast<VarDecl>(D)) - return VD->getStorageClass(); - if (auto *FD = dyn_cast<FunctionDecl>(D)) - return FD->getStorageClass(); - } - return SC_None; -} - LinkageInfo LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, LVComputationKind computation, @@ -633,28 +621,24 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, // C++ [basic.link]p3: // A name having namespace scope (3.3.6) has internal linkage if it // is the name of - - if (getStorageClass(D->getCanonicalDecl()) == SC_Static) { - // - a variable, variable template, function, or function template - // that is explicitly declared static; or - // (This bullet corresponds to C99 6.2.2p3.) - return getInternalLinkageFor(D); - } - + // - an object, reference, function or function template that is + // explicitly declared static; or, + // (This bullet corresponds to C99 6.2.2p3.) if (const auto *Var = dyn_cast<VarDecl>(D)) { - // - a non-template variable of non-volatile const-qualified type, unless - // - it is explicitly declared extern, or - // - it is inline or exported, or - // - it was previously declared and the prior declaration did not have - // internal linkage - // (There is no equivalent in C99.) + // Explicitly declared static. + if (Var->getStorageClass() == SC_Static) + return getInternalLinkageFor(Var); + + // - a non-inline, non-volatile object or reference that is explicitly + // declared const or constexpr and neither explicitly declared extern + // nor previously declared to have external linkage; or (there is no + // equivalent in C99) + // The C++ modules TS adds "non-exported" to this list. if (Context.getLangOpts().CPlusPlus && Var->getType().isConstQualified() && !Var->getType().isVolatileQualified() && !Var->isInline() && - !isExportedFromModuleInterfaceUnit(Var) && - !isa<VarTemplateSpecializationDecl>(Var) && - !Var->getDescribedVarTemplate()) { + !isExportedFromModuleInterfaceUnit(Var)) { const VarDecl *PrevVar = Var->getPreviousDecl(); if (PrevVar) return getLVForDecl(PrevVar, computation); @@ -674,6 +658,14 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, if (PrevVar->getStorageClass() == SC_Static) return getInternalLinkageFor(Var); } + } else if (const FunctionDecl *Function = D->getAsFunction()) { + // C++ [temp]p4: + // A non-member function template can have internal linkage; any + // other template name shall have external linkage. + + // Explicitly declared static. + if (Function->getCanonicalDecl()->getStorageClass() == SC_Static) + return getInternalLinkageFor(Function); } else if (const auto *IFD = dyn_cast<IndirectFieldDecl>(D)) { // - a data member of an anonymous union. const VarDecl *VD = IFD->getVarDecl(); @@ -682,8 +674,6 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, } assert(!isa<FieldDecl>(D) && "Didn't expect a FieldDecl!"); - // FIXME: This gives internal linkage to names that should have no linkage - // (those not covered by [basic.link]p6). if (D->isInAnonymousNamespace()) { const auto *Var = dyn_cast<VarDecl>(D); const auto *Func = dyn_cast<FunctionDecl>(D); @@ -743,20 +733,10 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, // C++ [basic.link]p4: - // A name having namespace scope that has not been given internal linkage - // above and that is the name of - // [...bullets...] - // has its linkage determined as follows: - // - if the enclosing namespace has internal linkage, the name has - // internal linkage; [handled above] - // - otherwise, if the declaration of the name is attached to a named - // module and is not exported, the name has module linkage; - // - otherwise, the name has external linkage. - // LV is currently set up to handle the last two bullets. + // A name having namespace scope has external linkage if it is the + // name of // - // The bullets are: - - // - a variable; or + // - an object or reference, unless it has internal linkage; or if (const auto *Var = dyn_cast<VarDecl>(D)) { // GCC applies the following optimization to variables and static // data members, but not to functions: @@ -802,7 +782,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, mergeTemplateLV(LV, spec, computation); } - // - a function; or + // - a function, unless it has internal linkage; or } else if (const auto *Function = dyn_cast<FunctionDecl>(D)) { // In theory, we can modify the function's LV by the LV of its // type unless it has C linkage (see comment above about variables @@ -856,8 +836,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, mergeTemplateLV(LV, spec, computation); } - // FIXME: This is not part of the C++ standard any more. - // - an enumerator belonging to an enumeration with external linkage; or + // - an enumerator belonging to an enumeration with external linkage; } else if (isa<EnumConstantDecl>(D)) { LinkageInfo EnumLV = getLVForDecl(cast<NamedDecl>(D->getDeclContext()), computation); @@ -865,16 +844,16 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, return LinkageInfo::none(); LV.merge(EnumLV); - // - a template + // - a template, unless it is a function template that has + // internal linkage (Clause 14); } else if (const auto *temp = dyn_cast<TemplateDecl>(D)) { bool considerVisibility = !hasExplicitVisibilityAlready(computation); LinkageInfo tempLV = getLVForTemplateParameterList(temp->getTemplateParameters(), computation); LV.mergeMaybeWithVisibility(tempLV, considerVisibility); - // An unnamed namespace or a namespace declared directly or indirectly - // within an unnamed namespace has internal linkage. All other namespaces - // have external linkage. + // - a namespace (7.3), unless it is declared within an unnamed + // namespace. // // We handled names in anonymous namespaces above. } else if (isa<NamespaceDecl>(D)) { |