unsigned getTag() const {
return getUnsignedField(0) & ~VersionMask;
}
+
};
/// DIAnchor - A wrapper for various anchor descriptors.
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}').
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() {}
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.
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.
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;
};
/// 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;
};
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
//===----------------------------------------------------------------------===//
/// ValidDebugInfo - Return true if V represents valid debug info value.
bool ValidDebugInfo(Value *V) {
+ if (!V)
+ return false;
+
if (!shouldEmit)
return false;
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;
}
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());
}
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);
}
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);
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));
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))
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(),
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));
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));
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;