[llvm-commits] [llvm-gcc-4.2] r100049 - in /llvm-gcc-4.2/trunk/gcc: llvm-backend.cpp llvm-convert.cpp llvm-debug.cpp llvm-debug.h llvm-internal.h

Stuart Hastings stuart at apple.com
Wed Mar 31 14:12:42 PDT 2010


Author: stuart
Date: Wed Mar 31 16:12:42 2010
New Revision: 100049

URL: http://llvm.org/viewvc/llvm-project?rev=100049&view=rev
Log:
Debug info can now properly represent functions inside classes inside other functions.  Partial fix for Radar 7424645.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-debug.h
    llvm-gcc-4.2/trunk/gcc/llvm-internal.h

Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=100049&r1=100048&r2=100049&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Wed Mar 31 16:12:42 2010
@@ -512,6 +512,8 @@
   if (!flag_pch_file &&
       debug_info_level > DINFO_LEVEL_NONE)
     TheDebugInfo = new DebugInfo(TheModule);
+  else
+    TheDebugInfo = 0;
 }
 
 /// performLateBackendInitialization - Set backend options that may only be
@@ -533,8 +535,6 @@
 }
 
 void llvm_lang_dependent_init(const char *Name) {
-  if (TheDebugInfo)
-    TheDebugInfo->Initialize();
   if (Name)
     TheModule->setModuleIdentifier(Name);
 }
@@ -1010,7 +1010,7 @@
   // Convert the AST to raw/ugly LLVM code.
   Function *Fn;
   {
-    TreeToLLVM Emitter(fndecl);
+    TreeToLLVM *Emitter = getTreeToLLVM(fndecl);
     enum symbol_visibility vis = DECL_VISIBILITY (fndecl);
 
     if (vis != VISIBILITY_DEFAULT)
@@ -1018,7 +1018,7 @@
       // visibility that's not supported by the target.
       targetm.asm_out.visibility(fndecl, vis);
 
-    Fn = Emitter.EmitFunction();
+    Fn = Emitter->EmitFunction();
   }
 
 #if 0

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=100049&r1=100048&r2=100049&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Mar 31 16:12:42 2010
@@ -148,7 +148,6 @@
 //===----------------------------------------------------------------------===//
 
 /// TheTreeToLLVM - Keep track of the current function being compiled.
-static TreeToLLVM *TheTreeToLLVM = 0;
 
 const TargetData &getTargetData() {
   return *TheTarget->getTargetData();
@@ -163,7 +162,7 @@
 }
 
 TreeToLLVM::TreeToLLVM(tree fndecl) :
-    TD(getTargetData()), Builder(Context, *TheFolder) {
+  TD(getTargetData()), Builder(Context, *TheFolder) {
   FnDecl = fndecl;
   Fn = 0;
   ReturnBB = UnwindBB = 0;
@@ -179,6 +178,7 @@
       TheDebugInfo->setLocationFile("<unknown file>");
       TheDebugInfo->setLocationLine(0);
     }
+    TheDebugInfo->Initialize();
   }
 
   AllocaInsertionPoint = 0;
@@ -188,13 +188,23 @@
   FuncEHException = 0;
   FuncEHSelector = 0;
   FuncEHGetTypeID = 0;
+}
+
+
+TreeToLLVM::~TreeToLLVM() {}
 
-  assert(TheTreeToLLVM == 0 && "Reentering function creation?");
-  TheTreeToLLVM = this;
+TreeToLLVM *getTreeToLLVM(tree fndecl) {
+  // FIXME: should this static move into the TreeToLLVM class decl?
+  static std::map<tree_node *, TreeToLLVM * > FunctionMap;
+  TreeToLLVM *newTreeToLLVM = FunctionMap[fndecl];
+  if (!newTreeToLLVM)
+    newTreeToLLVM = FunctionMap[fndecl] = new TreeToLLVM(fndecl);
+  return newTreeToLLVM;
 }
 
