Verify debug info.
authorDevang Patel <dpatel@apple.com>
Mon, 19 Jan 2009 23:21:49 +0000 (23:21 +0000)
committerDevang Patel <dpatel@apple.com>
Mon, 19 Jan 2009 23:21:49 +0000 (23:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62545 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/DebugInfo.h
lib/Analysis/DebugInfo.cpp
lib/CodeGen/AsmPrinter/DwarfWriter.cpp
lib/CodeGen/SelectionDAG/FastISel.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp

index e7c3581694646ee90daf9b05a5265990f2f35e94..1eaa69a04cf85cd76bd209bd6d61205a69529cc9 100644 (file)
@@ -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<DIArray>(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<DICompositeType>(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;
   };
   
   
index f27321780e0c9d8c40601674376958cd9e86add5..98335ae2dcca65bed9e4c3cf477bd914775135ec 100644 (file)
@@ -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
 //===----------------------------------------------------------------------===//
index f74e1a46e69d7b5a2264396532e192f2ead780d2..18be9bf3b5c8db5f74c8e2d7529550ff0cf39a7e 100644 (file)
@@ -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;
   }
 
index d797d909c86640ca9ee312b30efd5213f1df54f4..dff75510ac13b280bf0658454a7e4d58e8261b39 100644 (file)
@@ -317,7 +317,7 @@ bool FastISel::SelectCall(User *I) {
   default: break;
   case Intrinsic::dbg_stoppoint: {
     DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
-    if (DW && SPI->getContext() && DW->ValidDebugInfo(SPI->getContext())) {
+    if (DW && DW->ValidDebugInfo(SPI->getContext())) {
       DICompileUnit CU(cast<GlobalVariable>(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<DbgRegionStartInst>(I);
-    if (DW && RSI->getContext() && DW->ValidDebugInfo(RSI->getContext())) {
+    if (DW && DW->ValidDebugInfo(RSI->getContext())) {
       unsigned ID = 
         DW->RecordRegionStart(cast<GlobalVariable>(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<DbgRegionEndInst>(I);
-    if (DW && REI->getContext() && DW->ValidDebugInfo(REI->getContext())) {
+    if (DW && DW->ValidDebugInfo(REI->getContext())) {
       unsigned ID = 
         DW->RecordRegionEnd(cast<GlobalVariable>(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<DbgFuncStartInst>(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<GlobalVariable>(SP));
@@ -375,7 +375,7 @@ bool FastISel::SelectCall(User *I) {
   case Intrinsic::dbg_declare: {
     DbgDeclareInst *DI = cast<DbgDeclareInst>(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<BitCastInst>(Address))
index 7dc64e01ff19d82c143825de5a42de699b68431d..21bf911a9b5904663f0c18dd2170adde0604defe 100644 (file)
@@ -3747,7 +3747,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
   case Intrinsic::dbg_stoppoint: {
     DwarfWriter *DW = DAG.getDwarfWriter();
     DbgStopPointInst &SPI = cast<DbgStopPointInst>(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<DbgRegionStartInst>(I);
-    if (DW && RSI.getContext() && DW->ValidDebugInfo(RSI.getContext())) {
+    if (DW && DW->ValidDebugInfo(RSI.getContext())) {
       unsigned LabelID =
         DW->RecordRegionStart(cast<GlobalVariable>(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<DbgRegionEndInst>(I);
-    if (DW && REI.getContext() && DW->ValidDebugInfo(REI.getContext())) {
+    if (DW && DW->ValidDebugInfo(REI.getContext())) {
       unsigned LabelID =
         DW->RecordRegionEnd(cast<GlobalVariable>(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<DbgDeclareInst>(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;