//===-- 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/Target/TargetOptions.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<MachineModuleInfo> 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<GlobalVariable*> &Result) {
  // Scan though value users.
  for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I)) {
      // If the user is a GlobalVariable then add to result.
      Result.push_back(GV);
    } else if (Constant *C = dyn_cast<Constant>(*I)) {
      // If the user is a constant variable then scan its users
      getGlobalVariablesUsing(C, Result);
    }
  }
}

/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
/// named GlobalVariable.
static std::vector<GlobalVariable*>
getGlobalVariablesUsing(Module &M, const std::string &RootName) {
  std::vector<GlobalVariable*> Result;  // GlobalVariables matching criteria.
  
  std::vector<const Type*> 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<GlobalVariable>(V)) {
    if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
      ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
      return Init->isString();
    }
  } else if (Constant *C = dyn_cast<Constant>(V)) {
    if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
      return isStringValue(GV);
    else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
      if (CE->getOpcode() == Instruction::GetElementPtr) {
        if (CE->getNumOperands() == 3 &&
            cast<Constant>(CE->getOperand(1))->isNullValue() &&
            isa<ConstantInt>(CE->getOperand(2))) {
          return isStringValue(CE->getOperand(0));
        }
      }
    }
  }
  return false;
}

/// getGlobalVariable - Return either a direct or cast Global value.
///
static GlobalVariable *getGlobalVariable(Value *V) {
  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
    return GV;
  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
    if (CE->getOpcode() == Instruction::BitCast) {
      return dyn_cast<GlobalVariable>(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<GlobalVariable>(V) || isa<ConstantPointerNull>(V)) {
    return true;
  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
    if (CE->getOpcode() == Instruction::BitCast) {
      return isa<GlobalVariable>(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<ConstantStruct>(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<ConstantInt>(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<DebugInfoDesc *> &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<ConstantStruct>(GV->getInitializer()))
  {}
  
  /// Apply - Set the value of each of the fields.
  ///
  virtual void Apply(int &Field) {
    Constant *C = CI->getOperand(I++);
    Field = cast<ConstantInt>(C)->getSExtValue();
  }
  virtual void Apply(unsigned &Field) {
    Constant *C = CI->getOperand(I++);
    Field = cast<ConstantInt>(C)->getZExtValue();
  }
  virtual void Apply(int64_t &Field) {
    Constant *C = CI->getOperand(I++);
    Field = cast<ConstantInt>(C)->getSExtValue();
  }
  virtual void Apply(uint64_t &Field) {
    Constant *C = CI->getOperand(I++);
    Field = cast<ConstantInt>(C)->getZExtValue();
  }
  virtual void Apply(bool &Field) {
    Constant *C = CI->getOperand(I++);
    Field = cast<ConstantInt>(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<DebugInfoDesc *> &Field) {
    Field.resize(0);
    Constant *C = CI->getOperand(I++);
    GlobalVariable *GV = getGlobalVariable(C);
    if (GV->hasInitializer()) {
      if (ConstantArray *CA = dyn_cast<ConstantArray>(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<ArrayType>(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<Constant*> &Elements;     // Element accumulator.
  
public:
  DISerializeVisitor(DISerializer &S, std::vector<Constant*> &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<DebugInfoDesc *> &Field) {
    const PointerType *EmptyTy = SR.getEmptyStructPtrType();
    unsigned N = Field.size();
    ArrayType *AT = ArrayType::get(EmptyTy, N);
    std::vector<Constant *> 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<Constant>(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<const Type*> &Fields;     // Type accumulator.
  
public:
  DIGetTypesVisitor(DISerializer &S, std::vector<const Type*> &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<DebugInfoDesc *> &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<ConstantStruct>(GV->getInitializer()))
  {
  }
  
  // Accessors.
  bool isValid() const { return IsValid; }
  
  /// Apply - Set the value of each of the fields.
  ///
  virtual void Apply(int &Field) {
    Constant *C = CI->getOperand(I++);
    IsValid = IsValid && isa<ConstantInt>(C);
  }
  virtual void Apply(unsigned &Field) {
    Constant *C = CI->getOperand(I++);
    IsValid = IsValid && isa<ConstantInt>(C);
  }
  virtual void Apply(int64_t &Field) {
    Constant *C = CI->getOperand(I++);
    IsValid = IsValid && isa<ConstantInt>(C);
  }
  virtual void Apply(uint64_t &Field) {
    Constant *C = CI->getOperand(I++);
    IsValid = IsValid && isa<ConstantInt>(C);
  }
  virtual void Apply(bool &Field) {
    Constant *C = CI->getOperand(I++);
    IsValid = IsValid && isa<ConstantInt>(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<DebugInfoDesc *> &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<ConstantArray>(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<const Type*>());
    // Construct the pointer to empty structure type.
    EmptyStructPtrTy = PointerType::get(EmptyStructTy);
  }
  
  return EmptyStructPtrTy;
}

/// getTagType - Return the type describing the specified descriptor (via tag.)
///
const StructType *DISerializer::getTagType(DebugInfoDesc *DD) {
  // Attempt to get the previously defined type.
  StructType *&Ty = TagTypes[DD->getTag()];
  
  // If not already defined.
  if (!Ty) {
    // Set up fields vector.
    std::vector<const Type*> Fields;
    // 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<Constant*> 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<ConstantStruct>(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()
, LandingPads()
{}
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 line info.
  Lines.clear();

  // Clean up frame info.
  FrameMoves.clear();
  
  // Clean up exception info.
  LandingPads.clear();
  TypeInfos.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);
}

/// needsFrameInfo - Returns true if we need to gather callee-saved register
/// move info for the frame.
bool MachineModuleInfo::needsFrameInfo() const {
  return hasDebugInfo() || ExceptionHandling;
}

/// SetupCompileUnits - Set up the unique vector of compile units.
///
void MachineModuleInfo::SetupCompileUnits(Module &M) {
  std::vector<CompileUnitDesc *>CU = getAnchoredDescriptors<CompileUnitDesc>(M);
  
  for (unsigned i = 0, N = CU.size(); i < N; i++) {
    CompileUnits.insert(CU[i]);
  }
}

/// getCompileUnits - Return a vector of debug compile units.
///
const UniqueVector<CompileUnitDesc *> MachineModuleInfo::getCompileUnits()const{
  return CompileUnits;
}

/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
/// named GlobalVariable.
std::vector<GlobalVariable*>
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<VariableDesc>(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<BlockDesc>(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;
}

//===-EH-------------------------------------------------------------------===//

/// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
/// specified MachineBasicBlock.
LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
    (MachineBasicBlock *LandingPad) {
  unsigned N = LandingPads.size();
  for (unsigned i = 0; i < N; ++i) {
    LandingPadInfo &LP = LandingPads[i];
    if (LP.LandingPadBlock == LandingPad)
      return LP;
  }
  
  LandingPads.push_back(LandingPadInfo(LandingPad));
  return LandingPads[N];
}

/// addInvoke - Provide the begin and end labels of an invoke style call and
/// associate it with a try landing pad block.
void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad,
                                  unsigned BeginLabel, unsigned EndLabel) {
  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
  if (!LP.BeginLabel) LP.BeginLabel = BeginLabel;  
  LP.EndLabel = EndLabel;  
}

/// addLandingPad - Provide the label of a try LandingPad block.
///
unsigned MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
  unsigned LandingPadLabel = NextLabelID();
  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
  LP.LandingPadLabel = LandingPadLabel;  
  return LandingPadLabel;
}

/// addPersonality - Provide the personality function for the exception
/// information.
void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad,
                                       Function *Personality) {
  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
  LP.Personality = Personality;
}

/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
///
void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad,
                                        std::vector<GlobalVariable *> &TyInfo) {
  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
  for (unsigned N = TyInfo.size(); N; --N)
    LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
}
                        
/// setIsFilterLandingPad - Indicates that the landing pad is a throw filter.
///
void MachineModuleInfo::setIsFilterLandingPad(MachineBasicBlock *LandingPad) {
  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
  LP.IsFilter = true;
}

/// TidyLandingPads - Remap landing pad labels and remove any deleted landing
/// pads.
void MachineModuleInfo::TidyLandingPads() {
  for (unsigned i = 0; i != LandingPads.size(); ) {
    LandingPadInfo &LandingPad = LandingPads[i];
    LandingPad.BeginLabel = MappedLabel(LandingPad.BeginLabel);
    LandingPad.EndLabel = MappedLabel(LandingPad.EndLabel);
    LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel);
    
    if (!LandingPad.BeginLabel ||
        !LandingPad.EndLabel ||
        !LandingPad.LandingPadLabel) {
      LandingPads.erase(LandingPads.begin() + i);
      continue;
    }
    
    ++i;
  }
}

/// getTypeIDFor - Return the type id for the specified typeinfo.  This is 
/// function wide.
unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) {
  for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i)
    if (TypeInfos[i] == TI) return i + 1;

  TypeInfos.push_back(TI);
  return TypeInfos.size();
}

/// getLandingPadInfos - Return a reference to the landing pad info for the
/// current function.
Function *MachineModuleInfo::getPersonality() const {
  return !LandingPads.empty() ? LandingPads[0].Personality : NULL;
}


//===----------------------------------------------------------------------===//
/// 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<MachineModuleInfo>();
  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(); }

}

