From b79b5359fbe44bc82bedff2c081ed1db787f8d49 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Mon, 19 Jan 2009 23:21:49 +0000 Subject: [PATCH] Verify debug info. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62545 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/DebugInfo.h | 17 ++++ lib/Analysis/DebugInfo.cpp | 94 +++++++++++++++++++ lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 19 +++- lib/CodeGen/SelectionDAG/FastISel.cpp | 10 +- .../SelectionDAG/SelectionDAGBuild.cpp | 8 +- 5 files changed, 138 insertions(+), 10 deletions(-) diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index e7c35816946..1eaa69a04cf 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -78,6 +78,7 @@ namespace llvm { unsigned getTag() const { return getUnsignedField(0) & ~VersionMask; } + }; /// DIAnchor - A wrapper for various anchor descriptors. @@ -117,6 +118,8 @@ namespace llvm { std::string getFilename() const { return getStringField(3); } std::string getDirectory() const { return getStringField(4); } std::string getProducer() const { return getStringField(5); } + /// Verify - Verify that a compile unit is well formed. + bool Verify() const; }; /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). @@ -155,6 +158,8 @@ namespace llvm { return TAG == dwarf::DW_TAG_base_type; } + /// Verify - Verify that a type descriptor is well formed. + bool Verify() const; public: explicit DIType(GlobalVariable *GV); explicit DIType() {} @@ -217,6 +222,9 @@ namespace llvm { DIArray getTypeArray() const { return getFieldAs(10); } std::string getFilename() const { return getStringField(11); } std::string getDirectory() const { return getStringField(12); } + + /// Verify - Verify that a composite type descriptor is well formed. + bool Verify() const; }; /// DIGlobal - This is a common class for global variables and subprograms. @@ -273,6 +281,9 @@ namespace llvm { std::string getFilename() const { return getStringField(11); } std::string getDirectory() const { return getStringField(12); } DICompositeType getType() const { return getFieldAs(8); } + + /// Verify - Verify that a subprogram descriptor is well formed. + bool Verify() const; }; /// DIGlobalVariable - This is a wrapper for a global variable. @@ -283,6 +294,9 @@ namespace llvm { GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } std::string getFilename() const { return getStringField(12); } std::string getDirectory() const { return getStringField(13); } + + /// Verify - Verify that a global variable descriptor is well formed. + bool Verify() const; }; @@ -303,6 +317,9 @@ namespace llvm { /// isVariable - Return true if the specified tag is legal for DIVariable. static bool isVariable(unsigned Tag); + + /// Verify - Verify that a variable descriptor is well formed. + bool Verify() const; }; diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index f27321780e0..98335ae2dcc 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -180,6 +180,100 @@ unsigned DIArray::getNumElements() const { 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; +} + + + //===----------------------------------------------------------------------===// // DIFactory: Basic Helpers //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index f74e1a46e69..18be9bf3b5c 100644 --- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -3029,6 +3029,9 @@ public: /// ValidDebugInfo - Return true if V represents valid debug info value. bool ValidDebugInfo(Value *V) { + if (!V) + return false; + if (!shouldEmit) return false; @@ -3046,7 +3049,21 @@ public: if (Version != DIDescriptor::Version7 && Version != DIDescriptor::Version6) return false; - //FIXME - Check individual descriptors. + unsigned Tag = DI.getTag(); + switch (Tag) { + case DW_TAG_variable: + assert (DIVariable(GV).Verify() && "Invalid DebugInfo value"); + break; + case DW_TAG_compile_unit: + assert (DICompileUnit(GV).Verify() && "Invalid DebugInfo value"); + break; + case DW_TAG_subprogram: + assert (DISubprogram(GV).Verify() && "Invalid DebugInfo value"); + break; + default: + break; + } + return true; } diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index d797d909c86..dff75510ac1 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -317,7 +317,7 @@ bool FastISel::SelectCall(User *I) { default: break; case Intrinsic::dbg_stoppoint: { DbgStopPointInst *SPI = cast(I); - if (DW && SPI->getContext() && DW->ValidDebugInfo(SPI->getContext())) { + if (DW && DW->ValidDebugInfo(SPI->getContext())) { DICompileUnit CU(cast(SPI->getContext())); unsigned SrcFile = DW->RecordSource(CU.getDirectory(), CU.getFilename()); @@ -331,7 +331,7 @@ bool FastISel::SelectCall(User *I) { } case Intrinsic::dbg_region_start: { DbgRegionStartInst *RSI = cast(I); - if (DW && RSI->getContext() && DW->ValidDebugInfo(RSI->getContext())) { + if (DW && DW->ValidDebugInfo(RSI->getContext())) { unsigned ID = DW->RecordRegionStart(cast(RSI->getContext())); const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); @@ -341,7 +341,7 @@ bool FastISel::SelectCall(User *I) { } case Intrinsic::dbg_region_end: { DbgRegionEndInst *REI = cast(I); - if (DW && REI->getContext() && DW->ValidDebugInfo(REI->getContext())) { + if (DW && DW->ValidDebugInfo(REI->getContext())) { unsigned ID = DW->RecordRegionEnd(cast(REI->getContext())); const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); @@ -353,7 +353,7 @@ bool FastISel::SelectCall(User *I) { if (!DW) return true; DbgFuncStartInst *FSI = cast(I); Value *SP = FSI->getSubprogram(); - if (SP && DW->ValidDebugInfo(SP)) { + if (DW->ValidDebugInfo(SP)) { // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is // what (most?) gdb expects. DISubprogram Subprogram(cast(SP)); @@ -375,7 +375,7 @@ bool FastISel::SelectCall(User *I) { case Intrinsic::dbg_declare: { DbgDeclareInst *DI = cast(I); Value *Variable = DI->getVariable(); - if (DW && Variable && DW->ValidDebugInfo(Variable)) { + if (DW && DW->ValidDebugInfo(Variable)) { // Determine the address of the declared object. Value *Address = DI->getAddress(); if (BitCastInst *BCI = dyn_cast(Address)) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 7dc64e01ff1..21bf911a9b5 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -3747,7 +3747,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { case Intrinsic::dbg_stoppoint: { DwarfWriter *DW = DAG.getDwarfWriter(); DbgStopPointInst &SPI = cast(I); - if (DW && SPI.getContext() && DW->ValidDebugInfo(SPI.getContext())) + if (DW && DW->ValidDebugInfo(SPI.getContext())) DAG.setRoot(DAG.getDbgStopPoint(getRoot(), SPI.getLine(), SPI.getColumn(), @@ -3757,7 +3757,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { case Intrinsic::dbg_region_start: { DwarfWriter *DW = DAG.getDwarfWriter(); DbgRegionStartInst &RSI = cast(I); - if (DW && RSI.getContext() && DW->ValidDebugInfo(RSI.getContext())) { + if (DW && DW->ValidDebugInfo(RSI.getContext())) { unsigned LabelID = DW->RecordRegionStart(cast(RSI.getContext())); DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID)); @@ -3768,7 +3768,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { case Intrinsic::dbg_region_end: { DwarfWriter *DW = DAG.getDwarfWriter(); DbgRegionEndInst &REI = cast(I); - if (DW && REI.getContext() && DW->ValidDebugInfo(REI.getContext())) { + if (DW && DW->ValidDebugInfo(REI.getContext())) { unsigned LabelID = DW->RecordRegionEnd(cast(REI.getContext())); DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID)); @@ -3803,7 +3803,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { DwarfWriter *DW = DAG.getDwarfWriter(); DbgDeclareInst &DI = cast(I); Value *Variable = DI.getVariable(); - if (DW && Variable && DW->ValidDebugInfo(Variable)) + if (DW && DW->ValidDebugInfo(Variable)) DAG.setRoot(DAG.getNode(ISD::DECLARE, MVT::Other, getRoot(), getValue(DI.getAddress()), getValue(Variable))); return 0;