From: Jim Laskey Date: Fri, 26 Jan 2007 21:38:26 +0000 (+0000) Subject: rename files X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6da186480b55c10b96a255ce0a4ab731155da907;p=oota-llvm.git rename files git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33552 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/MachineDebugInfo.h b/include/llvm/CodeGen/MachineDebugInfo.h deleted file mode 100644 index 1676f6b85b3..00000000000 --- a/include/llvm/CodeGen/MachineDebugInfo.h +++ /dev/null @@ -1,1154 +0,0 @@ -//===-- llvm/CodeGen/MachineDebugInfo.h -------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by James M. Laskey and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Collect debug information for a module. This information should be in a -// neutral form that can be used by different debugging schemes. -// -// The organization of information is primarily clustered around the source -// compile units. The main exception is source line correspondence where -// inlining may interleave code from various compile units. -// -// 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.) -// -- Source files - Files are also uniqued based on their name and directory -// ID. A file ID is sequential number (base 1.) -// -- Source line correspondence - 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 -// emitter to generate labels referenced by debug information tables. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_MACHINEDEBUGINFO_H -#define LLVM_CODEGEN_MACHINEDEBUGINFO_H - -#include "llvm/Support/Dwarf.h" -#include "llvm/Support/DataTypes.h" -#include "llvm/ADT/UniqueVector.h" -#include "llvm/GlobalValue.h" -#include "llvm/Pass.h" - -namespace llvm { - -//===----------------------------------------------------------------------===// -// Forward declarations. -class Constant; -class DebugInfoDesc; -class GlobalVariable; -class MachineFunction; -class MachineMove; -class Module; -class PointerType; -class StructType; - -//===----------------------------------------------------------------------===// -// Debug info constants. - -enum { - LLVMDebugVersion = (6 << 16), // Current version of debug information. - LLVMDebugVersion5 = (5 << 16), // Constant for version 5. - LLVMDebugVersion4 = (4 << 16), // Constant for version 4. - LLVMDebugVersionMask = 0xffff0000 // Mask for version number. -}; - -//===----------------------------------------------------------------------===// -/// DIVisitor - Subclasses of this class apply steps to each of the fields in -/// the supplied DebugInfoDesc. -class DIVisitor { -public: - DIVisitor() {} - virtual ~DIVisitor() {} - - /// ApplyToFields - Target the visitor 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(int64_t &Field) = 0; - virtual void Apply(uint64_t &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; - virtual void Apply(std::vector &Field) = 0; -}; - -//===----------------------------------------------------------------------===// -/// DebugInfoDesc - This class is the base class for debug info descriptors. -/// -class DebugInfoDesc { -private: - unsigned Tag; // Content indicator. Dwarf values are - // used but that does not limit use to - // Dwarf writers. - -protected: - DebugInfoDesc(unsigned T) : Tag(T | LLVMDebugVersion) {} - -public: - virtual ~DebugInfoDesc() {} - - // Accessors - unsigned getTag() const { return Tag & ~LLVMDebugVersionMask; } - unsigned getVersion() const { return Tag & LLVMDebugVersionMask; } - void setTag(unsigned T) { Tag = T | LLVMDebugVersion; } - - /// TagFromGlobal - Returns the tag number from a debug info descriptor - /// GlobalVariable. Return DIIValid if operand is not an unsigned int. - static unsigned TagFromGlobal(GlobalVariable *GV); - - /// VersionFromGlobal - Returns the version number from a debug info - /// descriptor GlobalVariable. Return DIIValid if operand is not an unsigned - /// int. - static unsigned VersionFromGlobal(GlobalVariable *GV); - - /// DescFactory - Create an instance of debug info descriptor based on Tag. - /// Return NULL if not a recognized Tag. - static DebugInfoDesc *DescFactory(unsigned Tag); - - /// getLinkage - get linkage appropriate for this type of descriptor. - /// - virtual GlobalValue::LinkageTypes getLinkage() const; - - //===--------------------------------------------------------------------===// - // 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 vistor to the fields of the descriptor. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const = 0; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const = 0; - -#ifndef NDEBUG - virtual void dump() = 0; -#endif -}; - -//===----------------------------------------------------------------------===// -/// AnchorDesc - Descriptors of this class act as markers for identifying -/// descriptors of certain groups. -class AnchoredDesc; -class AnchorDesc : public DebugInfoDesc { -private: - unsigned AnchorTag; // Tag number of descriptors anchored - // by this object. - -public: - AnchorDesc(); - AnchorDesc(AnchoredDesc *D); - - // Accessors - unsigned getAnchorTag() const { return AnchorTag; } - - // Implement isa/cast/dyncast. - static bool classof(const AnchorDesc *) { return true; } - static bool classof(const DebugInfoDesc *D); - - /// getLinkage - get linkage appropriate for this type of descriptor. - /// - virtual GlobalValue::LinkageTypes getLinkage() const; - - /// ApplyToFields - Target the visitor to the fields of the AnchorDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// AnchoredDesc - This class manages anchors for a variety of top level -/// descriptors. -class AnchoredDesc : public DebugInfoDesc { -private: - DebugInfoDesc *Anchor; // Anchor for all descriptors of the - // same type. - -protected: - - AnchoredDesc(unsigned T); - -public: - // Accessors. - AnchorDesc *getAnchor() const { return static_cast(Anchor); } - void setAnchor(AnchorDesc *A) { Anchor = static_cast(A); } - - //===--------------------------------------------------------------------===// - // Subclasses should supply the following virtual methods. - - /// getAnchorString - Return a string used to label descriptor's anchor. - /// - virtual const char *getAnchorString() const = 0; - - /// ApplyToFields - Target the visitor to the fields of the AnchoredDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); -}; - -//===----------------------------------------------------------------------===// -/// CompileUnitDesc - This class packages debug information associated with a -/// source/header file. -class CompileUnitDesc : public AnchoredDesc { -private: - 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. - -public: - CompileUnitDesc(); - - - // Accessors - 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. - - // Implement isa/cast/dyncast. - static bool classof(const CompileUnitDesc *) { return true; } - static bool classof(const DebugInfoDesc *D); - - /// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - - /// getAnchorString - Return a string used to label this descriptor's anchor. - /// - static const char *AnchorString; - virtual const char *getAnchorString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// TypeDesc - This class packages debug information associated with a type. -/// -class TypeDesc : public DebugInfoDesc { -private: - enum { - FlagPrivate = 1 << 0, - FlagProtected = 1 << 1 - }; - DebugInfoDesc *Context; // Context debug descriptor. - std::string Name; // Type name (may be empty.) - DebugInfoDesc *File; // Defined compile unit (may be NULL.) - unsigned Line; // Defined line# (may be zero.) - uint64_t Size; // Type bit size (may be zero.) - uint64_t Align; // Type bit alignment (may be zero.) - uint64_t Offset; // Type bit offset (may be zero.) - unsigned Flags; // Miscellaneous flags. - -public: - TypeDesc(unsigned T); - - // Accessors - DebugInfoDesc *getContext() const { return Context; } - const std::string &getName() const { return Name; } - CompileUnitDesc *getFile() const { - return static_cast(File); - } - unsigned getLine() const { return Line; } - uint64_t getSize() const { return Size; } - uint64_t getAlign() const { return Align; } - uint64_t getOffset() const { return Offset; } - bool isPrivate() const { - return (Flags & FlagPrivate) != 0; - } - bool isProtected() const { - return (Flags & FlagProtected) != 0; - } - void setContext(DebugInfoDesc *C) { Context = C; } - void setName(const std::string &N) { Name = N; } - void setFile(CompileUnitDesc *U) { - File = static_cast(U); - } - void setLine(unsigned L) { Line = L; } - void setSize(uint64_t S) { Size = S; } - void setAlign(uint64_t A) { Align = A; } - void setOffset(uint64_t O) { Offset = O; } - void setIsPrivate() { Flags |= FlagPrivate; } - void setIsProtected() { Flags |= FlagProtected; } - - /// ApplyToFields - Target the visitor to the fields of the TypeDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// BasicTypeDesc - This class packages debug information associated with a -/// basic type (eg. int, bool, double.) -class BasicTypeDesc : public TypeDesc { -private: - unsigned Encoding; // Type encoding. - -public: - BasicTypeDesc(); - - // Accessors - unsigned getEncoding() const { return Encoding; } - void setEncoding(unsigned E) { Encoding = E; } - - // Implement isa/cast/dyncast. - static bool classof(const BasicTypeDesc *) { return true; } - static bool classof(const DebugInfoDesc *D); - - /// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - - -//===----------------------------------------------------------------------===// -/// DerivedTypeDesc - This class packages debug information associated with a -/// derived types (eg., typedef, pointer, reference.) -class DerivedTypeDesc : public TypeDesc { -private: - DebugInfoDesc *FromType; // Type derived from. - -public: - DerivedTypeDesc(unsigned T); - - // Accessors - TypeDesc *getFromType() const { - return static_cast(FromType); - } - void setFromType(TypeDesc *F) { - FromType = static_cast(F); - } - - // Implement isa/cast/dyncast. - static bool classof(const DerivedTypeDesc *) { return true; } - static bool classof(const DebugInfoDesc *D); - - /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// CompositeTypeDesc - This class packages debug information associated with a -/// array/struct types (eg., arrays, struct, union, enums.) -class CompositeTypeDesc : public DerivedTypeDesc { -private: - std::vector Elements;// Information used to compose type. - -public: - CompositeTypeDesc(unsigned T); - - // Accessors - std::vector &getElements() { return Elements; } - - // Implement isa/cast/dyncast. - static bool classof(const CompositeTypeDesc *) { return true; } - static bool classof(const DebugInfoDesc *D); - - /// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// SubrangeDesc - This class packages debug information associated with integer -/// value ranges. -class SubrangeDesc : public DebugInfoDesc { -private: - int64_t Lo; // Low value of range. - int64_t Hi; // High value of range. - -public: - SubrangeDesc(); - - // Accessors - int64_t getLo() const { return Lo; } - int64_t getHi() const { return Hi; } - void setLo(int64_t L) { Lo = L; } - void setHi(int64_t H) { Hi = H; } - - // Implement isa/cast/dyncast. - static bool classof(const SubrangeDesc *) { return true; } - static bool classof(const DebugInfoDesc *D); - - /// ApplyToFields - Target the visitor to the fields of the SubrangeDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// EnumeratorDesc - This class packages debug information associated with -/// named integer constants. -class EnumeratorDesc : public DebugInfoDesc { -private: - std::string Name; // Enumerator name. - int64_t Value; // Enumerator value. - -public: - EnumeratorDesc(); - - // Accessors - const std::string &getName() const { return Name; } - int64_t getValue() const { return Value; } - void setName(const std::string &N) { Name = N; } - void setValue(int64_t V) { Value = V; } - - // Implement isa/cast/dyncast. - static bool classof(const EnumeratorDesc *) { return true; } - static bool classof(const DebugInfoDesc *D); - - /// ApplyToFields - Target the visitor to the fields of the EnumeratorDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// VariableDesc - This class packages debug information associated with a -/// subprogram variable. -/// -class VariableDesc : public DebugInfoDesc { -private: - DebugInfoDesc *Context; // Context debug descriptor. - std::string Name; // Type name (may be empty.) - DebugInfoDesc *File; // Defined compile unit (may be NULL.) - unsigned Line; // Defined line# (may be zero.) - DebugInfoDesc *TyDesc; // Type of variable. - -public: - VariableDesc(unsigned T); - - // Accessors - DebugInfoDesc *getContext() const { return Context; } - const std::string &getName() const { return Name; } - CompileUnitDesc *getFile() const { - return static_cast(File); - } - unsigned getLine() const { return Line; } - TypeDesc *getType() const { - return static_cast(TyDesc); - } - void setContext(DebugInfoDesc *C) { Context = C; } - void setName(const std::string &N) { Name = N; } - void setFile(CompileUnitDesc *U) { - File = static_cast(U); - } - void setLine(unsigned L) { Line = L; } - void setType(TypeDesc *T) { - TyDesc = static_cast(T); - } - - // Implement isa/cast/dyncast. - static bool classof(const VariableDesc *) { return true; } - static bool classof(const DebugInfoDesc *D); - - /// ApplyToFields - Target the visitor to the fields of the VariableDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// GlobalDesc - This class is the base descriptor for global functions and -/// variables. -class GlobalDesc : public AnchoredDesc { -private: - DebugInfoDesc *Context; // Context debug descriptor. - std::string Name; // Global name. - std::string FullName; // Fully qualified name. - std::string LinkageName; // Name for binding to MIPS linkage. - DebugInfoDesc *File; // Defined compile unit (may be NULL.) - unsigned Line; // Defined line# (may be zero.) - DebugInfoDesc *TyDesc; // Type debug descriptor. - bool IsStatic; // Is the global a static. - bool IsDefinition; // Is the global defined in context. - -protected: - GlobalDesc(unsigned T); - -public: - // Accessors - DebugInfoDesc *getContext() const { return Context; } - const std::string &getName() const { return Name; } - const std::string &getFullName() const { return FullName; } - const std::string &getLinkageName() const { return LinkageName; } - CompileUnitDesc *getFile() const { - return static_cast(File); - } - unsigned getLine() const { return Line; } - TypeDesc *getType() const { - return static_cast(TyDesc); - } - bool isStatic() const { return IsStatic; } - bool isDefinition() const { return IsDefinition; } - void setContext(DebugInfoDesc *C) { Context = C; } - void setName(const std::string &N) { Name = N; } - void setFullName(const std::string &N) { FullName = N; } - void setLinkageName(const std::string &N) { LinkageName = N; } - void setFile(CompileUnitDesc *U) { - File = static_cast(U); - } - void setLine(unsigned L) { Line = L; } - void setType(TypeDesc *T) { - TyDesc = static_cast(T); - } - void setIsStatic(bool IS) { IsStatic = IS; } - void setIsDefinition(bool ID) { IsDefinition = ID; } - - /// ApplyToFields - Target the visitor to the fields of the GlobalDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); -}; - -//===----------------------------------------------------------------------===// -/// GlobalVariableDesc - This class packages debug information associated with a -/// GlobalVariable. -class GlobalVariableDesc : public GlobalDesc { -private: - GlobalVariable *Global; // llvm global. - -public: - GlobalVariableDesc(); - - // Accessors. - GlobalVariable *getGlobalVariable() const { return Global; } - void setGlobalVariable(GlobalVariable *GV) { Global = GV; } - - // Implement isa/cast/dyncast. - static bool classof(const GlobalVariableDesc *) { return true; } - static bool classof(const DebugInfoDesc *D); - - /// ApplyToFields - Target the visitor to the fields of the - /// GlobalVariableDesc. - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - - /// getAnchorString - Return a string used to label this descriptor's anchor. - /// - static const char *AnchorString; - virtual const char *getAnchorString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// SubprogramDesc - This class packages debug information associated with a -/// subprogram/function. -class SubprogramDesc : public GlobalDesc { -private: - -public: - SubprogramDesc(); - - // Accessors - - // Implement isa/cast/dyncast. - static bool classof(const SubprogramDesc *) { return true; } - static bool classof(const DebugInfoDesc *D); - - /// ApplyToFields - Target the visitor to the fields of the SubprogramDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - - /// getAnchorString - Return a string used to label this descriptor's anchor. - /// - static const char *AnchorString; - virtual const char *getAnchorString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// BlockDesc - This descriptor groups variables and blocks nested in a block. -/// -class BlockDesc : public DebugInfoDesc { -private: - DebugInfoDesc *Context; // Context debug descriptor. - -public: - BlockDesc(); - - // Accessors - DebugInfoDesc *getContext() const { return Context; } - void setContext(DebugInfoDesc *C) { Context = C; } - - // Implement isa/cast/dyncast. - static bool classof(const BlockDesc *) { return true; } - static bool classof(const DebugInfoDesc *D); - - /// ApplyToFields - Target the visitor to the fields of the BlockDesc. - /// - virtual void ApplyToFields(DIVisitor *Visitor); - - /// getDescString - Return a string used to compose global names and labels. - /// - virtual const char *getDescString() const; - - /// getTypeString - Return a string used to label this descriptor's type. - /// - virtual const char *getTypeString() const; - -#ifndef NDEBUG - virtual void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIDeserializer - This class is responsible for casting GlobalVariables -/// into DebugInfoDesc objects. -class DIDeserializer { -private: - std::map GlobalDescs; - // Previously defined gloabls. - -public: - DIDeserializer() {} - ~DIDeserializer() {} - - /// 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 TagTypes; - // Types per Tag. Created lazily. - std::map DescGlobals; - // Previously defined descriptors. - std::map StringCache; - // Previously defined strings. - -public: - DISerializer() - : M(NULL) - , StrPtrTy(NULL) - , EmptyStructPtrTy(NULL) - , TagTypes() - , DescGlobals() - , StringCache() - {} - ~DISerializer() {} - - // Accessors - Module *getModule() const { return M; }; - void setModule(Module *module) { M = module; } - - /// getStrPtrType - Return a "sbyte *" type. - /// - const PointerType *getStrPtrType(); - - /// getEmptyStructPtrType - Return a "{ }*" type. - /// - 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. - /// - Constant *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); -}; - -//===----------------------------------------------------------------------===// -/// DIVerifier - This class is responsible for verifying the given network of -/// GlobalVariables are valid as DebugInfoDesc objects. -class DIVerifier { -private: - enum { - Unknown = 0, - Invalid, - Valid - }; - std::map Validity;// Tracks prior results. - std::map Counts; // Count of fields per Tag type. - -public: - DIVerifier() - : Validity() - , Counts() - {} - ~DIVerifier() {} - - /// Verify - Return true if the GlobalVariable appears to be a valid - /// serialization of a DebugInfoDesc. - bool Verify(Value *V); - bool Verify(GlobalVariable *GV); -}; - -//===----------------------------------------------------------------------===// -/// SourceLineInfo - This class is used to record source line correspondence. -/// -class SourceLineInfo { -private: - unsigned Line; // Source line number. - unsigned Column; // Source column. - unsigned SourceID; // Source ID number. - unsigned LabelID; // Label in code ID number. - -public: - SourceLineInfo(unsigned L, unsigned C, unsigned S, unsigned I) - : Line(L), Column(C), SourceID(S), LabelID(I) {} - - // Accessors - unsigned getLine() const { return Line; } - unsigned getColumn() const { return Column; } - unsigned getSourceID() const { return SourceID; } - unsigned getLabelID() const { return LabelID; } -}; - -//===----------------------------------------------------------------------===// -/// SourceFileInfo - This class is used to track source information. -/// -class SourceFileInfo { -private: - unsigned DirectoryID; // Directory ID number. - std::string Name; // File name (not including directory.) - -public: - SourceFileInfo(unsigned D, const std::string &N) : DirectoryID(D), Name(N) {} - - // Accessors - unsigned getDirectoryID() const { return DirectoryID; } - const std::string &getName() const { return Name; } - - /// operator== - Used by UniqueVector to locate entry. - /// - bool operator==(const SourceFileInfo &SI) const { - return getDirectoryID() == SI.getDirectoryID() && getName() == SI.getName(); - } - - /// operator< - Used by UniqueVector to locate entry. - /// - bool operator<(const SourceFileInfo &SI) const { - return getDirectoryID() < SI.getDirectoryID() || - (getDirectoryID() == SI.getDirectoryID() && getName() < SI.getName()); - } -}; - -//===----------------------------------------------------------------------===// -/// DebugVariable - This class is used to track local variable information. -/// -class DebugVariable { -private: - VariableDesc *Desc; // Variable Descriptor. - unsigned FrameIndex; // Variable frame index. - -public: - DebugVariable(VariableDesc *D, unsigned I) - : Desc(D) - , FrameIndex(I) - {} - - // Accessors. - VariableDesc *getDesc() const { return Desc; } - unsigned getFrameIndex() const { return FrameIndex; } -}; - -//===----------------------------------------------------------------------===// -/// DebugScope - This class is used to track scope information. -/// -class DebugScope { -private: - DebugScope *Parent; // Parent to this scope. - DebugInfoDesc *Desc; // Debug info descriptor for scope. - // Either subprogram or block. - unsigned StartLabelID; // Label ID of the beginning of scope. - unsigned EndLabelID; // Label ID of the end of scope. - std::vector Scopes; // Scopes defined in scope. - std::vector Variables;// Variables declared in scope. - -public: - DebugScope(DebugScope *P, DebugInfoDesc *D) - : Parent(P) - , Desc(D) - , StartLabelID(0) - , EndLabelID(0) - , Scopes() - , Variables() - {} - ~DebugScope(); - - // Accessors. - DebugScope *getParent() const { return Parent; } - DebugInfoDesc *getDesc() const { return Desc; } - unsigned getStartLabelID() const { return StartLabelID; } - unsigned getEndLabelID() const { return EndLabelID; } - std::vector &getScopes() { return Scopes; } - std::vector &getVariables() { return Variables; } - void setStartLabelID(unsigned S) { StartLabelID = S; } - void setEndLabelID(unsigned E) { EndLabelID = E; } - - /// AddScope - Add a scope to the scope. - /// - void AddScope(DebugScope *S) { Scopes.push_back(S); } - - /// AddVariable - Add a variable to the scope. - /// - void AddVariable(DebugVariable *V) { Variables.push_back(V); } -}; - -//===----------------------------------------------------------------------===// -/// MachineDebugInfo - This class contains debug information specific to a -/// module. Queries can be made by different debugging schemes and reformated -/// for specific use. -/// -class MachineDebugInfo : public ImmutablePass { -private: - // Use the same deserializer/verifier for the module. - DIDeserializer DR; - DIVerifier VR; - - // CompileUnits - Uniquing vector for compile units. - UniqueVector CompileUnits; - - // Directories - Uniquing vector for directories. - UniqueVector Directories; - - // SourceFiles - Uniquing vector for source files. - UniqueVector SourceFiles; - - // Lines - List of of source line correspondence. - std::vector Lines; - - // LabelIDList - One entry per assigned label. Normally the entry is equal to - // the list index(+1). If the entry is zero then the label has been deleted. - // Any other value indicates the label has been deleted by is mapped to - // another label. - std::vector LabelIDList; - - // ScopeMap - Tracks the scopes in the current function. - std::map ScopeMap; - - // RootScope - Top level scope for the current function. - // - DebugScope *RootScope; - - // FrameMoves - List of moves done by a function's prolog. Used to construct - // frame maps by debug consumers. - std::vector FrameMoves; - -public: - MachineDebugInfo(); - ~MachineDebugInfo(); - - /// doInitialization - Initialize the debug state for a new module. - /// - bool doInitialization(); - - /// doFinalization - Tear down the debug state after completion of a module. - /// - bool doFinalization(); - - /// BeginFunction - Begin gathering function debug information. - /// - void BeginFunction(MachineFunction *MF); - - /// EndFunction - Discard function debug information. - /// - void EndFunction(); - - /// getDescFor - Convert a Value to a debug information descriptor. - /// - // FIXME - use new Value type when available. - DebugInfoDesc *getDescFor(Value *V); - - /// Verify - Verify that a Value is debug information descriptor. - /// - bool Verify(Value *V); - - /// AnalyzeModule - Scan the module for global debug information. - /// - void AnalyzeModule(Module &M); - - /// hasInfo - Returns true if valid debug info is present. - /// - bool hasInfo() const { return !CompileUnits.empty(); } - - /// NextLabelID - Return the next unique label id. - /// - unsigned NextLabelID() { - unsigned ID = LabelIDList.size() + 1; - LabelIDList.push_back(ID); - return ID; - } - - /// RecordLabel - Records location information and associates it with a - /// debug label. Returns a unique label ID used to generate a label and - /// provide correspondence to the source line list. - unsigned RecordLabel(unsigned Line, unsigned Column, unsigned Source); - - /// InvalidateLabel - Inhibit use of the specified label # from - /// MachineDebugInfo, for example because the code was deleted. - void InvalidateLabel(unsigned LabelID) { - // Remap to zero to indicate deletion. - RemapLabel(LabelID, 0); - } - - /// RemapLabel - Indicate that a label has been merged into another. - /// - void RemapLabel(unsigned OldLabelID, unsigned NewLabelID) { - assert(0 < OldLabelID && OldLabelID <= LabelIDList.size() && - "Old debug label ID out of range."); - assert(NewLabelID <= LabelIDList.size() && - "New debug label ID out of range."); - LabelIDList[OldLabelID - 1] = NewLabelID; - } - - /// MappedLabel - Find out the label's final ID. Zero indicates deletion. - /// ID != Mapped ID indicates that the label was folded into another label. - unsigned MappedLabel(unsigned LabelID) const { - assert(LabelID <= LabelIDList.size() && "Debug label ID out of range."); - return LabelID ? LabelIDList[LabelID - 1] : 0; - } - - /// RecordSource - Register a source file with debug info. Returns an source - /// ID. - unsigned RecordSource(const std::string &Directory, - const std::string &Source); - unsigned RecordSource(const CompileUnitDesc *CompileUnit); - - /// getDirectories - Return the UniqueVector of std::string representing - /// directories. - const UniqueVector &getDirectories() const { - return Directories; - } - - /// getSourceFiles - Return the UniqueVector of source files. - /// - const UniqueVector &getSourceFiles() const { - return SourceFiles; - } - - /// getSourceLines - Return a vector of source lines. - /// - const std::vector &getSourceLines() const { - return Lines; - } - - // FIXME: nuke this. - void ClearLineInfo() { - Lines.clear(); - } - - /// SetupCompileUnits - Set up the unique vector of compile units. - /// - void SetupCompileUnits(Module &M); - - /// getCompileUnits - Return a vector of debug compile units. - /// - const UniqueVector getCompileUnits() const; - - /// getGlobalVariablesUsing - Return all of the GlobalVariables that use the - /// named GlobalVariable. - std::vector - getGlobalVariablesUsing(Module &M, const std::string &RootName); - - /// getAnchoredDescriptors - Return a vector of anchored debug descriptors. - /// - template std::vector getAnchoredDescriptors(Module &M) { - T Desc; - std::vector Globals = - getGlobalVariablesUsing(M, Desc.getAnchorString()); - std::vector AnchoredDescs; - for (unsigned i = 0, N = Globals.size(); i < N; ++i) { - GlobalVariable *GV = Globals[i]; - - // FIXME - In the short term, changes are too drastic to continue. - if (DebugInfoDesc::TagFromGlobal(GV) == Desc.getTag() && - DebugInfoDesc::VersionFromGlobal(GV) == LLVMDebugVersion) { - AnchoredDescs.push_back(cast(DR.Deserialize(GV))); - } - } - - return AnchoredDescs; - } - - /// RecordRegionStart - Indicate the start of a region. - /// - unsigned RecordRegionStart(Value *V); - - /// RecordRegionEnd - Indicate the end of a region. - /// - unsigned RecordRegionEnd(Value *V); - - /// RecordVariable - Indicate the declaration of a local variable. - /// - void RecordVariable(Value *V, unsigned FrameIndex); - - /// getRootScope - Return current functions root scope. - /// - DebugScope *getRootScope() { return RootScope; } - - /// getOrCreateScope - Returns the scope associated with the given descriptor. - /// - DebugScope *getOrCreateScope(DebugInfoDesc *ScopeDesc); - - /// getFrameMoves - Returns a reference to a list of moves done in the current - /// function's prologue. Used to construct frame maps for debug comsumers. - std::vector &getFrameMoves() { return FrameMoves; } - -}; // End class MachineDebugInfo - -} // End llvm namespace - -#endif diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h new file mode 100644 index 00000000000..a1c69083be1 --- /dev/null +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -0,0 +1,1156 @@ +//===-- llvm/CodeGen/MachineModuleInfo.h ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by James M. Laskey and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Collect meta information for a module. This information should be in a +// neutral form that can be used by different debugging and exception handling +// schemes. +// +// The organization of information is primarily clustered around the source +// compile units. The main exception is source line correspondence where +// inlining may interleave code from various compile units. +// +// The following information can be retrieved from the MachineModuleInfo. +// +// -- Source directories - Directories are uniqued based on their canonical +// 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.) +// -- Source line correspondence - 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 +// emitter to generate labels referenced by debug information tables. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MACHINEMODULEINFO_H +#define LLVM_CODEGEN_MACHINEMODULEINFO_H + +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/ADT/UniqueVector.h" +#include "llvm/GlobalValue.h" +#include "llvm/Pass.h" + +namespace llvm { + +//===----------------------------------------------------------------------===// +// Forward declarations. +class Constant; +class DebugInfoDesc; +class GlobalVariable; +class MachineFunction; +class MachineMove; +class Module; +class PointerType; +class StructType; + +//===----------------------------------------------------------------------===// +// Debug info constants. + +enum { + LLVMDebugVersion = (6 << 16), // Current version of debug information. + LLVMDebugVersion5 = (5 << 16), // Constant for version 5. + LLVMDebugVersion4 = (4 << 16), // Constant for version 4. + LLVMDebugVersionMask = 0xffff0000 // Mask for version number. +}; + +//===----------------------------------------------------------------------===// +/// DIVisitor - Subclasses of this class apply steps to each of the fields in +/// the supplied DebugInfoDesc. +class DIVisitor { +public: + DIVisitor() {} + virtual ~DIVisitor() {} + + /// ApplyToFields - Target the visitor 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(int64_t &Field) = 0; + virtual void Apply(uint64_t &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; + virtual void Apply(std::vector &Field) = 0; +}; + +//===----------------------------------------------------------------------===// +/// DebugInfoDesc - This class is the base class for debug info descriptors. +/// +class DebugInfoDesc { +private: + unsigned Tag; // Content indicator. Dwarf values are + // used but that does not limit use to + // Dwarf writers. + +protected: + DebugInfoDesc(unsigned T) : Tag(T | LLVMDebugVersion) {} + +public: + virtual ~DebugInfoDesc() {} + + // Accessors + unsigned getTag() const { return Tag & ~LLVMDebugVersionMask; } + unsigned getVersion() const { return Tag & LLVMDebugVersionMask; } + void setTag(unsigned T) { Tag = T | LLVMDebugVersion; } + + /// TagFromGlobal - Returns the tag number from a debug info descriptor + /// GlobalVariable. Return DIIValid if operand is not an unsigned int. + static unsigned TagFromGlobal(GlobalVariable *GV); + + /// VersionFromGlobal - Returns the version number from a debug info + /// descriptor GlobalVariable. Return DIIValid if operand is not an unsigned + /// int. + static unsigned VersionFromGlobal(GlobalVariable *GV); + + /// DescFactory - Create an instance of debug info descriptor based on Tag. + /// Return NULL if not a recognized Tag. + static DebugInfoDesc *DescFactory(unsigned Tag); + + /// getLinkage - get linkage appropriate for this type of descriptor. + /// + virtual GlobalValue::LinkageTypes getLinkage() const; + + //===--------------------------------------------------------------------===// + // 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 vistor to the fields of the descriptor. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const = 0; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const = 0; + +#ifndef NDEBUG + virtual void dump() = 0; +#endif +}; + +//===----------------------------------------------------------------------===// +/// AnchorDesc - Descriptors of this class act as markers for identifying +/// descriptors of certain groups. +class AnchoredDesc; +class AnchorDesc : public DebugInfoDesc { +private: + unsigned AnchorTag; // Tag number of descriptors anchored + // by this object. + +public: + AnchorDesc(); + AnchorDesc(AnchoredDesc *D); + + // Accessors + unsigned getAnchorTag() const { return AnchorTag; } + + // Implement isa/cast/dyncast. + static bool classof(const AnchorDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// getLinkage - get linkage appropriate for this type of descriptor. + /// + virtual GlobalValue::LinkageTypes getLinkage() const; + + /// ApplyToFields - Target the visitor to the fields of the AnchorDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// AnchoredDesc - This class manages anchors for a variety of top level +/// descriptors. +class AnchoredDesc : public DebugInfoDesc { +private: + DebugInfoDesc *Anchor; // Anchor for all descriptors of the + // same type. + +protected: + + AnchoredDesc(unsigned T); + +public: + // Accessors. + AnchorDesc *getAnchor() const { return static_cast(Anchor); } + void setAnchor(AnchorDesc *A) { Anchor = static_cast(A); } + + //===--------------------------------------------------------------------===// + // Subclasses should supply the following virtual methods. + + /// getAnchorString - Return a string used to label descriptor's anchor. + /// + virtual const char *getAnchorString() const = 0; + + /// ApplyToFields - Target the visitor to the fields of the AnchoredDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); +}; + +//===----------------------------------------------------------------------===// +/// CompileUnitDesc - This class packages debug information associated with a +/// source/header file. +class CompileUnitDesc : public AnchoredDesc { +private: + 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. + +public: + CompileUnitDesc(); + + + // Accessors + 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. + + // Implement isa/cast/dyncast. + static bool classof(const CompileUnitDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + + /// getAnchorString - Return a string used to label this descriptor's anchor. + /// + static const char *AnchorString; + virtual const char *getAnchorString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// TypeDesc - This class packages debug information associated with a type. +/// +class TypeDesc : public DebugInfoDesc { +private: + enum { + FlagPrivate = 1 << 0, + FlagProtected = 1 << 1 + }; + DebugInfoDesc *Context; // Context debug descriptor. + std::string Name; // Type name (may be empty.) + DebugInfoDesc *File; // Defined compile unit (may be NULL.) + unsigned Line; // Defined line# (may be zero.) + uint64_t Size; // Type bit size (may be zero.) + uint64_t Align; // Type bit alignment (may be zero.) + uint64_t Offset; // Type bit offset (may be zero.) + unsigned Flags; // Miscellaneous flags. + +public: + TypeDesc(unsigned T); + + // Accessors + DebugInfoDesc *getContext() const { return Context; } + const std::string &getName() const { return Name; } + CompileUnitDesc *getFile() const { + return static_cast(File); + } + unsigned getLine() const { return Line; } + uint64_t getSize() const { return Size; } + uint64_t getAlign() const { return Align; } + uint64_t getOffset() const { return Offset; } + bool isPrivate() const { + return (Flags & FlagPrivate) != 0; + } + bool isProtected() const { + return (Flags & FlagProtected) != 0; + } + void setContext(DebugInfoDesc *C) { Context = C; } + void setName(const std::string &N) { Name = N; } + void setFile(CompileUnitDesc *U) { + File = static_cast(U); + } + void setLine(unsigned L) { Line = L; } + void setSize(uint64_t S) { Size = S; } + void setAlign(uint64_t A) { Align = A; } + void setOffset(uint64_t O) { Offset = O; } + void setIsPrivate() { Flags |= FlagPrivate; } + void setIsProtected() { Flags |= FlagProtected; } + + /// ApplyToFields - Target the visitor to the fields of the TypeDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// BasicTypeDesc - This class packages debug information associated with a +/// basic type (eg. int, bool, double.) +class BasicTypeDesc : public TypeDesc { +private: + unsigned Encoding; // Type encoding. + +public: + BasicTypeDesc(); + + // Accessors + unsigned getEncoding() const { return Encoding; } + void setEncoding(unsigned E) { Encoding = E; } + + // Implement isa/cast/dyncast. + static bool classof(const BasicTypeDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + + +//===----------------------------------------------------------------------===// +/// DerivedTypeDesc - This class packages debug information associated with a +/// derived types (eg., typedef, pointer, reference.) +class DerivedTypeDesc : public TypeDesc { +private: + DebugInfoDesc *FromType; // Type derived from. + +public: + DerivedTypeDesc(unsigned T); + + // Accessors + TypeDesc *getFromType() const { + return static_cast(FromType); + } + void setFromType(TypeDesc *F) { + FromType = static_cast(F); + } + + // Implement isa/cast/dyncast. + static bool classof(const DerivedTypeDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// CompositeTypeDesc - This class packages debug information associated with a +/// array/struct types (eg., arrays, struct, union, enums.) +class CompositeTypeDesc : public DerivedTypeDesc { +private: + std::vector Elements;// Information used to compose type. + +public: + CompositeTypeDesc(unsigned T); + + // Accessors + std::vector &getElements() { return Elements; } + + // Implement isa/cast/dyncast. + static bool classof(const CompositeTypeDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// SubrangeDesc - This class packages debug information associated with integer +/// value ranges. +class SubrangeDesc : public DebugInfoDesc { +private: + int64_t Lo; // Low value of range. + int64_t Hi; // High value of range. + +public: + SubrangeDesc(); + + // Accessors + int64_t getLo() const { return Lo; } + int64_t getHi() const { return Hi; } + void setLo(int64_t L) { Lo = L; } + void setHi(int64_t H) { Hi = H; } + + // Implement isa/cast/dyncast. + static bool classof(const SubrangeDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// ApplyToFields - Target the visitor to the fields of the SubrangeDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// EnumeratorDesc - This class packages debug information associated with +/// named integer constants. +class EnumeratorDesc : public DebugInfoDesc { +private: + std::string Name; // Enumerator name. + int64_t Value; // Enumerator value. + +public: + EnumeratorDesc(); + + // Accessors + const std::string &getName() const { return Name; } + int64_t getValue() const { return Value; } + void setName(const std::string &N) { Name = N; } + void setValue(int64_t V) { Value = V; } + + // Implement isa/cast/dyncast. + static bool classof(const EnumeratorDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// ApplyToFields - Target the visitor to the fields of the EnumeratorDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// VariableDesc - This class packages debug information associated with a +/// subprogram variable. +/// +class VariableDesc : public DebugInfoDesc { +private: + DebugInfoDesc *Context; // Context debug descriptor. + std::string Name; // Type name (may be empty.) + DebugInfoDesc *File; // Defined compile unit (may be NULL.) + unsigned Line; // Defined line# (may be zero.) + DebugInfoDesc *TyDesc; // Type of variable. + +public: + VariableDesc(unsigned T); + + // Accessors + DebugInfoDesc *getContext() const { return Context; } + const std::string &getName() const { return Name; } + CompileUnitDesc *getFile() const { + return static_cast(File); + } + unsigned getLine() const { return Line; } + TypeDesc *getType() const { + return static_cast(TyDesc); + } + void setContext(DebugInfoDesc *C) { Context = C; } + void setName(const std::string &N) { Name = N; } + void setFile(CompileUnitDesc *U) { + File = static_cast(U); + } + void setLine(unsigned L) { Line = L; } + void setType(TypeDesc *T) { + TyDesc = static_cast(T); + } + + // Implement isa/cast/dyncast. + static bool classof(const VariableDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// ApplyToFields - Target the visitor to the fields of the VariableDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// GlobalDesc - This class is the base descriptor for global functions and +/// variables. +class GlobalDesc : public AnchoredDesc { +private: + DebugInfoDesc *Context; // Context debug descriptor. + std::string Name; // Global name. + std::string FullName; // Fully qualified name. + std::string LinkageName; // Name for binding to MIPS linkage. + DebugInfoDesc *File; // Defined compile unit (may be NULL.) + unsigned Line; // Defined line# (may be zero.) + DebugInfoDesc *TyDesc; // Type debug descriptor. + bool IsStatic; // Is the global a static. + bool IsDefinition; // Is the global defined in context. + +protected: + GlobalDesc(unsigned T); + +public: + // Accessors + DebugInfoDesc *getContext() const { return Context; } + const std::string &getName() const { return Name; } + const std::string &getFullName() const { return FullName; } + const std::string &getLinkageName() const { return LinkageName; } + CompileUnitDesc *getFile() const { + return static_cast(File); + } + unsigned getLine() const { return Line; } + TypeDesc *getType() const { + return static_cast(TyDesc); + } + bool isStatic() const { return IsStatic; } + bool isDefinition() const { return IsDefinition; } + void setContext(DebugInfoDesc *C) { Context = C; } + void setName(const std::string &N) { Name = N; } + void setFullName(const std::string &N) { FullName = N; } + void setLinkageName(const std::string &N) { LinkageName = N; } + void setFile(CompileUnitDesc *U) { + File = static_cast(U); + } + void setLine(unsigned L) { Line = L; } + void setType(TypeDesc *T) { + TyDesc = static_cast(T); + } + void setIsStatic(bool IS) { IsStatic = IS; } + void setIsDefinition(bool ID) { IsDefinition = ID; } + + /// ApplyToFields - Target the visitor to the fields of the GlobalDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); +}; + +//===----------------------------------------------------------------------===// +/// GlobalVariableDesc - This class packages debug information associated with a +/// GlobalVariable. +class GlobalVariableDesc : public GlobalDesc { +private: + GlobalVariable *Global; // llvm global. + +public: + GlobalVariableDesc(); + + // Accessors. + GlobalVariable *getGlobalVariable() const { return Global; } + void setGlobalVariable(GlobalVariable *GV) { Global = GV; } + + // Implement isa/cast/dyncast. + static bool classof(const GlobalVariableDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// ApplyToFields - Target the visitor to the fields of the + /// GlobalVariableDesc. + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + + /// getAnchorString - Return a string used to label this descriptor's anchor. + /// + static const char *AnchorString; + virtual const char *getAnchorString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// SubprogramDesc - This class packages debug information associated with a +/// subprogram/function. +class SubprogramDesc : public GlobalDesc { +private: + +public: + SubprogramDesc(); + + // Accessors + + // Implement isa/cast/dyncast. + static bool classof(const SubprogramDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// ApplyToFields - Target the visitor to the fields of the SubprogramDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + + /// getAnchorString - Return a string used to label this descriptor's anchor. + /// + static const char *AnchorString; + virtual const char *getAnchorString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// BlockDesc - This descriptor groups variables and blocks nested in a block. +/// +class BlockDesc : public DebugInfoDesc { +private: + DebugInfoDesc *Context; // Context debug descriptor. + +public: + BlockDesc(); + + // Accessors + DebugInfoDesc *getContext() const { return Context; } + void setContext(DebugInfoDesc *C) { Context = C; } + + // Implement isa/cast/dyncast. + static bool classof(const BlockDesc *) { return true; } + static bool classof(const DebugInfoDesc *D); + + /// ApplyToFields - Target the visitor to the fields of the BlockDesc. + /// + virtual void ApplyToFields(DIVisitor *Visitor); + + /// getDescString - Return a string used to compose global names and labels. + /// + virtual const char *getDescString() const; + + /// getTypeString - Return a string used to label this descriptor's type. + /// + virtual const char *getTypeString() const; + +#ifndef NDEBUG + virtual void dump(); +#endif +}; + +//===----------------------------------------------------------------------===// +/// DIDeserializer - This class is responsible for casting GlobalVariables +/// into DebugInfoDesc objects. +class DIDeserializer { +private: + std::map GlobalDescs; + // Previously defined gloabls. + +public: + DIDeserializer() {} + ~DIDeserializer() {} + + /// 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 TagTypes; + // Types per Tag. Created lazily. + std::map DescGlobals; + // Previously defined descriptors. + std::map StringCache; + // Previously defined strings. + +public: + DISerializer() + : M(NULL) + , StrPtrTy(NULL) + , EmptyStructPtrTy(NULL) + , TagTypes() + , DescGlobals() + , StringCache() + {} + ~DISerializer() {} + + // Accessors + Module *getModule() const { return M; }; + void setModule(Module *module) { M = module; } + + /// getStrPtrType - Return a "sbyte *" type. + /// + const PointerType *getStrPtrType(); + + /// getEmptyStructPtrType - Return a "{ }*" type. + /// + 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. + /// + Constant *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); +}; + +//===----------------------------------------------------------------------===// +/// DIVerifier - This class is responsible for verifying the given network of +/// GlobalVariables are valid as DebugInfoDesc objects. +class DIVerifier { +private: + enum { + Unknown = 0, + Invalid, + Valid + }; + std::map Validity;// Tracks prior results. + std::map Counts; // Count of fields per Tag type. + +public: + DIVerifier() + : Validity() + , Counts() + {} + ~DIVerifier() {} + + /// Verify - Return true if the GlobalVariable appears to be a valid + /// serialization of a DebugInfoDesc. + bool Verify(Value *V); + bool Verify(GlobalVariable *GV); +}; + +//===----------------------------------------------------------------------===// +/// SourceLineInfo - This class is used to record source line correspondence. +/// +class SourceLineInfo { +private: + unsigned Line; // Source line number. + unsigned Column; // Source column. + unsigned SourceID; // Source ID number. + unsigned LabelID; // Label in code ID number. + +public: + SourceLineInfo(unsigned L, unsigned C, unsigned S, unsigned I) + : Line(L), Column(C), SourceID(S), LabelID(I) {} + + // Accessors + unsigned getLine() const { return Line; } + unsigned getColumn() const { return Column; } + unsigned getSourceID() const { return SourceID; } + unsigned getLabelID() const { return LabelID; } +}; + +//===----------------------------------------------------------------------===// +/// SourceFileInfo - This class is used to track source information. +/// +class SourceFileInfo { +private: + unsigned DirectoryID; // Directory ID number. + std::string Name; // File name (not including directory.) + +public: + SourceFileInfo(unsigned D, const std::string &N) : DirectoryID(D), Name(N) {} + + // Accessors + unsigned getDirectoryID() const { return DirectoryID; } + const std::string &getName() const { return Name; } + + /// operator== - Used by UniqueVector to locate entry. + /// + bool operator==(const SourceFileInfo &SI) const { + return getDirectoryID() == SI.getDirectoryID() && getName() == SI.getName(); + } + + /// operator< - Used by UniqueVector to locate entry. + /// + bool operator<(const SourceFileInfo &SI) const { + return getDirectoryID() < SI.getDirectoryID() || + (getDirectoryID() == SI.getDirectoryID() && getName() < SI.getName()); + } +}; + +//===----------------------------------------------------------------------===// +/// DebugVariable - This class is used to track local variable information. +/// +class DebugVariable { +private: + VariableDesc *Desc; // Variable Descriptor. + unsigned FrameIndex; // Variable frame index. + +public: + DebugVariable(VariableDesc *D, unsigned I) + : Desc(D) + , FrameIndex(I) + {} + + // Accessors. + VariableDesc *getDesc() const { return Desc; } + unsigned getFrameIndex() const { return FrameIndex; } +}; + +//===----------------------------------------------------------------------===// +/// DebugScope - This class is used to track scope information. +/// +class DebugScope { +private: + DebugScope *Parent; // Parent to this scope. + DebugInfoDesc *Desc; // Debug info descriptor for scope. + // Either subprogram or block. + unsigned StartLabelID; // Label ID of the beginning of scope. + unsigned EndLabelID; // Label ID of the end of scope. + std::vector Scopes; // Scopes defined in scope. + std::vector Variables;// Variables declared in scope. + +public: + DebugScope(DebugScope *P, DebugInfoDesc *D) + : Parent(P) + , Desc(D) + , StartLabelID(0) + , EndLabelID(0) + , Scopes() + , Variables() + {} + ~DebugScope(); + + // Accessors. + DebugScope *getParent() const { return Parent; } + DebugInfoDesc *getDesc() const { return Desc; } + unsigned getStartLabelID() const { return StartLabelID; } + unsigned getEndLabelID() const { return EndLabelID; } + std::vector &getScopes() { return Scopes; } + std::vector &getVariables() { return Variables; } + void setStartLabelID(unsigned S) { StartLabelID = S; } + void setEndLabelID(unsigned E) { EndLabelID = E; } + + /// AddScope - Add a scope to the scope. + /// + void AddScope(DebugScope *S) { Scopes.push_back(S); } + + /// AddVariable - Add a variable to the scope. + /// + void AddVariable(DebugVariable *V) { Variables.push_back(V); } +}; + +//===----------------------------------------------------------------------===// +/// MachineModuleInfo - This class contains meta information specific to a +/// module. Queries can be made by different debugging and exception handling +/// schemes and reformated for specific use. +/// +class MachineModuleInfo : public ImmutablePass { +private: + // Use the same deserializer/verifier for the module. + DIDeserializer DR; + DIVerifier VR; + + // CompileUnits - Uniquing vector for compile units. + UniqueVector CompileUnits; + + // Directories - Uniquing vector for directories. + UniqueVector Directories; + + // SourceFiles - Uniquing vector for source files. + UniqueVector SourceFiles; + + // Lines - List of of source line correspondence. + std::vector Lines; + + // LabelIDList - One entry per assigned label. Normally the entry is equal to + // the list index(+1). If the entry is zero then the label has been deleted. + // Any other value indicates the label has been deleted by is mapped to + // another label. + std::vector LabelIDList; + + // ScopeMap - Tracks the scopes in the current function. + std::map ScopeMap; + + // RootScope - Top level scope for the current function. + // + DebugScope *RootScope; + + // FrameMoves - List of moves done by a function's prolog. Used to construct + // frame maps by debug and exception handling consumers. + std::vector FrameMoves; + +public: + MachineModuleInfo(); + ~MachineModuleInfo(); + + /// doInitialization - Initialize the state for a new module. + /// + bool doInitialization(); + + /// doFinalization - Tear down the state after completion of a module. + /// + bool doFinalization(); + + /// BeginFunction - Begin gathering function meta information. + /// + void BeginFunction(MachineFunction *MF); + + /// EndFunction - Discard function meta information. + /// + void EndFunction(); + + /// getDescFor - Convert a Value to a debug information descriptor. + /// + // FIXME - use new Value type when available. + DebugInfoDesc *getDescFor(Value *V); + + /// Verify - Verify that a Value is debug information descriptor. + /// + bool Verify(Value *V); + + /// AnalyzeModule - Scan the module for global debug information. + /// + void AnalyzeModule(Module &M); + + /// hasDebugInfo - Returns true if valid debug info is present. + /// + bool hasDebugInfo() const { return !CompileUnits.empty(); } + + /// NextLabelID - Return the next unique label id. + /// + unsigned NextLabelID() { + unsigned ID = LabelIDList.size() + 1; + LabelIDList.push_back(ID); + return ID; + } + + /// RecordLabel - Records location information and associates it with a + /// label. Returns a unique label ID used to generate a label and + /// provide correspondence to the source line list. + unsigned RecordLabel(unsigned Line, unsigned Column, unsigned Source); + + /// InvalidateLabel - Inhibit use of the specified label # from + /// MachineModuleInfo, for example because the code was deleted. + void InvalidateLabel(unsigned LabelID) { + // Remap to zero to indicate deletion. + RemapLabel(LabelID, 0); + } + + /// RemapLabel - Indicate that a label has been merged into another. + /// + void RemapLabel(unsigned OldLabelID, unsigned NewLabelID) { + assert(0 < OldLabelID && OldLabelID <= LabelIDList.size() && + "Old label ID out of range."); + assert(NewLabelID <= LabelIDList.size() && + "New label ID out of range."); + LabelIDList[OldLabelID - 1] = NewLabelID; + } + + /// MappedLabel - Find out the label's final ID. Zero indicates deletion. + /// ID != Mapped ID indicates that the label was folded into another label. + unsigned MappedLabel(unsigned LabelID) const { + assert(LabelID <= LabelIDList.size() && "Debug label ID out of range."); + return LabelID ? LabelIDList[LabelID - 1] : 0; + } + + /// RecordSource - Register a source file with debug info. Returns an source + /// ID. + unsigned RecordSource(const std::string &Directory, + const std::string &Source); + unsigned RecordSource(const CompileUnitDesc *CompileUnit); + + /// getDirectories - Return the UniqueVector of std::string representing + /// directories. + const UniqueVector &getDirectories() const { + return Directories; + } + + /// getSourceFiles - Return the UniqueVector of source files. + /// + const UniqueVector &getSourceFiles() const { + return SourceFiles; + } + + /// getSourceLines - Return a vector of source lines. + /// + const std::vector &getSourceLines() const { + return Lines; + } + + // FIXME: nuke this. + void ClearLineInfo() { + Lines.clear(); + } + + /// SetupCompileUnits - Set up the unique vector of compile units. + /// + void SetupCompileUnits(Module &M); + + /// getCompileUnits - Return a vector of debug compile units. + /// + const UniqueVector getCompileUnits() const; + + /// getGlobalVariablesUsing - Return all of the GlobalVariables that use the + /// named GlobalVariable. + std::vector + getGlobalVariablesUsing(Module &M, const std::string &RootName); + + /// getAnchoredDescriptors - Return a vector of anchored debug descriptors. + /// + template std::vector getAnchoredDescriptors(Module &M) { + T Desc; + std::vector Globals = + getGlobalVariablesUsing(M, Desc.getAnchorString()); + std::vector AnchoredDescs; + for (unsigned i = 0, N = Globals.size(); i < N; ++i) { + GlobalVariable *GV = Globals[i]; + + // FIXME - In the short term, changes are too drastic to continue. + if (DebugInfoDesc::TagFromGlobal(GV) == Desc.getTag() && + DebugInfoDesc::VersionFromGlobal(GV) == LLVMDebugVersion) { + AnchoredDescs.push_back(cast(DR.Deserialize(GV))); + } + } + + return AnchoredDescs; + } + + /// RecordRegionStart - Indicate the start of a region. + /// + unsigned RecordRegionStart(Value *V); + + /// RecordRegionEnd - Indicate the end of a region. + /// + unsigned RecordRegionEnd(Value *V); + + /// RecordVariable - Indicate the declaration of a local variable. + /// + void RecordVariable(Value *V, unsigned FrameIndex); + + /// getRootScope - Return current functions root scope. + /// + DebugScope *getRootScope() { return RootScope; } + + /// getOrCreateScope - Returns the scope associated with the given descriptor. + /// + DebugScope *getOrCreateScope(DebugInfoDesc *ScopeDesc); + + /// getFrameMoves - Returns a reference to a list of moves done in the current + /// function's prologue. Used to construct frame maps for debug and exception + /// handling comsumers. + std::vector &getFrameMoves() { return FrameMoves; } + +}; // End class MachineModuleInfo + +} // End llvm namespace + +#endif diff --git a/lib/CodeGen/MachineDebugInfo.cpp b/lib/CodeGen/MachineDebugInfo.cpp deleted file mode 100644 index 45e7fa2a6b1..00000000000 --- a/lib/CodeGen/MachineDebugInfo.cpp +++ /dev/null @@ -1,1696 +0,0 @@ -//===-- llvm/CodeGen/MachineDebugInfo.cpp -----------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by James M. Laskey and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CodeGen/MachineDebugInfo.h" - -#include "llvm/Constants.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineLocation.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.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 "llvm/Support/Streams.h" -using namespace llvm; -using namespace llvm::dwarf; - -// Handle the Pass registration stuff necessary to use TargetData's. -namespace { - RegisterPass X("machinedebuginfo", "Debug Information"); -} - -//===----------------------------------------------------------------------===// - -/// getGlobalVariablesUsing - Return all of the GlobalVariables which have the -/// specified value in their initializer somewhere. -static void -getGlobalVariablesUsing(Value *V, std::vector &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(*I)) { - // If the user is a GlobalVariable then add to result. - Result.push_back(GV); - } else if (Constant *C = dyn_cast(*I)) { - // If the user is a constant variable then scan its users - getGlobalVariablesUsing(C, Result); - } - } -} - -/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the -/// named GlobalVariable. -static std::vector -getGlobalVariablesUsing(Module &M, const std::string &RootName) { - std::vector Result; // GlobalVariables matching criteria. - - std::vector FieldTypes; - FieldTypes.push_back(Type::Int32Ty); - FieldTypes.push_back(Type::Int32Ty); - - // Get the GlobalVariable root. - GlobalVariable *UseRoot = M.getGlobalVariable(RootName, - StructType::get(FieldTypes)); - - // If present and linkonce then scan for users. - if (UseRoot && UseRoot->hasLinkOnceLinkage()) { - getGlobalVariablesUsing(UseRoot, Result); - } - - return Result; -} - -/// isStringValue - Return true if the given value can be coerced to a string. -/// -static bool isStringValue(Value *V) { - if (GlobalVariable *GV = dyn_cast(V)) { - if (GV->hasInitializer() && isa(GV->getInitializer())) { - ConstantArray *Init = cast(GV->getInitializer()); - return Init->isString(); - } - } else if (Constant *C = dyn_cast(V)) { - if (GlobalValue *GV = dyn_cast(C)) - return isStringValue(GV); - else if (ConstantExpr *CE = dyn_cast(C)) { - if (CE->getOpcode() == Instruction::GetElementPtr) { - if (CE->getNumOperands() == 3 && - cast(CE->getOperand(1))->isNullValue() && - isa(CE->getOperand(2))) { - return isStringValue(CE->getOperand(0)); - } - } - } - } - return false; -} - -/// getGlobalVariable - Return either a direct or cast Global value. -/// -static GlobalVariable *getGlobalVariable(Value *V) { - if (GlobalVariable *GV = dyn_cast(V)) { - return GV; - } else if (ConstantExpr *CE = dyn_cast(V)) { - if (CE->getOpcode() == Instruction::BitCast) { - return dyn_cast(CE->getOperand(0)); - } - } - return NULL; -} - -/// isGlobalVariable - Return true if the given value can be coerced to a -/// GlobalVariable. -static bool isGlobalVariable(Value *V) { - if (isa(V) || isa(V)) { - return true; - } else if (ConstantExpr *CE = dyn_cast(V)) { - if (CE->getOpcode() == Instruction::BitCast) { - return isa(CE->getOperand(0)); - } - } - return false; -} - -/// getUIntOperand - Return ith operand if it is an unsigned integer. -/// -static ConstantInt *getUIntOperand(GlobalVariable *GV, unsigned i) { - // Make sure the GlobalVariable has an initializer. - if (!GV->hasInitializer()) return NULL; - - // Get the initializer constant. - ConstantStruct *CI = dyn_cast(GV->getInitializer()); - if (!CI) return NULL; - - // Check if there is at least i + 1 operands. - unsigned N = CI->getNumOperands(); - if (i >= N) return NULL; - - // Check constant. - return dyn_cast(CI->getOperand(i)); -} - -//===----------------------------------------------------------------------===// - -/// ApplyToFields - Target the visitor to each field of the debug information -/// descriptor. -void DIVisitor::ApplyToFields(DebugInfoDesc *DD) { - DD->ApplyToFields(this); -} - -//===----------------------------------------------------------------------===// -/// DICountVisitor - This DIVisitor counts all the fields in the supplied debug -/// the supplied DebugInfoDesc. -class DICountVisitor : public DIVisitor { -private: - unsigned Count; // Running count of fields. - -public: - DICountVisitor() : DIVisitor(), Count(0) {} - - // 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(int64_t &Field) { ++Count; } - virtual void Apply(uint64_t &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; } - virtual void Apply(std::vector &Field) { - ++Count; - } -}; - -//===----------------------------------------------------------------------===// -/// DIDeserializeVisitor - This DIVisitor deserializes all the fields in the -/// supplied DebugInfoDesc. -class DIDeserializeVisitor : public DIVisitor { -private: - DIDeserializer &DR; // Active deserializer. - unsigned I; // Current operand index. - ConstantStruct *CI; // GlobalVariable constant initializer. - -public: - DIDeserializeVisitor(DIDeserializer &D, GlobalVariable *GV) - : DIVisitor() - , DR(D) - , I(0) - , CI(cast(GV->getInitializer())) - {} - - /// Apply - Set the value of each of the fields. - /// - virtual void Apply(int &Field) { - Constant *C = CI->getOperand(I++); - Field = cast(C)->getSExtValue(); - } - virtual void Apply(unsigned &Field) { - Constant *C = CI->getOperand(I++); - Field = cast(C)->getZExtValue(); - } - virtual void Apply(int64_t &Field) { - Constant *C = CI->getOperand(I++); - Field = cast(C)->getSExtValue(); - } - virtual void Apply(uint64_t &Field) { - Constant *C = CI->getOperand(I++); - Field = cast(C)->getZExtValue(); - } - virtual void Apply(bool &Field) { - Constant *C = CI->getOperand(I++); - Field = cast(C)->getZExtValue(); - } - virtual void Apply(std::string &Field) { - Constant *C = CI->getOperand(I++); - Field = C->getStringValue(); - } - 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 = getGlobalVariable(C); - } - virtual void Apply(std::vector &Field) { - Field.resize(0); - Constant *C = CI->getOperand(I++); - GlobalVariable *GV = getGlobalVariable(C); - if (GV->hasInitializer()) { - if (ConstantArray *CA = dyn_cast(GV->getInitializer())) { - for (unsigned i = 0, N = CA->getNumOperands(); i < N; ++i) { - GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i)); - DebugInfoDesc *DE = DR.Deserialize(GVE); - Field.push_back(DE); - } - } else if (GV->getInitializer()->isNullValue()) { - if (const ArrayType *T = - dyn_cast(GV->getType()->getElementType())) { - Field.resize(T->getNumElements()); - } - } - } - } -}; - -//===----------------------------------------------------------------------===// -/// DISerializeVisitor - This DIVisitor serializes all the fields in -/// the supplied DebugInfoDesc. -class DISerializeVisitor : public DIVisitor { -private: - DISerializer &SR; // Active serializer. - std::vector &Elements; // Element accumulator. - -public: - DISerializeVisitor(DISerializer &S, std::vector &E) - : DIVisitor() - , SR(S) - , Elements(E) - {} - - /// Apply - Set the value of each of the fields. - /// - virtual void Apply(int &Field) { - Elements.push_back(ConstantInt::get(Type::Int32Ty, int32_t(Field))); - } - virtual void Apply(unsigned &Field) { - Elements.push_back(ConstantInt::get(Type::Int32Ty, uint32_t(Field))); - } - virtual void Apply(int64_t &Field) { - Elements.push_back(ConstantInt::get(Type::Int64Ty, int64_t(Field))); - } - virtual void Apply(uint64_t &Field) { - Elements.push_back(ConstantInt::get(Type::Int64Ty, uint64_t(Field))); - } - virtual void Apply(bool &Field) { - Elements.push_back(ConstantInt::get(Type::Int1Ty, Field)); - } - virtual void Apply(std::string &Field) { - Elements.push_back(SR.getString(Field)); - } - virtual void Apply(DebugInfoDesc *&Field) { - GlobalVariable *GV = NULL; - - // If non-NULL then 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::getBitCast(GV, EmptyTy)); - } else { - // Use NULL. - Elements.push_back(ConstantPointerNull::get(EmptyTy)); - } - } - virtual void Apply(GlobalVariable *&Field) { - const PointerType *EmptyTy = SR.getEmptyStructPtrType(); - if (Field) { - Elements.push_back(ConstantExpr::getBitCast(Field, EmptyTy)); - } else { - Elements.push_back(ConstantPointerNull::get(EmptyTy)); - } - } - virtual void Apply(std::vector &Field) { - const PointerType *EmptyTy = SR.getEmptyStructPtrType(); - unsigned N = Field.size(); - ArrayType *AT = ArrayType::get(EmptyTy, N); - std::vector ArrayElements; - - for (unsigned i = 0, N = Field.size(); i < N; ++i) { - if (DebugInfoDesc *Element = Field[i]) { - GlobalVariable *GVE = SR.Serialize(Element); - Constant *CE = ConstantExpr::getBitCast(GVE, EmptyTy); - ArrayElements.push_back(cast(CE)); - } else { - ArrayElements.push_back(ConstantPointerNull::get(EmptyTy)); - } - } - - Constant *CA = ConstantArray::get(AT, ArrayElements); - GlobalVariable *CAGV = new GlobalVariable(AT, true, - GlobalValue::InternalLinkage, - CA, "llvm.dbg.array", - SR.getModule()); - CAGV->setSection("llvm.metadata"); - Constant *CAE = ConstantExpr::getBitCast(CAGV, EmptyTy); - Elements.push_back(CAE); - } -}; - -//===----------------------------------------------------------------------===// -/// DIGetTypesVisitor - This DIVisitor gathers all the field types in -/// the supplied DebugInfoDesc. -class DIGetTypesVisitor : public DIVisitor { -private: - DISerializer &SR; // Active serializer. - std::vector &Fields; // Type accumulator. - -public: - DIGetTypesVisitor(DISerializer &S, std::vector &F) - : DIVisitor() - , SR(S) - , Fields(F) - {} - - /// Apply - Set the value of each of the fields. - /// - virtual void Apply(int &Field) { - Fields.push_back(Type::Int32Ty); - } - virtual void Apply(unsigned &Field) { - Fields.push_back(Type::Int32Ty); - } - virtual void Apply(int64_t &Field) { - Fields.push_back(Type::Int64Ty); - } - virtual void Apply(uint64_t &Field) { - Fields.push_back(Type::Int64Ty); - } - virtual void Apply(bool &Field) { - Fields.push_back(Type::Int1Ty); - } - 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); - } - virtual void Apply(std::vector &Field) { - const PointerType *EmptyTy = SR.getEmptyStructPtrType(); - Fields.push_back(EmptyTy); - } -}; - -//===----------------------------------------------------------------------===// -/// DIVerifyVisitor - This DIVisitor verifies all the field types against -/// a constant initializer. -class DIVerifyVisitor : public DIVisitor { -private: - DIVerifier &VR; // Active verifier. - bool IsValid; // Validity status. - unsigned I; // Current operand index. - ConstantStruct *CI; // GlobalVariable constant initializer. - -public: - DIVerifyVisitor(DIVerifier &V, GlobalVariable *GV) - : DIVisitor() - , VR(V) - , IsValid(true) - , I(0) - , CI(cast(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(C); - } - virtual void Apply(unsigned &Field) { - Constant *C = CI->getOperand(I++); - IsValid = IsValid && isa(C); - } - virtual void Apply(int64_t &Field) { - Constant *C = CI->getOperand(I++); - IsValid = IsValid && isa(C); - } - virtual void Apply(uint64_t &Field) { - Constant *C = CI->getOperand(I++); - IsValid = IsValid && isa(C); - } - virtual void Apply(bool &Field) { - Constant *C = CI->getOperand(I++); - IsValid = IsValid && isa(C) && C->getType() == Type::Int1Ty; - } - virtual void Apply(std::string &Field) { - Constant *C = CI->getOperand(I++); - IsValid = IsValid && - (!C || isStringValue(C) || C->isNullValue()); - } - virtual void Apply(DebugInfoDesc *&Field) { - // FIXME - Prepare the correct descriptor. - Constant *C = CI->getOperand(I++); - IsValid = IsValid && isGlobalVariable(C); - } - virtual void Apply(GlobalVariable *&Field) { - Constant *C = CI->getOperand(I++); - IsValid = IsValid && isGlobalVariable(C); - } - virtual void Apply(std::vector &Field) { - Constant *C = CI->getOperand(I++); - IsValid = IsValid && isGlobalVariable(C); - if (!IsValid) return; - - GlobalVariable *GV = getGlobalVariable(C); - IsValid = IsValid && GV && GV->hasInitializer(); - if (!IsValid) return; - - ConstantArray *CA = dyn_cast(GV->getInitializer()); - IsValid = IsValid && CA; - if (!IsValid) return; - - for (unsigned i = 0, N = CA->getNumOperands(); IsValid && i < N; ++i) { - IsValid = IsValid && isGlobalVariable(CA->getOperand(i)); - if (!IsValid) return; - - GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i)); - VR.Verify(GVE); - } - } -}; - - -//===----------------------------------------------------------------------===// - -/// TagFromGlobal - Returns the tag number from a debug info descriptor -/// GlobalVariable. Return DIIValid if operand is not an unsigned int. -unsigned DebugInfoDesc::TagFromGlobal(GlobalVariable *GV) { - ConstantInt *C = getUIntOperand(GV, 0); - return C ? ((unsigned)C->getZExtValue() & ~LLVMDebugVersionMask) : - (unsigned)DW_TAG_invalid; -} - -/// VersionFromGlobal - Returns the version number from a debug info -/// descriptor GlobalVariable. Return DIIValid if operand is not an unsigned -/// int. -unsigned DebugInfoDesc::VersionFromGlobal(GlobalVariable *GV) { - ConstantInt *C = getUIntOperand(GV, 0); - return C ? ((unsigned)C->getZExtValue() & LLVMDebugVersionMask) : - (unsigned)DW_TAG_invalid; -} - -/// 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 DW_TAG_anchor: return new AnchorDesc(); - case DW_TAG_compile_unit: return new CompileUnitDesc(); - case DW_TAG_variable: return new GlobalVariableDesc(); - case DW_TAG_subprogram: return new SubprogramDesc(); - case DW_TAG_lexical_block: return new BlockDesc(); - case DW_TAG_base_type: return new BasicTypeDesc(); - case DW_TAG_typedef: - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - case DW_TAG_const_type: - case DW_TAG_volatile_type: - case DW_TAG_restrict_type: - case DW_TAG_member: - case DW_TAG_inheritance: return new DerivedTypeDesc(Tag); - case DW_TAG_array_type: - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_enumeration_type: - case DW_TAG_vector_type: - case DW_TAG_subroutine_type: return new CompositeTypeDesc(Tag); - case DW_TAG_subrange_type: return new SubrangeDesc(); - case DW_TAG_enumerator: return new EnumeratorDesc(); - case DW_TAG_return_variable: - case DW_TAG_arg_variable: - case DW_TAG_auto_variable: return new VariableDesc(Tag); - default: break; - } - return NULL; -} - -/// getLinkage - get linkage appropriate for this type of descriptor. -/// -GlobalValue::LinkageTypes DebugInfoDesc::getLinkage() const { - return GlobalValue::InternalLinkage; -} - -/// ApplyToFields - Target the vistor to the fields of the descriptor. -/// -void DebugInfoDesc::ApplyToFields(DIVisitor *Visitor) { - Visitor->Apply(Tag); -} - -//===----------------------------------------------------------------------===// - -AnchorDesc::AnchorDesc() -: DebugInfoDesc(DW_TAG_anchor) -, AnchorTag(0) -{} -AnchorDesc::AnchorDesc(AnchoredDesc *D) -: DebugInfoDesc(DW_TAG_anchor) -, AnchorTag(D->getTag()) -{} - -// Implement isa/cast/dyncast. -bool AnchorDesc::classof(const DebugInfoDesc *D) { - return D->getTag() == DW_TAG_anchor; -} - -/// getLinkage - get linkage appropriate for this type of descriptor. -/// -GlobalValue::LinkageTypes AnchorDesc::getLinkage() const { - return GlobalValue::LinkOnceLinkage; -} - -/// ApplyToFields - Target the visitor to the fields of the TransUnitDesc. -/// -void AnchorDesc::ApplyToFields(DIVisitor *Visitor) { - DebugInfoDesc::ApplyToFields(Visitor); - - Visitor->Apply(AnchorTag); -} - -/// getDescString - Return a string used to compose global names and labels. A -/// A global variable name needs to be defined for each debug descriptor that is -/// anchored. NOTE: that each global variable named here also needs to be added -/// to the list of names left external in the internalizer. -/// ExternalNames.insert("llvm.dbg.compile_units"); -/// ExternalNames.insert("llvm.dbg.global_variables"); -/// ExternalNames.insert("llvm.dbg.subprograms"); -const char *AnchorDesc::getDescString() const { - switch (AnchorTag) { - case DW_TAG_compile_unit: return CompileUnitDesc::AnchorString; - case DW_TAG_variable: return GlobalVariableDesc::AnchorString; - case DW_TAG_subprogram: return SubprogramDesc::AnchorString; - default: break; - } - - assert(0 && "Tag does not have a case for anchor string"); - return ""; -} - -/// getTypeString - Return a string used to label this descriptors type. -/// -const char *AnchorDesc::getTypeString() const { - return "llvm.dbg.anchor.type"; -} - -#ifndef NDEBUG -void AnchorDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "AnchorTag(" << AnchorTag << ")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -AnchoredDesc::AnchoredDesc(unsigned T) -: DebugInfoDesc(T) -, Anchor(NULL) -{} - -/// ApplyToFields - Target the visitor to the fields of the AnchoredDesc. -/// -void AnchoredDesc::ApplyToFields(DIVisitor *Visitor) { - DebugInfoDesc::ApplyToFields(Visitor); - - Visitor->Apply(Anchor); -} - -//===----------------------------------------------------------------------===// - -CompileUnitDesc::CompileUnitDesc() -: AnchoredDesc(DW_TAG_compile_unit) -, Language(0) -, FileName("") -, Directory("") -, Producer("") -{} - -// Implement isa/cast/dyncast. -bool CompileUnitDesc::classof(const DebugInfoDesc *D) { - return D->getTag() == DW_TAG_compile_unit; -} - -/// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc. -/// -void CompileUnitDesc::ApplyToFields(DIVisitor *Visitor) { - AnchoredDesc::ApplyToFields(Visitor); - - // Handle cases out of sync with compiler. - if (getVersion() == 0) { - unsigned DebugVersion; - Visitor->Apply(DebugVersion); - } - - Visitor->Apply(Language); - Visitor->Apply(FileName); - Visitor->Apply(Directory); - Visitor->Apply(Producer); -} - -/// getDescString - Return a string used to compose global names and labels. -/// -const char *CompileUnitDesc::getDescString() const { - return "llvm.dbg.compile_unit"; -} - -/// getTypeString - Return a string used to label this descriptors type. -/// -const char *CompileUnitDesc::getTypeString() const { - return "llvm.dbg.compile_unit.type"; -} - -/// getAnchorString - Return a string used to label this descriptor's anchor. -/// -const char *CompileUnitDesc::AnchorString = "llvm.dbg.compile_units"; -const char *CompileUnitDesc::getAnchorString() const { - return AnchorString; -} - -#ifndef NDEBUG -void CompileUnitDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Anchor(" << getAnchor() << "), " - << "Language(" << Language << "), " - << "FileName(\"" << FileName << "\"), " - << "Directory(\"" << Directory << "\"), " - << "Producer(\"" << Producer << "\")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -TypeDesc::TypeDesc(unsigned T) -: DebugInfoDesc(T) -, Context(NULL) -, Name("") -, File(NULL) -, Line(0) -, Size(0) -, Align(0) -, Offset(0) -, Flags(0) -{} - -/// ApplyToFields - Target the visitor to the fields of the TypeDesc. -/// -void TypeDesc::ApplyToFields(DIVisitor *Visitor) { - DebugInfoDesc::ApplyToFields(Visitor); - - Visitor->Apply(Context); - Visitor->Apply(Name); - Visitor->Apply(File); - Visitor->Apply(Line); - Visitor->Apply(Size); - Visitor->Apply(Align); - Visitor->Apply(Offset); - if (getVersion() > LLVMDebugVersion4) Visitor->Apply(Flags); -} - -/// getDescString - Return a string used to compose global names and labels. -/// -const char *TypeDesc::getDescString() const { - return "llvm.dbg.type"; -} - -/// getTypeString - Return a string used to label this descriptor's type. -/// -const char *TypeDesc::getTypeString() const { - return "llvm.dbg.type.type"; -} - -#ifndef NDEBUG -void TypeDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Context(" << Context << "), " - << "Name(\"" << Name << "\"), " - << "File(" << File << "), " - << "Line(" << Line << "), " - << "Size(" << Size << "), " - << "Align(" << Align << "), " - << "Offset(" << Offset << "), " - << "Flags(" << Flags << ")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -BasicTypeDesc::BasicTypeDesc() -: TypeDesc(DW_TAG_base_type) -, Encoding(0) -{} - -// Implement isa/cast/dyncast. -bool BasicTypeDesc::classof(const DebugInfoDesc *D) { - return D->getTag() == DW_TAG_base_type; -} - -/// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. -/// -void BasicTypeDesc::ApplyToFields(DIVisitor *Visitor) { - TypeDesc::ApplyToFields(Visitor); - - Visitor->Apply(Encoding); -} - -/// getDescString - Return a string used to compose global names and labels. -/// -const char *BasicTypeDesc::getDescString() const { - return "llvm.dbg.basictype"; -} - -/// getTypeString - Return a string used to label this descriptor's type. -/// -const char *BasicTypeDesc::getTypeString() const { - return "llvm.dbg.basictype.type"; -} - -#ifndef NDEBUG -void BasicTypeDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Context(" << getContext() << "), " - << "Name(\"" << getName() << "\"), " - << "Size(" << getSize() << "), " - << "Encoding(" << Encoding << ")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -DerivedTypeDesc::DerivedTypeDesc(unsigned T) -: TypeDesc(T) -, FromType(NULL) -{} - -// Implement isa/cast/dyncast. -bool DerivedTypeDesc::classof(const DebugInfoDesc *D) { - unsigned T = D->getTag(); - switch (T) { - case DW_TAG_typedef: - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - case DW_TAG_const_type: - case DW_TAG_volatile_type: - case DW_TAG_restrict_type: - case DW_TAG_member: - case DW_TAG_inheritance: - return true; - default: break; - } - return false; -} - -/// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. -/// -void DerivedTypeDesc::ApplyToFields(DIVisitor *Visitor) { - TypeDesc::ApplyToFields(Visitor); - - Visitor->Apply(FromType); -} - -/// getDescString - Return a string used to compose global names and labels. -/// -const char *DerivedTypeDesc::getDescString() const { - return "llvm.dbg.derivedtype"; -} - -/// getTypeString - Return a string used to label this descriptor's type. -/// -const char *DerivedTypeDesc::getTypeString() const { - return "llvm.dbg.derivedtype.type"; -} - -#ifndef NDEBUG -void DerivedTypeDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Context(" << getContext() << "), " - << "Name(\"" << getName() << "\"), " - << "Size(" << getSize() << "), " - << "File(" << getFile() << "), " - << "Line(" << getLine() << "), " - << "FromType(" << FromType << ")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -CompositeTypeDesc::CompositeTypeDesc(unsigned T) -: DerivedTypeDesc(T) -, Elements() -{} - -// Implement isa/cast/dyncast. -bool CompositeTypeDesc::classof(const DebugInfoDesc *D) { - unsigned T = D->getTag(); - switch (T) { - case DW_TAG_array_type: - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_enumeration_type: - case DW_TAG_vector_type: - case DW_TAG_subroutine_type: - return true; - default: break; - } - return false; -} - -/// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc. -/// -void CompositeTypeDesc::ApplyToFields(DIVisitor *Visitor) { - DerivedTypeDesc::ApplyToFields(Visitor); - - Visitor->Apply(Elements); -} - -/// getDescString - Return a string used to compose global names and labels. -/// -const char *CompositeTypeDesc::getDescString() const { - return "llvm.dbg.compositetype"; -} - -/// getTypeString - Return a string used to label this descriptor's type. -/// -const char *CompositeTypeDesc::getTypeString() const { - return "llvm.dbg.compositetype.type"; -} - -#ifndef NDEBUG -void CompositeTypeDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Context(" << getContext() << "), " - << "Name(\"" << getName() << "\"), " - << "Size(" << getSize() << "), " - << "File(" << getFile() << "), " - << "Line(" << getLine() << "), " - << "FromType(" << getFromType() << "), " - << "Elements.size(" << Elements.size() << ")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -SubrangeDesc::SubrangeDesc() -: DebugInfoDesc(DW_TAG_subrange_type) -, Lo(0) -, Hi(0) -{} - -// Implement isa/cast/dyncast. -bool SubrangeDesc::classof(const DebugInfoDesc *D) { - return D->getTag() == DW_TAG_subrange_type; -} - -/// ApplyToFields - Target the visitor to the fields of the SubrangeDesc. -/// -void SubrangeDesc::ApplyToFields(DIVisitor *Visitor) { - DebugInfoDesc::ApplyToFields(Visitor); - - Visitor->Apply(Lo); - Visitor->Apply(Hi); -} - -/// getDescString - Return a string used to compose global names and labels. -/// -const char *SubrangeDesc::getDescString() const { - return "llvm.dbg.subrange"; -} - -/// getTypeString - Return a string used to label this descriptor's type. -/// -const char *SubrangeDesc::getTypeString() const { - return "llvm.dbg.subrange.type"; -} - -#ifndef NDEBUG -void SubrangeDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Lo(" << Lo << "), " - << "Hi(" << Hi << ")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -EnumeratorDesc::EnumeratorDesc() -: DebugInfoDesc(DW_TAG_enumerator) -, Name("") -, Value(0) -{} - -// Implement isa/cast/dyncast. -bool EnumeratorDesc::classof(const DebugInfoDesc *D) { - return D->getTag() == DW_TAG_enumerator; -} - -/// ApplyToFields - Target the visitor to the fields of the EnumeratorDesc. -/// -void EnumeratorDesc::ApplyToFields(DIVisitor *Visitor) { - DebugInfoDesc::ApplyToFields(Visitor); - - Visitor->Apply(Name); - Visitor->Apply(Value); -} - -/// getDescString - Return a string used to compose global names and labels. -/// -const char *EnumeratorDesc::getDescString() const { - return "llvm.dbg.enumerator"; -} - -/// getTypeString - Return a string used to label this descriptor's type. -/// -const char *EnumeratorDesc::getTypeString() const { - return "llvm.dbg.enumerator.type"; -} - -#ifndef NDEBUG -void EnumeratorDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Name(" << Name << "), " - << "Value(" << Value << ")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -VariableDesc::VariableDesc(unsigned T) -: DebugInfoDesc(T) -, Context(NULL) -, Name("") -, File(NULL) -, Line(0) -, TyDesc(0) -{} - -// Implement isa/cast/dyncast. -bool VariableDesc::classof(const DebugInfoDesc *D) { - unsigned T = D->getTag(); - switch (T) { - case DW_TAG_auto_variable: - case DW_TAG_arg_variable: - case DW_TAG_return_variable: - return true; - default: break; - } - return false; -} - -/// ApplyToFields - Target the visitor to the fields of the VariableDesc. -/// -void VariableDesc::ApplyToFields(DIVisitor *Visitor) { - DebugInfoDesc::ApplyToFields(Visitor); - - Visitor->Apply(Context); - Visitor->Apply(Name); - Visitor->Apply(File); - Visitor->Apply(Line); - Visitor->Apply(TyDesc); -} - -/// getDescString - Return a string used to compose global names and labels. -/// -const char *VariableDesc::getDescString() const { - return "llvm.dbg.variable"; -} - -/// getTypeString - Return a string used to label this descriptor's type. -/// -const char *VariableDesc::getTypeString() const { - return "llvm.dbg.variable.type"; -} - -#ifndef NDEBUG -void VariableDesc::dump() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Context(" << Context << "), " - << "Name(\"" << Name << "\"), " - << "File(" << File << "), " - << "Line(" << Line << "), " - << "TyDesc(" << TyDesc << ")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -GlobalDesc::GlobalDesc(unsigned T) -: AnchoredDesc(T) -, Context(0) -, Name("") -, FullName("") -, LinkageName("") -, File(NULL) -, Line(0) -, TyDesc(NULL) -, IsStatic(false) -, IsDefinition(false) -{} - -/// ApplyToFields - Target the visitor to the fields of the global. -/// -void GlobalDesc::ApplyToFields(DIVisitor *Visitor) { - AnchoredDesc::ApplyToFields(Visitor); - - Visitor->Apply(Context); - Visitor->Apply(Name); - Visitor->Apply(FullName); - Visitor->Apply(LinkageName); - Visitor->Apply(File); - Visitor->Apply(Line); - Visitor->Apply(TyDesc); - Visitor->Apply(IsStatic); - Visitor->Apply(IsDefinition); -} - -//===----------------------------------------------------------------------===// - -GlobalVariableDesc::GlobalVariableDesc() -: GlobalDesc(DW_TAG_variable) -, Global(NULL) -{} - -// Implement isa/cast/dyncast. -bool GlobalVariableDesc::classof(const DebugInfoDesc *D) { - return D->getTag() == DW_TAG_variable; -} - -/// ApplyToFields - Target the visitor to the fields of the GlobalVariableDesc. -/// -void GlobalVariableDesc::ApplyToFields(DIVisitor *Visitor) { - GlobalDesc::ApplyToFields(Visitor); - - Visitor->Apply(Global); -} - -/// getDescString - Return a string used to compose global names and labels. -/// -const char *GlobalVariableDesc::getDescString() const { - return "llvm.dbg.global_variable"; -} - -/// getTypeString - Return a string used to label this descriptors type. -/// -const char *GlobalVariableDesc::getTypeString() const { - return "llvm.dbg.global_variable.type"; -} - -/// 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() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Anchor(" << getAnchor() << "), " - << "Name(\"" << getName() << "\"), " - << "FullName(\"" << getFullName() << "\"), " - << "LinkageName(\"" << getLinkageName() << "\"), " - << "File(" << getFile() << ")," - << "Line(" << getLine() << ")," - << "Type(" << getType() << "), " - << "IsStatic(" << (isStatic() ? "true" : "false") << "), " - << "IsDefinition(" << (isDefinition() ? "true" : "false") << "), " - << "Global(" << Global << ")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -SubprogramDesc::SubprogramDesc() -: GlobalDesc(DW_TAG_subprogram) -{} - -// Implement isa/cast/dyncast. -bool SubprogramDesc::classof(const DebugInfoDesc *D) { - return D->getTag() == DW_TAG_subprogram; -} - -/// ApplyToFields - Target the visitor to the fields of the -/// SubprogramDesc. -void SubprogramDesc::ApplyToFields(DIVisitor *Visitor) { - GlobalDesc::ApplyToFields(Visitor); -} - -/// 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() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << "), " - << "Anchor(" << getAnchor() << "), " - << "Name(\"" << getName() << "\"), " - << "FullName(\"" << getFullName() << "\"), " - << "LinkageName(\"" << getLinkageName() << "\"), " - << "File(" << getFile() << ")," - << "Line(" << getLine() << ")," - << "Type(" << getType() << "), " - << "IsStatic(" << (isStatic() ? "true" : "false") << "), " - << "IsDefinition(" << (isDefinition() ? "true" : "false") << ")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -BlockDesc::BlockDesc() -: DebugInfoDesc(DW_TAG_lexical_block) -, Context(NULL) -{} - -// 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(Context); -} - -/// 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() { - cerr << getDescString() << " " - << "Version(" << getVersion() << "), " - << "Tag(" << getTag() << ")," - << "Context(" << Context << ")\n"; -} -#endif - -//===----------------------------------------------------------------------===// - -DebugInfoDesc *DIDeserializer::Deserialize(Value *V) { - return Deserialize(getGlobalVariable(V)); -} -DebugInfoDesc *DIDeserializer::Deserialize(GlobalVariable *GV) { - // Handle NULL. - if (!GV) return NULL; - - // 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); - - // 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); - } - - return 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::Int8Ty); - } - - 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()); - // 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 Fields; - // Get types of fields. - DIGetTypesVisitor GTAM(*this, Fields); - GTAM.ApplyToFields(DD); - - // Construct structured type. - Ty = StructType::get(Fields); - - // Register type name with module. - M->addTypeName(DD->getTypeString(), Ty); - } - - return 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 (Slot) return Slot; - // 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::getBitCast(StrGV, getStrPtrType()); - } - return Slot; - -} - -/// 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); - GV->setSection("llvm.metadata"); - - // Insert new GlobalVariable in DescGlobals map. - Slot = GV; - - // Set up elements vector - std::vector Elements; - // Add fields. - DISerializeVisitor SRAM(*this, Elements); - SRAM.ApplyToFields(DD); - - // Set the globals initializer. - GV->setInitializer(ConstantStruct::get(Ty, Elements)); - - return GV; -} - -//===----------------------------------------------------------------------===// - -/// Verify - Return true if the GlobalVariable appears to be a valid -/// serialization of a DebugInfoDesc. -bool DIVerifier::Verify(Value *V) { - return !V || Verify(getGlobalVariable(V)); -} -bool DIVerifier::Verify(GlobalVariable *GV) { - // NULLs are valid. - if (!GV) return true; - - // Check prior validity. - unsigned &ValiditySlot = Validity[GV]; - - // If visited before then use old state. - if (ValiditySlot) return ValiditySlot == Valid; - - // Assume validity for the time being (recursion.) - ValiditySlot = Valid; - - // Make sure the global is internal or link once (anchor.) - if (GV->getLinkage() != GlobalValue::InternalLinkage && - GV->getLinkage() != GlobalValue::LinkOnceLinkage) { - ValiditySlot = Invalid; - return false; - } - - // Get the Tag. - unsigned Tag = DebugInfoDesc::TagFromGlobal(GV); - - // Check for user defined descriptors. - if (Tag == DW_TAG_invalid) { - ValiditySlot = Valid; - return true; - } - - // Get the Version. - unsigned Version = DebugInfoDesc::VersionFromGlobal(GV); - - // Check for version mismatch. - if (Version != LLVMDebugVersion) { - ValiditySlot = 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(GV->getInitializer()); - - // Get the operand count. - unsigned N = CI->getNumOperands(); - - // Get the field count. - unsigned &CountSlot = Counts[Tag]; - if (!CountSlot) { - // Check the operand count to the field count - DICountVisitor CTAM; - CTAM.ApplyToFields(DD); - CountSlot = CTAM.getCount(); - } - - // Field count must be at most equal operand count. - if (CountSlot > N) { - delete DD; - ValiditySlot = Invalid; - return false; - } - - // Check each field for valid type. - DIVerifyVisitor VRAM(*this, GV); - VRAM.ApplyToFields(DD); - - // Release empty DebugInfoDesc. - delete DD; - - // If fields are not valid. - if (!VRAM.isValid()) { - ValiditySlot = Invalid; - return false; - } - - return true; -} - -//===----------------------------------------------------------------------===// - -DebugScope::~DebugScope() { - for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i]; - for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j]; -} - -//===----------------------------------------------------------------------===// - -MachineDebugInfo::MachineDebugInfo() -: DR() -, VR() -, CompileUnits() -, Directories() -, SourceFiles() -, Lines() -, LabelIDList() -, ScopeMap() -, RootScope(NULL) -, FrameMoves() -{} -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; -} - -/// BeginFunction - Begin gathering function debug information. -/// -void MachineDebugInfo::BeginFunction(MachineFunction *MF) { - // Coming soon. -} - -/// MachineDebugInfo::EndFunction - Discard function debug information. -/// -void MachineDebugInfo::EndFunction() { - // Clean up scope information. - if (RootScope) { - delete RootScope; - ScopeMap.clear(); - RootScope = NULL; - } - - // Clean up frame info. - FrameMoves.clear(); -} - -/// 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) { - 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::vectorCU = getAnchoredDescriptors(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 MachineDebugInfo::getCompileUnits()const{ - return CompileUnits; -} - -/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the -/// named GlobalVariable. -std::vector -MachineDebugInfo::getGlobalVariablesUsing(Module &M, - const std::string &RootName) { - return ::getGlobalVariablesUsing(M, RootName); -} - -/// RecordLabel - Records location information and associates it with a -/// debug label. Returns a unique label ID used to generate a label and -/// provide correspondence to the source line list. -unsigned MachineDebugInfo::RecordLabel(unsigned Line, unsigned Column, - unsigned Source) { - unsigned ID = NextLabelID(); - Lines.push_back(SourceLineInfo(Line, Column, Source, ID)); - return ID; -} - -/// RecordSource - Register a source file with debug info. Returns an source -/// ID. -unsigned MachineDebugInfo::RecordSource(const std::string &Directory, - const std::string &Source) { - unsigned DirectoryID = Directories.insert(Directory); - return SourceFiles.insert(SourceFileInfo(DirectoryID, Source)); -} -unsigned MachineDebugInfo::RecordSource(const CompileUnitDesc *CompileUnit) { - return RecordSource(CompileUnit->getDirectory(), - CompileUnit->getFileName()); -} - -/// RecordRegionStart - Indicate the start of a region. -/// -unsigned MachineDebugInfo::RecordRegionStart(Value *V) { - // FIXME - need to be able to handle split scopes because of bb cloning. - DebugInfoDesc *ScopeDesc = DR.Deserialize(V); - DebugScope *Scope = getOrCreateScope(ScopeDesc); - unsigned ID = NextLabelID(); - if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID); - return ID; -} - -/// RecordRegionEnd - Indicate the end of a region. -/// -unsigned MachineDebugInfo::RecordRegionEnd(Value *V) { - // FIXME - need to be able to handle split scopes because of bb cloning. - DebugInfoDesc *ScopeDesc = DR.Deserialize(V); - DebugScope *Scope = getOrCreateScope(ScopeDesc); - unsigned ID = NextLabelID(); - Scope->setEndLabelID(ID); - return ID; -} - -/// RecordVariable - Indicate the declaration of a local variable. -/// -void MachineDebugInfo::RecordVariable(Value *V, unsigned FrameIndex) { - VariableDesc *VD = cast(DR.Deserialize(V)); - DebugScope *Scope = getOrCreateScope(VD->getContext()); - DebugVariable *DV = new DebugVariable(VD, FrameIndex); - Scope->AddVariable(DV); -} - -/// getOrCreateScope - Returns the scope associated with the given descriptor. -/// -DebugScope *MachineDebugInfo::getOrCreateScope(DebugInfoDesc *ScopeDesc) { - DebugScope *&Slot = ScopeMap[ScopeDesc]; - if (!Slot) { - // FIXME - breaks down when the context is an inlined function. - DebugInfoDesc *ParentDesc = NULL; - if (BlockDesc *Block = dyn_cast(ScopeDesc)) { - ParentDesc = Block->getContext(); - } - DebugScope *Parent = ParentDesc ? getOrCreateScope(ParentDesc) : NULL; - Slot = new DebugScope(Parent, ScopeDesc); - if (Parent) { - Parent->AddScope(Slot); - } else if (RootScope) { - // FIXME - Add inlined function scopes to the root so we can delete - // them later. Long term, handle inlined functions properly. - RootScope->AddScope(Slot); - } else { - // First function is top level function. - RootScope = Slot; - } - } - return Slot; -} - -//===----------------------------------------------------------------------===// -/// DebugLabelFolding pass - This pass prunes out redundant debug labels. This -/// allows a debug emitter to determine if the range of two labels is empty, -/// by seeing if the labels map to the same reduced label. - -namespace llvm { - -struct DebugLabelFolder : public MachineFunctionPass { - virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char *getPassName() const { return "Debug Label Folder"; } -}; - -bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) { - // Get machine debug info. - MachineDebugInfo *MDI = getAnalysisToUpdate(); - if (!MDI) return false; - // Get target instruction info. - const TargetInstrInfo *TII = MF.getTarget().getInstrInfo(); - if (!TII) return false; - - // Track if change is made. - bool MadeChange = false; - // No prior label to begin. - unsigned PriorLabel = 0; - - // Iterate through basic blocks. - for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); - BB != E; ++BB) { - // Iterate through instructions. - for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { - // Is it a debug label. - if ((unsigned)I->getOpcode() == TargetInstrInfo::LABEL) { - // The label ID # is always operand #0, an immediate. - unsigned NextLabel = I->getOperand(0).getImm(); - - // If there was an immediate prior label. - if (PriorLabel) { - // Remap the current label to prior label. - MDI->RemapLabel(NextLabel, PriorLabel); - // Delete the current label. - I = BB->erase(I); - // Indicate a change has been made. - MadeChange = true; - continue; - } else { - // Start a new round. - PriorLabel = NextLabel; - } - } else { - // No consecutive labels. - PriorLabel = 0; - } - - ++I; - } - } - - return MadeChange; -} - -FunctionPass *createDebugLabelFoldingPass() { return new DebugLabelFolder(); } - -} - diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp new file mode 100644 index 00000000000..065d6cf295e --- /dev/null +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -0,0 +1,1696 @@ +//===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by James M. Laskey and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/MachineModuleInfo.h" + +#include "llvm/Constants.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineLocation.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.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 "llvm/Support/Streams.h" +using namespace llvm; +using namespace llvm::dwarf; + +// Handle the Pass registration stuff necessary to use TargetData's. +namespace { + RegisterPass X("machinemoduleinfo", "Module Information"); +} + +//===----------------------------------------------------------------------===// + +/// getGlobalVariablesUsing - Return all of the GlobalVariables which have the +/// specified value in their initializer somewhere. +static void +getGlobalVariablesUsing(Value *V, std::vector &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(*I)) { + // If the user is a GlobalVariable then add to result. + Result.push_back(GV); + } else if (Constant *C = dyn_cast(*I)) { + // If the user is a constant variable then scan its users + getGlobalVariablesUsing(C, Result); + } + } +} + +/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the +/// named GlobalVariable. +static std::vector +getGlobalVariablesUsing(Module &M, const std::string &RootName) { + std::vector Result; // GlobalVariables matching criteria. + + std::vector FieldTypes; + FieldTypes.push_back(Type::Int32Ty); + FieldTypes.push_back(Type::Int32Ty); + + // Get the GlobalVariable root. + GlobalVariable *UseRoot = M.getGlobalVariable(RootName, + StructType::get(FieldTypes)); + + // If present and linkonce then scan for users. + if (UseRoot && UseRoot->hasLinkOnceLinkage()) { + getGlobalVariablesUsing(UseRoot, Result); + } + + return Result; +} + +/// isStringValue - Return true if the given value can be coerced to a string. +/// +static bool isStringValue(Value *V) { + if (GlobalVariable *GV = dyn_cast(V)) { + if (GV->hasInitializer() && isa(GV->getInitializer())) { + ConstantArray *Init = cast(GV->getInitializer()); + return Init->isString(); + } + } else if (Constant *C = dyn_cast(V)) { + if (GlobalValue *GV = dyn_cast(C)) + return isStringValue(GV); + else if (ConstantExpr *CE = dyn_cast(C)) { + if (CE->getOpcode() == Instruction::GetElementPtr) { + if (CE->getNumOperands() == 3 && + cast(CE->getOperand(1))->isNullValue() && + isa(CE->getOperand(2))) { + return isStringValue(CE->getOperand(0)); + } + } + } + } + return false; +} + +/// getGlobalVariable - Return either a direct or cast Global value. +/// +static GlobalVariable *getGlobalVariable(Value *V) { + if (GlobalVariable *GV = dyn_cast(V)) { + return GV; + } else if (ConstantExpr *CE = dyn_cast(V)) { + if (CE->getOpcode() == Instruction::BitCast) { + return dyn_cast(CE->getOperand(0)); + } + } + return NULL; +} + +/// isGlobalVariable - Return true if the given value can be coerced to a +/// GlobalVariable. +static bool isGlobalVariable(Value *V) { + if (isa(V) || isa(V)) { + return true; + } else if (ConstantExpr *CE = dyn_cast(V)) { + if (CE->getOpcode() == Instruction::BitCast) { + return isa(CE->getOperand(0)); + } + } + return false; +} + +/// getUIntOperand - Return ith operand if it is an unsigned integer. +/// +static ConstantInt *getUIntOperand(GlobalVariable *GV, unsigned i) { + // Make sure the GlobalVariable has an initializer. + if (!GV->hasInitializer()) return NULL; + + // Get the initializer constant. + ConstantStruct *CI = dyn_cast(GV->getInitializer()); + if (!CI) return NULL; + + // Check if there is at least i + 1 operands. + unsigned N = CI->getNumOperands(); + if (i >= N) return NULL; + + // Check constant. + return dyn_cast(CI->getOperand(i)); +} + +//===----------------------------------------------------------------------===// + +/// ApplyToFields - Target the visitor to each field of the debug information +/// descriptor. +void DIVisitor::ApplyToFields(DebugInfoDesc *DD) { + DD->ApplyToFields(this); +} + +//===----------------------------------------------------------------------===// +/// DICountVisitor - This DIVisitor counts all the fields in the supplied debug +/// the supplied DebugInfoDesc. +class DICountVisitor : public DIVisitor { +private: + unsigned Count; // Running count of fields. + +public: + DICountVisitor() : DIVisitor(), Count(0) {} + + // 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(int64_t &Field) { ++Count; } + virtual void Apply(uint64_t &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; } + virtual void Apply(std::vector &Field) { + ++Count; + } +}; + +//===----------------------------------------------------------------------===// +/// DIDeserializeVisitor - This DIVisitor deserializes all the fields in the +/// supplied DebugInfoDesc. +class DIDeserializeVisitor : public DIVisitor { +private: + DIDeserializer &DR; // Active deserializer. + unsigned I; // Current operand index. + ConstantStruct *CI; // GlobalVariable constant initializer. + +public: + DIDeserializeVisitor(DIDeserializer &D, GlobalVariable *GV) + : DIVisitor() + , DR(D) + , I(0) + , CI(cast(GV->getInitializer())) + {} + + /// Apply - Set the value of each of the fields. + /// + virtual void Apply(int &Field) { + Constant *C = CI->getOperand(I++); + Field = cast(C)->getSExtValue(); + } + virtual void Apply(unsigned &Field) { + Constant *C = CI->getOperand(I++); + Field = cast(C)->getZExtValue(); + } + virtual void Apply(int64_t &Field) { + Constant *C = CI->getOperand(I++); + Field = cast(C)->getSExtValue(); + } + virtual void Apply(uint64_t &Field) { + Constant *C = CI->getOperand(I++); + Field = cast(C)->getZExtValue(); + } + virtual void Apply(bool &Field) { + Constant *C = CI->getOperand(I++); + Field = cast(C)->getZExtValue(); + } + virtual void Apply(std::string &Field) { + Constant *C = CI->getOperand(I++); + Field = C->getStringValue(); + } + 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 = getGlobalVariable(C); + } + virtual void Apply(std::vector &Field) { + Field.resize(0); + Constant *C = CI->getOperand(I++); + GlobalVariable *GV = getGlobalVariable(C); + if (GV->hasInitializer()) { + if (ConstantArray *CA = dyn_cast(GV->getInitializer())) { + for (unsigned i = 0, N = CA->getNumOperands(); i < N; ++i) { + GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i)); + DebugInfoDesc *DE = DR.Deserialize(GVE); + Field.push_back(DE); + } + } else if (GV->getInitializer()->isNullValue()) { + if (const ArrayType *T = + dyn_cast(GV->getType()->getElementType())) { + Field.resize(T->getNumElements()); + } + } + } + } +}; + +//===----------------------------------------------------------------------===// +/// DISerializeVisitor - This DIVisitor serializes all the fields in +/// the supplied DebugInfoDesc. +class DISerializeVisitor : public DIVisitor { +private: + DISerializer &SR; // Active serializer. + std::vector &Elements; // Element accumulator. + +public: + DISerializeVisitor(DISerializer &S, std::vector &E) + : DIVisitor() + , SR(S) + , Elements(E) + {} + + /// Apply - Set the value of each of the fields. + /// + virtual void Apply(int &Field) { + Elements.push_back(ConstantInt::get(Type::Int32Ty, int32_t(Field))); + } + virtual void Apply(unsigned &Field) { + Elements.push_back(ConstantInt::get(Type::Int32Ty, uint32_t(Field))); + } + virtual void Apply(int64_t &Field) { + Elements.push_back(ConstantInt::get(Type::Int64Ty, int64_t(Field))); + } + virtual void Apply(uint64_t &Field) { + Elements.push_back(ConstantInt::get(Type::Int64Ty, uint64_t(Field))); + } + virtual void Apply(bool &Field) { + Elements.push_back(ConstantInt::get(Type::Int1Ty, Field)); + } + virtual void Apply(std::string &Field) { + Elements.push_back(SR.getString(Field)); + } + virtual void Apply(DebugInfoDesc *&Field) { + GlobalVariable *GV = NULL; + + // If non-NULL then 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::getBitCast(GV, EmptyTy)); + } else { + // Use NULL. + Elements.push_back(ConstantPointerNull::get(EmptyTy)); + } + } + virtual void Apply(GlobalVariable *&Field) { + const PointerType *EmptyTy = SR.getEmptyStructPtrType(); + if (Field) { + Elements.push_back(ConstantExpr::getBitCast(Field, EmptyTy)); + } else { + Elements.push_back(ConstantPointerNull::get(EmptyTy)); + } + } + virtual void Apply(std::vector &Field) { + const PointerType *EmptyTy = SR.getEmptyStructPtrType(); + unsigned N = Field.size(); + ArrayType *AT = ArrayType::get(EmptyTy, N); + std::vector ArrayElements; + + for (unsigned i = 0, N = Field.size(); i < N; ++i) { + if (DebugInfoDesc *Element = Field[i]) { + GlobalVariable *GVE = SR.Serialize(Element); + Constant *CE = ConstantExpr::getBitCast(GVE, EmptyTy); + ArrayElements.push_back(cast(CE)); + } else { + ArrayElements.push_back(ConstantPointerNull::get(EmptyTy)); + } + } + + Constant *CA = ConstantArray::get(AT, ArrayElements); + GlobalVariable *CAGV = new GlobalVariable(AT, true, + GlobalValue::InternalLinkage, + CA, "llvm.dbg.array", + SR.getModule()); + CAGV->setSection("llvm.metadata"); + Constant *CAE = ConstantExpr::getBitCast(CAGV, EmptyTy); + Elements.push_back(CAE); + } +}; + +//===----------------------------------------------------------------------===// +/// DIGetTypesVisitor - This DIVisitor gathers all the field types in +/// the supplied DebugInfoDesc. +class DIGetTypesVisitor : public DIVisitor { +private: + DISerializer &SR; // Active serializer. + std::vector &Fields; // Type accumulator. + +public: + DIGetTypesVisitor(DISerializer &S, std::vector &F) + : DIVisitor() + , SR(S) + , Fields(F) + {} + + /// Apply - Set the value of each of the fields. + /// + virtual void Apply(int &Field) { + Fields.push_back(Type::Int32Ty); + } + virtual void Apply(unsigned &Field) { + Fields.push_back(Type::Int32Ty); + } + virtual void Apply(int64_t &Field) { + Fields.push_back(Type::Int64Ty); + } + virtual void Apply(uint64_t &Field) { + Fields.push_back(Type::Int64Ty); + } + virtual void Apply(bool &Field) { + Fields.push_back(Type::Int1Ty); + } + 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); + } + virtual void Apply(std::vector &Field) { + const PointerType *EmptyTy = SR.getEmptyStructPtrType(); + Fields.push_back(EmptyTy); + } +}; + +//===----------------------------------------------------------------------===// +/// DIVerifyVisitor - This DIVisitor verifies all the field types against +/// a constant initializer. +class DIVerifyVisitor : public DIVisitor { +private: + DIVerifier &VR; // Active verifier. + bool IsValid; // Validity status. + unsigned I; // Current operand index. + ConstantStruct *CI; // GlobalVariable constant initializer. + +public: + DIVerifyVisitor(DIVerifier &V, GlobalVariable *GV) + : DIVisitor() + , VR(V) + , IsValid(true) + , I(0) + , CI(cast(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(C); + } + virtual void Apply(unsigned &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa(C); + } + virtual void Apply(int64_t &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa(C); + } + virtual void Apply(uint64_t &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa(C); + } + virtual void Apply(bool &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa(C) && C->getType() == Type::Int1Ty; + } + virtual void Apply(std::string &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && + (!C || isStringValue(C) || C->isNullValue()); + } + virtual void Apply(DebugInfoDesc *&Field) { + // FIXME - Prepare the correct descriptor. + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isGlobalVariable(C); + } + virtual void Apply(GlobalVariable *&Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isGlobalVariable(C); + } + virtual void Apply(std::vector &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isGlobalVariable(C); + if (!IsValid) return; + + GlobalVariable *GV = getGlobalVariable(C); + IsValid = IsValid && GV && GV->hasInitializer(); + if (!IsValid) return; + + ConstantArray *CA = dyn_cast(GV->getInitializer()); + IsValid = IsValid && CA; + if (!IsValid) return; + + for (unsigned i = 0, N = CA->getNumOperands(); IsValid && i < N; ++i) { + IsValid = IsValid && isGlobalVariable(CA->getOperand(i)); + if (!IsValid) return; + + GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i)); + VR.Verify(GVE); + } + } +}; + + +//===----------------------------------------------------------------------===// + +/// TagFromGlobal - Returns the tag number from a debug info descriptor +/// GlobalVariable. Return DIIValid if operand is not an unsigned int. +unsigned DebugInfoDesc::TagFromGlobal(GlobalVariable *GV) { + ConstantInt *C = getUIntOperand(GV, 0); + return C ? ((unsigned)C->getZExtValue() & ~LLVMDebugVersionMask) : + (unsigned)DW_TAG_invalid; +} + +/// VersionFromGlobal - Returns the version number from a debug info +/// descriptor GlobalVariable. Return DIIValid if operand is not an unsigned +/// int. +unsigned DebugInfoDesc::VersionFromGlobal(GlobalVariable *GV) { + ConstantInt *C = getUIntOperand(GV, 0); + return C ? ((unsigned)C->getZExtValue() & LLVMDebugVersionMask) : + (unsigned)DW_TAG_invalid; +} + +/// 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 DW_TAG_anchor: return new AnchorDesc(); + case DW_TAG_compile_unit: return new CompileUnitDesc(); + case DW_TAG_variable: return new GlobalVariableDesc(); + case DW_TAG_subprogram: return new SubprogramDesc(); + case DW_TAG_lexical_block: return new BlockDesc(); + case DW_TAG_base_type: return new BasicTypeDesc(); + case DW_TAG_typedef: + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_const_type: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: + case DW_TAG_member: + case DW_TAG_inheritance: return new DerivedTypeDesc(Tag); + case DW_TAG_array_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + case DW_TAG_vector_type: + case DW_TAG_subroutine_type: return new CompositeTypeDesc(Tag); + case DW_TAG_subrange_type: return new SubrangeDesc(); + case DW_TAG_enumerator: return new EnumeratorDesc(); + case DW_TAG_return_variable: + case DW_TAG_arg_variable: + case DW_TAG_auto_variable: return new VariableDesc(Tag); + default: break; + } + return NULL; +} + +/// getLinkage - get linkage appropriate for this type of descriptor. +/// +GlobalValue::LinkageTypes DebugInfoDesc::getLinkage() const { + return GlobalValue::InternalLinkage; +} + +/// ApplyToFields - Target the vistor to the fields of the descriptor. +/// +void DebugInfoDesc::ApplyToFields(DIVisitor *Visitor) { + Visitor->Apply(Tag); +} + +//===----------------------------------------------------------------------===// + +AnchorDesc::AnchorDesc() +: DebugInfoDesc(DW_TAG_anchor) +, AnchorTag(0) +{} +AnchorDesc::AnchorDesc(AnchoredDesc *D) +: DebugInfoDesc(DW_TAG_anchor) +, AnchorTag(D->getTag()) +{} + +// Implement isa/cast/dyncast. +bool AnchorDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_anchor; +} + +/// getLinkage - get linkage appropriate for this type of descriptor. +/// +GlobalValue::LinkageTypes AnchorDesc::getLinkage() const { + return GlobalValue::LinkOnceLinkage; +} + +/// ApplyToFields - Target the visitor to the fields of the TransUnitDesc. +/// +void AnchorDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(AnchorTag); +} + +/// getDescString - Return a string used to compose global names and labels. A +/// A global variable name needs to be defined for each debug descriptor that is +/// anchored. NOTE: that each global variable named here also needs to be added +/// to the list of names left external in the internalizer. +/// ExternalNames.insert("llvm.dbg.compile_units"); +/// ExternalNames.insert("llvm.dbg.global_variables"); +/// ExternalNames.insert("llvm.dbg.subprograms"); +const char *AnchorDesc::getDescString() const { + switch (AnchorTag) { + case DW_TAG_compile_unit: return CompileUnitDesc::AnchorString; + case DW_TAG_variable: return GlobalVariableDesc::AnchorString; + case DW_TAG_subprogram: return SubprogramDesc::AnchorString; + default: break; + } + + assert(0 && "Tag does not have a case for anchor string"); + return ""; +} + +/// getTypeString - Return a string used to label this descriptors type. +/// +const char *AnchorDesc::getTypeString() const { + return "llvm.dbg.anchor.type"; +} + +#ifndef NDEBUG +void AnchorDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "AnchorTag(" << AnchorTag << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +AnchoredDesc::AnchoredDesc(unsigned T) +: DebugInfoDesc(T) +, Anchor(NULL) +{} + +/// ApplyToFields - Target the visitor to the fields of the AnchoredDesc. +/// +void AnchoredDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Anchor); +} + +//===----------------------------------------------------------------------===// + +CompileUnitDesc::CompileUnitDesc() +: AnchoredDesc(DW_TAG_compile_unit) +, Language(0) +, FileName("") +, Directory("") +, Producer("") +{} + +// Implement isa/cast/dyncast. +bool CompileUnitDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_compile_unit; +} + +/// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc. +/// +void CompileUnitDesc::ApplyToFields(DIVisitor *Visitor) { + AnchoredDesc::ApplyToFields(Visitor); + + // Handle cases out of sync with compiler. + if (getVersion() == 0) { + unsigned DebugVersion; + Visitor->Apply(DebugVersion); + } + + Visitor->Apply(Language); + Visitor->Apply(FileName); + Visitor->Apply(Directory); + Visitor->Apply(Producer); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *CompileUnitDesc::getDescString() const { + return "llvm.dbg.compile_unit"; +} + +/// getTypeString - Return a string used to label this descriptors type. +/// +const char *CompileUnitDesc::getTypeString() const { + return "llvm.dbg.compile_unit.type"; +} + +/// getAnchorString - Return a string used to label this descriptor's anchor. +/// +const char *CompileUnitDesc::AnchorString = "llvm.dbg.compile_units"; +const char *CompileUnitDesc::getAnchorString() const { + return AnchorString; +} + +#ifndef NDEBUG +void CompileUnitDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Anchor(" << getAnchor() << "), " + << "Language(" << Language << "), " + << "FileName(\"" << FileName << "\"), " + << "Directory(\"" << Directory << "\"), " + << "Producer(\"" << Producer << "\")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +TypeDesc::TypeDesc(unsigned T) +: DebugInfoDesc(T) +, Context(NULL) +, Name("") +, File(NULL) +, Line(0) +, Size(0) +, Align(0) +, Offset(0) +, Flags(0) +{} + +/// ApplyToFields - Target the visitor to the fields of the TypeDesc. +/// +void TypeDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Context); + Visitor->Apply(Name); + Visitor->Apply(File); + Visitor->Apply(Line); + Visitor->Apply(Size); + Visitor->Apply(Align); + Visitor->Apply(Offset); + if (getVersion() > LLVMDebugVersion4) Visitor->Apply(Flags); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *TypeDesc::getDescString() const { + return "llvm.dbg.type"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *TypeDesc::getTypeString() const { + return "llvm.dbg.type.type"; +} + +#ifndef NDEBUG +void TypeDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Context(" << Context << "), " + << "Name(\"" << Name << "\"), " + << "File(" << File << "), " + << "Line(" << Line << "), " + << "Size(" << Size << "), " + << "Align(" << Align << "), " + << "Offset(" << Offset << "), " + << "Flags(" << Flags << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +BasicTypeDesc::BasicTypeDesc() +: TypeDesc(DW_TAG_base_type) +, Encoding(0) +{} + +// Implement isa/cast/dyncast. +bool BasicTypeDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_base_type; +} + +/// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. +/// +void BasicTypeDesc::ApplyToFields(DIVisitor *Visitor) { + TypeDesc::ApplyToFields(Visitor); + + Visitor->Apply(Encoding); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *BasicTypeDesc::getDescString() const { + return "llvm.dbg.basictype"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *BasicTypeDesc::getTypeString() const { + return "llvm.dbg.basictype.type"; +} + +#ifndef NDEBUG +void BasicTypeDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Context(" << getContext() << "), " + << "Name(\"" << getName() << "\"), " + << "Size(" << getSize() << "), " + << "Encoding(" << Encoding << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +DerivedTypeDesc::DerivedTypeDesc(unsigned T) +: TypeDesc(T) +, FromType(NULL) +{} + +// Implement isa/cast/dyncast. +bool DerivedTypeDesc::classof(const DebugInfoDesc *D) { + unsigned T = D->getTag(); + switch (T) { + case DW_TAG_typedef: + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_const_type: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: + case DW_TAG_member: + case DW_TAG_inheritance: + return true; + default: break; + } + return false; +} + +/// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. +/// +void DerivedTypeDesc::ApplyToFields(DIVisitor *Visitor) { + TypeDesc::ApplyToFields(Visitor); + + Visitor->Apply(FromType); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *DerivedTypeDesc::getDescString() const { + return "llvm.dbg.derivedtype"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *DerivedTypeDesc::getTypeString() const { + return "llvm.dbg.derivedtype.type"; +} + +#ifndef NDEBUG +void DerivedTypeDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Context(" << getContext() << "), " + << "Name(\"" << getName() << "\"), " + << "Size(" << getSize() << "), " + << "File(" << getFile() << "), " + << "Line(" << getLine() << "), " + << "FromType(" << FromType << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +CompositeTypeDesc::CompositeTypeDesc(unsigned T) +: DerivedTypeDesc(T) +, Elements() +{} + +// Implement isa/cast/dyncast. +bool CompositeTypeDesc::classof(const DebugInfoDesc *D) { + unsigned T = D->getTag(); + switch (T) { + case DW_TAG_array_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + case DW_TAG_vector_type: + case DW_TAG_subroutine_type: + return true; + default: break; + } + return false; +} + +/// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc. +/// +void CompositeTypeDesc::ApplyToFields(DIVisitor *Visitor) { + DerivedTypeDesc::ApplyToFields(Visitor); + + Visitor->Apply(Elements); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *CompositeTypeDesc::getDescString() const { + return "llvm.dbg.compositetype"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *CompositeTypeDesc::getTypeString() const { + return "llvm.dbg.compositetype.type"; +} + +#ifndef NDEBUG +void CompositeTypeDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Context(" << getContext() << "), " + << "Name(\"" << getName() << "\"), " + << "Size(" << getSize() << "), " + << "File(" << getFile() << "), " + << "Line(" << getLine() << "), " + << "FromType(" << getFromType() << "), " + << "Elements.size(" << Elements.size() << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +SubrangeDesc::SubrangeDesc() +: DebugInfoDesc(DW_TAG_subrange_type) +, Lo(0) +, Hi(0) +{} + +// Implement isa/cast/dyncast. +bool SubrangeDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_subrange_type; +} + +/// ApplyToFields - Target the visitor to the fields of the SubrangeDesc. +/// +void SubrangeDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Lo); + Visitor->Apply(Hi); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *SubrangeDesc::getDescString() const { + return "llvm.dbg.subrange"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *SubrangeDesc::getTypeString() const { + return "llvm.dbg.subrange.type"; +} + +#ifndef NDEBUG +void SubrangeDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Lo(" << Lo << "), " + << "Hi(" << Hi << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +EnumeratorDesc::EnumeratorDesc() +: DebugInfoDesc(DW_TAG_enumerator) +, Name("") +, Value(0) +{} + +// Implement isa/cast/dyncast. +bool EnumeratorDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_enumerator; +} + +/// ApplyToFields - Target the visitor to the fields of the EnumeratorDesc. +/// +void EnumeratorDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Name); + Visitor->Apply(Value); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *EnumeratorDesc::getDescString() const { + return "llvm.dbg.enumerator"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *EnumeratorDesc::getTypeString() const { + return "llvm.dbg.enumerator.type"; +} + +#ifndef NDEBUG +void EnumeratorDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Name(" << Name << "), " + << "Value(" << Value << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +VariableDesc::VariableDesc(unsigned T) +: DebugInfoDesc(T) +, Context(NULL) +, Name("") +, File(NULL) +, Line(0) +, TyDesc(0) +{} + +// Implement isa/cast/dyncast. +bool VariableDesc::classof(const DebugInfoDesc *D) { + unsigned T = D->getTag(); + switch (T) { + case DW_TAG_auto_variable: + case DW_TAG_arg_variable: + case DW_TAG_return_variable: + return true; + default: break; + } + return false; +} + +/// ApplyToFields - Target the visitor to the fields of the VariableDesc. +/// +void VariableDesc::ApplyToFields(DIVisitor *Visitor) { + DebugInfoDesc::ApplyToFields(Visitor); + + Visitor->Apply(Context); + Visitor->Apply(Name); + Visitor->Apply(File); + Visitor->Apply(Line); + Visitor->Apply(TyDesc); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *VariableDesc::getDescString() const { + return "llvm.dbg.variable"; +} + +/// getTypeString - Return a string used to label this descriptor's type. +/// +const char *VariableDesc::getTypeString() const { + return "llvm.dbg.variable.type"; +} + +#ifndef NDEBUG +void VariableDesc::dump() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Context(" << Context << "), " + << "Name(\"" << Name << "\"), " + << "File(" << File << "), " + << "Line(" << Line << "), " + << "TyDesc(" << TyDesc << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +GlobalDesc::GlobalDesc(unsigned T) +: AnchoredDesc(T) +, Context(0) +, Name("") +, FullName("") +, LinkageName("") +, File(NULL) +, Line(0) +, TyDesc(NULL) +, IsStatic(false) +, IsDefinition(false) +{} + +/// ApplyToFields - Target the visitor to the fields of the global. +/// +void GlobalDesc::ApplyToFields(DIVisitor *Visitor) { + AnchoredDesc::ApplyToFields(Visitor); + + Visitor->Apply(Context); + Visitor->Apply(Name); + Visitor->Apply(FullName); + Visitor->Apply(LinkageName); + Visitor->Apply(File); + Visitor->Apply(Line); + Visitor->Apply(TyDesc); + Visitor->Apply(IsStatic); + Visitor->Apply(IsDefinition); +} + +//===----------------------------------------------------------------------===// + +GlobalVariableDesc::GlobalVariableDesc() +: GlobalDesc(DW_TAG_variable) +, Global(NULL) +{} + +// Implement isa/cast/dyncast. +bool GlobalVariableDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_variable; +} + +/// ApplyToFields - Target the visitor to the fields of the GlobalVariableDesc. +/// +void GlobalVariableDesc::ApplyToFields(DIVisitor *Visitor) { + GlobalDesc::ApplyToFields(Visitor); + + Visitor->Apply(Global); +} + +/// getDescString - Return a string used to compose global names and labels. +/// +const char *GlobalVariableDesc::getDescString() const { + return "llvm.dbg.global_variable"; +} + +/// getTypeString - Return a string used to label this descriptors type. +/// +const char *GlobalVariableDesc::getTypeString() const { + return "llvm.dbg.global_variable.type"; +} + +/// 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() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Anchor(" << getAnchor() << "), " + << "Name(\"" << getName() << "\"), " + << "FullName(\"" << getFullName() << "\"), " + << "LinkageName(\"" << getLinkageName() << "\"), " + << "File(" << getFile() << ")," + << "Line(" << getLine() << ")," + << "Type(" << getType() << "), " + << "IsStatic(" << (isStatic() ? "true" : "false") << "), " + << "IsDefinition(" << (isDefinition() ? "true" : "false") << "), " + << "Global(" << Global << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +SubprogramDesc::SubprogramDesc() +: GlobalDesc(DW_TAG_subprogram) +{} + +// Implement isa/cast/dyncast. +bool SubprogramDesc::classof(const DebugInfoDesc *D) { + return D->getTag() == DW_TAG_subprogram; +} + +/// ApplyToFields - Target the visitor to the fields of the +/// SubprogramDesc. +void SubprogramDesc::ApplyToFields(DIVisitor *Visitor) { + GlobalDesc::ApplyToFields(Visitor); +} + +/// 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() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << "), " + << "Anchor(" << getAnchor() << "), " + << "Name(\"" << getName() << "\"), " + << "FullName(\"" << getFullName() << "\"), " + << "LinkageName(\"" << getLinkageName() << "\"), " + << "File(" << getFile() << ")," + << "Line(" << getLine() << ")," + << "Type(" << getType() << "), " + << "IsStatic(" << (isStatic() ? "true" : "false") << "), " + << "IsDefinition(" << (isDefinition() ? "true" : "false") << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +BlockDesc::BlockDesc() +: DebugInfoDesc(DW_TAG_lexical_block) +, Context(NULL) +{} + +// 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(Context); +} + +/// 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() { + cerr << getDescString() << " " + << "Version(" << getVersion() << "), " + << "Tag(" << getTag() << ")," + << "Context(" << Context << ")\n"; +} +#endif + +//===----------------------------------------------------------------------===// + +DebugInfoDesc *DIDeserializer::Deserialize(Value *V) { + return Deserialize(getGlobalVariable(V)); +} +DebugInfoDesc *DIDeserializer::Deserialize(GlobalVariable *GV) { + // Handle NULL. + if (!GV) return NULL; + + // 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); + + // 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); + } + + return 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::Int8Ty); + } + + 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()); + // 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 Fields; + // Get types of fields. + DIGetTypesVisitor GTAM(*this, Fields); + GTAM.ApplyToFields(DD); + + // Construct structured type. + Ty = StructType::get(Fields); + + // Register type name with module. + M->addTypeName(DD->getTypeString(), Ty); + } + + return 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 (Slot) return Slot; + // 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::getBitCast(StrGV, getStrPtrType()); + } + return Slot; + +} + +/// 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); + GV->setSection("llvm.metadata"); + + // Insert new GlobalVariable in DescGlobals map. + Slot = GV; + + // Set up elements vector + std::vector Elements; + // Add fields. + DISerializeVisitor SRAM(*this, Elements); + SRAM.ApplyToFields(DD); + + // Set the globals initializer. + GV->setInitializer(ConstantStruct::get(Ty, Elements)); + + return GV; +} + +//===----------------------------------------------------------------------===// + +/// Verify - Return true if the GlobalVariable appears to be a valid +/// serialization of a DebugInfoDesc. +bool DIVerifier::Verify(Value *V) { + return !V || Verify(getGlobalVariable(V)); +} +bool DIVerifier::Verify(GlobalVariable *GV) { + // NULLs are valid. + if (!GV) return true; + + // Check prior validity. + unsigned &ValiditySlot = Validity[GV]; + + // If visited before then use old state. + if (ValiditySlot) return ValiditySlot == Valid; + + // Assume validity for the time being (recursion.) + ValiditySlot = Valid; + + // Make sure the global is internal or link once (anchor.) + if (GV->getLinkage() != GlobalValue::InternalLinkage && + GV->getLinkage() != GlobalValue::LinkOnceLinkage) { + ValiditySlot = Invalid; + return false; + } + + // Get the Tag. + unsigned Tag = DebugInfoDesc::TagFromGlobal(GV); + + // Check for user defined descriptors. + if (Tag == DW_TAG_invalid) { + ValiditySlot = Valid; + return true; + } + + // Get the Version. + unsigned Version = DebugInfoDesc::VersionFromGlobal(GV); + + // Check for version mismatch. + if (Version != LLVMDebugVersion) { + ValiditySlot = 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(GV->getInitializer()); + + // Get the operand count. + unsigned N = CI->getNumOperands(); + + // Get the field count. + unsigned &CountSlot = Counts[Tag]; + if (!CountSlot) { + // Check the operand count to the field count + DICountVisitor CTAM; + CTAM.ApplyToFields(DD); + CountSlot = CTAM.getCount(); + } + + // Field count must be at most equal operand count. + if (CountSlot > N) { + delete DD; + ValiditySlot = Invalid; + return false; + } + + // Check each field for valid type. + DIVerifyVisitor VRAM(*this, GV); + VRAM.ApplyToFields(DD); + + // Release empty DebugInfoDesc. + delete DD; + + // If fields are not valid. + if (!VRAM.isValid()) { + ValiditySlot = Invalid; + return false; + } + + return true; +} + +//===----------------------------------------------------------------------===// + +DebugScope::~DebugScope() { + for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i]; + for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j]; +} + +//===----------------------------------------------------------------------===// + +MachineModuleInfo::MachineModuleInfo() +: DR() +, VR() +, CompileUnits() +, Directories() +, SourceFiles() +, Lines() +, LabelIDList() +, ScopeMap() +, RootScope(NULL) +, FrameMoves() +{} +MachineModuleInfo::~MachineModuleInfo() { + +} + +/// doInitialization - Initialize the state for a new module. +/// +bool MachineModuleInfo::doInitialization() { + return false; +} + +/// doFinalization - Tear down the state after completion of a module. +/// +bool MachineModuleInfo::doFinalization() { + return false; +} + +/// BeginFunction - Begin gathering function meta information. +/// +void MachineModuleInfo::BeginFunction(MachineFunction *MF) { + // Coming soon. +} + +/// EndFunction - Discard function meta information. +/// +void MachineModuleInfo::EndFunction() { + // Clean up scope information. + if (RootScope) { + delete RootScope; + ScopeMap.clear(); + RootScope = NULL; + } + + // Clean up frame info. + FrameMoves.clear(); +} + +/// getDescFor - Convert a Value to a debug information descriptor. +/// +// FIXME - use new Value type when available. +DebugInfoDesc *MachineModuleInfo::getDescFor(Value *V) { + return DR.Deserialize(V); +} + +/// Verify - Verify that a Value is debug information descriptor. +/// +bool MachineModuleInfo::Verify(Value *V) { + return VR.Verify(V); +} + +/// AnalyzeModule - Scan the module for global debug information. +/// +void MachineModuleInfo::AnalyzeModule(Module &M) { + SetupCompileUnits(M); +} + +/// SetupCompileUnits - Set up the unique vector of compile units. +/// +void MachineModuleInfo::SetupCompileUnits(Module &M) { + std::vectorCU = getAnchoredDescriptors(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 MachineModuleInfo::getCompileUnits()const{ + return CompileUnits; +} + +/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the +/// named GlobalVariable. +std::vector +MachineModuleInfo::getGlobalVariablesUsing(Module &M, + const std::string &RootName) { + return ::getGlobalVariablesUsing(M, RootName); +} + +/// RecordLabel - Records location information and associates it with a +/// debug label. Returns a unique label ID used to generate a label and +/// provide correspondence to the source line list. +unsigned MachineModuleInfo::RecordLabel(unsigned Line, unsigned Column, + unsigned Source) { + unsigned ID = NextLabelID(); + Lines.push_back(SourceLineInfo(Line, Column, Source, ID)); + return ID; +} + +/// RecordSource - Register a source file with debug info. Returns an source +/// ID. +unsigned MachineModuleInfo::RecordSource(const std::string &Directory, + const std::string &Source) { + unsigned DirectoryID = Directories.insert(Directory); + return SourceFiles.insert(SourceFileInfo(DirectoryID, Source)); +} +unsigned MachineModuleInfo::RecordSource(const CompileUnitDesc *CompileUnit) { + return RecordSource(CompileUnit->getDirectory(), + CompileUnit->getFileName()); +} + +/// RecordRegionStart - Indicate the start of a region. +/// +unsigned MachineModuleInfo::RecordRegionStart(Value *V) { + // FIXME - need to be able to handle split scopes because of bb cloning. + DebugInfoDesc *ScopeDesc = DR.Deserialize(V); + DebugScope *Scope = getOrCreateScope(ScopeDesc); + unsigned ID = NextLabelID(); + if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID); + return ID; +} + +/// RecordRegionEnd - Indicate the end of a region. +/// +unsigned MachineModuleInfo::RecordRegionEnd(Value *V) { + // FIXME - need to be able to handle split scopes because of bb cloning. + DebugInfoDesc *ScopeDesc = DR.Deserialize(V); + DebugScope *Scope = getOrCreateScope(ScopeDesc); + unsigned ID = NextLabelID(); + Scope->setEndLabelID(ID); + return ID; +} + +/// RecordVariable - Indicate the declaration of a local variable. +/// +void MachineModuleInfo::RecordVariable(Value *V, unsigned FrameIndex) { + VariableDesc *VD = cast(DR.Deserialize(V)); + DebugScope *Scope = getOrCreateScope(VD->getContext()); + DebugVariable *DV = new DebugVariable(VD, FrameIndex); + Scope->AddVariable(DV); +} + +/// getOrCreateScope - Returns the scope associated with the given descriptor. +/// +DebugScope *MachineModuleInfo::getOrCreateScope(DebugInfoDesc *ScopeDesc) { + DebugScope *&Slot = ScopeMap[ScopeDesc]; + if (!Slot) { + // FIXME - breaks down when the context is an inlined function. + DebugInfoDesc *ParentDesc = NULL; + if (BlockDesc *Block = dyn_cast(ScopeDesc)) { + ParentDesc = Block->getContext(); + } + DebugScope *Parent = ParentDesc ? getOrCreateScope(ParentDesc) : NULL; + Slot = new DebugScope(Parent, ScopeDesc); + if (Parent) { + Parent->AddScope(Slot); + } else if (RootScope) { + // FIXME - Add inlined function scopes to the root so we can delete + // them later. Long term, handle inlined functions properly. + RootScope->AddScope(Slot); + } else { + // First function is top level function. + RootScope = Slot; + } + } + return Slot; +} + +//===----------------------------------------------------------------------===// +/// DebugLabelFolding pass - This pass prunes out redundant labels. This allows +/// a info consumer to determine if the range of two labels is empty, by seeing +/// if the labels map to the same reduced label. + +namespace llvm { + +struct DebugLabelFolder : public MachineFunctionPass { + virtual bool runOnMachineFunction(MachineFunction &MF); + virtual const char *getPassName() const { return "Label Folder"; } +}; + +bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) { + // Get machine module info. + MachineModuleInfo *MMI = getAnalysisToUpdate(); + if (!MMI) return false; + // Get target instruction info. + const TargetInstrInfo *TII = MF.getTarget().getInstrInfo(); + if (!TII) return false; + + // Track if change is made. + bool MadeChange = false; + // No prior label to begin. + unsigned PriorLabel = 0; + + // Iterate through basic blocks. + for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); + BB != E; ++BB) { + // Iterate through instructions. + for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { + // Is it a label. + if ((unsigned)I->getOpcode() == TargetInstrInfo::LABEL) { + // The label ID # is always operand #0, an immediate. + unsigned NextLabel = I->getOperand(0).getImm(); + + // If there was an immediate prior label. + if (PriorLabel) { + // Remap the current label to prior label. + MMI->RemapLabel(NextLabel, PriorLabel); + // Delete the current label. + I = BB->erase(I); + // Indicate a change has been made. + MadeChange = true; + continue; + } else { + // Start a new round. + PriorLabel = NextLabel; + } + } else { + // No consecutive labels. + PriorLabel = 0; + } + + ++I; + } + } + + return MadeChange; +} + +FunctionPass *createDebugLabelFoldingPass() { return new DebugLabelFolder(); } + +} +