-TreeToLLVM::~TreeToLLVM() {
-  TheTreeToLLVM = 0;
+TreeToLLVM *getCurrentTreeToLLVM(void) {
+  assert(current_function_decl && "no current_function_decl?");
+  return getTreeToLLVM(current_function_decl);
 }
 
 /// getLabelDeclBlock - Lazily get and create a basic block for the specified
@@ -308,7 +318,8 @@
       assert(TREE_CODE(TREE_TYPE(ResultDecl)) == REFERENCE_TYPE &&
              "Not type match and not passing by reference?");
       // Create an alloca for the ResultDecl.
-      Value *Tmp = TheTreeToLLVM->CreateTemporary(AI->getType());
+      TreeToLLVM *Emitter = getCurrentTreeToLLVM();
+      Value *Tmp = Emitter->CreateTemporary(AI->getType());
       Builder.CreateStore(AI, Tmp);
 
       SET_DECL_LLVM(ResultDecl, Tmp);
@@ -451,7 +462,7 @@
   }
 }
 
-void TreeToLLVM::StartFunctionBody() {
+Function *TreeToLLVM::StartFunctionBody() {
   const char *Name = "";
   // Get the name of the function.
   if (tree ID = DECL_ASSEMBLER_NAME(FnDecl))
@@ -610,10 +621,10 @@
   // Set the BLOCK_NUMBER()s to the depth of each lexical block.
   setLexicalBlockDepths(FnDecl, block_declared_vars, 1);
 
-  SeenBlocks.clear();
-
-  if (EmitDebugInfo())
-    TheDebugInfo->EmitFunctionStart(FnDecl, Fn, Builder.GetInsertBlock());
+  if (TheDebugInfo) {
+    TheDebugInfo->EmitFunctionStart(FnDecl);
+    Builder.GetInsertBlock();
+  }
 
   // Loop over all of the arguments to the function, setting Argument names and
   // creating argument alloca's for the PARM_DECLs in case their address is
@@ -628,7 +639,7 @@
   ABIConverter.HandleReturnType(TREE_TYPE(TREE_TYPE(FnDecl)), FnDecl,
                                 DECL_BUILT_IN(FnDecl));
   // Remember this for use by FinishFunctionBody.
-  TheTreeToLLVM->ReturnOffset = Client.Offset;
+  ReturnOffset = Client.Offset;
 
   // Prepend the static chain (if any) to the list of arguments.
   tree Args = static_chain ? static_chain : DECL_ARGUMENTS(FnDecl);
@@ -709,12 +720,7 @@
         block_declared_vars.count(TREE_VALUE(t)) == 0)
       EmitAutomaticVariableDecl(TREE_VALUE(t));
   }
-
-  // Push the outermost lexical block onto the RegionStack.
-  switchLexicalBlock(DECL_INITIAL(FnDecl));
-
-  // Create a new block for the return node, but don't insert it yet.
-  ReturnBB = BasicBlock::Create(Context, "return");
+  return Fn;
 }
 
 Function *TreeToLLVM::FinishFunctionBody() {
@@ -802,9 +808,19 @@
 }
 
 Function *TreeToLLVM::EmitFunction() {
-  // Set up parameters and prepare for return, for the function.
+  // Set up parameters for the function.
   StartFunctionBody();
 
+  // We'll remember the lexical BLOCKs we've seen here.
+  SeenBlocks.clear();
+
+  // FIXME: Should these two statements move to StartFunctionBody() ?
+  // Push the outermost lexical block onto the RegionStack.
+  switchLexicalBlock(DECL_INITIAL(FnDecl));
+
+  // Create a new block for the return node, but don't insert it yet.
+  ReturnBB = BasicBlock::Create(Context, "return");
+
   // Emit the body of the function iterating over all BBs
   basic_block bb;
   edge e;
@@ -2610,7 +2626,7 @@
       if (!Loc) {
         // A value.  Store to a temporary, and return the temporary's address.
         // Any future access to this argument will reuse the same address.
-        Loc = TheTreeToLLVM->CreateTemporary(TheValue->getType());
+        Loc = getCurrentTreeToLLVM()->CreateTemporary(TheValue->getType());
         Builder.CreateStore(TheValue, Loc);
       }
       return Loc;
@@ -2650,7 +2666,7 @@
         assert(ConvertType(type) ==
                cast<PointerType>(RetBuf.Ptr->getType())->getElementType() &&
                "Inconsistent result types!");
-        TheTreeToLLVM->EmitAggregateCopy(*DestLoc, RetBuf, type);
+        getCurrentTreeToLLVM()->EmitAggregateCopy(*DestLoc, RetBuf, type);
         return 0;
       } else {
         // Read out the scalar return value now.
@@ -2693,7 +2709,7 @@
 
       if (DestLoc == 0) {
         // The result is unused, but still needs to be stored somewhere.
-        Value *Buf = TheTreeToLLVM->CreateTemporary(PtrArgTy->getElementType());
+        Value *Buf = getCurrentTreeToLLVM()->CreateTemporary(PtrArgTy->getElementType());
         CallOperands.push_back(Buf);
       } else if (useReturnSlot) {
         // Letting the call write directly to the final destination is safe and
@@ -2703,7 +2719,7 @@
         // Letting the call write directly to the final destination may not be
         // safe (eg: if DestLoc aliases a parameter) and is not required - pass
         // a buffer and copy it to DestLoc after the call.
-        RetBuf = TheTreeToLLVM->CreateTempLoc(PtrArgTy->getElementType());
+        RetBuf = getCurrentTreeToLLVM()->CreateTempLoc(PtrArgTy->getElementType());
         CallOperands.push_back(RetBuf.Ptr);
       }
 
@@ -2724,7 +2740,7 @@
              "Call returns a scalar but caller expects aggregate!");
       // Create a buffer to hold the result.  The result will be loaded out of
       // it after the call.
