diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 11 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/Mangle.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 33 |
4 files changed, 62 insertions, 5 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 5f639d807dc..224bf877ad2 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -157,6 +157,17 @@ void Decl::setLexicalDeclContext(DeclContext *DC) { } } +bool Decl::isInAnonymousNamespace() const { + const DeclContext *DC = getDeclContext(); + do { + if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC)) + if (ND->isAnonymousNamespace()) + return true; + } while ((DC = DC->getParent())); + + return false; +} + TranslationUnitDecl *Decl::getTranslationUnitDecl() { if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this)) return TUD; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index bc8cc2652d9..f93c6048a74 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -247,6 +247,11 @@ void CodeGenModule::EmitAnnotations() { static CodeGenModule::GVALinkage GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD, const LangOptions &Features) { + // Everything located semantically within an anonymous namespace is + // always internal. + if (FD->isInAnonymousNamespace()) + return CodeGenModule::GVA_Internal; + // The kind of external linkage this function will have, if it is not // inline or static. CodeGenModule::GVALinkage External = CodeGenModule::GVA_StrongExternal; @@ -1000,7 +1005,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { GV->setAlignment(getContext().getDeclAlignInBytes(D)); // Set the llvm linkage type as appropriate. - if (D->getStorageClass() == VarDecl::Static) + if (D->isInAnonymousNamespace()) + GV->setLinkage(llvm::Function::InternalLinkage); + else if (D->getStorageClass() == VarDecl::Static) GV->setLinkage(llvm::Function::InternalLinkage); else if (D->hasAttr<DLLImportAttr>()) GV->setLinkage(llvm::Function::DLLImportLinkage); diff --git a/clang/lib/CodeGen/Mangle.cpp b/clang/lib/CodeGen/Mangle.cpp index 61555ad19db..7555ae5da46 100644 --- a/clang/lib/CodeGen/Mangle.cpp +++ b/clang/lib/CodeGen/Mangle.cpp @@ -254,7 +254,8 @@ static bool isStdNamespace(const DeclContext *DC) { return false; const NamespaceDecl *NS = cast<NamespaceDecl>(DC); - return NS->getOriginalNamespace()->getIdentifier()->isStr("std"); + const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier(); + return II && II->isStr("std"); } static const TemplateDecl * @@ -403,6 +404,14 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) { DeclarationName Name = ND->getDeclName(); switch (Name.getNameKind()) { case DeclarationName::Identifier: + if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) + if (NS->isAnonymousNamespace()) { + // This is how gcc mangles these names. It's apparently + // always '1', no matter how many different anonymous + // namespaces appear in a context. + Out << "12_GLOBAL__N_1"; + break; + } mangleSourceName(Name.getAsIdentifierInfo()); break; @@ -1204,8 +1213,7 @@ static bool isCharSpecialization(QualType T, const char *Name) { bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) { // <substitution> ::= St # ::std:: if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) { - if (NS->getParent()->isTranslationUnit() && - NS->getOriginalNamespace()->getIdentifier()->isStr("std")) { + if (isStdNamespace(NS)) { Out << "St"; return true; } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 1966aebca2d..23a6b58a9c3 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2397,7 +2397,38 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope, PushOnScopeChains(Namespc, DeclRegionScope); } else { - // FIXME: Handle anonymous namespaces + // Anonymous namespaces. + + // C++ [namespace.unnamed]p1. An unnamed-namespace-definition + // behaves as if it were replaced by + // namespace unique { /* empty body */ } + // using namespace unique; + // namespace unique { namespace-body } + // where all occurrences of 'unique' in a translation unit are + // replaced by the same identifier and this identifier differs + // from all other identifiers in the entire program. + + // We just create the namespace with an empty name and then add an + // implicit using declaration, just like the standard suggests. + // + // CodeGen enforces the "universally unique" aspect by giving all + // declarations semantically contained within an anonymous + // namespace internal linkage. + + assert(Namespc->isAnonymousNamespace()); + CurContext->addDecl(Namespc); + + UsingDirectiveDecl* UD + = UsingDirectiveDecl::Create(Context, CurContext, + /* 'using' */ LBrace, + /* 'namespace' */ SourceLocation(), + /* qualifier */ SourceRange(), + /* NNS */ NULL, + /* identifier */ SourceLocation(), + Namespc, + /* Ancestor */ CurContext); + UD->setImplicit(); + CurContext->addDecl(UD); } // Although we could have an invalid decl (i.e. the namespace name is a |