]> granicus.if.org Git - clang/commitdiff
[CGDebugInfo] Finalize SubPrograms when we're done with them
authorKeno Fischer <keno@alumni.harvard.edu>
Thu, 1 Jun 2017 21:14:03 +0000 (21:14 +0000)
committerKeno Fischer <keno@alumni.harvard.edu>
Thu, 1 Jun 2017 21:14:03 +0000 (21:14 +0000)
`GenerateVarArgsThunk` in `CGVTables` clones a function before the frontend
is done emitting the compilation unit. Because of the way that DIBuilder
works, this means that the attached subprogram had incomplete (temporary)
metadata. Cloning such metadata is semantically disallowed, but happened
to work anyway due to bugs in the cloning logic. rL304226 attempted to fix
up that logic, but in the process exposed the incorrect API use here and
had to be reverted. To be able to fix this, I added a new method to
DIBuilder in rL304467, to allow finalizing a subprogram independently
of the entire compilation unit. Use that here, in preparation of re-applying
rL304226.

Reviewers: aprantl, dblaikie
Differential Revision: https://reviews.llvm.org/D33705

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@304470 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CGDebugInfo.h
lib/CodeGen/CodeGenFunction.cpp

index 0a1dc09211c25252c2d34f0edb002c0a7799e23c..3ed388974c46544a8934129fd2f486c84056c890 100644 (file)
@@ -3263,7 +3263,7 @@ void CGDebugInfo::EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD) {
 
 void CGDebugInfo::EmitInlineFunctionEnd(CGBuilderTy &Builder) {
   assert(CurInlinedAt && "unbalanced inline scope stack");
-  EmitFunctionEnd(Builder);
+  EmitFunctionEnd(Builder, nullptr);
   setInlinedAt(llvm::DebugLoc(CurInlinedAt).getInlinedAt());
 }
 
@@ -3332,7 +3332,7 @@ void CGDebugInfo::EmitLexicalBlockEnd(CGBuilderTy &Builder,
   LexicalBlockStack.pop_back();
 }
 
-void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder) {
+void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn) {
   assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
   unsigned RCount = FnBeginRegionCount.back();
   assert(RCount <= LexicalBlockStack.size() && "Region stack mismatch");
@@ -3344,6 +3344,9 @@ void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder) {
     LexicalBlockStack.pop_back();
   }
   FnBeginRegionCount.pop_back();
+
+  if (Fn && Fn->getSubprogram())
+    DBuilder.finalizeSubprogram(Fn->getSubprogram());
 }
 
 llvm::DIType *CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
index 7de48f2789945db519004c614b0710f255ac4677..39249c7cf4da25051ae8e678faa8dbacf1fa21c6 100644 (file)
@@ -367,7 +367,7 @@ public:
   void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType);
 
   /// Constructs the debug code for exiting a function.
-  void EmitFunctionEnd(CGBuilderTy &Builder);
+  void EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn);
 
   /// Emit metadata to indicate the beginning of a new lexical block
   /// and push the block onto the stack.
index 85da3ae47db0bb782141e1789b27d0d9639c108e..b6d7f02550177d43a73814aa844b57fc0577a787 100644 (file)
@@ -348,7 +348,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
 
   // Emit debug descriptor for function end.
   if (CGDebugInfo *DI = getDebugInfo())
-    DI->EmitFunctionEnd(Builder);
+    DI->EmitFunctionEnd(Builder, CurFn);
 
   // Reset the debug location to that of the simple 'return' expression, if any
   // rather than that of the end of the function's scope '}'.