-      RetBuf = TheTreeToLLVM->CreateTempLoc(PtrArgTy->getElementType());
+      RetBuf = getCurrentTreeToLLVM()->CreateTempLoc(PtrArgTy->getElementType());
       CallOperands.push_back(RetBuf.Ptr);
 
       // Note the use of a shadow argument.
@@ -2748,7 +2764,7 @@
         if (Loc->getType() != CalledTy) {
           assert(type && "Inconsistent parameter types?");
           bool isSigned = !TYPE_UNSIGNED(type);
-          Loc = TheTreeToLLVM->CastToAnyType(Loc, isSigned, CalledTy, false);
+          Loc = getCurrentTreeToLLVM()->CastToAnyType(Loc, isSigned, CalledTy, false);
         }
       }
 
@@ -8451,18 +8467,18 @@
 
 /// EmitLV_LABEL_DECL - Someone took the address of a label.
 Constant *TreeConstantToLLVM::EmitLV_LABEL_DECL(tree exp) {
-  assert(TheTreeToLLVM &&
+  assert(getCurrentTreeToLLVM() &&
          "taking the address of a label while not compiling the function!");
 
   // Figure out which function this is for, verify it's the one we're compiling.
   if (DECL_CONTEXT(exp)) {
     assert(TREE_CODE(DECL_CONTEXT(exp)) == FUNCTION_DECL &&
            "Address of label in nested function?");
-    assert(TheTreeToLLVM->getFUNCTION_DECL() == DECL_CONTEXT(exp) &&
+    assert(getCurrentTreeToLLVM()->getFUNCTION_DECL() == DECL_CONTEXT(exp) &&
            "Taking the address of a label that isn't in the current fn!?");
   }
 
-  return TheTreeToLLVM->EmitLV_LABEL_DECL(exp);
+  return getCurrentTreeToLLVM()->EmitLV_LABEL_DECL(exp);
 }
 
 Constant *TreeConstantToLLVM::EmitLV_COMPLEX_CST(tree exp) {

Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=100049&r1=100048&r2=100049&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Wed Mar 31 16:12:42 2010
@@ -289,12 +289,10 @@
   setCurrentLexicalBlock(desired);
 }
 
-/// EmitFunctionStart - Constructs the debug code for entering a function -
-/// "llvm.dbg.func.start."
-void DebugInfo::EmitFunctionStart(tree FnDecl, Function *Fn,
-                                  BasicBlock *CurBB) {
-  setCurrentLexicalBlock(FnDecl);
+/// CreateSubprogramFromFnDecl - Constructs the debug code for
+/// entering a function - "llvm.dbg.func.start."
 
+DISubprogram DebugInfo::CreateSubprogramFromFnDecl(tree FnDecl) {
   DIType FNType = getOrCreateType(TREE_TYPE(FnDecl));
 
   std::map<tree_node *, WeakVH >::iterator I = SPCache.find(FnDecl);
@@ -302,12 +300,9 @@
     DISubprogram SPDecl(cast<MDNode>(I->second));
     DISubprogram SP = 
       DebugFactory.CreateSubprogramDefinition(SPDecl);
-    SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
-
-    // Push function on region stack.
-    RegionStack.push_back(WeakVH(SP.getNode()));
-    RegionMap[FnDecl] = WeakVH(SP.getNode());
-    return;
+    if (SP.getNode() != SPDecl.getNode())
+      SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
+    return SP;
   } 
 
   bool ArtificialFnWithAbstractOrigin = false;
@@ -329,12 +324,13 @@
     DISubprogram SPDecl(cast<MDNode>(I->second));
     DISubprogram SP = 
       DebugFactory.CreateSubprogramDefinition(SPDecl);
-    SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
+    if (SP.getNode() != SPDecl.getNode())
+      SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
 
     // Push function on region stack.
     RegionStack.push_back(WeakVH(SP.getNode()));
     RegionMap[FnDecl] = WeakVH(SP.getNode());
-    return;
+    return SP;
   } 
 
   // Gather location information.
@@ -356,23 +352,36 @@
   }
 
   StringRef FnName = getFunctionName(FnDecl);
-
+  // If the Function * hasn't been created yet, use a bogus value for
+  // the debug internal linkage bit.
+  bool hasInternalLinkage = true;
+  if (GET_DECL_LLVM_INDEX(FnDecl)) {
+    Function *Fn = cast<Function>DECL_LLVM(FnDecl);
+    hasInternalLinkage = Fn->hasInternalLinkage();
+  }
   DISubprogram SP = 
     DebugFactory.CreateSubprogram(SPContext,
                                   FnName, FnName,
                                   LinkageName,
                                   getOrCreateFile(Loc.file), lineno,
                                   FNType,
-                                  Fn->hasInternalLinkage(),
+                                  hasInternalLinkage,
                                   true /*definition*/,
                                   Virtuality, VIndex, ContainingType);
                           
 
   SPCache[FnDecl] = WeakVH(SP.getNode());
+  RegionMap[FnDecl] = WeakVH(SP.getNode());
+  return SP;
+}
 
