Skip to content
MachineDebugInfo.cpp 41.1 KiB
Newer Older
}

/// getAnchorString - Return a string used to label this descriptor's anchor.
///
const char *GlobalVariableDesc::AnchorString = "llvm.dbg.global_variables";
const char *GlobalVariableDesc::getAnchorString() const {
  return AnchorString;
#ifndef NDEBUG
void GlobalVariableDesc::dump() {
            << "Tag(" << getTag() << "), "
            << "Anchor(" << getAnchor() << "), "
            << "Name(\"" << getName() << "\"), "
            << "File(" << getFile() << "),"
            << "Line(" << getLine() << "),"
            << "Type(\"" << getTypeDesc() << "\"), "
            << "IsStatic(" << (isStatic() ? "true" : "false") << "), "
            << "IsDefinition(" << (isDefinition() ? "true" : "false") << "), "
            << "Global(" << Global << ")\n";
#endif

//===----------------------------------------------------------------------===//

// Implement isa/cast/dyncast.
bool SubprogramDesc::classof(const DebugInfoDesc *D) {
  return D->getTag() == DW_TAG_subprogram;
}

Jim Laskey's avatar
Jim Laskey committed
/// ApplyToFields - Target the visitor to the fields of the
Jim Laskey's avatar
Jim Laskey committed
void SubprogramDesc::ApplyToFields(DIVisitor *Visitor) {

  Visitor->Apply(Elements);
}

/// getDescString - Return a string used to compose global names and labels.
///
const char *SubprogramDesc::getDescString() const {
  return "llvm.dbg.subprogram";
}

/// getTypeString - Return a string used to label this descriptors type.
///
const char *SubprogramDesc::getTypeString() const {
  return "llvm.dbg.subprogram.type";
/// getAnchorString - Return a string used to label this descriptor's anchor.
const char *SubprogramDesc::AnchorString = "llvm.dbg.subprograms";
const char *SubprogramDesc::getAnchorString() const {
  return AnchorString;
#ifndef NDEBUG
void SubprogramDesc::dump() {
            << "Tag(" << getTag() << "), "
            << "Anchor(" << getAnchor() << "), "
            << "Name(\"" << getName() << "\"), "
            << "File(" << getFile() << "),"
            << "Line(" << getLine() << "),"
            << "Type(\"" << getTypeDesc() << "\"), "
            << "IsStatic(" << (isStatic() ? "true" : "false") << "), "
            << "IsDefinition(" << (isDefinition() ? "true" : "false") << ")\n";
//===----------------------------------------------------------------------===//

BlockDesc::BlockDesc()
: DebugInfoDesc(DW_TAG_lexical_block)
{}

// Implement isa/cast/dyncast.
bool BlockDesc::classof(const DebugInfoDesc *D) {
  return D->getTag() == DW_TAG_lexical_block;
}

/// ApplyToFields - Target the visitor to the fields of the BlockDesc.
///
void BlockDesc::ApplyToFields(DIVisitor *Visitor) {
  DebugInfoDesc::ApplyToFields(Visitor);

  Visitor->Apply(Elements);
}

/// getDescString - Return a string used to compose global names and labels.
///
const char *BlockDesc::getDescString() const {
  return "llvm.dbg.block";
}

/// getTypeString - Return a string used to label this descriptors type.
///
const char *BlockDesc::getTypeString() const {
  return "llvm.dbg.block.type";
}

#ifndef NDEBUG
void BlockDesc::dump() {
  std::cerr << getDescString() << " "
            << "Tag(" << getTag() << ")\n";
}
#endif

//===----------------------------------------------------------------------===//

DebugInfoDesc *DIDeserializer::Deserialize(Value *V) {
  return Deserialize(getGlobalVariable(V));
DebugInfoDesc *DIDeserializer::Deserialize(GlobalVariable *GV) {
  // Check to see if it has been already deserialized.
  DebugInfoDesc *&Slot = GlobalDescs[GV];
  if (Slot) return Slot;
  // Get the Tag from the global.
  unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
  
  // Get the debug version if a compile unit.
    DebugVersion = CompileUnitDesc::DebugVersionFromGlobal(GV);
  }
  
  // Create an empty instance of the correct sort.
  Slot = DebugInfoDesc::DescFactory(Tag);
  
  // If not a user defined descriptor.
  if (Slot) {
    // Deserialize the fields.
    DIDeserializeVisitor DRAM(*this, GV);
    DRAM.ApplyToFields(Slot);
  }
//===----------------------------------------------------------------------===//

/// getStrPtrType - Return a "sbyte *" type.
const PointerType *DISerializer::getStrPtrType() {
  // If not already defined.
  if (!StrPtrTy) {
    // Construct the pointer to signed bytes.
    StrPtrTy = PointerType::get(Type::SByteTy);
  }
  
  return StrPtrTy;
/// getEmptyStructPtrType - Return a "{ }*" type.
const PointerType *DISerializer::getEmptyStructPtrType() {
  // If not already defined.
  if (!EmptyStructPtrTy) {
    // Construct the empty structure type.
    const StructType *EmptyStructTy =
                                    StructType::get(std::vector<const Type*>());
    // Construct the pointer to empty structure type.
    EmptyStructPtrTy = PointerType::get(EmptyStructTy);
  }
  
  return EmptyStructPtrTy;
/// getTagType - Return the type describing the specified descriptor (via tag.)
const StructType *DISerializer::getTagType(DebugInfoDesc *DD) {
  // Attempt to get the previously defined type.
  StructType *&Ty = TagTypes[DD->getTag()];
  
  // If not already defined.
  if (!Ty) {
    // Set up fields vector.
    std::vector<const Type*> Fields;
Jim Laskey's avatar
Jim Laskey committed
    DIGetTypesVisitor GTAM(*this, Fields);
    GTAM.ApplyToFields(DD);

    // Construct structured type.
    Ty = StructType::get(Fields);
    
    // Register type name with module.
    M->addTypeName(DD->getTypeString(), Ty);
/// getString - Construct the string as constant string global.
Constant *DISerializer::getString(const std::string &String) {
  // Check string cache for previous edition.
  Constant *&Slot = StringCache[String];
  // Return Constant if previously defined.
  // If empty string then use a sbyte* null instead.
  if (String.empty()) {
    Slot = ConstantPointerNull::get(getStrPtrType());
  } else {
    // Construct string as an llvm constant.
    Constant *ConstStr = ConstantArray::get(String);
    // Otherwise create and return a new string global.
    GlobalVariable *StrGV = new GlobalVariable(ConstStr->getType(), true,
                                               GlobalVariable::InternalLinkage,
                                               ConstStr, "str", M);
    StrGV->setSection("llvm.metadata");
    // Convert to generic string pointer.
    Slot = ConstantExpr::getCast(StrGV, getStrPtrType());
  }
/// Serialize - Recursively cast the specified descriptor into a GlobalVariable
/// so that it can be serialized to a .bc or .ll file.
GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) {
  // Check if the DebugInfoDesc is already in the map.
  GlobalVariable *&Slot = DescGlobals[DD];
  
  // See if DebugInfoDesc exists, if so return prior GlobalVariable.
  if (Slot) return Slot;
  
  // Get the type associated with the Tag.
  const StructType *Ty = getTagType(DD);

  // Create the GlobalVariable early to prevent infinite recursion.
  GlobalVariable *GV = new GlobalVariable(Ty, true, DD->getLinkage(),
                                          NULL, DD->getDescString(), M);

  // Insert new GlobalVariable in DescGlobals map.
  Slot = GV;
 
  // Set up elements vector
  std::vector<Constant*> Elements;
Jim Laskey's avatar
Jim Laskey committed
  DISerializeVisitor SRAM(*this, Elements);
  SRAM.ApplyToFields(DD);
  
  // Set the globals initializer.
  GV->setInitializer(ConstantStruct::get(Ty, Elements));
  
  return GV;
//===----------------------------------------------------------------------===//

/// markVisited - Return true if the GlobalVariable hase been "seen" before.
/// Mark visited otherwise.
bool DIVerifier::markVisited(GlobalVariable *GV) {
  // Check if the GlobalVariable is already in the Visited set.
  std::set<GlobalVariable *>::iterator VI = Visited.lower_bound(GV);
  
  // See if GlobalVariable exists.
  bool Exists = VI != Visited.end() && *VI == GV;

  // Insert in set.
  if (!Exists) Visited.insert(VI, GV);
  
  return Exists;
}

/// Verify - Return true if the GlobalVariable appears to be a valid
/// serialization of a DebugInfoDesc.
bool DIVerifier::Verify(Value *V) {
  return Verify(getGlobalVariable(V));
}
bool DIVerifier::Verify(GlobalVariable *GV) {
  // Check if seen before.
  if (markVisited(GV)) return true;
  
  // Get the Tag
Jim Laskey's avatar
Jim Laskey committed
  unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
  if (Tag == DW_TAG_invalid) return false;

  // If a compile unit we need the debug version.
Jim Laskey's avatar
Jim Laskey committed
    DebugVersion = CompileUnitDesc::DebugVersionFromGlobal(GV);
    if (DebugVersion == DW_TAG_invalid) return false;
  }

  // Construct an empty DebugInfoDesc.
  DebugInfoDesc *DD = DebugInfoDesc::DescFactory(Tag);
  
  // Allow for user defined descriptors.
  if (!DD) return true;
  
  // Get the initializer constant.
  ConstantStruct *CI = cast<ConstantStruct>(GV->getInitializer());
  
  // Get the operand count.
  unsigned N = CI->getNumOperands();
  
  // Get the field count.
  unsigned &Slot = Counts[Tag];
  if (!Slot) {
    // Check the operand count to the field count
Jim Laskey's avatar
Jim Laskey committed
    DICountVisitor CTAM;
    CTAM.ApplyToFields(DD);
    Slot = CTAM.getCount();
  }
  
  // Field count must be at most equal operand count.
  if (Slot >  N) {
    delete DD;
    return false;
  }
  
  // Check each field for valid type.
Jim Laskey's avatar
Jim Laskey committed
  DIVerifyVisitor VRAM(*this, GV);
  VRAM.ApplyToFields(DD);
  
  // Release empty DebugInfoDesc.
  delete DD;
  
  // Return result of field tests.
  return VRAM.isValid();
}

//===----------------------------------------------------------------------===//


MachineDebugInfo::MachineDebugInfo()
, Directories()
, SourceFiles()
, Lines()
{
  
}
MachineDebugInfo::~MachineDebugInfo() {

}

/// doInitialization - Initialize the debug state for a new module.
///
bool MachineDebugInfo::doInitialization() {
  return false;
}
/// doFinalization - Tear down the debug state after completion of a module.
///
bool MachineDebugInfo::doFinalization() {
  return false;
}
/// getDescFor - Convert a Value to a debug information descriptor.
// FIXME - use new Value type when available.
DebugInfoDesc *MachineDebugInfo::getDescFor(Value *V) {
  return DR.Deserialize(V);
}

/// Verify - Verify that a Value is debug information descriptor.
///
bool MachineDebugInfo::Verify(Value *V) {
  DIVerifier VR;
  return VR.Verify(V);
}

/// AnalyzeModule - Scan the module for global debug information.
///
void MachineDebugInfo::AnalyzeModule(Module &M) {
  SetupCompileUnits(M);
}

/// SetupCompileUnits - Set up the unique vector of compile units.
///
void MachineDebugInfo::SetupCompileUnits(Module &M) {
  std::vector<CompileUnitDesc *>CU = getAnchoredDescriptors<CompileUnitDesc>(M);
  for (unsigned i = 0, N = CU.size(); i < N; i++) {
    CompileUnits.insert(CU[i]);
/// getCompileUnits - Return a vector of debug compile units.
///
const UniqueVector<CompileUnitDesc *> MachineDebugInfo::getCompileUnits()const{
/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
/// named GlobalVariable.
std::vector<GlobalVariable*>
MachineDebugInfo::getGlobalVariablesUsing(Module &M,
                                          const std::string &RootName) {
  return ::getGlobalVariablesUsing(M, RootName);