aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/DwarfWriter.h4
-rw-r--r--include/llvm/CodeGen/MachineDebugInfo.h427
-rw-r--r--lib/CodeGen/DwarfWriter.cpp22
-rw-r--r--lib/CodeGen/MachineDebugInfo.cpp702
4 files changed, 953 insertions, 202 deletions
diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h
index c98dbbce39..841a029d60 100644
--- a/include/llvm/CodeGen/DwarfWriter.h
+++ b/include/llvm/CodeGen/DwarfWriter.h
@@ -33,7 +33,7 @@ namespace llvm {
// Forward declarations.
//
class AsmPrinter;
- class CompileUnitWrapper;
+ class CompileUnitDesc;
class DIE;
class DwarfWriter;
class DWContext;
@@ -657,7 +657,7 @@ private:
/// NewCompileUnit - Create new compile unit information.
///
- DIE *NewCompileUnit(const CompileUnitWrapper &CompileUnit);
+ DIE *NewCompileUnit(const CompileUnitDesc *CompileUnit);
/// EmitInitial - Emit initial Dwarf declarations.
///
diff --git a/include/llvm/CodeGen/MachineDebugInfo.h b/include/llvm/CodeGen/MachineDebugInfo.h
index fe12802dcd..a04f778c16 100644
--- a/include/llvm/CodeGen/MachineDebugInfo.h
+++ b/include/llvm/CodeGen/MachineDebugInfo.h
@@ -17,160 +17,385 @@
// The following information can be retrieved from the MachineDebugInfo.
//
// -- Source directories - Directories are uniqued based on their canonical
-// string and assigned a sequential numeric ID (base 1.) A directory ID - 1
-// provides the index of directory information in a queried directory list.
+// string and assigned a sequential numeric ID (base 1.)
// -- Source files - Files are also uniqued based on their name and directory
-// ID. A file ID is sequential number (base 1.) A file ID - 1 provides the
-// index of source information in a queried file list.
+// ID. A file ID is sequential number (base 1.)
// -- Source line coorespondence - A vector of file ID, line#, column# triples.
// A DEBUG_LOCATION instruction is generated by the DAG Legalizer
// corresponding to each entry in the source line list. This allows a debug
-// information emitter to generate labels to map code addressed to debug
-// tables.
+// emitter to generate labels referenced by degug information tables.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINEDEBUGINFO_H
#define LLVM_CODEGEN_MACHINEDEBUGINFO_H
-#include "llvm/Pass.h"
+#include "llvm/Support/Dwarf.h"
#include "llvm/ADT/UniqueVector.h"
+#include "llvm/Pass.h"
+#include "llvm/User.h"
+
#include <string>
+#include <set>
namespace llvm {
+//===----------------------------------------------------------------------===//
// Forward declarations.
-class ConstantStruct;
+class DebugInfoDesc;
class GlobalVariable;
class Module;
+class PointerType;
+class StructType;
//===----------------------------------------------------------------------===//
-/// DebugInfoWrapper - This class is the base class for debug info wrappers.
+// Debug info constants.
+enum {
+ LLVMDebugVersion = 1, // Current version of debug information.
+ DIInvalid = ~0U, // Invalid result indicator.
+
+ // DebugInfoDesc type identifying tags.
+ // FIXME - Change over with gcc4.
+#if 1
+ DI_TAG_compile_unit = DW_TAG_compile_unit,
+ DI_TAG_global_variable = DW_TAG_variable,
+ DI_TAG_subprogram = DW_TAG_subprogram
+#else
+ DI_TAG_compile_unit = 1,
+ DI_TAG_global_variable,
+ DI_TAG_subprogram
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// DIApplyManager - Subclasses of this class apply steps to each of the fields
+/// in the supplied DebugInfoDesc.
+class DIApplyManager {
+public:
+ DIApplyManager() {}
+ virtual ~DIApplyManager() {}
+
+
+ /// ApplyToFields - Target the manager to each field of the debug information
+ /// descriptor.
+ void ApplyToFields(DebugInfoDesc *DD);
+
+ /// Apply - Subclasses override each of these methods to perform the
+ /// appropriate action for the type of field.
+ virtual void Apply(int &Field) = 0;
+ virtual void Apply(unsigned &Field) = 0;
+ virtual void Apply(bool &Field) = 0;
+ virtual void Apply(std::string &Field) = 0;
+ virtual void Apply(DebugInfoDesc *&Field) = 0;
+ virtual void Apply(GlobalVariable *&Field) = 0;
+};
+
+//===----------------------------------------------------------------------===//
+/// DebugInfoDesc - This class is the base class for debug info descriptors.
///
-class DebugInfoWrapper {
+class DebugInfoDesc {
+private:
+ unsigned Tag; // Content indicator. Dwarf values are
+ // used but that does not limit use to
+ // Dwarf writers.
+
protected:
- GlobalVariable *GV; // "llvm.db" global
- ConstantStruct *IC; // Initializer constant.
+ DebugInfoDesc(unsigned T) : Tag(T) {}
public:
- DebugInfoWrapper(GlobalVariable *G);
+ virtual ~DebugInfoDesc() {}
+
+ // Accessors
+ unsigned getTag() const { return Tag; }
- /// getGlobal - Return the "llvm.db" global.
- ///
- GlobalVariable *getGlobal() const { return GV; }
+ /// TagFromGlobal - Returns the Tag number from a debug info descriptor
+ /// GlobalVariable.
+ static unsigned TagFromGlobal(GlobalVariable *GV, bool Checking = false);
- /// operator== - Used by Uniquevector to locate entry.
+ /// DescFactory - Create an instance of debug info descriptor based on Tag.
+ /// Return NULL if not a recognized Tag.
+ static DebugInfoDesc *DescFactory(unsigned Tag);
+
+ //===--------------------------------------------------------------------===//
+ // Subclasses should supply the following static methods.
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DebugInfoDesc *) { return true; }
+
+ //===--------------------------------------------------------------------===//
+ // Subclasses should supply the following virtual methods.
+
+ /// ApplyToFields - Target the apply manager to the fields of the descriptor.
///
- bool operator==(const DebugInfoWrapper &DI) const { return IC == DI.IC; }
+ virtual void ApplyToFields(DIApplyManager *Mgr) = 0;
- /// operator< - Used by Uniquevector to locate entry.
+ /// TypeString - Return a string used to compose globalnames and labels.
///
- bool operator<(const DebugInfoWrapper &DI) const { return IC < DI.IC; }
+ virtual const char *TypeString() const = 0;
+
+#ifndef NDEBUG
+ virtual void dump() = 0;
+#endif
};
//===----------------------------------------------------------------------===//
-/// CompileUnitWrapper - This class wraps a "lldb.compile_unit" global to
-/// provide easy access to its attributes.
-class CompileUnitWrapper : public DebugInfoWrapper {
-private:
- // Operand indices.
- enum {
- Tag_op,
- Version_op,
- Language_op,
- FileName_op,
- Directory_op,
- Producer_op,
- Anchor_op, // ignored
- N_op
- };
+/// CompileUnitDesc - This class packages debug information associated with a
+/// source/header file.
+class CompileUnitDesc : public DebugInfoDesc {
+private:
+ unsigned DebugVersion; // LLVM debug version when produced.
+ unsigned Language; // Language number (ex. DW_LANG_C89.)
+ std::string FileName; // Source file name.
+ std::string Directory; // Source file directory.
+ std::string Producer; // Compiler string.
+ GlobalVariable *TransUnit; // Translation unit - ignored.
public:
- CompileUnitWrapper(GlobalVariable *G);
+ CompileUnitDesc()
+ : DebugInfoDesc(DI_TAG_compile_unit)
+ , DebugVersion(LLVMDebugVersion)
+ , Language(0)
+ , FileName("")
+ , Directory("")
+ , Producer("")
+ , TransUnit(NULL)
+ {}
- /// getGlobal - Return the "lldb.compile_unit" global.
- ///
- GlobalVariable *getGlobal() const { return GV; }
-
- /// getTag - Return the compile unit's tag number. Currently DW_TAG_variable,
- /// DW_TAG_subprogram or DW_TAG_compile_unit.
- unsigned getTag() const;
+ // Accessors
+ unsigned getDebugVersion() const { return DebugVersion; }
+ unsigned getLanguage() const { return Language; }
+ const std::string &getFileName() const { return FileName; }
+ const std::string &getDirectory() const { return Directory; }
+ const std::string &getProducer() const { return Producer; }
+ void setLanguage(unsigned L) { Language = L; }
+ void setFileName(const std::string &FN) { FileName = FN; }
+ void setDirectory(const std::string &D) { Directory = D; }
+ void setProducer(const std::string &P) { Producer = P; }
+ // FIXME - Need translation unit getter/setter.
- /// isCorrectDebugVersion - Return true if is the correct llvm debug version.
- /// Currently the value is 0 (zero.) If the value is is not correct then
- /// ignore all debug information.
- bool isCorrectDebugVersion() const;
+ // Implement isa/cast/dyncast.
+ static bool classof(const CompileUnitDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D) {
+ return D->getTag() == DI_TAG_compile_unit;
+ }
- /// getLanguage - Return the compile unit's language number (ex. DW_LANG_C89.)
- ///
- unsigned getLanguage() const;
+ /// DebugVersionFromGlobal - Returns the version number from a compile unit
+ /// GlobalVariable.
+ static unsigned DebugVersionFromGlobal(GlobalVariable *GV,
+ bool Checking = false);
- /// getFileName - Return the compile unit's file name.
+ /// ApplyToFields - Target the apply manager to the fields of the
+ /// CompileUnitDesc.
+ virtual void ApplyToFields(DIApplyManager *Mgr);
+
+ /// TypeString - Return a string used to compose globalnames and labels.
///
- const std::string getFileName() const;
+ virtual const char *TypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// GlobalVariableDesc - This class packages debug information associated with a
+/// GlobalVariable.
+class GlobalVariableDesc : public DebugInfoDesc {
+private:
+ DebugInfoDesc *Context; // Context debug descriptor.
+ std::string Name; // Global name.
+ GlobalVariable *TransUnit; // Translation unit - ignored.
+ // FIXME - Use a descriptor.
+ GlobalVariable *TyDesc; // Type debug descriptor.
+ bool IsStatic; // Is the global a static.
+ bool IsDefinition; // Is the global defined in context.
+ GlobalVariable *Global; // llvm global.
- /// getDirectory - Return the compile unit's file directory.
- ///
- const std::string getDirectory() const;
+public:
+ GlobalVariableDesc()
+ : DebugInfoDesc(DI_TAG_global_variable)
+ , Context(0)
+ , Name("")
+ , TransUnit(NULL)
+ , TyDesc(NULL)
+ , IsStatic(false)
+ , IsDefinition(false)
+ , Global(NULL)
+ {}
- /// getProducer - Return the compile unit's generator name.
+ // Accessors
+ DebugInfoDesc *getContext() const { return Context; }
+ const std::string &getName() const { return Name; }
+ bool isStatic() const { return IsStatic; }
+ bool isDefinition() const { return IsDefinition; }
+ GlobalVariable *getGlobalVariable() const { return Global; }
+ void setName(const std::string &N) { Name = N; }
+ void setIsStatic(bool IS) { IsStatic = IS; }
+ void setIsDefinition(bool ID) { IsDefinition = ID; }
+ void setGlobalVariable(GlobalVariable *GV) { Global = GV; }
+ // FIXME - Other getters/setters.
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const GlobalVariableDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D) {
+ return D->getTag() == DI_TAG_global_variable;
+ }
+
+ /// ApplyToFields - Target the apply manager to the fields of the
+ /// GlobalVariableDesc.
+ virtual void ApplyToFields(DIApplyManager *Mgr);
+
+ /// TypeString - Return a string used to compose globalnames and labels.
///
- const std::string getProducer() const;
+ virtual const char *TypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
};
//===----------------------------------------------------------------------===//
-/// GlobalWrapper - This class wraps a "lldb.global" global to provide easy
-/// access to its attributes.
-class GlobalWrapper : public DebugInfoWrapper {
+/// SubprogramDesc - This class packages debug information associated with a
+/// subprogram/function.
+class SubprogramDesc : public DebugInfoDesc {
private:
- // Operand indices.
- enum {
- Tag_op,
- Context_op,
- Name_op,
- Anchor_op, // ignored
- Type_op,
- Static_op,
- Definition_op,
- GlobalVariable_op,
- N_op
- };
+ DebugInfoDesc *Context; // Context debug descriptor.
+ std::string Name; // Subprogram name.
+ GlobalVariable *TransUnit; // Translation unit - ignored.
+ // FIXME - Use a descriptor.
+ GlobalVariable *TyDesc; // Type debug descriptor.
+ bool IsStatic; // Is the subprogram a static.
+ bool IsDefinition; // Is the subprogram defined in context.
public:
- GlobalWrapper(GlobalVariable *G);
+ SubprogramDesc()
+ : DebugInfoDesc(DI_TAG_subprogram)
+ , Context(0)
+ , Name("")
+ , TransUnit(NULL)
+ , TyDesc(NULL)
+ , IsStatic(false)
+ , IsDefinition(false)
+ {}
- /// getGlobal - Return the "lldb.global" global.
- ///
- GlobalVariable *getGlobal() const { return GV; }
+ // Accessors
+ DebugInfoDesc *getContext() const { return Context; }
+ const std::string &getName() const { return Name; }
+ bool isStatic() const { return IsStatic; }
+ bool isDefinition() const { return IsDefinition; }
+ void setName(const std::string &N) { Name = N; }
+ void setIsStatic(bool IS) { IsStatic = IS; }
+ void setIsDefinition(bool ID) { IsDefinition = ID; }
+ // FIXME - Other getters/setters.
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const SubprogramDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D) {
+ return D->getTag() == DI_TAG_subprogram;
+ }
+
+ /// ApplyToFields - Target the apply manager to the fields of the
+ /// SubprogramDesc.
+ virtual void ApplyToFields(DIApplyManager *Mgr);
- /// getContext - Return the "lldb.compile_unit" context global.
+ /// TypeString - Return a string used to compose globalnames and labels.
///
- GlobalVariable *getContext() const;
+ virtual const char *TypeString() const;
- /// getTag - Return the global's tag number. Currently should be
- /// DW_TAG_variable or DW_TAG_subprogram.
- unsigned getTag() const;
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// DIDeserializer - This class is responsible for casting GlobalVariables
+/// into DebugInfoDesc objects.
+class DIDeserializer {
+private:
+ Module *M; // Definition space module.
+ unsigned DebugVersion; // Version of debug information in use.
+ std::map<GlobalVariable *, DebugInfoDesc *> GlobalDescs;
+ // Previously defined gloabls.
+
+public:
+ DIDeserializer() : M(NULL), DebugVersion(LLVMDebugVersion) {}
+ ~DIDeserializer() {}
+
+ // Accessors
+ Module *getModule() const { return M; };
+ void setModule(Module *module) { M = module; }
+ unsigned getDebugVersion() const { return DebugVersion; }
- /// getName - Return the name of the global.
+ /// Deserialize - Reconstitute a GlobalVariable into it's component
+ /// DebugInfoDesc objects.
+ DebugInfoDesc *Deserialize(Value *V);
+ DebugInfoDesc *Deserialize(GlobalVariable *GV);
+};
+
+//===----------------------------------------------------------------------===//
+/// DISerializer - This class is responsible for casting DebugInfoDesc objects
+/// into GlobalVariables.
+class DISerializer {
+private:
+ Module *M; // Definition space module.
+ PointerType *StrPtrTy; // A "sbyte *" type. Created lazily.
+ PointerType *EmptyStructPtrTy; // A "{ }*" type. Created lazily.
+ std::map<unsigned, StructType *> TagTypes;
+ // Types per Tag. Created lazily.
+ std::map<DebugInfoDesc *, GlobalVariable *> DescGlobals;
+ // Previously defined descriptors.
+ std::map<const std::string, GlobalVariable*> StringCache;
+ // Previously defined strings.
+public:
+ DISerializer() : M(NULL) {}
+ ~DISerializer() {}
+
+ // Accessors
+ Module *getModule() const { return M; };
+ void setModule(Module *module) { M = module; }
+
+ /// getStrPtrType - Return a "sbyte *" type.
///
- const std::string getName() const;
+ const PointerType *getStrPtrType();
- /// getType - Return the type of the global.
+ /// getEmptyStructPtrType - Return a "{ }*" type.
///
- const GlobalVariable *getType() const;
-
- /// isStatic - Return true if the global is static.
+ const PointerType *getEmptyStructPtrType();
+
+ /// getTagType - Return the type describing the specified descriptor (via
+ /// tag.)
+ const StructType *getTagType(DebugInfoDesc *DD);
+
+ /// getString - Construct the string as constant string global.
///
- bool isStatic() const;
+ GlobalVariable *getString(const std::string &String);
+
+ /// Serialize - Recursively cast the specified descriptor into a
+ /// GlobalVariable so that it can be serialized to a .bc or .ll file.
+ GlobalVariable *Serialize(DebugInfoDesc *DD);
+};
- /// isDefinition - Return true if the global is a definition.
- ///
- bool isDefinition() const;
+//===----------------------------------------------------------------------===//
+/// DIVerifier - This class is responsible for verifying the given network of
+/// GlobalVariables are valid as DebugInfoDesc objects.
+class DIVerifier {
+private:
+ unsigned DebugVersion; // Version of debug information in use.
+ std::set<GlobalVariable *> Visited; // Tracks visits during recursion.
+ std::map<unsigned, unsigned> Counts; // Count of fields per Tag type.
+
+ /// markVisited - Return true if the GlobalVariable hase been "seen" before.
+ /// Mark markVisited otherwise.
+ bool markVisited(GlobalVariable *GV);
- /// getGlobalVariable - Return the global variable (tag == DW_TAG_variable.)
- ///
- GlobalVariable *getGlobalVariable() const;
+public:
+ DIVerifier() : DebugVersion(LLVMDebugVersion) {}
+ ~DIVerifier() {}
+
+ /// Verify - Return true if the GlobalVariable appears to be a valid
+ /// serialization of a DebugInfoDesc.
+ bool Verify(GlobalVariable *GV);
};
//===----------------------------------------------------------------------===//
@@ -228,8 +453,14 @@ public:
///
class MachineDebugInfo : public ImmutablePass {
private:
+ // Debug indforma
+ // Use the same serializer/deserializer/verifier for the module.
+ DISerializer SR;
+ DIDeserializer DR;
+ DIVerifier VR;
+
// CompileUnits - Uniquing vector for compile units.
- UniqueVector<CompileUnitWrapper> CompileUnits;
+ UniqueVector<CompileUnitDesc *> CompileUnits;
// Directories - Uniquing vector for directories.
UniqueVector<std::string> Directories;
@@ -300,11 +531,11 @@ public:
/// getCompileUnits - Return a vector of debug compile units.
///
- const UniqueVector<CompileUnitWrapper> getCompileUnits() const;
+ const UniqueVector<CompileUnitDesc *> getCompileUnits() const;
- /// getGlobalVariables - Return a vector of debug global variables.
+ /// getGlobalVariables - Return a vector of debug GlobalVariables.
///
- static std::vector<GlobalWrapper> getGlobalVariables(Module &M);
+ std::vector<GlobalVariableDesc *> getGlobalVariables(Module &M);
}; // End class MachineDebugInfo
diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp
index 4de5dcfc2a..f7bb0923bb 100644
--- a/lib/CodeGen/DwarfWriter.cpp
+++ b/lib/CodeGen/DwarfWriter.cpp
@@ -1269,16 +1269,16 @@ void DwarfWriter::NewGlobalVariable(DWContext *Context,
/// NewCompileUnit - Create new compile unit information.
///
-DIE *DwarfWriter::NewCompileUnit(const CompileUnitWrapper &CompileUnit) {
+DIE *DwarfWriter::NewCompileUnit(const CompileUnitDesc *CompileUnit) {
DIE *Unit = new DIE(DW_TAG_compile_unit, DW_CHILDREN_yes);
// FIXME - use the correct line set.
Unit->AddLabel (DW_AT_stmt_list, DW_FORM_data4, DWLabel("line", 0));
Unit->AddLabel (DW_AT_high_pc, DW_FORM_addr, DWLabel("text_end", 0));
Unit->AddLabel (DW_AT_low_pc, DW_FORM_addr, DWLabel("text_begin", 0));
- Unit->AddString(DW_AT_producer, DW_FORM_string, CompileUnit.getProducer());
- Unit->AddUInt (DW_AT_language, DW_FORM_data1, CompileUnit.getLanguage());
- Unit->AddString(DW_AT_name, DW_FORM_string, CompileUnit.getFileName());
- Unit->AddString(DW_AT_comp_dir, DW_FORM_string, CompileUnit.getDirectory());
+ Unit->AddString(DW_AT_producer, DW_FORM_string, CompileUnit->getProducer());
+ Unit->AddUInt (DW_AT_language, DW_FORM_data1, CompileUnit->getLanguage());
+ Unit->AddString(DW_AT_name, DW_FORM_string, CompileUnit->getFileName());
+ Unit->AddString(DW_AT_comp_dir, DW_FORM_string, CompileUnit->getDirectory());
Unit->Complete(*this);
return Unit;
@@ -1723,11 +1723,10 @@ void DwarfWriter::EmitDebugMacInfo() {
/// ConstructCompileUnitDIEs - Create a compile unit DIE for each source and
/// header file.
void DwarfWriter::ConstructCompileUnitDIEs() {
- const UniqueVector<CompileUnitWrapper> CUW = DebugInfo->getCompileUnits();
+ const UniqueVector<CompileUnitDesc *> CUW = DebugInfo->getCompileUnits();
for (unsigned i = 1, N = CUW.size(); i <= N; ++i) {
- const CompileUnitWrapper &CompileUnit = CUW[i];
- DIE *Unit = NewCompileUnit(CompileUnit);
+ DIE *Unit = NewCompileUnit(CUW[i]);
DWContext *Context = new DWContext(*this, NULL, Unit);
CompileUnits.push_back(Unit);
}
@@ -1738,11 +1737,12 @@ void DwarfWriter::ConstructCompileUnitDIEs() {
void DwarfWriter::ConstructGlobalDIEs(Module &M) {
const TargetData &TD = Asm->TM.getTargetData();
- std::vector<GlobalWrapper> GlobalVariables = DebugInfo->getGlobalVariables(M);
+ std::vector<GlobalVariableDesc *> GlobalVariables =
+ DebugInfo->getGlobalVariables(M);
for (unsigned i = 0, N = GlobalVariables.size(); i < N; ++i) {
- GlobalWrapper &GW = GlobalVariables[i];
- GlobalVariable *GV = GW.getGlobalVariable();
+ GlobalVariableDesc *GVD = GlobalVariables[i];
+ GlobalVariable *GV = GVD->getGlobalVariable();
if (!GV->hasInitializer()) continue; // External global require no code
diff --git a/lib/CodeGen/MachineDebugInfo.cpp b/lib/CodeGen/MachineDebugInfo.cpp
index ab42886cb4..e3b24ab03b 100644
--- a/lib/CodeGen/MachineDebugInfo.cpp
+++ b/lib/CodeGen/MachineDebugInfo.cpp
@@ -11,11 +11,14 @@
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
#include "llvm/Intrinsics.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Support/Dwarf.h"
+#include <iostream>
+
using namespace llvm;
// Handle the Pass registration stuff necessary to use TargetData's.
@@ -25,14 +28,14 @@ namespace {
//===----------------------------------------------------------------------===//
-/// getGlobalVariablesUsing - Return all of the global variables which have the
+/// getGlobalVariablesUsing - Return all of the GlobalVariables which have the
/// specified value in their initializer somewhere.
static void
getGlobalVariablesUsing(Value *V, std::vector<GlobalVariable*> &Result) {
// Scan though value users.
for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I)) {
- // If the user is a global variable then add to result.
+ // If the user is a GlobalVariable then add to result.
Result.push_back(GV);
} else if (Constant *C = dyn_cast<Constant>(*I)) {
// If the user is a constant variable then scan its users
@@ -41,13 +44,13 @@ getGlobalVariablesUsing(Value *V, std::vector<GlobalVariable*> &Result) {
}
}
-/// getGlobalVariablesUsing - Return all of the global variables that use the
-/// named global variable.
+/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
+/// named GlobalVariable.
static std::vector<GlobalVariable*>
getGlobalVariablesUsing(Module &M, const std::string &RootName) {
- std::vector<GlobalVariable*> Result; // Global variables matching criteria.
+ std::vector<GlobalVariable*> Result; // GlobalVariables matching criteria.
- // Get the global variable root.
+ // Get the GlobalVariable root.
GlobalVariable *UseRoot = M.getGlobalVariable(RootName,
StructType::get(std::vector<const Type*>()));
@@ -98,131 +101,646 @@ static const std::string getStringValue(Value *V, unsigned Offset = 0) {
return "";
}
+/// isStringValue - Return true if the given value can be coerced to a string.
+///
+static bool isStringValue(Value *V) {
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
+ if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
+ ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
+ return Init->isString();
+ }
+ } else if (Constant *C = dyn_cast<Constant>(V)) {
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
+ return isStringValue(GV);
+ else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ if (CE->getOpcode() == Instruction::GetElementPtr) {
+ if (CE->getNumOperands() == 3 &&
+ cast<Constant>(CE->getOperand(1))->isNullValue() &&
+ isa<ConstantInt>(CE->getOperand(2))) {
+ return isStringValue(CE->getOperand(0));
+ }
+ }
+ }
+ }
+ return false;
+}
+
/// getGlobalValue - Return either a direct or cast Global value.
///
static GlobalVariable *getGlobalValue(Value *V) {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
return GV;
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
- return CE->getOpcode() == Instruction::Cast ? dyn_cast<GlobalVariable>(V)
- : NULL;
+ if (CE->getOpcode() == Instruction::Cast) {
+ return dyn_cast<GlobalVariable>(CE->getOperand(0));
+ }
}
return NULL;
}
+/// isGlobalValue - Return true if the given value can be coerced to a
+/// GlobalVariable.
+static bool isGlobalValue(Value *V) {
+ if (isa<GlobalVariable>(V) || isa<ConstantPointerNull>(V)) {
+ return true;
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
+ if (CE->getOpcode() == Instruction::Cast) {
+ return isa<GlobalVariable>(CE->getOperand(0));
+ }
+ }
+ return false;
+}
+
+/// isUIntOperand - Return true if the ith operand is an unsigned integer.
+///
+static bool isUIntOperand(GlobalVariable *GV, unsigned i) {
+ // Make sure the GlobalVariable has an initializer.
+ if (!GV->hasInitializer()) return false;
+
+ // Get the initializer constant.
+ ConstantStruct *CI = dyn_cast<ConstantStruct>(GV->getInitializer());
+ if (!CI) return false;
+ // Check if there is at least i + 1 operands.
+ unsigned N = CI->getNumOperands();
+ if (i >= N) return false;
+
+ // Check constant.
+ return isa<ConstantUInt>(CI->getOperand(i));
+}
+
//===----------------------------------------------------------------------===//
-DebugInfoWrapper::DebugInfoWrapper(GlobalVariable *G)
-: GV(G)
-, IC(dyn_cast<ConstantStruct>(GV->getInitializer())) {
- assert(IC && "llvm.db.global is missing structured constant");
+/// TagFromGlobal - Returns the Tag number from a debug info descriptor
+/// GlobalVariable.
+unsigned DebugInfoDesc::TagFromGlobal(GlobalVariable *GV, bool Checking) {
+ if (Checking && !isUIntOperand(GV, 0)) return DIInvalid;
+ ConstantStruct *CI = cast<ConstantStruct>(GV->getInitializer());
+ Constant *C = CI->getOperand(0);
+ return cast<ConstantUInt>(C)->getValue();
}
+
+/// DescFactory - Create an instance of debug info descriptor based on Tag.
+/// Return NULL if not a recognized Tag.
+DebugInfoDesc *DebugInfoDesc::DescFactory(unsigned Tag) {
+ switch (Tag) {
+ case DI_TAG_compile_unit: return new CompileUnitDesc();
+ case DI_TAG_global_variable: return new GlobalVariableDesc();
+ case DI_TAG_subprogram: return new SubprogramDesc();
+ default: break;
+ }
+ return NULL;
+}
+
+//===----------------------------------------------------------------------===//
+
+/// ApplyToFields - Target the manager to each field of the debug information
+/// descriptor.
+void DIApplyManager::ApplyToFields(DebugInfoDesc *DD) {
+ DD->ApplyToFields(this);
+}
+
+//===----------------------------------------------------------------------===//
+/// DICountAppMgr - This DIApplyManager counts all the fields in the supplied
+/// debug the supplied DebugInfoDesc.
+class DICountAppMgr : public DIApplyManager {
+private:
+ unsigned Count; // Running count of fields.
+
+public:
+ DICountAppMgr() : DIApplyManager(), Count(1) {}
+ // Accessors.
+ unsigned getCount() const { return Count; }
+
+ /// Apply - Count each of the fields.
+ ///
+ virtual void Apply(int &Field) { ++Count; }
+ virtual void Apply(unsigned &Field) { ++Count; }
+ virtual void Apply(bool &Field) { ++Count; }
+ virtual void Apply(std::string &Field) { ++Count; }
+ virtual void Apply(DebugInfoDesc *&Field) { ++Count; }
+ virtual void Apply(GlobalVariable *&Field) { ++Count; }
+};
+
//===----------------------------------------------------------------------===//
+/// DIDeserializeAppMgr - This DIApplyManager deserializes all the fields in
+/// the supplied DebugInfoDesc.
+class DIDeserializeAppMgr : public DIApplyManager {
+private:
+ DIDeserializer &DR; // Active deserializer.
+ unsigned I; // Current operand index.
+ ConstantStruct *CI; // GlobalVariable constant initializer.
+
+public:
+ DIDeserializeAppMgr(DIDeserializer &D, GlobalVariable *GV)
+ : DIApplyManager()
+ , DR(D)
+ , I(1)
+ , CI(cast<ConstantStruct>(GV->getInitializer()))
+ {}
+
+ /// Apply - Set the value of each of the fields.
+ ///
+ virtual void Apply(int &Field) {
+ Constant *C = CI->getOperand(I++);
+ Field = cast<ConstantSInt>(C)->getValue();
+ }
+ virtual void Apply(unsigned &Field) {
+ Constant *C = CI->getOperand(I++);
+ Field = cast<ConstantUInt>(C)->getValue();
+ }
+ virtual void Apply(bool &Field) {
+ Constant *C = CI->getOperand(I++);
+ Field = cast<ConstantBool>(C)->getValue();
+ }
+ virtual void Apply(std::string &Field) {
+ Constant *C = CI->getOperand(I++);
+ Field = getStringValue(C);
+ }
+ virtual void Apply(DebugInfoDesc *&Field) {
+ Constant *C = CI->getOperand(I++);
+ Field = DR.Deserialize(C);
+ }
+ virtual void Apply(GlobalVariable *&Field) {
+ Constant *C = CI->getOperand(I++);
+ Field = getGlobalValue(C);
+ }
+};
-CompileUnitWrapper::CompileUnitWrapper(GlobalVariable *G)
-: DebugInfoWrapper(G)
-{
- // FIXME - should probably ease up on the number of operands (version.)
- assert(IC->getNumOperands() == N_op &&
- "Compile unit does not have correct number of operands");
+//===----------------------------------------------------------------------===//
+/// DISerializeAppMgr - This DIApplyManager serializes all the fields in
+/// the supplied DebugInfoDesc.
+class DISerializeAppMgr : public DIApplyManager {
+private:
+ DISerializer &SR; // Active serializer.
+ std::vector<Constant*> &Elements; // Element accumulator.
+
+public:
+ DISerializeAppMgr(DISerializer &S, std::vector<Constant*> &E)
+ : DIApplyManager()
+ , SR(S)
+ , Elements(E)
+ {}
+
+ /// Apply - Set the value of each of the fields.
+ ///
+ virtual void Apply(int &Field) {
+ Elements.push_back(ConstantUInt::get(Type::IntTy, Field));
+ }
+ virtual void Apply(unsigned &Field) {
+ Elements.push_back(ConstantUInt::get(Type::UIntTy, Field));
+ }
+ virtual void Apply(bool &Field) {
+ Elements.push_back(ConstantBool::get(Field));
+ }
+ virtual void Apply(std::string &Field) {
+ Elements.push_back(SR.getString(Field));
+ }
+ virtual void Apply(DebugInfoDesc *&Field) {
+ GlobalVariable *GV = NULL;
+
+ // If non-NULL the convert to global.
+ if (Field) GV = SR.Serialize(Field);
+
+ // FIXME - At some point should use specific type.
+ const PointerType *EmptyTy = SR.getEmptyStructPtrType();
+
+ if (GV) {
+ // Set to pointer to global.
+ Elements.push_back(ConstantExpr::getCast(GV, EmptyTy));
+ } else {
+ // Use NULL.
+ Elements.push_back(ConstantPointerNull::get(EmptyTy));
+ }
+ }
+ virtual void Apply(GlobalVariable *&Field) {
+ const PointerType *EmptyTy = SR.getEmptyStructPtrType();
+ Elements.push_back(ConstantExpr::getCast(Field, EmptyTy));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// DIGetTypesAppMgr - This DIApplyManager gathers all the field types in
+/// the supplied DebugInfoDesc.
+class DIGetTypesAppMgr : public DIApplyManager {
+private:
+ DISerializer &SR; // Active serializer.
+ std::vector<const Type*> &Fields; // Type accumulator.
+
+public:
+ DIGetTypesAppMgr(DISerializer &S, std::vector<const Type*> &F)
+ : DIApplyManager()
+ , SR(S)
+ , Fields(F)
+ {}
+
+ /// Apply - Set the value of each of the fields.
+ ///
+ virtual void Apply(int &Field) {
+ Fields.push_back(Type::IntTy);
+ }
+ virtual void Apply(unsigned &Field) {
+ Fields.push_back(Type::UIntTy);
+ }
+ virtual void Apply(bool &Field) {
+ Fields.push_back(Type::BoolTy);
+ }
+ virtual void Apply(std::string &Field) {
+ Fields.push_back(SR.getStrPtrType());
+ }
+ virtual void Apply(DebugInfoDesc *&Field) {
+ // FIXME - At some point should use specific type.
+ const PointerType *EmptyTy = SR.getEmptyStructPtrType();
+ Fields.push_back(EmptyTy);
+ }
+ virtual void Apply(GlobalVariable *&Field) {
+ const PointerType *EmptyTy = SR.getEmptyStructPtrType();
+ Fields.push_back(EmptyTy);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// DIVerifyAppMgr - This DIApplyManager verifies all the field types against
+/// a constant initializer.
+class DIVerifyAppMgr : public DIApplyManager {
+private:
+ DIVerifier &VR; // Active verifier.
+ bool IsValid; // Validity status.
+ unsigned I; // Current operand index.
+ ConstantStruct *CI; // GlobalVariable constant initializer.
+
+public:
+ DIVerifyAppMgr(DIVerifier &V, GlobalVariable *GV)
+ : DIApplyManager()
+ , VR(V)
+ , IsValid(true)
+ , I(1)
+ , CI(cast<ConstantStruct>(GV->getInitializer()))
+ {
+ }
+
+ // Accessors.
+ bool isValid() const { return IsValid; }
+
+ /// Apply - Set the value of each of the fields.
+ ///
+ virtual void Apply(int &Field) {
+ Constant *C = CI->getOperand(I++);
+ IsValid = IsValid && isa<ConstantInt>(C);
+ }
+ virtual void Apply(unsigned &Field) {
+ Constant *C = CI->getOperand(I++);
+ IsValid = IsValid && isa<ConstantInt>(C);
+ }
+ virtual void Apply(bool &Field) {
+ Constant *C = CI->getOperand(I++);
+ IsValid = IsValid && isa<ConstantBoo