Today the front-ends (llvm-gcc and clang) generate multiple llvm.dbg.compile_units...
[oota-llvm.git] / lib / Analysis / DebugInfo.cpp
index 7de3c54808bb410ae07757044b433137090bf158..f1f7d8eff35a71015a877f9ff9448091c37dc9d1 100644 (file)
@@ -16,6 +16,7 @@
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Intrinsics.h"
+#include "llvm/IntrinsicInst.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
 #include "llvm/Analysis/ValueTracking.h"
@@ -80,14 +81,6 @@ GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const {
 
 
 
-/// getCastToEmpty - Return this descriptor as a Constant* with type '{}*'.
-/// This is only valid when the descriptor is non-null.
-Constant *DIDescriptor::getCastToEmpty() const {
-  const Type *DestTy = PointerType::getUnqual(StructType::get(NULL, NULL));
-  if (isNull()) return Constant::getNullValue(DestTy);
-  return ConstantExpr::getBitCast(GV, DestTy);
-}
-
 //===----------------------------------------------------------------------===//
 // Simple Descriptor Constructors and other Methods
 //===----------------------------------------------------------------------===//
@@ -108,6 +101,14 @@ DIGlobalVariable::DIGlobalVariable(GlobalVariable *GV)
   : DIGlobal(GV, dwarf::DW_TAG_variable) {}
 DIBlock::DIBlock(GlobalVariable *GV)
   : DIDescriptor(GV, dwarf::DW_TAG_lexical_block) {}
+// needed by DIVariable::getType()
+DIType::DIType(GlobalVariable *gv) : DIDescriptor(gv) {
+  if (!gv) return;
+  unsigned tag = getTag();
+  if (tag != dwarf::DW_TAG_base_type && !DIDerivedType::isDerivedType(tag) &&
+      !DICompositeType::isCompositeType(tag))
+    GV = 0;
+}
 
 /// isDerivedType - Return true if the specified tag is legal for
 /// DIDerivedType.
@@ -179,10 +180,22 @@ DIVariable::DIVariable(GlobalVariable *GV) : DIDescriptor(GV) {
 // DIFactory: Basic Helpers
 //===----------------------------------------------------------------------===//
 
+DIFactory::DIFactory(Module &m) : M(m) {
+  StopPointFn = FuncStartFn = RegionStartFn = RegionEndFn = DeclareFn = 0;
+  EmptyStructPtr = PointerType::getUnqual(StructType::get(NULL, NULL));
+}
+
+/// getCastToEmpty - Return this descriptor as a Constant* with type '{}*'.
+/// This is only valid when the descriptor is non-null.
+Constant *DIFactory::getCastToEmpty(DIDescriptor D) {
+  if (D.isNull()) return Constant::getNullValue(EmptyStructPtr);
+  return ConstantExpr::getBitCast(D.getGV(), EmptyStructPtr);
+}
+
 Constant *DIFactory::GetTagConstant(unsigned TAG) {
   assert((TAG & DIDescriptor::VersionMask) == 0 &&
          "Tag too large for debug encoding!");
-  return ConstantInt::get(Type::Int32Ty, TAG | DIDescriptor::Version6);
+  return ConstantInt::get(Type::Int32Ty, TAG | DIDescriptor::Version7);
 }
 
 Constant *DIFactory::GetStringConstant(const std::string &String) {
@@ -212,7 +225,7 @@ Constant *DIFactory::GetStringConstant(const std::string &String) {
 /// GetOrCreateAnchor - Look up an anchor for the specified tag and name.  If it
 /// already exists, return it.  If not, create a new one and return it.
 DIAnchor DIFactory::GetOrCreateAnchor(unsigned TAG, const char *Name) {
-  const Type *EltTy = StructType::get(Type::Int32Ty,  Type::Int32Ty, NULL);
+  const Type *EltTy = StructType::get(Type::Int32Ty, Type::Int32Ty, NULL);
   
   // Otherwise, create the global or return it if already in the module.
   Constant *C = M.getOrInsertGlobal(Name, EltTy);
@@ -280,11 +293,10 @@ DIArray DIFactory::GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys) {
   SmallVector<Constant*, 16> Elts;
   
   for (unsigned i = 0; i != NumTys; ++i)
-    Elts.push_back(Tys[i].getCastToEmpty());
+    Elts.push_back(getCastToEmpty(Tys[i]));
   
-  const Type *EltTy = PointerType::getUnqual(StructType::get(NULL,NULL));
-  
-  Constant *Init = ConstantArray::get(ArrayType::get(EltTy, Elts.size()),
+  Constant *Init = ConstantArray::get(ArrayType::get(EmptyStructPtr,
+                                                     Elts.size()),
                                       &Elts[0], Elts.size());
   // If we already have this array, just return the uniqued version.
   DIDescriptor &Entry = SimpleConstantCache[Init];
@@ -333,7 +345,7 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
                                            const std::string &Producer) {
   Constant *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_compile_unit),
-    GetOrCreateCompileUnitAnchor().getCastToEmpty(),
+    getCastToEmpty(GetOrCreateCompileUnitAnchor()),
     ConstantInt::get(Type::Int32Ty, LangID),
     GetStringConstant(Filename),
     GetStringConstant(Directory),
@@ -377,18 +389,22 @@ DIBasicType DIFactory::CreateBasicType(DIDescriptor Context,
                                        uint64_t SizeInBits,
                                        uint64_t AlignInBits,
                                        uint64_t OffsetInBits, unsigned Flags,
-                                       unsigned Encoding) {
+                                       unsigned Encoding,
+                                       const std::string *FileName,
+                                       const std::string *Directory) {
   Constant *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_base_type),
-    Context.getCastToEmpty(),
+    getCastToEmpty(Context),
     GetStringConstant(Name),
-    CompileUnit.getCastToEmpty(),
+    getCastToEmpty(CompileUnit),
     ConstantInt::get(Type::Int32Ty, LineNumber),
     ConstantInt::get(Type::Int64Ty, SizeInBits),
     ConstantInt::get(Type::Int64Ty, AlignInBits),
     ConstantInt::get(Type::Int64Ty, OffsetInBits),
     ConstantInt::get(Type::Int32Ty, Flags),
-    ConstantInt::get(Type::Int32Ty, Encoding)
+    ConstantInt::get(Type::Int32Ty, Encoding),
+    GetStringConstant(FileName ? FileName->c_str() : ""),
+    GetStringConstant(Directory ? Directory->c_str() : "")
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -412,18 +428,22 @@ DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
                                            uint64_t AlignInBits,
                                            uint64_t OffsetInBits,
                                            unsigned Flags,
-                                           DIType DerivedFrom) {
+                                           DIType DerivedFrom,
+                                           const std::string *FileName,
+                                           const std::string *Directory) {
   Constant *Elts[] = {
     GetTagConstant(Tag),
-    Context.getCastToEmpty(),
+    getCastToEmpty(Context),
     GetStringConstant(Name),
-    CompileUnit.getCastToEmpty(),
+    getCastToEmpty(CompileUnit),
     ConstantInt::get(Type::Int32Ty, LineNumber),
     ConstantInt::get(Type::Int64Ty, SizeInBits),
     ConstantInt::get(Type::Int64Ty, AlignInBits),
     ConstantInt::get(Type::Int64Ty, OffsetInBits),
     ConstantInt::get(Type::Int32Ty, Flags),
-    DerivedFrom.getCastToEmpty()
+    getCastToEmpty(DerivedFrom),
+    GetStringConstant(FileName ? FileName->c_str() : ""),
+    GetStringConstant(Directory ? Directory->c_str() : "")
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -447,19 +467,24 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
                                                uint64_t OffsetInBits,
                                                unsigned Flags,
                                                DIType DerivedFrom,
-                                               DIArray Elements) {
+                                               DIArray Elements,
+                                               const std::string *FileName,
+                                               const std::string *Directory) {
+
   Constant *Elts[] = {
     GetTagConstant(Tag),
-    Context.getCastToEmpty(),
+    getCastToEmpty(Context),
     GetStringConstant(Name),
-    CompileUnit.getCastToEmpty(),
+    getCastToEmpty(CompileUnit),
     ConstantInt::get(Type::Int32Ty, LineNumber),
     ConstantInt::get(Type::Int64Ty, SizeInBits),
     ConstantInt::get(Type::Int64Ty, AlignInBits),
     ConstantInt::get(Type::Int64Ty, OffsetInBits),
     ConstantInt::get(Type::Int32Ty, Flags),
-    DerivedFrom.getCastToEmpty(),
-    Elements.getCastToEmpty()
+    getCastToEmpty(DerivedFrom),
+    getCastToEmpty(Elements),
+    GetStringConstant(FileName ? FileName->c_str() : ""),
+    GetStringConstant(Directory ? Directory->c_str() : "")
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -483,19 +508,24 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
                                          DICompileUnit CompileUnit,
                                          unsigned LineNo, DIType Type,
                                          bool isLocalToUnit,
-                                         bool isDefinition) {
+                                         bool isDefinition,
+                                         const std::string *FileName,
+                                         const std::string *Directory) {
+
   Constant *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_subprogram),
-    GetOrCreateSubprogramAnchor().getCastToEmpty(),
-    Context.getCastToEmpty(),
+    getCastToEmpty(GetOrCreateSubprogramAnchor()),
+    getCastToEmpty(Context),
     GetStringConstant(Name),
     GetStringConstant(DisplayName),
     GetStringConstant(LinkageName),
-    CompileUnit.getCastToEmpty(),
+    getCastToEmpty(CompileUnit),
     ConstantInt::get(Type::Int32Ty, LineNo),
-    Type.getCastToEmpty(),
+    getCastToEmpty(Type),
     ConstantInt::get(Type::Int1Ty, isLocalToUnit),
-    ConstantInt::get(Type::Int1Ty, isDefinition)
+    ConstantInt::get(Type::Int1Ty, isDefinition),
+    GetStringConstant(FileName ? FileName->c_str() : ""),
+    GetStringConstant(Directory ? Directory->c_str() : "")
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -515,22 +545,24 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
                                 const std::string &LinkageName,
                                 DICompileUnit CompileUnit,
                                 unsigned LineNo, DIType Type,bool isLocalToUnit,
-                                bool isDefinition, llvm::GlobalVariable *Val) {
-  
+                                bool isDefinition, llvm::GlobalVariable *Val,
+                                const std::string *FileName,
+                                const std::string *Directory) {
   Constant *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_variable),
-    GetOrCreateGlobalVariableAnchor().getCastToEmpty(),
-    Context.getCastToEmpty(),
+    getCastToEmpty(GetOrCreateGlobalVariableAnchor()),
+    getCastToEmpty(Context),
     GetStringConstant(Name),
     GetStringConstant(DisplayName),
     GetStringConstant(LinkageName),
-    CompileUnit.getCastToEmpty(),
+    getCastToEmpty(CompileUnit),
     ConstantInt::get(Type::Int32Ty, LineNo),
-    Type.getCastToEmpty(),
+    getCastToEmpty(Type),
     ConstantInt::get(Type::Int1Ty, isLocalToUnit),
     ConstantInt::get(Type::Int1Ty, isDefinition),
-    ConstantExpr::getBitCast(Val, 
-                             PointerType::getUnqual(StructType::get(NULL,NULL)))
+    ConstantExpr::getBitCast(Val, EmptyStructPtr),
+    GetStringConstant(FileName ? FileName->c_str() : ""),
+    GetStringConstant(Directory ? Directory->c_str() : "")
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -548,15 +580,20 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
 DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
                                      const std::string &Name,
                                      DICompileUnit CompileUnit, unsigned LineNo,
-                                     DIType Type) {
+                                     DIType Type,
+                                     const std::string *FileName,
+                                     const std::string *Directory) {
+
   
   Constant *Elts[] = {
     GetTagConstant(Tag),
-    Context.getCastToEmpty(),
+    getCastToEmpty(Context),
     GetStringConstant(Name),
-    CompileUnit.getCastToEmpty(),
+    getCastToEmpty(CompileUnit),
     ConstantInt::get(Type::Int32Ty, LineNo),
-    Type.getCastToEmpty(),
+    getCastToEmpty(Type),
+    GetStringConstant(FileName ? FileName->c_str() : ""),
+    GetStringConstant(Directory ? Directory->c_str() : "")
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -575,7 +612,7 @@ DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
 DIBlock DIFactory::CreateBlock(DIDescriptor Context) {
   Constant *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_lexical_block),
-    Context.getCastToEmpty()
+    getCastToEmpty(Context)
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -607,7 +644,7 @@ void DIFactory::InsertStopPoint(DICompileUnit CU, unsigned LineNo,
   Value *Args[] = {
     llvm::ConstantInt::get(llvm::Type::Int32Ty, LineNo),
     llvm::ConstantInt::get(llvm::Type::Int32Ty, ColNo),
-    CU.getCastToEmpty()
+    getCastToEmpty(CU)
   };
   CallInst::Create(StopPointFn, Args, Args+3, "", BB);
 }
@@ -621,7 +658,7 @@ void DIFactory::InsertSubprogramStart(DISubprogram SP, BasicBlock *BB) {
                                               llvm::Intrinsic::dbg_func_start);
   
   // Call llvm.dbg.func.start which also implicitly sets a stoppoint.
-  CallInst::Create(FuncStartFn, SP.getCastToEmpty(), "", BB);
+  CallInst::Create(FuncStartFn, getCastToEmpty(SP), "", BB);
 }
 
 /// InsertRegionStart - Insert a new llvm.dbg.region.start intrinsic call to
@@ -632,7 +669,7 @@ void DIFactory::InsertRegionStart(DIDescriptor D, BasicBlock *BB) {
     RegionStartFn = llvm::Intrinsic::getDeclaration(&M, 
                                             llvm::Intrinsic::dbg_region_start);
   // Call llvm.dbg.func.start.
-  CallInst::Create(RegionStartFn, D.getCastToEmpty(), "", BB);
+  CallInst::Create(RegionStartFn, getCastToEmpty(D), "", BB);
 }
 
 
@@ -644,19 +681,90 @@ void DIFactory::InsertRegionEnd(DIDescriptor D, BasicBlock *BB) {
     RegionEndFn = llvm::Intrinsic::getDeclaration(&M,
                                                llvm::Intrinsic::dbg_region_end);
   
-  CallInst::Create(RegionEndFn, D.getCastToEmpty(), "", BB);
+  CallInst::Create(RegionEndFn, getCastToEmpty(D), "", BB);
 }
 
 /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
 void DIFactory::InsertDeclare(llvm::Value *Storage, DIVariable D,
                               BasicBlock *BB) {
   // Cast the storage to a {}* for the call to llvm.dbg.declare.
-  const Type *DestTy = PointerType::getUnqual(StructType::get(NULL, NULL));
-  Storage = new llvm::BitCastInst(Storage, DestTy, Storage->getName(), BB);
+  Storage = new llvm::BitCastInst(Storage, EmptyStructPtr, "", BB);
   
   if (!DeclareFn)
     DeclareFn = llvm::Intrinsic::getDeclaration(&M,
                                                 llvm::Intrinsic::dbg_declare);
-  Value *Args[] = { Storage, D.getCastToEmpty() };
+  Value *Args[] = { Storage, getCastToEmpty(D) };
   CallInst::Create(DeclareFn, Args, Args+2, "", BB);
 }
+
+namespace llvm {
+  /// Finds the stoppoint coressponding to this instruction, that is the
+  /// stoppoint that dominates this instruction 
+  const DbgStopPointInst *findStopPoint(const Instruction *Inst)
+  {
+    if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(Inst))
+      return DSI;
+
+    const BasicBlock *BB = Inst->getParent();
+    BasicBlock::const_iterator I = Inst, B;
+    do {
+      B = BB->begin();
+      // A BB consisting only of a terminator can't have a stoppoint.
+      if (I != B) {
+        do {
+          --I;
+          if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(I))
+            return DSI;
+        } while (I != B);
+      }
+      // This BB didn't have a stoppoint: if there is only one
+      // predecessor, look for a stoppoint there.
+      // We could use getIDom(), but that would require dominator info.
+      BB = I->getParent()->getUniquePredecessor();
+      if (BB)
+        I = BB->getTerminator();
+    } while (BB != 0);
+    return 0;
+  }
+
+  /// Finds the stoppoint corresponding to first real (non-debug intrinsic) 
+  /// instruction in this Basic Block, and returns the stoppoint for it.
+  const DbgStopPointInst *findBBStopPoint(const BasicBlock *BB)
+  {
+    for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
+      if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(I))
+        return DSI;
+    }
+    // Fallback to looking for stoppoint of unique predecessor.
+    // Useful if this BB contains no stoppoints, but unique predecessor does.
+    BB = BB->getUniquePredecessor();
+    if (BB)
+      return findStopPoint(BB->getTerminator());
+    return 0;
+  }
+
+  /// Finds the dbg.declare intrinsic corresponding to this value if any.
+  /// It looks through pointer casts too.
+  const DbgDeclareInst *findDbgDeclare(const Value *V, bool stripCasts)
+  {
+    if (stripCasts) {
+      V = V->stripPointerCasts();
+      // Look for the bitcast.
+      for (Value::use_const_iterator I = V->use_begin(), E =V->use_end();
+            I != E; ++I) {
+        if (isa<BitCastInst>(I))
+          return findDbgDeclare(*I, false);
+      }
+      return 0;
+    }
+
+    // Find dbg.declare among uses of the instruction.
+    for (Value::use_const_iterator I = V->use_begin(), E =V->use_end();
+          I != E; ++I) {
+      if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I))
+        return DDI;
+    }
+    return 0;
+  }
+}
+