diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 34 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 22 |
3 files changed, 38 insertions, 24 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 0f6e8b09706..8c50af615cd 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -635,6 +635,8 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, if (D->isInAnonymousNamespace()) { const auto *Var = dyn_cast<VarDecl>(D); const auto *Func = dyn_cast<FunctionDecl>(D); + // FIXME: In C++11 onwards, anonymous namespaces should give decls + // within them internal linkage, not unique external linkage. if ((!Var || !isFirstInExternCContext(Var)) && (!Func || !isFirstInExternCContext(Func))) return LinkageInfo::uniqueExternal(); @@ -821,10 +823,14 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, } else if (isa<ObjCInterfaceDecl>(D)) { // fallout + } else if (auto *TD = dyn_cast<TypedefNameDecl>(D)) { + // A typedef declaration has linkage if it gives a type a name for + // linkage purposes. + if (!TD->getAnonDeclWithTypedefName(/*AnyRedecl*/true)) + return LinkageInfo::none(); + // Everything not covered here has no linkage. } else { - // FIXME: A typedef declaration has linkage if it gives a type a name for - // linkage purposes. return LinkageInfo::none(); } @@ -1226,8 +1232,32 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D, switch (D->getKind()) { default: break; + + // Per C++ [basic.link]p2, only the names of objects, references, + // functions, types, templates, namespaces, and values ever have linkage. + // + // Note that the name of a typedef, namespace alias, using declaration, + // and so on are not the name of the corresponding type, namespace, or + // declaration, so they do *not* have linkage. + case Decl::EnumConstant: // FIXME: This has linkage, but that's dumb. + case Decl::ImplicitParam: + case Decl::Label: + case Decl::NamespaceAlias: case Decl::ParmVar: + case Decl::Using: + case Decl::UsingShadow: + case Decl::UsingDirective: return LinkageInfo::none(); + + case Decl::Typedef: + case Decl::TypeAlias: + // A typedef declaration has linkage if it gives a type a name for + // linkage purposes. + if (!cast<TypedefNameDecl>(D) + ->getAnonDeclWithTypedefName(/*AnyRedecl*/true)) + return LinkageInfo::none(); + break; + case Decl::TemplateTemplateParm: // count these as external case Decl::NonTypeTemplateParm: case Decl::ObjCAtDefsField: diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 728697e78f5..a23d9debb86 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4819,12 +4819,6 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, LookupResult Previous(*this, NameInfo, LookupOrdinaryName, ForRedeclaration); - // If we're hiding internal-linkage symbols in modules from redeclaration - // lookup, let name lookup know. - if ((getLangOpts().Modules || getLangOpts().ModulesLocalVisibility) && - D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef) - Previous.setAllowHiddenInternal(false); - // See if this is a redefinition of a variable in the same scope. if (!D.getCXXScopeSpec().isSet()) { bool IsLinkageLookup = false; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 74bffb2a044..910ebcf05dd 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7206,23 +7206,13 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope, // treated as an original-namespace-name. // // Since namespace names are unique in their scope, and we don't - // look through using directives, just look for any ordinary names. - - const unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Member | - Decl::IDNS_Type | Decl::IDNS_Using | Decl::IDNS_Tag | - Decl::IDNS_Namespace; - NamedDecl *PrevDecl = nullptr; - DeclContext::lookup_result R = CurContext->getRedeclContext()->lookup(II); - for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; - ++I) { - if ((*I)->getIdentifierNamespace() & IDNS) { - PrevDecl = *I; - break; - } - } - + // look through using directives, just look for any ordinary names + // as if by qualified name lookup. + LookupResult R(*this, II, IdentLoc, LookupOrdinaryName, ForRedeclaration); + LookupQualifiedName(R, CurContext->getRedeclContext()); + NamedDecl *PrevDecl = R.getAsSingle<NamedDecl>(); PrevNS = dyn_cast_or_null<NamespaceDecl>(PrevDecl); - + if (PrevNS) { // This is an extended namespace definition. if (IsInline != PrevNS->isInline()) |