From: Hans Wennborg Date: Tue, 23 Feb 2016 19:10:16 +0000 (+0000) Subject: Revert r261634 "Supporting all entities declared in lexical scope in LLVM debug info... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=70fc52567911cd418d5677f093808628313a869d;p=clang Revert r261634 "Supporting all entities declared in lexical scope in LLVM debug info." and r261657 r261634 and r261633 seems to have caused PR26715. r261657 depends on the former two. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@261670 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index a0fff814e4..52bd805b81 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -831,18 +831,15 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { - TypedefNameDecl *TD = Ty->getDecl(); // We don't set size information, but do specify where the typedef was // declared. - SourceLocation Loc = TD->getLocation(); - - llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0)); + SourceLocation Loc = Ty->getDecl()->getLocation(); // Typedefs are derived from some other type. return DBuilder.createTypedef( getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit), Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), - TDContext); + getDeclContextDescriptor(Ty->getDecl())); } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, @@ -1475,23 +1472,6 @@ llvm::DIType *CGDebugInfo::getOrCreateStandaloneType(QualType D, return T; } -void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { - assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && - "D is already mapped to lexical block scope"); - if (!LexicalBlockStack.empty()) - LexicalBlockMap[&D] = LexicalBlockStack.back(); -} - -llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D, - QualType Ty) { - auto I = LexicalBlockMap.find(&D); - if (I != LexicalBlockMap.end()) { - RetainedTypes.push_back(Ty.getAsOpaquePtr()); - return I->second; - } - return getDeclContextDescriptor(cast(&D)); -} - void CGDebugInfo::completeType(const EnumDecl *ED) { if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; @@ -2071,22 +2051,24 @@ llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) { // If this is just a forward declaration, construct an appropriately // marked node and just return it. if (isImportedFromModule || !ED->getDefinition()) { - // Note that it is possible for enums to be created as part of - // their own declcontext. In this case a FwdDecl will be created - // twice. This doesn't cause a problem because both FwdDecls are - // entered into the ReplaceMap: finalize() will replace the first - // FwdDecl with the second and then replace the second with - // complete type. - llvm::DIScope *EDContext = getDeclContextDescriptor(ED); llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); + + // It is possible for enums to be created as part of their own + // declcontext. We need to cache a placeholder to avoid the type being + // created twice before hitting the cache. llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType( llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0)); unsigned Line = getLineNumber(ED->getLocation()); StringRef EDName = ED->getName(); llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType( - llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line, - 0, Size, Align, llvm::DINode::FlagFwdDecl, FullName); + llvm::dwarf::DW_TAG_enumeration_type, EDName, TmpContext.get(), DefUnit, + Line, 0, Size, Align, llvm::DINode::FlagFwdDecl, FullName); + + // Cache the enum type so it is available when building the declcontext + // and replace the declcontect with the real thing. + TypeCache[Ty].reset(RetTy); + TmpContext->replaceAllUsesWith(getDeclContextDescriptor(ED)); ReplaceMap.emplace_back( std::piecewise_construct, std::make_tuple(Ty), @@ -2121,7 +2103,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) { llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); unsigned Line = getLineNumber(ED->getLocation()); - llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); + llvm::DIScope *EnumContext = getDeclContextDescriptor(ED); llvm::DIType *ClassTy = ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr; return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, @@ -2382,7 +2364,7 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) { unsigned Line = getLineNumber(RD->getLocation()); StringRef RDName = getClassName(RD); - llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0)); + llvm::DIScope *RDContext = getDeclContextDescriptor(RD); // If we ended up creating the type during the context chain construction, // just return that. @@ -2529,15 +2511,8 @@ void CGDebugInfo::collectVarDeclProps(const VarDecl *VD, llvm::DIFile *&Unit, if (DC->isRecord()) DC = CGM.getContext().getTranslationUnitDecl(); - if (VD->isStaticLocal()) { - // Get context for static locals (that are technically globals) the same way - // we do for "local" locals -- by using current lexical block. - assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); - VDContext = LexicalBlockStack.back(); - } else { - llvm::DIScope *Mod = getParentModuleOrNull(VD); - VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); - } + llvm::DIScope *Mod = getParentModuleOrNull(VD); + VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); } llvm::DISubprogram * diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 795dc0ad42..989ecad9b4 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -116,11 +116,6 @@ class CGDebugInfo { /// Keep track of our current nested lexical block. std::vector> LexicalBlockStack; - - /// Map of AST declaration to its lexical block scope. - llvm::DenseMap> - LexicalBlockMap; - llvm::DenseMap RegionMap; /// Keep track of LexicalBlockStack counter at the beginning of a /// function. This is used to pop unbalanced regions at the end of a @@ -383,12 +378,6 @@ public: /// Emit an Objective-C interface type standalone debug info. llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc); - /// Map AST declaration to its lexical block scope if available. - void recordDeclarationLexicalScope(const Decl &D); - - /// Get lexical scope of AST declaration. - llvm::DIScope *getDeclarationLexicalScope(const Decl &D, QualType Ty); - /// Emit standalone debug info for a type. llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 809012b17a..5b88ef1830 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -83,7 +83,11 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::UsingShadow: case Decl::ObjCTypeParam: llvm_unreachable("Declaration should not be in declstmts!"); - case Decl::Function: // void X(); + case Decl::Function: // void X(); + case Decl::Record: // struct/union/class X; + case Decl::Enum: // enum X; + case Decl::EnumConstant: // enum ? { X = ? } + case Decl::CXXRecord: // struct/union/class X; [C++] case Decl::StaticAssert: // static_assert(X, ""); [C++0x] case Decl::Label: // __label__ x; case Decl::Import: @@ -93,21 +97,13 @@ void CodeGenFunction::EmitDecl(const Decl &D) { // None of these decls require codegen support. return; - case Decl::Record: // struct/union/class X; - case Decl::Enum: // enum X; - case Decl::EnumConstant: // enum ? { X = ? } - case Decl::CXXRecord: // struct/union/class X; [C++] - if (CGDebugInfo *DI = getDebugInfo()) - DI->recordDeclarationLexicalScope(D); - return; - case Decl::NamespaceAlias: if (CGDebugInfo *DI = getDebugInfo()) - DI->EmitNamespaceAlias(cast(D)); + DI->EmitNamespaceAlias(cast(D)); return; case Decl::Using: // using X; [C++] if (CGDebugInfo *DI = getDebugInfo()) - DI->EmitUsingDecl(cast(D)); + DI->EmitUsingDecl(cast(D)); return; case Decl::UsingDirective: // using namespace X; [C++] if (CGDebugInfo *DI = getDebugInfo()) @@ -125,9 +121,6 @@ void CodeGenFunction::EmitDecl(const Decl &D) { const TypedefNameDecl &TD = cast(D); QualType Ty = TD.getUnderlyingType(); - if (CGDebugInfo *DI = getDebugInfo()) - DI->recordDeclarationLexicalScope(D); - if (Ty->isVariablyModifiedType()) EmitVariablyModifiedType(Ty); } diff --git a/test/CodeGenCXX/debug-info-anon-union-vars.cpp b/test/CodeGenCXX/debug-info-anon-union-vars.cpp index 8e047f84a4..5b0370eb74 100644 --- a/test/CodeGenCXX/debug-info-anon-union-vars.cpp +++ b/test/CodeGenCXX/debug-info-anon-union-vars.cpp @@ -44,12 +44,7 @@ void instantiate(int x) { buildBytes(x); } -// CHECK: ![[UNION:[0-9]+]] = !DICompositeType(tag: DW_TAG_union_type, -// CHECK-NOT: name: -// CHECK: elements // CHECK: [[FILE:.*]] = !DIFile(filename: "{{.*}}debug-info-anon-union-vars.cpp", -// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i", scope: ![[UNION]], -// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "c", scope: ![[UNION]], // CHECK: !DIGlobalVariable(name: "c",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true // CHECK: !DIGlobalVariable(name: "d",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true // CHECK: !DIGlobalVariable(name: "a",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true @@ -60,4 +55,9 @@ void instantiate(int x) { // CHECK: !DILocalVariable(name: "c", {{.*}}, flags: DIFlagArtificial // CHECK: !DILocalVariable( // CHECK-NOT: name: -// CHECK: type: ![[UNION]] +// CHECK: type: ![[UNION:[0-9]+]] +// CHECK: ![[UNION]] = !DICompositeType(tag: DW_TAG_union_type, +// CHECK-NOT: name: +// CHECK: elements +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i", scope: ![[UNION]], +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "c", scope: ![[UNION]], diff --git a/test/CodeGenCXX/debug-info-lb.cpp b/test/CodeGenCXX/debug-info-lb.cpp deleted file mode 100644 index beb160c8c7..0000000000 --- a/test/CodeGenCXX/debug-info-lb.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s - -void foo() { - static int bar = 1; - { - struct X {}; - typedef char Y; - static int bar = 0; - // The following basic block is intended, in order to check the case where - // types "X", "Y" are defined in a different scope than where they are used. - // They should have the scope they are defined at as their parent scope. - { - X a; - Y b; - } - } -} - -// CHECK: !{{[0-9]+}} = !DICompositeType(tag: DW_TAG_structure_type, name: "X", scope: [[LBScope:![0-9]+]], -// CHECK: [[LBScope]] = distinct !DILexicalBlock(scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 5) - -// CHECK: [[FuncScope:![0-9]+]] = distinct !DISubprogram(name: "foo", - -// CHECK: !{{[0-9]+}} = !DIDerivedType(tag: DW_TAG_typedef, name: "Y", scope: [[LBScope]], -// CHECK: !{{[0-9]+}} = !DIGlobalVariable(name: "bar", scope: [[FuncScope]], file: !{{[0-9]+}}, line: 4 -// CHECK: !{{[0-9]+}} = !DIGlobalVariable(name: "bar", scope: [[LBScope]], file: !{{[0-9]+}}, line: 8 -