+/// EmitFunctionStart - Constructs the debug code for entering a function -
+/// "llvm.dbg.func.start", and pushes it onto the RegionStack.
+void DebugInfo::EmitFunctionStart(tree FnDecl) {
+  setCurrentLexicalBlock(FnDecl);
+  DISubprogram SP = CreateSubprogramFromFnDecl(FnDecl);
   // Push function on region stack.
   RegionStack.push_back(WeakVH(SP.getNode()));
-  RegionMap[FnDecl] = WeakVH(SP.getNode());
 }
 
 /// getOrCreateNameSpace - Get name space descriptor for the tree node.
@@ -405,12 +414,20 @@
     DIType Ty = getOrCreateType(Node);
     return DIDescriptor(Ty.getNode());
   } else if (DECL_P (Node)) {
-    if (TREE_CODE (Node) == NAMESPACE_DECL) {
+    switch (TREE_CODE(Node)) {
+    default:
+      /// What kind of DECL is this?
+      return findRegion (DECL_CONTEXT (Node));
+    case NAMESPACE_DECL: {
       DIDescriptor NSContext = findRegion(DECL_CONTEXT(Node));
       DINameSpace NS = getOrCreateNameSpace(Node, NSContext);
       return DIDescriptor(NS.getNode());
     }
-    return findRegion (DECL_CONTEXT (Node));
+    case FUNCTION_DECL: {
+      DISubprogram SP = CreateSubprogramFromFnDecl(Node);
+      return SP;
+    }
+    }
   } else if (TREE_CODE(Node) == BLOCK) {
     // TREE_BLOCK is GCC's lexical block.
     // Recursively create all necessary contexts:
@@ -631,7 +648,7 @@
   sprintf(FwdTypeName, "fwd.type.%d", FwdTypeCount++);
   llvm::DIType FwdType = 
     DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
-                                     getOrCreateFile(main_input_filename),
+                                     findRegion(TYPE_CONTEXT(type)),
                                      FwdTypeName,
                                      getOrCreateFile(main_input_filename),
                                      0, 0, 0, 0, 0,
@@ -717,9 +734,10 @@
       return Ty;
     }
   
+  tree type_with_context = TYPE_CONTEXT(type) ? type : TREE_TYPE(type);
   StringRef PName = FromTy.getName();
   DIType PTy = 
-    DebugFactory.CreateDerivedType(Tag, findRegion(TYPE_CONTEXT(type)), 
+    DebugFactory.CreateDerivedType(Tag, findRegion(type_with_context), 
                                    Tag == DW_TAG_pointer_type ? 
                                    StringRef() : PName,
                                    getOrCreateFile(main_input_filename),

Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.h?rev=100049&r1=100048&r2=100049&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-debug.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-debug.h Wed Mar 31 16:12:42 2010
@@ -118,9 +118,13 @@
   // by GCC's cfglayout.c:change_scope().
   void change_regions(tree_node *desired, tree_node *grand);
 
-  /// EmitFunctionStart - Constructs the debug code for entering a function -
+  /// CreateSubprogramFromFnDecl - Constructs the debug code for entering a function -
   /// "llvm.dbg.func.start."
-  void EmitFunctionStart(tree_node *FnDecl, Function *Fn, BasicBlock *CurBB);
+  DISubprogram CreateSubprogramFromFnDecl(tree_node *FnDecl);
+
+  /// EmitFunctionStart - Constructs the debug code for entering a function -
+  /// "llvm.dbg.func.start", and pushes it onto the RegionStack.
+  void EmitFunctionStart(tree_node *FnDecl);
 
   /// EmitFunctionEnd - Constructs the debug code for exiting a declarative
   /// region - "llvm.dbg.region.end."

Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=100049&r1=100048&r2=100049&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Wed Mar 31 16:12:42 2010
@@ -75,7 +75,7 @@
 extern llvm::Module *TheModule;
 
 /// TheDebugInfo - This object is responsible for gather all debug information.
-/// If it's value is NULL then no debug information should be gathered.
+/// If its value is NULL then no debug information should be gathered.
 extern llvm::DebugInfo *TheDebugInfo;
 
 /// TheTarget - The current target being compiled for.
@@ -281,6 +281,7 @@
   BasicBlock *ReturnBB;
   BasicBlock *UnwindBB;
   unsigned ReturnOffset;
+
   // Lexical BLOCKS that we have previously seen and processed.
   treeset SeenBlocks;
 
@@ -397,6 +398,10 @@
   // allocation would change with -g, and users dislike that.
   void switchLexicalBlock(tree_node *exp);
 
+  /// StartFunctionBody - Start the emission of 'FnDecl', outputing all
+  /// declarations for parameters and setting things up.
+  Function *StartFunctionBody();
+  
 private: // Helper functions.
 
   // Walk over the lexical BLOCK() tree of the given FUNCTION_DECL;
@@ -405,10 +410,6 @@
   // the given set.
   void setLexicalBlockDepths(tree_node *t, treeset &s, unsigned level);
 
-  /// StartFunctionBody - Start the emission of 'fndecl', outputing all
-  /// declarations for parameters and setting things up.
-  void StartFunctionBody();
-  
   /// FinishFunctionBody - Once the body of the function has been emitted, this
   /// cleans up and returns the result function.
   Function *FinishFunctionBody();
@@ -608,6 +609,9 @@
   Constant *EmitLV_LABEL_DECL(tree_node *exp);
 };
 
+/// Locate a previously exiting TreeToLLVM.  Construct one if necessary.
+TreeToLLVM *getTreeToLLVM(tree_node *fndecl);
+
 /// TreeConstantToLLVM - An instance of this class is created and used to 
 /// convert tree constant values to LLVM.  This is primarily for things like
 /// global variable initializers.





More information about the llvm-commits mailing list