Propagate debug loc info through prologue/epilogue.
[oota-llvm.git] / lib / Analysis / DebugInfo.cpp
index c46091c9554d3685d7ae5d4d447bd63e95222c5d..12bb2921f51ee5dc04869149c788a5599f6eced2 100644 (file)
 #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"
-#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Streams.h"
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
@@ -111,7 +112,7 @@ DIType::DIType(GlobalVariable *gv) : DIDescriptor(gv) {
 
 /// isDerivedType - Return true if the specified tag is legal for
 /// DIDerivedType.
-bool DIDerivedType::isDerivedType(unsigned Tag) {
+bool DIType::isDerivedType(unsigned Tag) {
   switch (Tag) {
   case dwarf::DW_TAG_typedef:
   case dwarf::DW_TAG_pointer_type:
@@ -136,7 +137,7 @@ DIDerivedType::DIDerivedType(GlobalVariable *GV) : DIType(GV, true, true) {
 
 /// isCompositeType - Return true if the specified tag is legal for
 /// DICompositeType.
-bool DICompositeType::isCompositeType(unsigned TAG) {
+bool DIType::isCompositeType(unsigned TAG) {
   switch (TAG) {
   case dwarf::DW_TAG_array_type:
   case dwarf::DW_TAG_structure_type:
@@ -168,12 +169,120 @@ bool DIVariable::isVariable(unsigned Tag) {
   }
 }
 
-DIVariable::DIVariable(GlobalVariable *GV) : DIDescriptor(GV) {
-  if (GV && !isVariable(getTag()))
+DIVariable::DIVariable(GlobalVariable *gv) : DIDescriptor(gv) {
+  if (gv && !isVariable(getTag()))
     GV = 0;
 }
 
+unsigned DIArray::getNumElements() const {
+  assert (GV && "Invalid DIArray");
+  Constant *C = GV->getInitializer();
+  assert (C && "Invalid DIArray initializer");
+  return C->getNumOperands();
+}
+
+/// Verify - Verify that a compile unit is well formed.
+bool DICompileUnit::Verify() const {
+  if (isNull()) 
+    return false;
+  if (getFilename().empty()) 
+    return false;
+  // It is possible that directory and produce string is empty.
+  return true;
+}
+
+/// Verify - Verify that a type descriptor is well formed.
+bool DIType::Verify() const {
+  if (isNull()) 
+    return false;
+  if (getContext().isNull()) 
+    return false;
+
+  DICompileUnit CU = getCompileUnit();
+  if (!CU.isNull() && !CU.Verify()) 
+    return false;
+  return true;
+}
+
+/// Verify - Verify that a composite type descriptor is well formed.
+bool DICompositeType::Verify() const {
+  if (isNull()) 
+    return false;
+  if (getContext().isNull()) 
+    return false;
 
+  DICompileUnit CU = getCompileUnit();
+  if (!CU.isNull() && !CU.Verify()) 
+    return false;
+  return true;
+}
+
+/// Verify - Verify that a subprogram descriptor is well formed.
+bool DISubprogram::Verify() const {
+  if (isNull())
+    return false;
+  
+  if (getContext().isNull())
+    return false;
+
+  DICompileUnit CU = getCompileUnit();
+  if (!CU.Verify()) 
+    return false;
+
+  DICompositeType Ty = getType();
+  if (!Ty.isNull() && !Ty.Verify())
+    return false;
+  return true;
+}
+
+/// Verify - Verify that a global variable descriptor is well formed.
+bool DIGlobalVariable::Verify() const {
+  if (isNull())
+    return false;
+  
+  if (getContext().isNull())
+    return false;
+
+  DICompileUnit CU = getCompileUnit();
+  if (!CU.Verify()) 
+    return false;
+
+  DIType Ty = getType();
+  if (!Ty.Verify())
+    return false;
+
+  if (!getGlobal())
+    return false;
+
+  return true;
+}
+
+/// Verify - Verify that a variable descriptor is well formed.
+bool DIVariable::Verify() const {
+  if (isNull())
+    return false;
+  
+  if (getContext().isNull())
+    return false;
+
+  DIType Ty = getType();
+  if (!Ty.Verify())
+    return false;
+
+
+  return true;
+}
+
+/// getOriginalTypeSize - If this type is derived from a base type then
+/// return base type size.
+uint64_t DIDerivedType::getOriginalTypeSize() const {
+  if (getTag() != dwarf::DW_TAG_member)
+    return getSizeInBits();
+  DIType BT = getTypeDerivedFrom();
+  if (BT.getTag() != dwarf::DW_TAG_base_type)
+    return getSizeInBits();
+  return BT.getSizeInBits();
+}
 
 //===----------------------------------------------------------------------===//
 // DIFactory: Basic Helpers
@@ -192,9 +301,9 @@ Constant *DIFactory::getCastToEmpty(DIDescriptor D) {
 }
 
 Constant *DIFactory::GetTagConstant(unsigned TAG) {
-  assert((TAG & DIDescriptor::VersionMask) == 0 &&
+  assert((TAG & LLVMDebugVersionMask) == 0 &&
          "Tag too large for debug encoding!");
-  return ConstantInt::get(Type::Int32Ty, TAG | DIDescriptor::Version6);
+  return ConstantInt::get(Type::Int32Ty, TAG | LLVMDebugVersion);
 }
 
 Constant *DIFactory::GetStringConstant(const std::string &String) {
@@ -341,14 +450,22 @@ DISubrange DIFactory::GetOrCreateSubrange(int64_t Lo, int64_t Hi) {
 DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
                                            const std::string &Filename,
                                            const std::string &Directory,
-                                           const std::string &Producer) {
+                                           const std::string &Producer,
+                                           bool isMain,
+                                           bool isOptimized,
+                                           const char *Flags,
+                                           unsigned RunTimeVer) {
   Constant *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_compile_unit),
     getCastToEmpty(GetOrCreateCompileUnitAnchor()),
     ConstantInt::get(Type::Int32Ty, LangID),
     GetStringConstant(Filename),
     GetStringConstant(Directory),
-    GetStringConstant(Producer)
+    GetStringConstant(Producer),
+    ConstantInt::get(Type::Int1Ty, isMain),
+    ConstantInt::get(Type::Int1Ty, isOptimized),
+    GetStringConstant(Flags),
+    ConstantInt::get(Type::Int32Ty, RunTimeVer)
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -458,7 +575,9 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
                                                uint64_t OffsetInBits,
                                                unsigned Flags,
                                                DIType DerivedFrom,
-                                               DIArray Elements) {
+                                               DIArray Elements,
+                                               unsigned RuntimeLang) {
+
   Constant *Elts[] = {
     GetTagConstant(Tag),
     getCastToEmpty(Context),
@@ -470,7 +589,8 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
     ConstantInt::get(Type::Int64Ty, OffsetInBits),
     ConstantInt::get(Type::Int32Ty, Flags),
     getCastToEmpty(DerivedFrom),
-    getCastToEmpty(Elements)
+    getCastToEmpty(Elements),
+    ConstantInt::get(Type::Int32Ty, RuntimeLang)
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -495,6 +615,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
                                          unsigned LineNo, DIType Type,
                                          bool isLocalToUnit,
                                          bool isDefinition) {
+
   Constant *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_subprogram),
     getCastToEmpty(GetOrCreateSubprogramAnchor()),
@@ -527,7 +648,6 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
                                 DICompileUnit CompileUnit,
                                 unsigned LineNo, DIType Type,bool isLocalToUnit,
                                 bool isDefinition, llvm::GlobalVariable *Val) {
-  
   Constant *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_variable),
     getCastToEmpty(GetOrCreateGlobalVariableAnchor()),
@@ -559,14 +679,13 @@ DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
                                      const std::string &Name,
                                      DICompileUnit CompileUnit, unsigned LineNo,
                                      DIType Type) {
-  
   Constant *Elts[] = {
     GetTagConstant(Tag),
     getCastToEmpty(Context),
     GetStringConstant(Name),
     getCastToEmpty(CompileUnit),
     ConstantInt::get(Type::Int32Ty, LineNo),
-    getCastToEmpty(Type),
+    getCastToEmpty(Type)
   };
   
   Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0]));
@@ -669,3 +788,175 @@ void DIFactory::InsertDeclare(llvm::Value *Storage, DIVariable D,
   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;
+  }
+}
+
+/// dump - print compile unit.
+void DICompileUnit::dump() const {
+  cerr << " [" << dwarf::LanguageString(getLanguage()) << "] ";
+  cerr << " [" << getDirectory() << "/" << getFilename() << " ]";
+}
+
+/// dump - print type.
+void DIType::dump() const {
+  if (isNull()) return;
+  if (!getName().empty())
+    cerr << " [" << getName() << "] ";
+  unsigned Tag = getTag();
+  cerr << " [" << dwarf::TagString(Tag) << "] ";
+  // TODO : Print context
+  getCompileUnit().dump();
+  cerr << " [" 
+       << getLineNumber() << ", " 
+       << getSizeInBits() << ", "
+       << getAlignInBits() << ", "
+       << getOffsetInBits() 
+       << "] ";
+  if (isPrivate()) 
+    cerr << " [private] ";
+  else if (isProtected())
+    cerr << " [protected] ";
+  if (isForwardDecl())
+    cerr << " [fwd] ";
+
+  if (isBasicType(Tag))
+    DIBasicType(GV).dump();
+  else if (isDerivedType(Tag))
+    DIDerivedType(GV).dump();
+  else if (isCompositeType(Tag))
+    DICompositeType(GV).dump();
+  else {
+    cerr << "Invalid DIType\n";
+    return;
+  }
+  cerr << "\n";
+}
+
+/// dump - print basic type.
+void DIBasicType::dump() const {
+  cerr << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] ";
+
+}
+
+/// dump - print derived type.
+void DIDerivedType::dump() const {
+  cerr << "\n\t Derived From: "; getTypeDerivedFrom().dump();
+}
+
+/// dump - print composite type.
+void DICompositeType::dump() const {
+  DIArray A = getTypeArray();
+  if (A.isNull())
+    return;
+  cerr << " [" << A.getNumElements() << " elements]";
+}
+
+/// dump - print global.
+void DIGlobal::dump() const {
+
+  if (!getName().empty())
+    cerr << " [" << getName() << "] ";
+  unsigned Tag = getTag();
+  cerr << " [" << dwarf::TagString(Tag) << "] ";
+  // TODO : Print context
+  getCompileUnit().dump();
+  cerr << " [" << getLineNumber() << "] ";
+  if (isLocalToUnit())
+    cerr << " [local] ";
+  if (isDefinition())
+    cerr << " [def] ";
+
+  if (isGlobalVariable(Tag))
+    DIGlobalVariable(GV).dump();
+
+  cerr << "\n";
+}
+
+/// dump - print subprogram.
+void DISubprogram::dump() const {
+  DIGlobal::dump();
+}
+
+/// dump - print global variable.
+void DIGlobalVariable::dump() const {
+  cerr << " ["; getGlobal()->dump(); cerr << "] ";
+}
+
+/// dump - print variable.
+void DIVariable::dump() const {
+  if (!getName().empty())
+    cerr << " [" << getName() << "] ";
+  getCompileUnit().dump();
+  cerr << " [" << getLineNumber() << "] ";
+  getType().dump();
+  cerr << "\n";
+}