Index: cfe/trunk/include/clang/Frontend/CodeGenOptions.def =================================================================== --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def @@ -166,6 +166,10 @@ 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, Index: cfe/trunk/include/clang/Parse/Parser.h =================================================================== --- cfe/trunk/include/clang/Parse/Parser.h +++ cfe/trunk/include/clang/Parse/Parser.h @@ -2337,8 +2337,8 @@ 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, Index: cfe/trunk/include/clang/Sema/Sema.h =================================================================== --- cfe/trunk/include/clang/Sema/Sema.h +++ cfe/trunk/include/clang/Sema/Sema.h @@ -4093,7 +4093,8 @@ SourceLocation IdentLoc, IdentifierInfo *Ident, SourceLocation LBrace, - AttributeList *AttrList); + AttributeList *AttrList, + UsingDirectiveDecl * &UsingDecl); void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace); NamespaceDecl *getStdNamespace() const; Index: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp @@ -3408,10 +3408,14 @@ 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) { Index: cfe/trunk/lib/Frontend/CompilerInvocation.cpp =================================================================== --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp @@ -365,6 +365,7 @@ 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 @@ 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('=')); Index: cfe/trunk/lib/Parse/ParseDecl.cpp =================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp +++ cfe/trunk/lib/Parse/ParseDecl.cpp @@ -1465,15 +1465,13 @@ 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); Index: cfe/trunk/lib/Parse/ParseDeclCXX.cpp =================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp @@ -55,9 +55,9 @@ /// 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 @@ if (Tok.is(tok::code_completion)) { Actions.CodeCompleteNamespaceDecl(getCurScope()); cutOffParsing(); - return nullptr; + return DeclGroupPtrTy();; } SourceLocation IdentLoc; @@ -109,15 +109,16 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ // 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()); } Index: cfe/trunk/lib/Sema/SemaDeclCXX.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp @@ -7185,7 +7185,8 @@ 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 @@ // 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); } Index: cfe/trunk/test/CodeGenCXX/debug-info-anon-namespace.cpp =================================================================== --- cfe/trunk/test/CodeGenCXX/debug-info-anon-namespace.cpp +++ cfe/trunk/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 +