aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/DebugInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/DebugInfo.cpp')
-rw-r--r--lib/Analysis/DebugInfo.cpp117
1 files changed, 117 insertions, 0 deletions
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp
index ff411a6935..7ecb1ad8d4 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.