From: Ekaterina Romanova Date: Thu, 10 Dec 2015 18:52:50 +0000 (+0000) Subject: Do not generate DW_TAG_imported_module for anonymous namespaces (even nested) for... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=34a3e1fd8ec31d535cf6967d9769546403ab75d7;p=clang Do not generate DW_TAG_imported_module for anonymous namespaces (even nested) for all the platforms except PS4. For PS4, generate explicit import for anonymous namespaces and mark it by DW_AT_artificial attribute. Differential Revision: http://reviews.llvm.org/D12624 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@255281 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index 5b8483ca9c..c08d95930f 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -166,6 +166,10 @@ CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information CODEGENOPT(DebugTypeExtRefs, 1, 0) ///< Whether or not debug info should contain ///< external references to a PCH or module. +CODEGENOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should + ///< contain explicit imports for + ///< anonymous namespaces + CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists. /// The user specified number of registers to be used for integral arguments, diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 67a3b7de54..ccbfb87944 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -2337,8 +2337,8 @@ private: void DiagnoseUnexpectedNamespace(NamedDecl *Context); - Decl *ParseNamespace(unsigned Context, SourceLocation &DeclEnd, - SourceLocation InlineLoc = SourceLocation()); + DeclGroupPtrTy ParseNamespace(unsigned Context, SourceLocation &DeclEnd, + SourceLocation InlineLoc = SourceLocation()); void ParseInnerNamespace(std::vector& IdentLoc, std::vector& Ident, std::vector& NamespaceLoc, diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index ddf5376527..44fd99cf95 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -4093,7 +4093,8 @@ public: SourceLocation IdentLoc, IdentifierInfo *Ident, SourceLocation LBrace, - AttributeList *AttrList); + AttributeList *AttrList, + UsingDirectiveDecl * &UsingDecl); void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace); NamespaceDecl *getStdNamespace() const; diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index ff6388bd1a..29ebfc6238 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -3408,10 +3408,14 @@ llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(const Decl *D) { void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) { if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) return; - DBuilder.createImportedModule( - getCurrentContextDescriptor(cast(UD.getDeclContext())), - getOrCreateNameSpace(UD.getNominatedNamespace()), - getLineNumber(UD.getLocation())); + const NamespaceDecl *NSDecl = UD.getNominatedNamespace(); + if (!NSDecl->isAnonymousNamespace() || + CGM.getCodeGenOpts().DebugExplicitImport) { + DBuilder.createImportedModule( + getCurrentContextDescriptor(cast(UD.getDeclContext())), + getOrCreateNameSpace(NSDecl), + getLineNumber(UD.getLocation())); + } } void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) { diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 4dd1d20c91..4dc0cf9386 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -365,6 +365,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, const TargetOptions &TargetOpts) { using namespace options; bool Success = true; + llvm::Triple Triple = llvm::Triple(TargetOpts.Triple); unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags); // TODO: This could be done in Driver @@ -409,6 +410,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.EmitCodeView = Args.hasArg(OPT_gcodeview); Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file); Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs); + if (Triple.isPS4CPU()) + Opts.DebugExplicitImport = true; for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) Opts.DebugPrefixMap.insert(StringRef(Arg).split('=')); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 817970dd07..4039f2ac2a 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1465,15 +1465,13 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context, if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) { ProhibitAttributes(attrs); SourceLocation InlineLoc = ConsumeToken(); - SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc); - break; + return ParseNamespace(Context, DeclEnd, InlineLoc); } return ParseSimpleDeclaration(Context, DeclEnd, attrs, true); case tok::kw_namespace: ProhibitAttributes(attrs); - SingleDecl = ParseNamespace(Context, DeclEnd); - break; + return ParseNamespace(Context, DeclEnd); case tok::kw_using: SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(), DeclEnd, attrs, &OwnedType); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 378cebe67d..b71ce20c34 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -55,9 +55,9 @@ using namespace clang; /// namespace-alias-definition: [C++ 7.3.2: namespace.alias] /// 'namespace' identifier '=' qualified-namespace-specifier ';' /// -Decl *Parser::ParseNamespace(unsigned Context, - SourceLocation &DeclEnd, - SourceLocation InlineLoc) { +Parser::DeclGroupPtrTy Parser::ParseNamespace(unsigned Context, + SourceLocation &DeclEnd, + SourceLocation InlineLoc) { assert(Tok.is(tok::kw_namespace) && "Not a namespace!"); SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'. ObjCDeclContextSwitch ObjCDC(*this); @@ -65,7 +65,7 @@ Decl *Parser::ParseNamespace(unsigned Context, if (Tok.is(tok::code_completion)) { Actions.CodeCompleteNamespaceDecl(getCurScope()); cutOffParsing(); - return nullptr; + return DeclGroupPtrTy();; } SourceLocation IdentLoc; @@ -109,15 +109,16 @@ Decl *Parser::ParseNamespace(unsigned Context, Diag(Tok, diag::err_expected) << tok::identifier; // Skip to end of the definition and eat the ';'. SkipUntil(tok::semi); - return nullptr; + return DeclGroupPtrTy(); } if (attrLoc.isValid()) Diag(attrLoc, diag::err_unexpected_namespace_attributes_alias); if (InlineLoc.isValid()) Diag(InlineLoc, diag::err_inline_namespace_alias) << FixItHint::CreateRemoval(InlineLoc); - return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd); - } + Decl *NSAlias = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd); + return Actions.ConvertDeclToDeclGroup(NSAlias); +} BalancedDelimiterTracker T(*this, tok::l_brace); if (T.consumeOpen()) { @@ -125,7 +126,7 @@ Decl *Parser::ParseNamespace(unsigned Context, Diag(Tok, diag::err_expected) << tok::l_brace; else Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace; - return nullptr; + return DeclGroupPtrTy(); } if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() || @@ -133,7 +134,7 @@ Decl *Parser::ParseNamespace(unsigned Context, getCurScope()->getFnParent()) { Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope); SkipUntil(tok::r_brace); - return nullptr; + return DeclGroupPtrTy(); } if (ExtraIdent.empty()) { @@ -180,10 +181,11 @@ Decl *Parser::ParseNamespace(unsigned Context, // Enter a scope for the namespace. ParseScope NamespaceScope(this, Scope::DeclScope); + UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr; Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident, T.getOpenLocation(), - attrs.getList()); + attrs.getList(), ImplicitUsingDirectiveDecl); PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc, "parsing namespace"); @@ -198,8 +200,9 @@ Decl *Parser::ParseNamespace(unsigned Context, DeclEnd = T.getCloseLocation(); Actions.ActOnFinishNamespaceDef(NamespcDecl, DeclEnd); - - return NamespcDecl; + + return Actions.ConvertDeclToDeclGroup(NamespcDecl, + ImplicitUsingDirectiveDecl); } /// ParseInnerNamespace - Parse the contents of a namespace. @@ -229,17 +232,19 @@ void Parser::ParseInnerNamespace(std::vector &IdentLoc, // FIXME: Preserve the source information through to the AST rather than // desugaring it here. ParseScope NamespaceScope(this, Scope::DeclScope); + UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr; Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(), NamespaceLoc[index], IdentLoc[index], Ident[index], Tracker.getOpenLocation(), - attrs.getList()); + attrs.getList(), ImplicitUsingDirectiveDecl); + assert(!ImplicitUsingDirectiveDecl && + "nested namespace definition cannot define anonymous namespace"); ParseInnerNamespace(IdentLoc, Ident, NamespaceLoc, ++index, InlineLoc, attrs, Tracker); NamespaceScope.Exit(); - Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation()); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 3745641eb0..3054088bd6 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -7185,7 +7185,8 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope, SourceLocation IdentLoc, IdentifierInfo *II, SourceLocation LBrace, - AttributeList *AttrList) { + AttributeList *AttrList, + UsingDirectiveDecl *&UD) { SourceLocation StartLoc = InlineLoc.isValid() ? InlineLoc : NamespaceLoc; // For anonymous namespace, take the location of the left brace. SourceLocation Loc = II ? IdentLoc : LBrace; @@ -7299,14 +7300,13 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope, // namespace internal linkage. if (!PrevNS) { - UsingDirectiveDecl* UD - = UsingDirectiveDecl::Create(Context, Parent, - /* 'using' */ LBrace, - /* 'namespace' */ SourceLocation(), - /* qualifier */ NestedNameSpecifierLoc(), - /* identifier */ SourceLocation(), - Namespc, - /* Ancestor */ Parent); + UD = UsingDirectiveDecl::Create(Context, Parent, + /* 'using' */ LBrace, + /* 'namespace' */ SourceLocation(), + /* qualifier */ NestedNameSpecifierLoc(), + /* identifier */ SourceLocation(), + Namespc, + /* Ancestor */ Parent); UD->setImplicit(); Parent->addDecl(UD); } diff --git a/test/CodeGenCXX/debug-info-anon-namespace.cpp b/test/CodeGenCXX/debug-info-anon-namespace.cpp new file mode 100644 index 0000000000..4e3e08af2b --- /dev/null +++ b/test/CodeGenCXX/debug-info-anon-namespace.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-scei-ps4 -O0 %s -o - | FileCheck --check-prefix=PS4 %s +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-unknown-linux-gnu -O0 %s -o - | FileCheck --check-prefix=NON-PS4 %s + +namespace +{ + int a = 5; +} +int *b = &a; + +namespace +{ + namespace { + int a1 = 5; + } + int a2 = 7; +} +int *b1 = &a1; +int *b2 = &a2; + + +// PS4: [[NS:![0-9]+]] = !DINamespace +// PS4: [[NS2:![0-9]+]] = !DINamespace +// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: [[NS]]) +// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[NS]], entity: [[NS2]], line: {{[0-9]+}}) +// NON-PS4-NOT: !DIImportedEntity +