aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Analysis/DebugInfo.h53
-rw-r--r--lib/Analysis/DebugInfo.cpp117
2 files changed, 170 insertions, 0 deletions
diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h
index b8e4c6c..4e511eb 100644
--- a/include/llvm/Analysis/DebugInfo.h
+++ b/include/llvm/Analysis/DebugInfo.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Dwarf.h"
namespace llvm {
@@ -609,6 +610,58 @@ namespace llvm {
/// isInlinedFnEnd - Return true if REI is ending an inlined function.
bool isInlinedFnEnd(DbgRegionEndInst &REI, const Function *CurrentFn);
+ /// DebugInfoEnumrator - This object collects DebugInfo from
+ /// the module.
+ class DebugInfoEnumerator {
+
+ public:
+ /// EnumerateModule - Enumerate entire module and collect debug info
+ /// anchors.
+ void enumerateModule(Module &M);
+
+ private:
+ /// enumerateType - Enumerate DIType.
+ /// for a type.
+ void enumerateType(DIType DT);
+
+ /// enumerateSubprogram - Enumberate DISubprogram.
+ void enumerateSubprogram(DISubprogram SP);
+
+ /// enumerateStopPoint - Enumerate DbgStopPointInst.
+ void enumerateStopPoint(DbgStopPointInst *SPI);
+
+ /// enumerateFuncStart - Enumberate DbgFuncStartInst.
+ void enumerateFuncStart(DbgFuncStartInst *FSI);
+
+ /// addCompileUnit - Add compile unit into CUs.
+ bool addCompileUnit(DICompileUnit CU);
+
+ /// addGlobalVariable - Add global variable into GVs.
+ bool addGlobalVariable(DIGlobalVariable DIG);
+
+ // addSubprogram - Add subprgoram into SPs.
+ bool addSubprogram(DISubprogram SP);
+
+ public:
+ typedef SmallVector<GlobalVariable *, 8>::iterator iterator;
+ iterator compile_unit_begin() { return CUs.begin(); }
+ iterator compile_unit_end() { return CUs.end(); }
+ iterator subprogram_begin() { return SPs.begin(); }
+ iterator subprogram_end() { return SPs.end(); }
+ iterator global_variable_begin() { return GVs.begin(); }
+ iterator global_variable_end() { return GVs.end(); }
+
+ unsigned compile_unit_count() { return CUs.size(); }
+ unsigned global_variable_count() { return GVs.size(); }
+ unsigned subprogram_count() { return SPs.size(); }
+
+ private:
+ SmallVector<GlobalVariable *, 8> CUs; // Compile Units
+ SmallVector<GlobalVariable *, 8> SPs; // Subprograms
+ SmallVector<GlobalVariable *, 8> GVs; // Global Variables;
+ SmallPtrSet<GlobalVariable *, 64> NodesSeen;
+
+ };
} // end namespace llvm
#endif
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp
index ff411a6..7ecb1ad 100644
--- a/lib/Analysis/DebugInfo.cpp
+++ b/lib/Analysis/DebugInfo.cpp
@@ -105,6 +105,7 @@ DIDescriptor::getStringField(unsigned Elt, std::string &Result) const {
uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {
if (DbgGV == 0) return 0;
+ if (!DbgGV->hasInitializer()) return 0;
Constant *C = DbgGV->getInitializer();
if (C == 0 || Elt >= C->getNumOperands())
@@ -904,6 +905,122 @@ void DIFactory::InsertDeclare(Value *Storage, DIVariable D, BasicBlock *BB) {
CallInst::Create(DeclareFn, Args, Args+2, "", BB);
}
+//===----------------------------------------------------------------------===//
+// DebugInfoEnumerator implementations.
+//===----------------------------------------------------------------------===//
+
+/// enumerateModule - Enumerate entire module and collect debug info.
+void DebugInfoEnumerator::enumerateModule(Module &M) {
+
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI)
+ for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); BI != BE;
+ ++BI) {
+ if (DbgStopPointInst *SPI = dyn_cast<DbgStopPointInst>(BI))
+ enumerateStopPoint(SPI);
+ else if (DbgFuncStartInst *FSI = dyn_cast<DbgFuncStartInst>(BI))
+ enumerateFuncStart(FSI);
+ }
+
+ for (Module::global_iterator GVI = M.global_begin(), GVE = M.global_end();
+ GVI != GVE; ++GVI) {
+ GlobalVariable *GV = GVI;
+ if (!GV->hasName() || !GV->isConstant()
+ || strcmp(GV->getName().data(), "llvm.dbg.global_variable")
+ || !GV->hasInitializer())
+ continue;
+ DIGlobalVariable DIG(GV);
+ if (addGlobalVariable(DIG)) {
+ addCompileUnit(DIG.getCompileUnit());
+ enumerateType(DIG.getType());
+ }
+ }
+}
+
+/// enumerateType - Enumerate DIType.
+void DebugInfoEnumerator::enumerateType(DIType DT) {
+ if (DT.isNull())
+ return;
+ if (!NodesSeen.insert(DT.getGV()))
+ return;
+
+ addCompileUnit(DT.getCompileUnit());
+ if (DT.isCompositeType(DT.getTag())) {
+ DICompositeType DCT(DT.getGV());
+ enumerateType(DCT.getTypeDerivedFrom());
+ DIArray DA = DCT.getTypeArray();
+ if (!DA.isNull())
+ for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) {
+ DIDescriptor D = DA.getElement(i);
+ DIType TypeE = DIType(D.getGV());
+ if (!TypeE.isNull())
+ enumerateType(TypeE);
+ else
+ enumerateSubprogram(DISubprogram(D.getGV()));
+ }
+ } else if (DT.isDerivedType(DT.getTag())) {
+ DIDerivedType DDT(DT.getGV());
+ if (!DDT.isNull())
+ enumerateType(DDT.getTypeDerivedFrom());
+ }
+}
+
+/// enumerateSubprogram - Enumberate DISubprogram.
+void DebugInfoEnumerator::enumerateSubprogram(DISubprogram SP) {
+ if (!addSubprogram(SP))
+ return;
+ addCompileUnit(SP.getCompileUnit());
+ enumerateType(SP.getType());
+}
+
+/// enumerateStopPoint - Enumerate DbgStopPointInst.
+void DebugInfoEnumerator::enumerateStopPoint(DbgStopPointInst *SPI) {
+ GlobalVariable *Context = dyn_cast<GlobalVariable>(SPI->getContext());
+ addCompileUnit(DICompileUnit(Context));
+}
+
+/// enumerateFuncStart - Enumberate DbgFuncStartInst.
+void DebugInfoEnumerator::enumerateFuncStart(DbgFuncStartInst *FSI) {
+ GlobalVariable *SP = dyn_cast<GlobalVariable>(FSI->getSubprogram());
+ enumerateSubprogram(DISubprogram(SP));
+}
+
+/// addCompileUnit - Add compile unit into CUs.
+bool DebugInfoEnumerator::addCompileUnit(DICompileUnit CU) {
+ if (CU.isNull())
+ return false;
+
+ if (!NodesSeen.insert(CU.getGV()))
+ return false;
+
+ CUs.push_back(CU.getGV());
+ return true;
+}
+
+/// addGlobalVariable - Add global variable into GVs.
+bool DebugInfoEnumerator::addGlobalVariable(DIGlobalVariable DIG) {
+ if (DIG.isNull())
+ return false;
+
+ if (!NodesSeen.insert(DIG.getGV()))
+ return false;
+
+ GVs.push_back(DIG.getGV());
+ return true;
+}
+
+// addSubprogram - Add subprgoram into SPs.
+bool DebugInfoEnumerator::addSubprogram(DISubprogram SP) {
+ if (SP.isNull())
+ return false;
+
+ if (!NodesSeen.insert(SP.getGV()))
+ return false;
+
+ SPs.push_back(SP.getGV());
+ return true;
+}
+
namespace llvm {
/// findStopPoint - Find the stoppoint coressponding to this instruction, that
/// is the stoppoint that dominates this instruction.