//===-- 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");
}
char MachineModuleInfo::ID = 0;

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

/// 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()
: ImmutablePass((intptr_t)&ID)
, DR()
, VR()
, CompileUnits()
, Directories()
, SourceFiles()
, Lines()
, LabelIDList()
, ScopeMap()
, RootScope(NULL)
, FrameMoves()
, LandingPads()
, Personalities()
{
  // Always emit "no personality" info
  Personalities.push_back(NULL);
}
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();
  FilterIds.clear();
  FilterEnds.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);
  LP.BeginLabels.push_back(BeginLabel);
  LP.EndLabels.push_back(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;

  for (unsigned i = 0; i < Personalities.size(); ++i)
    if (Personalities[i] == Personality)
      return;
  
  Personalities.push_back(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]));
}

/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
///
void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad,
                                        std::vector<GlobalVariable *> &TyInfo) {
  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
  std::vector<unsigned> IdsInFilter (TyInfo.size());
  for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
    IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
  LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
}

/// 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.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel);

    if (!LandingPad.LandingPadBlock)
      // Must not have cleanups if no landing pad.
      LandingPad.TypeIds.clear();

    // Special case: we *should* emit LPs with null LP MBB. This indicates
    // "rethrow" case.
    if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
      LandingPads.erase(LandingPads.begin() + i);
      continue;
    }
          
    for (unsigned j=0; j != LandingPads[i].BeginLabels.size(); ) {
      unsigned BeginLabel = MappedLabel(LandingPad.BeginLabels[j]);
      unsigned EndLabel = MappedLabel(LandingPad.EndLabels[j]);
            
          
      if (!BeginLabel || !EndLabel) {
        LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
        LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
        continue;
      }

      LandingPad.BeginLabels[j] = BeginLabel;
      LandingPad.EndLabels[j] = EndLabel;
      ++j;
    }
    
    ++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();
}

/// getFilterIDFor - Return the filter id for the specified typeinfos.  This is
/// function wide.
int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
  // If the new filter coincides with the tail of an existing filter, then
  // re-use the existing filter.  Folding filters more than this requires
  // re-ordering filters and/or their elements - probably not worth it.
  for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
       E = FilterEnds.end(); I != E; ++I) {
    unsigned i = *I, j = TyIds.size();

    while (i && j)
      if (FilterIds[--i] != TyIds[--j])
        goto try_next;

    if (!j)
      // The new filter coincides with range [i, end) of the existing filter.
      return -(1 + i);

try_next:;
  }

  // Add the new filter.
  int FilterID = -(1 + FilterIds.size());
  FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
  for (unsigned I = 0, N = TyIds.size(); I != N; ++I)
    FilterIds.push_back(TyIds[I]);
  FilterEnds.push_back(FilterIds.size());
  FilterIds.push_back(0); // terminator
  return FilterID;
}

/// getPersonality - Return the personality function for the current function.
Function *MachineModuleInfo::getPersonality() const {
  // FIXME: Until PR1414 will be fixed, we're using 1 personality function per
  // function
  return !LandingPads.empty() ? LandingPads[0].Personality : NULL;
}

/// getPersonalityIndex - Return unique index for current personality
/// function. NULL personality function should always get zero index.
unsigned MachineModuleInfo::getPersonalityIndex() const {
  const Function* Personality = NULL;
  
  // Scan landing pads. If there is at least one non-NULL personality - use it.
  for (unsigned i = 0; i != LandingPads.size(); ++i)
    if (LandingPads[i].Personality) {
      Personality = LandingPads[i].Personality;
      break;
    }
  
  for (unsigned i = 0; i < Personalities.size(); ++i) {
    if (Personalities[i] == Personality)
      return i;
  }

  // This should never happen
  assert(0 && "Personality function should be set!");
  return 0;
}

//===----------------------------------------------------------------------===//
/// 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 {
  static char ID;
  DebugLabelFolder() : MachineFunctionPass((intptr_t)&ID) {}

  virtual bool runOnMachineFunction(MachineFunction &MF);
  virtual const char *getPassName() const { return "Label Folder"; }
};

char DebugLabelFolder::ID = 0;

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

}

