Loading clang/include/clang/AST/GlobalDecl.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ enum class DynamicInitKind : unsigned { NoStub = 0, Initializer, AtExit, GlobalArrayDestructor }; /// GlobalDecl - represents a global declaration. This can either be a Loading clang/lib/CodeGen/CGDebugInfo.cpp +5 −2 Original line number Diff line number Diff line Loading @@ -1944,7 +1944,8 @@ StringRef CGDebugInfo::getDynamicInitializerName(const VarDecl *VD, llvm::Function *InitFn) { // If we're not emitting codeview, use the mangled name. For Itanium, this is // arbitrary. if (!CGM.getCodeGenOpts().EmitCodeView) if (!CGM.getCodeGenOpts().EmitCodeView || StubKind == DynamicInitKind::GlobalArrayDestructor) return InitFn->getName(); // Print the normal qualified name for the variable, then break off the last Loading @@ -1969,6 +1970,7 @@ StringRef CGDebugInfo::getDynamicInitializerName(const VarDecl *VD, switch (StubKind) { case DynamicInitKind::NoStub: case DynamicInitKind::GlobalArrayDestructor: llvm_unreachable("not an initializer"); case DynamicInitKind::Initializer: OS << "`dynamic initializer for '"; Loading Loading @@ -3644,7 +3646,8 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, if (Name.startswith("\01")) Name = Name.substr(1); if (!HasDecl || D->isImplicit() || D->hasAttr<ArtificialAttr>()) { if (!HasDecl || D->isImplicit() || D->hasAttr<ArtificialAttr>() || (isa<VarDecl>(D) && GD.getDynamicInitKind() != DynamicInitKind::NoStub)) { Flags |= llvm::DINode::FlagArtificial; // Artificial functions should not silently reuse CurLoc. CurLoc = SourceLocation(); Loading clang/lib/CodeGen/CGDeclCXX.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -244,6 +244,8 @@ llvm::Function *CodeGenFunction::createAtExitStub(const VarDecl &VD, CGF.StartFunction(GlobalDecl(&VD, DynamicInitKind::AtExit), CGM.getContext().VoidTy, fn, FI, FunctionArgList()); // Emit an artificial location for this function. auto AL = ApplyDebugLocation::CreateArtificial(CGF); llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr); Loading Loading @@ -644,8 +646,9 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, StartFunction(GlobalDecl(D, DynamicInitKind::Initializer), getContext().VoidTy, Fn, getTypes().arrangeNullaryFunction(), FunctionArgList(), D->getLocation(), D->getInit()->getExprLoc()); FunctionArgList()); // Emit an artificial location for this function. auto AL = ApplyDebugLocation::CreateArtificial(*this); // Use guarded initialization if the global variable is weak. This // occurs for, e.g., instantiated static data members and Loading Loading @@ -770,7 +773,10 @@ llvm::Function *CodeGenFunction::generateDestroyHelper( CurEHLocation = VD->getBeginLoc(); StartFunction(VD, getContext().VoidTy, fn, FI, args); StartFunction(GlobalDecl(VD, DynamicInitKind::GlobalArrayDestructor), getContext().VoidTy, fn, FI, args); // Emit an artificial location for this function. auto AL = ApplyDebugLocation::CreateArtificial(*this); emitDestroy(addr, type, destroyer, useEHCleanupForArray); Loading clang/test/CodeGenCXX/debug-info-atexit-stub.cpp 0 → 100644 +20 −0 Original line number Diff line number Diff line // RUN: %clang_cc1 -emit-llvm %s -triple x86_64-windows-msvc -gcodeview -debug-info-kind=limited -o - | FileCheck %s struct a { ~a(); }; template <typename b> struct c : a { c(void (b::*)()); }; struct B { virtual void e(); }; c<B> *d() { static c<B> f(&B::e); return &f; } // CHECK: define internal void @"??__Ff@?1??d@@YAPEAU?$c@UB@@@@XZ@YAXXZ"() // CHECK-SAME: !dbg ![[SUBPROGRAM:[0-9]+]] { // CHECK: call void @"??1?$c@UB@@@@QEAA@XZ"(%struct.c* @"?f@?1??d@@YAPEAU?$c@UB@@@@XZ@4U2@A"), !dbg ![[LOCATION:[0-9]+]] // CHECK-NEXT: ret void, !dbg ![[LOCATION]] // CHECK: ![[SUBPROGRAM]] = distinct !DISubprogram(name: "`dynamic atexit destructor for 'f'" // CHECK-SAME: flags: DIFlagArtificial // CHECK: ![[LOCATION]] = !DILocation(line: 0, scope: ![[SUBPROGRAM]]) clang/test/CodeGenCXX/debug-info-destroy-helper.cpp 0 → 100644 +24 −0 Original line number Diff line number Diff line // RUN: %clang_cc1 -emit-llvm %s -triple x86_64-windows-msvc -gcodeview -debug-info-kind=limited -o - | FileCheck %s struct b { b(char *); ~b(); }; struct a { ~a(); }; struct { b c; const a &d; } e[]{nullptr, {}}; // CHECK: define internal void @__cxx_global_array_dtor(i8* %0) // CHECK-SAME: !dbg ![[SUBPROGRAM:[0-9]+]] { // CHECK: arraydestroy.body // CHECK: %arraydestroy.elementPast = // CHECK-SAME: !dbg ![[LOCATION:[0-9]+]] // CHECK: call void @"??1<unnamed-type-e>@@QEAA@XZ"(%struct.anon* %arraydestroy.element) // CHECK-SAME: !dbg ![[LOCATION]] // CHECK: ![[SUBPROGRAM]] = distinct !DISubprogram(name: "__cxx_global_array_dtor" // CHECK-SAME: flags: DIFlagArtificial // CHECK: ![[LOCATION]] = !DILocation(line: 0, Loading
clang/include/clang/AST/GlobalDecl.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ enum class DynamicInitKind : unsigned { NoStub = 0, Initializer, AtExit, GlobalArrayDestructor }; /// GlobalDecl - represents a global declaration. This can either be a Loading
clang/lib/CodeGen/CGDebugInfo.cpp +5 −2 Original line number Diff line number Diff line Loading @@ -1944,7 +1944,8 @@ StringRef CGDebugInfo::getDynamicInitializerName(const VarDecl *VD, llvm::Function *InitFn) { // If we're not emitting codeview, use the mangled name. For Itanium, this is // arbitrary. if (!CGM.getCodeGenOpts().EmitCodeView) if (!CGM.getCodeGenOpts().EmitCodeView || StubKind == DynamicInitKind::GlobalArrayDestructor) return InitFn->getName(); // Print the normal qualified name for the variable, then break off the last Loading @@ -1969,6 +1970,7 @@ StringRef CGDebugInfo::getDynamicInitializerName(const VarDecl *VD, switch (StubKind) { case DynamicInitKind::NoStub: case DynamicInitKind::GlobalArrayDestructor: llvm_unreachable("not an initializer"); case DynamicInitKind::Initializer: OS << "`dynamic initializer for '"; Loading Loading @@ -3644,7 +3646,8 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, if (Name.startswith("\01")) Name = Name.substr(1); if (!HasDecl || D->isImplicit() || D->hasAttr<ArtificialAttr>()) { if (!HasDecl || D->isImplicit() || D->hasAttr<ArtificialAttr>() || (isa<VarDecl>(D) && GD.getDynamicInitKind() != DynamicInitKind::NoStub)) { Flags |= llvm::DINode::FlagArtificial; // Artificial functions should not silently reuse CurLoc. CurLoc = SourceLocation(); Loading
clang/lib/CodeGen/CGDeclCXX.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -244,6 +244,8 @@ llvm::Function *CodeGenFunction::createAtExitStub(const VarDecl &VD, CGF.StartFunction(GlobalDecl(&VD, DynamicInitKind::AtExit), CGM.getContext().VoidTy, fn, FI, FunctionArgList()); // Emit an artificial location for this function. auto AL = ApplyDebugLocation::CreateArtificial(CGF); llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr); Loading Loading @@ -644,8 +646,9 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, StartFunction(GlobalDecl(D, DynamicInitKind::Initializer), getContext().VoidTy, Fn, getTypes().arrangeNullaryFunction(), FunctionArgList(), D->getLocation(), D->getInit()->getExprLoc()); FunctionArgList()); // Emit an artificial location for this function. auto AL = ApplyDebugLocation::CreateArtificial(*this); // Use guarded initialization if the global variable is weak. This // occurs for, e.g., instantiated static data members and Loading Loading @@ -770,7 +773,10 @@ llvm::Function *CodeGenFunction::generateDestroyHelper( CurEHLocation = VD->getBeginLoc(); StartFunction(VD, getContext().VoidTy, fn, FI, args); StartFunction(GlobalDecl(VD, DynamicInitKind::GlobalArrayDestructor), getContext().VoidTy, fn, FI, args); // Emit an artificial location for this function. auto AL = ApplyDebugLocation::CreateArtificial(*this); emitDestroy(addr, type, destroyer, useEHCleanupForArray); Loading
clang/test/CodeGenCXX/debug-info-atexit-stub.cpp 0 → 100644 +20 −0 Original line number Diff line number Diff line // RUN: %clang_cc1 -emit-llvm %s -triple x86_64-windows-msvc -gcodeview -debug-info-kind=limited -o - | FileCheck %s struct a { ~a(); }; template <typename b> struct c : a { c(void (b::*)()); }; struct B { virtual void e(); }; c<B> *d() { static c<B> f(&B::e); return &f; } // CHECK: define internal void @"??__Ff@?1??d@@YAPEAU?$c@UB@@@@XZ@YAXXZ"() // CHECK-SAME: !dbg ![[SUBPROGRAM:[0-9]+]] { // CHECK: call void @"??1?$c@UB@@@@QEAA@XZ"(%struct.c* @"?f@?1??d@@YAPEAU?$c@UB@@@@XZ@4U2@A"), !dbg ![[LOCATION:[0-9]+]] // CHECK-NEXT: ret void, !dbg ![[LOCATION]] // CHECK: ![[SUBPROGRAM]] = distinct !DISubprogram(name: "`dynamic atexit destructor for 'f'" // CHECK-SAME: flags: DIFlagArtificial // CHECK: ![[LOCATION]] = !DILocation(line: 0, scope: ![[SUBPROGRAM]])
clang/test/CodeGenCXX/debug-info-destroy-helper.cpp 0 → 100644 +24 −0 Original line number Diff line number Diff line // RUN: %clang_cc1 -emit-llvm %s -triple x86_64-windows-msvc -gcodeview -debug-info-kind=limited -o - | FileCheck %s struct b { b(char *); ~b(); }; struct a { ~a(); }; struct { b c; const a &d; } e[]{nullptr, {}}; // CHECK: define internal void @__cxx_global_array_dtor(i8* %0) // CHECK-SAME: !dbg ![[SUBPROGRAM:[0-9]+]] { // CHECK: arraydestroy.body // CHECK: %arraydestroy.elementPast = // CHECK-SAME: !dbg ![[LOCATION:[0-9]+]] // CHECK: call void @"??1<unnamed-type-e>@@QEAA@XZ"(%struct.anon* %arraydestroy.element) // CHECK-SAME: !dbg ![[LOCATION]] // CHECK: ![[SUBPROGRAM]] = distinct !DISubprogram(name: "__cxx_global_array_dtor" // CHECK-SAME: flags: DIFlagArtificial // CHECK: ![[LOCATION]] = !DILocation(line: 0,