Changing DebugInfoFinder to iterate over all the compile units.
Solves http://llvm.org/bugs/show_bug.cgi?id=17507

Committed on behalf of alon.mishne@intel.com

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192879 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp
index 290aa62..ead426e 100644
--- a/lib/IR/DebugInfo.cpp
+++ b/lib/IR/DebugInfo.cpp
@@ -1,1421 +1,1419 @@
-//===--- DebugInfo.cpp - Debug Information Helper Classes -----------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the helper classes used to build and interpret debug
-// information in LLVM IR form.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/ValueHandle.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-using namespace llvm::dwarf;
-
-//===----------------------------------------------------------------------===//
-// DIDescriptor
-//===----------------------------------------------------------------------===//
-
-bool DIDescriptor::Verify() const {
-  return DbgNode &&
-         (DIDerivedType(DbgNode).Verify() ||
-          DICompositeType(DbgNode).Verify() || DIBasicType(DbgNode).Verify() ||
-          DIVariable(DbgNode).Verify() || DISubprogram(DbgNode).Verify() ||
-          DIGlobalVariable(DbgNode).Verify() || DIFile(DbgNode).Verify() ||
-          DICompileUnit(DbgNode).Verify() || DINameSpace(DbgNode).Verify() ||
-          DILexicalBlock(DbgNode).Verify() ||
-          DILexicalBlockFile(DbgNode).Verify() ||
-          DISubrange(DbgNode).Verify() || DIEnumerator(DbgNode).Verify() ||
-          DIObjCProperty(DbgNode).Verify() ||
-          DITemplateTypeParameter(DbgNode).Verify() ||
-          DITemplateValueParameter(DbgNode).Verify() ||
-          DIImportedEntity(DbgNode).Verify());
-}
-
-static Value *getField(const MDNode *DbgNode, unsigned Elt) {
-  if (DbgNode == 0 || Elt >= DbgNode->getNumOperands())
-    return 0;
-  return DbgNode->getOperand(Elt);
-}
-
-static MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) {
-  return dyn_cast_or_null<MDNode>(getField(DbgNode, Elt));
-}
-
-static StringRef getStringField(const MDNode *DbgNode, unsigned Elt) {
-  if (MDString *MDS = dyn_cast_or_null<MDString>(getField(DbgNode, Elt)))
-    return MDS->getString();
-  return StringRef();
-}
-
-StringRef DIDescriptor::getStringField(unsigned Elt) const {
-  return ::getStringField(DbgNode, Elt);
-}
-
-uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {
-  if (DbgNode == 0)
-    return 0;
-
-  if (Elt < DbgNode->getNumOperands())
-    if (ConstantInt *CI
-        = dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt)))
-      return CI->getZExtValue();
-
-  return 0;
-}
-
-int64_t DIDescriptor::getInt64Field(unsigned Elt) const {
-  if (DbgNode == 0)
-    return 0;
-
-  if (Elt < DbgNode->getNumOperands())
-    if (ConstantInt *CI
-        = dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt)))
-      return CI->getSExtValue();
-
-  return 0;
-}
-
-DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const {
-  MDNode *Field = getNodeField(DbgNode, Elt);
-  return DIDescriptor(Field);
-}
-
-GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const {
-  if (DbgNode == 0)
-    return 0;
-
-  if (Elt < DbgNode->getNumOperands())
-      return dyn_cast_or_null<GlobalVariable>(DbgNode->getOperand(Elt));
-  return 0;
-}
-
-Constant *DIDescriptor::getConstantField(unsigned Elt) const {
-  if (DbgNode == 0)
-    return 0;
-
-  if (Elt < DbgNode->getNumOperands())
-      return dyn_cast_or_null<Constant>(DbgNode->getOperand(Elt));
-  return 0;
-}
-
-Function *DIDescriptor::getFunctionField(unsigned Elt) const {
-  if (DbgNode == 0)
-    return 0;
-
-  if (Elt < DbgNode->getNumOperands())
-      return dyn_cast_or_null<Function>(DbgNode->getOperand(Elt));
-  return 0;
-}
-
-void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) {
-  if (DbgNode == 0)
-    return;
-
-  if (Elt < DbgNode->getNumOperands()) {
-    MDNode *Node = const_cast<MDNode*>(DbgNode);
-    Node->replaceOperandWith(Elt, F);
-  }
-}
-
-unsigned DIVariable::getNumAddrElements() const {
-  return DbgNode->getNumOperands()-8;
-}
-
-/// getInlinedAt - If this variable is inlined then return inline location.
-MDNode *DIVariable::getInlinedAt() const {
-  return getNodeField(DbgNode, 7);
-}
-
-//===----------------------------------------------------------------------===//
-// Predicates
-//===----------------------------------------------------------------------===//
-
-/// isBasicType - Return true if the specified tag is legal for
-/// DIBasicType.
-bool DIDescriptor::isBasicType() const {
-  if (!DbgNode) return false;
-  switch (getTag()) {
-  case dwarf::DW_TAG_base_type:
-  case dwarf::DW_TAG_unspecified_type:
-    return true;
-  default:
-    return false;
-  }
-}
-
-/// isDerivedType - Return true if the specified tag is legal for DIDerivedType.
-bool DIDescriptor::isDerivedType() const {
-  if (!DbgNode) return false;
-  switch (getTag()) {
-  case dwarf::DW_TAG_typedef:
-  case dwarf::DW_TAG_pointer_type:
-  case dwarf::DW_TAG_ptr_to_member_type:
-  case dwarf::DW_TAG_reference_type:
-  case dwarf::DW_TAG_rvalue_reference_type:
-  case dwarf::DW_TAG_const_type:
-  case dwarf::DW_TAG_volatile_type:
-  case dwarf::DW_TAG_restrict_type:
-  case dwarf::DW_TAG_member:
-  case dwarf::DW_TAG_inheritance:
-  case dwarf::DW_TAG_friend:
-    return true;
-  default:
-    // CompositeTypes are currently modelled as DerivedTypes.
-    return isCompositeType();
-  }
-}
-
-/// isCompositeType - Return true if the specified tag is legal for
-/// DICompositeType.
-bool DIDescriptor::isCompositeType() const {
-  if (!DbgNode) return false;
-  switch (getTag()) {
-  case dwarf::DW_TAG_array_type:
-  case dwarf::DW_TAG_structure_type:
-  case dwarf::DW_TAG_union_type:
-  case dwarf::DW_TAG_enumeration_type:
-  case dwarf::DW_TAG_subroutine_type:
-  case dwarf::DW_TAG_class_type:
-    return true;
-  default:
-    return false;
-  }
-}
-
-/// isVariable - Return true if the specified tag is legal for DIVariable.
-bool DIDescriptor::isVariable() const {
-  if (!DbgNode) return false;
-  switch (getTag()) {
-  case dwarf::DW_TAG_auto_variable:
-  case dwarf::DW_TAG_arg_variable:
-    return true;
-  default:
-    return false;
-  }
-}
-
-/// isType - Return true if the specified tag is legal for DIType.
-bool DIDescriptor::isType() const {
-  return isBasicType() || isCompositeType() || isDerivedType();
-}
-
-/// isSubprogram - Return true if the specified tag is legal for
-/// DISubprogram.
-bool DIDescriptor::isSubprogram() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_subprogram;
-}
-
-/// isGlobalVariable - Return true if the specified tag is legal for
-/// DIGlobalVariable.
-bool DIDescriptor::isGlobalVariable() const {
-  return DbgNode && (getTag() == dwarf::DW_TAG_variable ||
-                     getTag() == dwarf::DW_TAG_constant);
-}
-
-/// isUnspecifiedParmeter - Return true if the specified tag is
-/// DW_TAG_unspecified_parameters.
-bool DIDescriptor::isUnspecifiedParameter() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_unspecified_parameters;
-}
-
-/// isScope - Return true if the specified tag is one of the scope
-/// related tag.
-bool DIDescriptor::isScope() const {
-  if (!DbgNode) return false;
-  switch (getTag()) {
-  case dwarf::DW_TAG_compile_unit:
-  case dwarf::DW_TAG_lexical_block:
-  case dwarf::DW_TAG_subprogram:
-  case dwarf::DW_TAG_namespace:
-  case dwarf::DW_TAG_file_type:
-    return true;
-  default:
-    break;
-  }
-  return isType();
-}
-
-/// isTemplateTypeParameter - Return true if the specified tag is
-/// DW_TAG_template_type_parameter.
-bool DIDescriptor::isTemplateTypeParameter() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_template_type_parameter;
-}
-
-/// isTemplateValueParameter - Return true if the specified tag is
-/// DW_TAG_template_value_parameter.
-bool DIDescriptor::isTemplateValueParameter() const {
-  return DbgNode && (getTag() == dwarf::DW_TAG_template_value_parameter ||
-                     getTag() == dwarf::DW_TAG_GNU_template_template_param ||
-                     getTag() == dwarf::DW_TAG_GNU_template_parameter_pack);
-}
-
-/// isCompileUnit - Return true if the specified tag is DW_TAG_compile_unit.
-bool DIDescriptor::isCompileUnit() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_compile_unit;
-}
-
-/// isFile - Return true if the specified tag is DW_TAG_file_type.
-bool DIDescriptor::isFile() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_file_type;
-}
-
-/// isNameSpace - Return true if the specified tag is DW_TAG_namespace.
-bool DIDescriptor::isNameSpace() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_namespace;
-}
-
-/// isLexicalBlockFile - Return true if the specified descriptor is a
-/// lexical block with an extra file.
-bool DIDescriptor::isLexicalBlockFile() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&
-    (DbgNode->getNumOperands() == 3);
-}
-
-/// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block.
-bool DIDescriptor::isLexicalBlock() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&
-    (DbgNode->getNumOperands() > 3);
-}
-
-/// isSubrange - Return true if the specified tag is DW_TAG_subrange_type.
-bool DIDescriptor::isSubrange() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_subrange_type;
-}
-
-/// isEnumerator - Return true if the specified tag is DW_TAG_enumerator.
-bool DIDescriptor::isEnumerator() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_enumerator;
-}
-
-/// isObjCProperty - Return true if the specified tag is DW_TAG_APPLE_property.
-bool DIDescriptor::isObjCProperty() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_APPLE_property;
-}
-
-/// \brief Return true if the specified tag is DW_TAG_imported_module or
-/// DW_TAG_imported_declaration.
-bool DIDescriptor::isImportedEntity() const {
-  return DbgNode && (getTag() == dwarf::DW_TAG_imported_module ||
-                     getTag() == dwarf::DW_TAG_imported_declaration);
-}
-
-//===----------------------------------------------------------------------===//
-// Simple Descriptor Constructors and other Methods
-//===----------------------------------------------------------------------===//
-
-unsigned DIArray::getNumElements() const {
-  if (!DbgNode)
-    return 0;
-  return DbgNode->getNumOperands();
-}
-
-/// replaceAllUsesWith - Replace all uses of the MDNode used by this
-/// type with the one in the passed descriptor.
-void DIType::replaceAllUsesWith(DIDescriptor &D) {
-
-  assert(DbgNode && "Trying to replace an unverified type!");
-
-  // Since we use a TrackingVH for the node, its easy for clients to manufacture
-  // legitimate situations where they want to replaceAllUsesWith() on something
-  // which, due to uniquing, has merged with the source. We shield clients from
-  // this detail by allowing a value to be replaced with replaceAllUsesWith()
-  // itself.
-  if (DbgNode != D) {
-    MDNode *Node = const_cast<MDNode*>(DbgNode);
-    const MDNode *DN = D;
-    const Value *V = cast_or_null<Value>(DN);
-    Node->replaceAllUsesWith(const_cast<Value*>(V));
-    MDNode::deleteTemporary(Node);
-  }
-}
-
-/// replaceAllUsesWith - Replace all uses of the MDNode used by this
-/// type with the one in D.
-void DIType::replaceAllUsesWith(MDNode *D) {
-
-  assert(DbgNode && "Trying to replace an unverified type!");
-
-  // Since we use a TrackingVH for the node, its easy for clients to manufacture
-  // legitimate situations where they want to replaceAllUsesWith() on something
-  // which, due to uniquing, has merged with the source. We shield clients from
-  // this detail by allowing a value to be replaced with replaceAllUsesWith()
-  // itself.
-  if (DbgNode != D) {
-    MDNode *Node = const_cast<MDNode*>(DbgNode);
-    const MDNode *DN = D;
-    const Value *V = cast_or_null<Value>(DN);
-    Node->replaceAllUsesWith(const_cast<Value*>(V));
-    MDNode::deleteTemporary(Node);
-  }
-}
-
-/// Verify - Verify that a compile unit is well formed.
-bool DICompileUnit::Verify() const {
-  if (!isCompileUnit())
-    return false;
-
-  // Don't bother verifying the compilation directory or producer string
-  // as those could be empty.
-  if (getFilename().empty())
-    return false;
-
-  return DbgNode->getNumOperands() == 13;
-}
-
-/// Verify - Verify that an ObjC property is well formed.
-bool DIObjCProperty::Verify() const {
-  if (!isObjCProperty())
-    return false;
-
-  // Don't worry about the rest of the strings for now.
-  return DbgNode->getNumOperands() == 8;
-}
-
-/// Check if a field at position Elt of a MDNode is a MDNode.
-/// We currently allow an empty string and an integer.
-/// But we don't allow a non-empty string in a MDNode field.
-static bool fieldIsMDNode(const MDNode *DbgNode, unsigned Elt) {
-  // FIXME: This function should return true, if the field is null or the field
-  // is indeed a MDNode: return !Fld || isa<MDNode>(Fld).
-  Value *Fld = getField(DbgNode, Elt);
-  if (Fld && isa<MDString>(Fld) &&
-      !cast<MDString>(Fld)->getString().empty())
-    return false;
-  return true;
-}
-
-/// Check if a field at position Elt of a MDNode is a MDString.
-static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) {
-  Value *Fld = getField(DbgNode, Elt);
-  return !Fld || isa<MDString>(Fld);
-}
-
-/// Check if a value can be a reference to a type.
-static bool isTypeRef(const Value *Val) {
-  return !Val ||
-         (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||
-         (isa<MDNode>(Val) && DIType(cast<MDNode>(Val)).isType());
-}
-
-/// Check if a field at position Elt of a MDNode can be a reference to a type.
-static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) {
-  Value *Fld = getField(DbgNode, Elt);
-  return isTypeRef(Fld);
-}
-
-/// Check if a value can be a ScopeRef.
-static bool isScopeRef(const Value *Val) {
-  return !Val ||
-         (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||
-         (isa<MDNode>(Val) && DIScope(cast<MDNode>(Val)).isScope());
-}
-
-/// Check if a field at position Elt of a MDNode can be a ScopeRef.
-static bool fieldIsScopeRef(const MDNode *DbgNode, unsigned Elt) {
-  Value *Fld = getField(DbgNode, Elt);
-  return isScopeRef(Fld);
-}
-
-/// Verify - Verify that a type descriptor is well formed.
-bool DIType::Verify() const {
-  if (!isType())
-    return false;
-  // Make sure Context @ field 2 is MDNode.
-  if (!fieldIsScopeRef(DbgNode, 2))
-    return false;
-
-  // FIXME: Sink this into the various subclass verifies.
-  uint16_t Tag = getTag();
-  if (!isBasicType() && Tag != dwarf::DW_TAG_const_type &&
-      Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_pointer_type &&
-      Tag != dwarf::DW_TAG_ptr_to_member_type &&
-      Tag != dwarf::DW_TAG_reference_type &&
-      Tag != dwarf::DW_TAG_rvalue_reference_type &&
-      Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_array_type &&
-      Tag != dwarf::DW_TAG_enumeration_type &&
-      Tag != dwarf::DW_TAG_subroutine_type &&
-      Tag != dwarf::DW_TAG_inheritance && Tag != dwarf::DW_TAG_friend &&
-      getFilename().empty())
-    return false;
-  // DIType is abstract, it should be a BasicType, a DerivedType or
-  // a CompositeType.
-  if (isBasicType())
-    DIBasicType(DbgNode).Verify();
-  else if (isCompositeType())
-    DICompositeType(DbgNode).Verify();
-  else if (isDerivedType())
-    DIDerivedType(DbgNode).Verify();
-  else
-    return false;
-  return true;
-}
-
-/// Verify - Verify that a basic type descriptor is well formed.
-bool DIBasicType::Verify() const {
-  return isBasicType() && DbgNode->getNumOperands() == 10;
-}
-
-/// Verify - Verify that a derived type descriptor is well formed.
-bool DIDerivedType::Verify() const {
-  // Make sure DerivedFrom @ field 9 is TypeRef.
-  if (!fieldIsTypeRef(DbgNode, 9))
-    return false;
-  if (getTag() == dwarf::DW_TAG_ptr_to_member_type)
-    // Make sure ClassType @ field 10 is a TypeRef.
-    if (!fieldIsTypeRef(DbgNode, 10))
-      return false;
-
-  return isDerivedType() && DbgNode->getNumOperands() >= 10 &&
-         DbgNode->getNumOperands() <= 14;
-}
-
-/// Verify - Verify that a composite type descriptor is well formed.
-bool DICompositeType::Verify() const {
-  if (!isCompositeType())
-    return false;
-
-  // Make sure DerivedFrom @ field 9 and ContainingType @ field 12 are TypeRef.
-  if (!fieldIsTypeRef(DbgNode, 9))
-    return false;
-  if (!fieldIsTypeRef(DbgNode, 12))
-    return false;
-
-  // Make sure the type identifier at field 14 is MDString, it can be null.
-  if (!fieldIsMDString(DbgNode, 14))
-    return false;
-
-  return DbgNode->getNumOperands() == 15;
-}
-
-/// Verify - Verify that a subprogram descriptor is well formed.
-bool DISubprogram::Verify() const {
-  if (!isSubprogram())
-    return false;
-
-  // Make sure context @ field 2 is a ScopeRef and type @ field 7 is a MDNode.
-  if (!fieldIsScopeRef(DbgNode, 2))
-    return false;
-  if (!fieldIsMDNode(DbgNode, 7))
-    return false;
-  // Containing type @ field 12.
-  if (!fieldIsTypeRef(DbgNode, 12))
-    return false;
-  return DbgNode->getNumOperands() == 20;
-}
-
-/// Verify - Verify that a global variable descriptor is well formed.
-bool DIGlobalVariable::Verify() const {
-  if (!isGlobalVariable())
-    return false;
-
-  if (getDisplayName().empty())
-    return false;
-  // Make sure context @ field 2 and type @ field 8 are MDNodes.
-  if (!fieldIsMDNode(DbgNode, 2))
-    return false;
-  if (!fieldIsMDNode(DbgNode, 8))
-    return false;
-  // Make sure StaticDataMemberDeclaration @ field 12 is MDNode.
-  if (!fieldIsMDNode(DbgNode, 12))
-    return false;
-
-  return DbgNode->getNumOperands() == 13;
-}
-
-/// Verify - Verify that a variable descriptor is well formed.
-bool DIVariable::Verify() const {
-  if (!isVariable())
-    return false;
-
-  // Make sure context @ field 1 and type @ field 5 are MDNodes.
-  if (!fieldIsMDNode(DbgNode, 1))
-    return false;
-  if (!fieldIsMDNode(DbgNode, 5))
-    return false;
-  return DbgNode->getNumOperands() >= 8;
-}
-
-/// Verify - Verify that a location descriptor is well formed.
-bool DILocation::Verify() const {
-  if (!DbgNode)
-    return false;
-
-  return DbgNode->getNumOperands() == 4;
-}
-
-/// Verify - Verify that a namespace descriptor is well formed.
-bool DINameSpace::Verify() const {
-  if (!isNameSpace())
-    return false;
-  return DbgNode->getNumOperands() == 5;
-}
-
-/// \brief Retrieve the MDNode for the directory/file pair.
-MDNode *DIFile::getFileNode() const {
-  return getNodeField(DbgNode, 1);
-}
-
-/// \brief Verify that the file descriptor is well formed.
-bool DIFile::Verify() const {
-  return isFile() && DbgNode->getNumOperands() == 2;
-}
-
-/// \brief Verify that the enumerator descriptor is well formed.
-bool DIEnumerator::Verify() const {
-  return isEnumerator() && DbgNode->getNumOperands() == 3;
-}
-
-/// \brief Verify that the subrange descriptor is well formed.
-bool DISubrange::Verify() const {
-  return isSubrange() && DbgNode->getNumOperands() == 3;
-}
-
-/// \brief Verify that the lexical block descriptor is well formed.
-bool DILexicalBlock::Verify() const {
-  return isLexicalBlock() && DbgNode->getNumOperands() == 6;
-}
-
-/// \brief Verify that the file-scoped lexical block descriptor is well formed.
-bool DILexicalBlockFile::Verify() const {
-  return isLexicalBlockFile() && DbgNode->getNumOperands() == 3;
-}
-
-/// \brief Verify that the template type parameter descriptor is well formed.
-bool DITemplateTypeParameter::Verify() const {
-  return isTemplateTypeParameter() && DbgNode->getNumOperands() == 7;
-}
-
-/// \brief Verify that the template value parameter descriptor is well formed.
-bool DITemplateValueParameter::Verify() const {
-  return isTemplateValueParameter() && DbgNode->getNumOperands() == 8;
-}
-
-/// \brief Verify that the imported module descriptor is well formed.
-bool DIImportedEntity::Verify() const {
-  return isImportedEntity() &&
-         (DbgNode->getNumOperands() == 4 || DbgNode->getNumOperands() == 5);
-}
-
-/// getObjCProperty - Return property node, if this ivar is associated with one.
-MDNode *DIDerivedType::getObjCProperty() const {
-  return getNodeField(DbgNode, 10);
-}
-
-MDString *DICompositeType::getIdentifier() const {
-  return cast_or_null<MDString>(getField(DbgNode, 14));
-}
-
-#ifndef NDEBUG
-static void VerifySubsetOf(const MDNode *LHS, const MDNode *RHS) {
-  for (unsigned i = 0; i != LHS->getNumOperands(); ++i) {
-    // Skip the 'empty' list (that's a single i32 0, rather than truly empty).
-    if (i == 0 && isa<ConstantInt>(LHS->getOperand(i)))
-      continue;
-    const MDNode *E = cast<MDNode>(LHS->getOperand(i));
-    bool found = false;
-    for (unsigned j = 0; !found && j != RHS->getNumOperands(); ++j)
-      found = E == RHS->getOperand(j);
-    assert(found && "Losing a member during member list replacement");
-  }
-}
-#endif
-
-/// \brief Set the array of member DITypes.
-void DICompositeType::setTypeArray(DIArray Elements, DIArray TParams) {
-  assert((!TParams || DbgNode->getNumOperands() == 15) &&
-         "If you're setting the template parameters this should include a slot "
-         "for that!");
-  TrackingVH<MDNode> N(*this);
-  if (Elements) {
-#ifndef NDEBUG
-    // Check that the new list of members contains all the old members as well.
-    if (const MDNode *El = cast_or_null<MDNode>(N->getOperand(10)))
-      VerifySubsetOf(El, Elements);
-#endif
-    N->replaceOperandWith(10, Elements);
-  }
-  if (TParams)
-    N->replaceOperandWith(13, TParams);
-  DbgNode = N;
-}
-
-void DICompositeType::addMember(DIDescriptor D) {
-  SmallVector<llvm::Value *, 16> M;
-  DIArray OrigM = getTypeArray();
-  unsigned Elements = OrigM.getNumElements();
-  if (Elements == 1 && !OrigM.getElement(0))
-    Elements = 0;
-  M.reserve(Elements + 1);
-  for (unsigned i = 0; i != Elements; ++i)
-    M.push_back(OrigM.getElement(i));
-  M.push_back(D);
-  setTypeArray(DIArray(MDNode::get(DbgNode->getContext(), M)));
-}
-
-/// Generate a reference to this DIType. Uses the type identifier instead
-/// of the actual MDNode if possible, to help type uniquing.
-DIScopeRef DIScope::getRef() const {
-  if (!isCompositeType())
-    return DIScopeRef(*this);
-  DICompositeType DTy(DbgNode);
-  if (!DTy.getIdentifier())
-    return DIScopeRef(*this);
-  return DIScopeRef(DTy.getIdentifier());
-}
-
-/// \brief Set the containing type.
-void DICompositeType::setContainingType(DICompositeType ContainingType) {
-  TrackingVH<MDNode> N(*this);
-  N->replaceOperandWith(12, ContainingType.getRef());
-  DbgNode = N;
-}
-
-/// isInlinedFnArgument - Return true if this variable provides debugging
-/// information for an inlined function arguments.
-bool DIVariable::isInlinedFnArgument(const Function *CurFn) {
-  assert(CurFn && "Invalid function");
-  if (!getContext().isSubprogram())
-    return false;
-  // This variable is not inlined function argument if its scope
-  // does not describe current function.
-  return !DISubprogram(getContext()).describes(CurFn);
-}
-
-/// describes - Return true if this subprogram provides debugging
-/// information for the function F.
-bool DISubprogram::describes(const Function *F) {
-  assert(F && "Invalid function");
-  if (F == getFunction())
-    return true;
-  StringRef Name = getLinkageName();
-  if (Name.empty())
-    Name = getName();
-  if (F->getName() == Name)
-    return true;
-  return false;
-}
-
-unsigned DISubprogram::isOptimized() const {
-  assert (DbgNode && "Invalid subprogram descriptor!");
-  if (DbgNode->getNumOperands() == 15)
-    return getUnsignedField(14);
-  return 0;
-}
-
-MDNode *DISubprogram::getVariablesNodes() const {
-  return getNodeField(DbgNode, 18);
-}
-
-DIArray DISubprogram::getVariables() const {
-  return DIArray(getNodeField(DbgNode, 18));
-}
-
-Value *DITemplateValueParameter::getValue() const {
-  return getField(DbgNode, 4);
-}
-
-// If the current node has a parent scope then return that,
-// else return an empty scope.
-DIScopeRef DIScope::getContext() const {
-
-  if (isType())
-    return DIType(DbgNode).getContext();
-
-  if (isSubprogram())
-    return DIScopeRef(DISubprogram(DbgNode).getContext());
-
-  if (isLexicalBlock())
-    return DIScopeRef(DILexicalBlock(DbgNode).getContext());
-
-  if (isLexicalBlockFile())
-    return DIScopeRef(DILexicalBlockFile(DbgNode).getContext());
-
-  if (isNameSpace())
-    return DIScopeRef(DINameSpace(DbgNode).getContext());
-
-  assert((isFile() || isCompileUnit()) && "Unhandled type of scope.");
-  return DIScopeRef(NULL);
-}
-
-// If the scope node has a name, return that, else return an empty string.
-StringRef DIScope::getName() const {
-  if (isType())
-    return DIType(DbgNode).getName();
-  if (isSubprogram())
-    return DISubprogram(DbgNode).getName();
-  if (isNameSpace())
-    return DINameSpace(DbgNode).getName();
-  assert((isLexicalBlock() || isLexicalBlockFile() || isFile() ||
-          isCompileUnit()) && "Unhandled type of scope.");
-  return StringRef();
-}
-
-StringRef DIScope::getFilename() const {
-  if (!DbgNode)
-    return StringRef();
-  return ::getStringField(getNodeField(DbgNode, 1), 0);
-}
-
-StringRef DIScope::getDirectory() const {
-  if (!DbgNode)
-    return StringRef();
-  return ::getStringField(getNodeField(DbgNode, 1), 1);
-}
-
-DIArray DICompileUnit::getEnumTypes() const {
-  if (!DbgNode || DbgNode->getNumOperands() < 13)
-    return DIArray();
-
-  return DIArray(getNodeField(DbgNode, 7));
-}
-
-DIArray DICompileUnit::getRetainedTypes() const {
-  if (!DbgNode || DbgNode->getNumOperands() < 13)
-    return DIArray();
-
-  return DIArray(getNodeField(DbgNode, 8));
-}
-
-DIArray DICompileUnit::getSubprograms() const {
-  if (!DbgNode || DbgNode->getNumOperands() < 13)
-    return DIArray();
-
-  return DIArray(getNodeField(DbgNode, 9));
-}
-
-
-DIArray DICompileUnit::getGlobalVariables() const {
-  if (!DbgNode || DbgNode->getNumOperands() < 13)
-    return DIArray();
-
-  return DIArray(getNodeField(DbgNode, 10));
-}
-
-DIArray DICompileUnit::getImportedEntities() const {
-  if (!DbgNode || DbgNode->getNumOperands() < 13)
-    return DIArray();
-
-  return DIArray(getNodeField(DbgNode, 11));
-}
-
-/// fixupSubprogramName - Replace contains special characters used
-/// in a typical Objective-C names with '.' in a given string.
-static void fixupSubprogramName(DISubprogram Fn, SmallVectorImpl<char> &Out) {
-  StringRef FName =
-      Fn.getFunction() ? Fn.getFunction()->getName() : Fn.getName();
-  FName = Function::getRealLinkageName(FName);
-
-  StringRef Prefix("llvm.dbg.lv.");
-  Out.reserve(FName.size() + Prefix.size());
-  Out.append(Prefix.begin(), Prefix.end());
-
-  bool isObjCLike = false;
-  for (size_t i = 0, e = FName.size(); i < e; ++i) {
-    char C = FName[i];
-    if (C == '[')
-      isObjCLike = true;
-
-    if (isObjCLike && (C == '[' || C == ']' || C == ' ' || C == ':' ||
-                       C == '+' || C == '(' || C == ')'))
-      Out.push_back('.');
-    else
-      Out.push_back(C);
-  }
-}
-
-/// getFnSpecificMDNode - Return a NameMDNode, if available, that is
-/// suitable to hold function specific information.
-NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, DISubprogram Fn) {
-  SmallString<32> Name;
-  fixupSubprogramName(Fn, Name);
-  return M.getNamedMetadata(Name.str());
-}
-
-/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
-/// to hold function specific information.
-NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, DISubprogram Fn) {
-  SmallString<32> Name;
-  fixupSubprogramName(Fn, Name);
-  return M.getOrInsertNamedMetadata(Name.str());
-}
-
-/// createInlinedVariable - Create a new inlined variable based on current
-/// variable.
-/// @param DV            Current Variable.
-/// @param InlinedScope  Location at current variable is inlined.
-DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
-                                       LLVMContext &VMContext) {
-  SmallVector<Value *, 16> Elts;
-  // Insert inlined scope as 7th element.
-  for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i)
-    i == 7 ? Elts.push_back(InlinedScope) :
-             Elts.push_back(DV->getOperand(i));
-  return DIVariable(MDNode::get(VMContext, Elts));
-}
-
-/// cleanseInlinedVariable - Remove inlined scope from the variable.
-DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) {
-  SmallVector<Value *, 16> Elts;
-  // Insert inlined scope as 7th element.
-  for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i)
-    i == 7 ?
-      Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))):
-      Elts.push_back(DV->getOperand(i));
-  return DIVariable(MDNode::get(VMContext, Elts));
-}
-
-/// getDISubprogram - Find subprogram that is enclosing this scope.
-DISubprogram llvm::getDISubprogram(const MDNode *Scope) {
-  DIDescriptor D(Scope);
-  if (D.isSubprogram())
-    return DISubprogram(Scope);
-
-  if (D.isLexicalBlockFile())
-    return getDISubprogram(DILexicalBlockFile(Scope).getContext());
-
-  if (D.isLexicalBlock())
-    return getDISubprogram(DILexicalBlock(Scope).getContext());
-
-  return DISubprogram();
-}
-
-/// getDICompositeType - Find underlying composite type.
-DICompositeType llvm::getDICompositeType(DIType T) {
-  if (T.isCompositeType())
-    return DICompositeType(T);
-
-  if (T.isDerivedType()) {
-    // This function is currently used by dragonegg and dragonegg does
-    // not generate identifier for types, so using an empty map to resolve
-    // DerivedFrom should be fine.
-    DITypeIdentifierMap EmptyMap;
-    return getDICompositeType(DIDerivedType(T).getTypeDerivedFrom()
-                                              .resolve(EmptyMap));
-  }
-
-  return DICompositeType();
-}
-
-/// Update DITypeIdentifierMap by going through retained types of each CU.
-DITypeIdentifierMap llvm::generateDITypeIdentifierMap(
-                              const NamedMDNode *CU_Nodes) {
-  DITypeIdentifierMap Map;
-  for (unsigned CUi = 0, CUe = CU_Nodes->getNumOperands(); CUi != CUe; ++CUi) {
-    DICompileUnit CU(CU_Nodes->getOperand(CUi));
-    DIArray Retain = CU.getRetainedTypes();
-    for (unsigned Ti = 0, Te = Retain.getNumElements(); Ti != Te; ++Ti) {
-      if (!Retain.getElement(Ti).isCompositeType())
-        continue;
-      DICompositeType Ty(Retain.getElement(Ti));
-      if (MDString *TypeId = Ty.getIdentifier()) {
-        // Definition has priority over declaration.
-        // Try to insert (TypeId, Ty) to Map.
-        std::pair<DITypeIdentifierMap::iterator, bool> P =
-            Map.insert(std::make_pair(TypeId, Ty));
-        // If TypeId already exists in Map and this is a definition, replace
-        // whatever we had (declaration or definition) with the definition.
-        if (!P.second && !Ty.isForwardDecl())
-          P.first->second = Ty;
-      }
-    }
-  }
-  return Map;
-}
-
-//===----------------------------------------------------------------------===//
-// DebugInfoFinder implementations.
-//===----------------------------------------------------------------------===//
-
-void DebugInfoFinder::reset() {
-  CUs.clear();
-  SPs.clear();
-  GVs.clear();
-  TYs.clear();
-  Scopes.clear();
-  NodesSeen.clear();
-  TypeIdentifierMap.clear();
-}
-
-/// processModule - Process entire module and collect debug info.
-void DebugInfoFinder::processModule(const Module &M) {
-  if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) {
-    TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
-    for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
-      DICompileUnit CU(CU_Nodes->getOperand(i));
-      addCompileUnit(CU);
-      DIArray GVs = CU.getGlobalVariables();
-      for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) {
-        DIGlobalVariable DIG(GVs.getElement(i));
-        if (addGlobalVariable(DIG)) {
-          processScope(DIG.getContext());
-          processType(DIG.getType());
-        }
-      }
-      DIArray SPs = CU.getSubprograms();
-      for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i)
-        processSubprogram(DISubprogram(SPs.getElement(i)));
-      DIArray EnumTypes = CU.getEnumTypes();
-      for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i)
-        processType(DIType(EnumTypes.getElement(i)));
-      DIArray RetainedTypes = CU.getRetainedTypes();
-      for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i)
-        processType(DIType(RetainedTypes.getElement(i)));
-      DIArray Imports = CU.getImportedEntities();
-      for (unsigned i = 0, e = Imports.getNumElements(); i != e; ++i) {
-        DIImportedEntity Import = DIImportedEntity(
-                                    Imports.getElement(i));
-        DIDescriptor Entity = Import.getEntity();
-        if (Entity.isType())
-          processType(DIType(Entity));
-        else if (Entity.isSubprogram())
-          processSubprogram(DISubprogram(Entity));
-        else if (Entity.isNameSpace())
-          processScope(DINameSpace(Entity).getContext());
-      }
-      // FIXME: We really shouldn't be bailing out after visiting just one CU
-      return;
-    }
-  }
-}
-
-/// processLocation - Process DILocation.
-void DebugInfoFinder::processLocation(DILocation Loc) {
-  if (!Loc) return;
-  processScope(Loc.getScope());
-  processLocation(Loc.getOrigLocation());
-}
-
-/// processType - Process DIType.
-void DebugInfoFinder::processType(DIType DT) {
-  if (!addType(DT))
-    return;
-  processScope(DT.getContext().resolve(TypeIdentifierMap));
-  if (DT.isCompositeType()) {
-    DICompositeType DCT(DT);
-    processType(DCT.getTypeDerivedFrom().resolve(TypeIdentifierMap));
-    DIArray DA = DCT.getTypeArray();
-    for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) {
-      DIDescriptor D = DA.getElement(i);
-      if (D.isType())
-        processType(DIType(D));
-      else if (D.isSubprogram())
-        processSubprogram(DISubprogram(D));
-    }
-  } else if (DT.isDerivedType()) {
-    DIDerivedType DDT(DT);
-    processType(DDT.getTypeDerivedFrom().resolve(TypeIdentifierMap));
-  }
-}
-
-void DebugInfoFinder::processScope(DIScope Scope) {
-  if (Scope.isType()) {
-    DIType Ty(Scope);
-    processType(Ty);
-    return;
-  }
-  if (Scope.isCompileUnit()) {
-    addCompileUnit(DICompileUnit(Scope));
-    return;
-  }
-  if (Scope.isSubprogram()) {
-    processSubprogram(DISubprogram(Scope));
-    return;
-  }
-  if (!addScope(Scope))
-    return;
-  if (Scope.isLexicalBlock()) {
-    DILexicalBlock LB(Scope);
-    processScope(LB.getContext());
-  } else if (Scope.isLexicalBlockFile()) {
-    DILexicalBlockFile LBF = DILexicalBlockFile(Scope);
-    processScope(LBF.getScope());
-  } else if (Scope.isNameSpace()) {
-    DINameSpace NS(Scope);
-    processScope(NS.getContext());
-  }
-}
-
-/// processLexicalBlock
-void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) {
-  DIScope Context = LB.getContext();
-  if (Context.isLexicalBlock())
-    return processLexicalBlock(DILexicalBlock(Context));
-  else if (Context.isLexicalBlockFile()) {
-    DILexicalBlockFile DBF = DILexicalBlockFile(Context);
-    return processLexicalBlock(DILexicalBlock(DBF.getScope()));
-  }
-  else
-    return processSubprogram(DISubprogram(Context));
-}
-
-/// processSubprogram - Process DISubprogram.
-void DebugInfoFinder::processSubprogram(DISubprogram SP) {
-  if (!addSubprogram(SP))
-    return;
-  processScope(SP.getContext().resolve(TypeIdentifierMap));
-  processType(SP.getType());
-  DIArray TParams = SP.getTemplateParams();
-  for (unsigned I = 0, E = TParams.getNumElements(); I != E; ++I) {
-    DIDescriptor Element = TParams.getElement(I);
-    if (Element.isTemplateTypeParameter()) {
-      DITemplateTypeParameter TType(Element);
-      processScope(TType.getContext().resolve(TypeIdentifierMap));
-      processType(TType.getType().resolve(TypeIdentifierMap));
-    } else if (Element.isTemplateValueParameter()) {
-      DITemplateValueParameter TVal(Element);
-      processScope(TVal.getContext().resolve(TypeIdentifierMap));
-      processType(TVal.getType().resolve(TypeIdentifierMap));
-    }
-  }
-}
-
-/// processDeclare - Process DbgDeclareInst.
-void DebugInfoFinder::processDeclare(const DbgDeclareInst *DDI) {
-  MDNode *N = dyn_cast<MDNode>(DDI->getVariable());
-  if (!N) return;
-
-  DIDescriptor DV(N);
-  if (!DV.isVariable())
-    return;
-
-  if (!NodesSeen.insert(DV))
-    return;
-  processScope(DIVariable(N).getContext());
-  processType(DIVariable(N).getType());
-}
-
-void DebugInfoFinder::processValue(const DbgValueInst *DVI) {
-  MDNode *N = dyn_cast<MDNode>(DVI->getVariable());
-  if (!N) return;
-
-  DIDescriptor DV(N);
-  if (!DV.isVariable())
-    return;
-
-  if (!NodesSeen.insert(DV))
-    return;
-  processScope(DIVariable(N).getContext());
-  processType(DIVariable(N).getType());
-}
-
-/// addType - Add type into Tys.
-bool DebugInfoFinder::addType(DIType DT) {
-  if (!DT)
-    return false;
-
-  if (!NodesSeen.insert(DT))
-    return false;
-
-  TYs.push_back(DT);
-  return true;
-}
-
-/// addCompileUnit - Add compile unit into CUs.
-bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) {
-  if (!CU)
-    return false;
-  if (!NodesSeen.insert(CU))
-    return false;
-
-  CUs.push_back(CU);
-  return true;
-}
-
-/// addGlobalVariable - Add global variable into GVs.
-bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) {
-  if (!DIG)
-    return false;
-
-  if (!NodesSeen.insert(DIG))
-    return false;
-
-  GVs.push_back(DIG);
-  return true;
-}
-
-// addSubprogram - Add subprgoram into SPs.
-bool DebugInfoFinder::addSubprogram(DISubprogram SP) {
-  if (!SP)
-    return false;
-
-  if (!NodesSeen.insert(SP))
-    return false;
-
-  SPs.push_back(SP);
-  return true;
-}
-
-bool DebugInfoFinder::addScope(DIScope Scope) {
-  if (!Scope)
-    return false;
-  // FIXME: Ocaml binding generates a scope with no content, we treat it
-  // as null for now.
-  if (Scope->getNumOperands() == 0)
-    return false;
-  if (!NodesSeen.insert(Scope))
-    return false;
-  Scopes.push_back(Scope);
-  return true;
-}
-
-//===----------------------------------------------------------------------===//
-// DIDescriptor: dump routines for all descriptors.
-//===----------------------------------------------------------------------===//
-
-/// dump - Print descriptor to dbgs() with a newline.
-void DIDescriptor::dump() const {
-  print(dbgs()); dbgs() << '\n';
-}
-
-/// print - Print descriptor.
-void DIDescriptor::print(raw_ostream &OS) const {
-  if (!DbgNode) return;
-
-  if (const char *Tag = dwarf::TagString(getTag()))
-    OS << "[ " << Tag << " ]";
-
-  if (this->isSubrange()) {
-    DISubrange(DbgNode).printInternal(OS);
-  } else if (this->isCompileUnit()) {
-    DICompileUnit(DbgNode).printInternal(OS);
-  } else if (this->isFile()) {
-    DIFile(DbgNode).printInternal(OS);
-  } else if (this->isEnumerator()) {
-    DIEnumerator(DbgNode).printInternal(OS);
-  } else if (this->isBasicType()) {
-    DIType(DbgNode).printInternal(OS);
-  } else if (this->isDerivedType()) {
-    DIDerivedType(DbgNode).printInternal(OS);
-  } else if (this->isCompositeType()) {
-    DICompositeType(DbgNode).printInternal(OS);
-  } else if (this->isSubprogram()) {
-    DISubprogram(DbgNode).printInternal(OS);
-  } else if (this->isGlobalVariable()) {
-    DIGlobalVariable(DbgNode).printInternal(OS);
-  } else if (this->isVariable()) {
-    DIVariable(DbgNode).printInternal(OS);
-  } else if (this->isObjCProperty()) {
-    DIObjCProperty(DbgNode).printInternal(OS);
-  } else if (this->isNameSpace()) {
-    DINameSpace(DbgNode).printInternal(OS);
-  } else if (this->isScope()) {
-    DIScope(DbgNode).printInternal(OS);
-  }
-}
-
-void DISubrange::printInternal(raw_ostream &OS) const {
-  int64_t Count = getCount();
-  if (Count != -1)
-    OS << " [" << getLo() << ", " << Count - 1 << ']';
-  else
-    OS << " [unbounded]";
-}
-
-void DIScope::printInternal(raw_ostream &OS) const {
-  OS << " [" << getDirectory() << "/" << getFilename() << ']';
-}
-
-void DICompileUnit::printInternal(raw_ostream &OS) const {
-  DIScope::printInternal(OS);
-  OS << " [";
-  unsigned Lang = getLanguage();
-  if (const char *LangStr = dwarf::LanguageString(Lang))
-    OS << LangStr;
-  else
-    (OS << "lang 0x").write_hex(Lang);
-  OS << ']';
-}
-
-void DIEnumerator::printInternal(raw_ostream &OS) const {
-  OS << " [" << getName() << " :: " << getEnumValue() << ']';
-}
-
-void DIType::printInternal(raw_ostream &OS) const {
-  if (!DbgNode) return;
-
-  StringRef Res = getName();
-  if (!Res.empty())
-    OS << " [" << Res << "]";
-
-  // TODO: Print context?
-
-  OS << " [line " << getLineNumber()
-     << ", size " << getSizeInBits()
-     << ", align " << getAlignInBits()
-     << ", offset " << getOffsetInBits();
-  if (isBasicType())
-    if (const char *Enc =
-        dwarf::AttributeEncodingString(DIBasicType(DbgNode).getEncoding()))
-      OS << ", enc " << Enc;
-  OS << "]";
-
-  if (isPrivate())
-    OS << " [private]";
-  else if (isProtected())
-    OS << " [protected]";
-
-  if (isArtificial())
-    OS << " [artificial]";
-
-  if (isForwardDecl())
-    OS << " [decl]";
-  else if (getTag() == dwarf::DW_TAG_structure_type ||
-           getTag() == dwarf::DW_TAG_union_type ||
-           getTag() == dwarf::DW_TAG_enumeration_type ||
-           getTag() == dwarf::DW_TAG_class_type)
-    OS << " [def]";
-  if (isVector())
-    OS << " [vector]";
-  if (isStaticMember())
-    OS << " [static]";
-}
-
-void DIDerivedType::printInternal(raw_ostream &OS) const {
-  DIType::printInternal(OS);
-  OS << " [from " << getTypeDerivedFrom().getName() << ']';
-}
-
-void DICompositeType::printInternal(raw_ostream &OS) const {
-  DIType::printInternal(OS);
-  DIArray A = getTypeArray();
-  OS << " [" << A.getNumElements() << " elements]";
-}
-
-void DINameSpace::printInternal(raw_ostream &OS) const {
-  StringRef Name = getName();
-  if (!Name.empty())
-    OS << " [" << Name << ']';
-
-  OS << " [line " << getLineNumber() << ']';
-}
-
-void DISubprogram::printInternal(raw_ostream &OS) const {
-  // TODO : Print context
-  OS << " [line " << getLineNumber() << ']';
-
-  if (isLocalToUnit())
-    OS << " [local]";
-
-  if (isDefinition())
-    OS << " [def]";
-
-  if (getScopeLineNumber() != getLineNumber())
-    OS << " [scope " << getScopeLineNumber() << "]";
-
-  if (isPrivate())
-    OS << " [private]";
-  else if (isProtected())
-    OS << " [protected]";
-
-  StringRef Res = getName();
-  if (!Res.empty())
-    OS << " [" << Res << ']';
-}
-
-void DIGlobalVariable::printInternal(raw_ostream &OS) const {
-  StringRef Res = getName();
-  if (!Res.empty())
-    OS << " [" << Res << ']';
-
-  OS << " [line " << getLineNumber() << ']';
-
-  // TODO : Print context
-
-  if (isLocalToUnit())
-    OS << " [local]";
-
-  if (isDefinition())
-    OS << " [def]";
-}
-
-void DIVariable::printInternal(raw_ostream &OS) const {
-  StringRef Res = getName();
-  if (!Res.empty())
-    OS << " [" << Res << ']';
-
-  OS << " [line " << getLineNumber() << ']';
-}
-
-void DIObjCProperty::printInternal(raw_ostream &OS) const {
-  StringRef Name = getObjCPropertyName();
-  if (!Name.empty())
-    OS << " [" << Name << ']';
-
-  OS << " [line " << getLineNumber()
-     << ", properties " << getUnsignedField(6) << ']';
-}
-
-static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS,
-                          const LLVMContext &Ctx) {
-  if (!DL.isUnknown()) {          // Print source line info.
-    DIScope Scope(DL.getScope(Ctx));
-    assert(Scope.isScope() &&
-      "Scope of a DebugLoc should be a DIScope.");
-    // Omit the directory, because it's likely to be long and uninteresting.
-    CommentOS << Scope.getFilename();
-    CommentOS << ':' << DL.getLine();
-    if (DL.getCol() != 0)
-      CommentOS << ':' << DL.getCol();
-    DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx));
-    if (!InlinedAtDL.isUnknown()) {
-      CommentOS << " @[ ";
-      printDebugLoc(InlinedAtDL, CommentOS, Ctx);
-      CommentOS << " ]";
-    }
-  }
-}
-
-void DIVariable::printExtendedName(raw_ostream &OS) const {
-  const LLVMContext &Ctx = DbgNode->getContext();
-  StringRef Res = getName();
-  if (!Res.empty())
-    OS << Res << "," << getLineNumber();
-  if (MDNode *InlinedAt = getInlinedAt()) {
-    DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt);
-    if (!InlinedAtDL.isUnknown()) {
-      OS << " @[";
-      printDebugLoc(InlinedAtDL, OS, Ctx);
-      OS << "]";
-    }
-  }
-}
-
-/// Specialize constructor to make sure it has the correct type.
-template <>
-DIRef<DIScope>::DIRef(const Value *V) : Val(V) {
-  assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode");
-}
-template <>
-DIRef<DIType>::DIRef(const Value *V) : Val(V) {
-  assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode");
-}
-
-/// Specialize getFieldAs to handle fields that are references to DIScopes.
-template <>
-DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const {
-  return DIScopeRef(getField(DbgNode, Elt));
-}
-/// Specialize getFieldAs to handle fields that are references to DITypes.
-template <>
-DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const {
-  return DITypeRef(getField(DbgNode, Elt));
-}
+//===--- DebugInfo.cpp - Debug Information Helper Classes -----------------===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+// This file implements the helper classes used to build and interpret debug

+// information in LLVM IR form.

+//

+//===----------------------------------------------------------------------===//

+

+#include "llvm/DebugInfo.h"

+#include "llvm/ADT/STLExtras.h"

+#include "llvm/ADT/SmallPtrSet.h"

+#include "llvm/ADT/SmallString.h"

+#include "llvm/Analysis/ValueTracking.h"

+#include "llvm/IR/Constants.h"

+#include "llvm/IR/DerivedTypes.h"

+#include "llvm/IR/Instructions.h"

+#include "llvm/IR/IntrinsicInst.h"

+#include "llvm/IR/Intrinsics.h"

+#include "llvm/IR/Module.h"

+#include "llvm/Support/Debug.h"

+#include "llvm/Support/Dwarf.h"

+#include "llvm/Support/ValueHandle.h"

+#include "llvm/Support/raw_ostream.h"

+using namespace llvm;

+using namespace llvm::dwarf;

+

+//===----------------------------------------------------------------------===//

+// DIDescriptor

+//===----------------------------------------------------------------------===//

+

+bool DIDescriptor::Verify() const {

+  return DbgNode &&

+         (DIDerivedType(DbgNode).Verify() ||

+          DICompositeType(DbgNode).Verify() || DIBasicType(DbgNode).Verify() ||

+          DIVariable(DbgNode).Verify() || DISubprogram(DbgNode).Verify() ||

+          DIGlobalVariable(DbgNode).Verify() || DIFile(DbgNode).Verify() ||

+          DICompileUnit(DbgNode).Verify() || DINameSpace(DbgNode).Verify() ||

+          DILexicalBlock(DbgNode).Verify() ||

+          DILexicalBlockFile(DbgNode).Verify() ||

+          DISubrange(DbgNode).Verify() || DIEnumerator(DbgNode).Verify() ||

+          DIObjCProperty(DbgNode).Verify() ||

+          DITemplateTypeParameter(DbgNode).Verify() ||

+          DITemplateValueParameter(DbgNode).Verify() ||

+          DIImportedEntity(DbgNode).Verify());

+}

+

+static Value *getField(const MDNode *DbgNode, unsigned Elt) {

+  if (DbgNode == 0 || Elt >= DbgNode->getNumOperands())

+    return 0;

+  return DbgNode->getOperand(Elt);

+}

+

+static MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) {

+  return dyn_cast_or_null<MDNode>(getField(DbgNode, Elt));

+}

+

+static StringRef getStringField(const MDNode *DbgNode, unsigned Elt) {

+  if (MDString *MDS = dyn_cast_or_null<MDString>(getField(DbgNode, Elt)))

+    return MDS->getString();

+  return StringRef();

+}

+

+StringRef DIDescriptor::getStringField(unsigned Elt) const {

+  return ::getStringField(DbgNode, Elt);

+}

+

+uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const {

+  if (DbgNode == 0)

+    return 0;

+

+  if (Elt < DbgNode->getNumOperands())

+    if (ConstantInt *CI

+        = dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt)))

+      return CI->getZExtValue();

+

+  return 0;

+}

+

+int64_t DIDescriptor::getInt64Field(unsigned Elt) const {

+  if (DbgNode == 0)

+    return 0;

+

+  if (Elt < DbgNode->getNumOperands())

+    if (ConstantInt *CI

+        = dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(Elt)))

+      return CI->getSExtValue();

+

+  return 0;

+}

+

+DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const {

+  MDNode *Field = getNodeField(DbgNode, Elt);

+  return DIDescriptor(Field);

+}

+

+GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const {

+  if (DbgNode == 0)

+    return 0;

+

+  if (Elt < DbgNode->getNumOperands())

+      return dyn_cast_or_null<GlobalVariable>(DbgNode->getOperand(Elt));

+  return 0;

+}

+

+Constant *DIDescriptor::getConstantField(unsigned Elt) const {

+  if (DbgNode == 0)

+    return 0;

+

+  if (Elt < DbgNode->getNumOperands())

+      return dyn_cast_or_null<Constant>(DbgNode->getOperand(Elt));

+  return 0;

+}

+

+Function *DIDescriptor::getFunctionField(unsigned Elt) const {

+  if (DbgNode == 0)

+    return 0;

+

+  if (Elt < DbgNode->getNumOperands())

+      return dyn_cast_or_null<Function>(DbgNode->getOperand(Elt));

+  return 0;

+}

+

+void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) {

+  if (DbgNode == 0)

+    return;

+

+  if (Elt < DbgNode->getNumOperands()) {

+    MDNode *Node = const_cast<MDNode*>(DbgNode);

+    Node->replaceOperandWith(Elt, F);

+  }

+}

+

+unsigned DIVariable::getNumAddrElements() const {

+  return DbgNode->getNumOperands()-8;

+}

+

+/// getInlinedAt - If this variable is inlined then return inline location.

+MDNode *DIVariable::getInlinedAt() const {

+  return getNodeField(DbgNode, 7);

+}

+

+//===----------------------------------------------------------------------===//

+// Predicates

+//===----------------------------------------------------------------------===//

+

+/// isBasicType - Return true if the specified tag is legal for

+/// DIBasicType.

+bool DIDescriptor::isBasicType() const {

+  if (!DbgNode) return false;

+  switch (getTag()) {

+  case dwarf::DW_TAG_base_type:

+  case dwarf::DW_TAG_unspecified_type:

+    return true;

+  default:

+    return false;

+  }

+}

+

+/// isDerivedType - Return true if the specified tag is legal for DIDerivedType.

+bool DIDescriptor::isDerivedType() const {

+  if (!DbgNode) return false;

+  switch (getTag()) {

+  case dwarf::DW_TAG_typedef:

+  case dwarf::DW_TAG_pointer_type:

+  case dwarf::DW_TAG_ptr_to_member_type:

+  case dwarf::DW_TAG_reference_type:

+  case dwarf::DW_TAG_rvalue_reference_type:

+  case dwarf::DW_TAG_const_type:

+  case dwarf::DW_TAG_volatile_type:

+  case dwarf::DW_TAG_restrict_type:

+  case dwarf::DW_TAG_member:

+  case dwarf::DW_TAG_inheritance:

+  case dwarf::DW_TAG_friend:

+    return true;

+  default:

+    // CompositeTypes are currently modelled as DerivedTypes.

+    return isCompositeType();

+  }

+}

+

+/// isCompositeType - Return true if the specified tag is legal for

+/// DICompositeType.

+bool DIDescriptor::isCompositeType() const {

+  if (!DbgNode) return false;

+  switch (getTag()) {

+  case dwarf::DW_TAG_array_type:

+  case dwarf::DW_TAG_structure_type:

+  case dwarf::DW_TAG_union_type:

+  case dwarf::DW_TAG_enumeration_type:

+  case dwarf::DW_TAG_subroutine_type:

+  case dwarf::DW_TAG_class_type:

+    return true;

+  default:

+    return false;

+  }

+}

+

+/// isVariable - Return true if the specified tag is legal for DIVariable.

+bool DIDescriptor::isVariable() const {

+  if (!DbgNode) return false;

+  switch (getTag()) {

+  case dwarf::DW_TAG_auto_variable:

+  case dwarf::DW_TAG_arg_variable:

+    return true;

+  default:

+    return false;

+  }

+}

+

+/// isType - Return true if the specified tag is legal for DIType.

+bool DIDescriptor::isType() const {

+  return isBasicType() || isCompositeType() || isDerivedType();

+}

+

+/// isSubprogram - Return true if the specified tag is legal for

+/// DISubprogram.

+bool DIDescriptor::isSubprogram() const {

+  return DbgNode && getTag() == dwarf::DW_TAG_subprogram;

+}

+

+/// isGlobalVariable - Return true if the specified tag is legal for

+/// DIGlobalVariable.

+bool DIDescriptor::isGlobalVariable() const {

+  return DbgNode && (getTag() == dwarf::DW_TAG_variable ||

+                     getTag() == dwarf::DW_TAG_constant);

+}

+

+/// isUnspecifiedParmeter - Return true if the specified tag is

+/// DW_TAG_unspecified_parameters.

+bool DIDescriptor::isUnspecifiedParameter() const {

+  return DbgNode && getTag() == dwarf::DW_TAG_unspecified_parameters;

+}

+

+/// isScope - Return true if the specified tag is one of the scope

+/// related tag.

+bool DIDescriptor::isScope() const {

+  if (!DbgNode) return false;

+  switch (getTag()) {

+  case dwarf::DW_TAG_compile_unit:

+  case dwarf::DW_TAG_lexical_block:

+  case dwarf::DW_TAG_subprogram:

+  case dwarf::DW_TAG_namespace:

+  case dwarf::DW_TAG_file_type:

+    return true;

+  default:

+    break;

+  }

+  return isType();

+}

+

+/// isTemplateTypeParameter - Return true if the specified tag is

+/// DW_TAG_template_type_parameter.

+bool DIDescriptor::isTemplateTypeParameter() const {

+  return DbgNode && getTag() == dwarf::DW_TAG_template_type_parameter;

+}

+

+/// isTemplateValueParameter - Return true if the specified tag is

+/// DW_TAG_template_value_parameter.

+bool DIDescriptor::isTemplateValueParameter() const {

+  return DbgNode && (getTag() == dwarf::DW_TAG_template_value_parameter ||

+                     getTag() == dwarf::DW_TAG_GNU_template_template_param ||

+                     getTag() == dwarf::DW_TAG_GNU_template_parameter_pack);

+}

+

+/// isCompileUnit - Return true if the specified tag is DW_TAG_compile_unit.

+bool DIDescriptor::isCompileUnit() const {

+  return DbgNode && getTag() == dwarf::DW_TAG_compile_unit;

+}

+

+/// isFile - Return true if the specified tag is DW_TAG_file_type.

+bool DIDescriptor::isFile() const {

+  return DbgNode && getTag() == dwarf::DW_TAG_file_type;

+}

+

+/// isNameSpace - Return true if the specified tag is DW_TAG_namespace.

+bool DIDescriptor::isNameSpace() const {

+  return DbgNode && getTag() == dwarf::DW_TAG_namespace;

+}

+

+/// isLexicalBlockFile - Return true if the specified descriptor is a

+/// lexical block with an extra file.

+bool DIDescriptor::isLexicalBlockFile() const {

+  return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&

+    (DbgNode->getNumOperands() == 3);

+}

+

+/// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block.

+bool DIDescriptor::isLexicalBlock() const {

+  return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&

+    (DbgNode->getNumOperands() > 3);

+}

+

+/// isSubrange - Return true if the specified tag is DW_TAG_subrange_type.

+bool DIDescriptor::isSubrange() const {

+  return DbgNode && getTag() == dwarf::DW_TAG_subrange_type;

+}

+

+/// isEnumerator - Return true if the specified tag is DW_TAG_enumerator.

+bool DIDescriptor::isEnumerator() const {

+  return DbgNode && getTag() == dwarf::DW_TAG_enumerator;

+}

+

+/// isObjCProperty - Return true if the specified tag is DW_TAG_APPLE_property.

+bool DIDescriptor::isObjCProperty() const {

+  return DbgNode && getTag() == dwarf::DW_TAG_APPLE_property;

+}

+

+/// \brief Return true if the specified tag is DW_TAG_imported_module or

+/// DW_TAG_imported_declaration.

+bool DIDescriptor::isImportedEntity() const {

+  return DbgNode && (getTag() == dwarf::DW_TAG_imported_module ||

+                     getTag() == dwarf::DW_TAG_imported_declaration);

+}

+

+//===----------------------------------------------------------------------===//

+// Simple Descriptor Constructors and other Methods

+//===----------------------------------------------------------------------===//

+

+unsigned DIArray::getNumElements() const {

+  if (!DbgNode)

+    return 0;

+  return DbgNode->getNumOperands();

+}

+

+/// replaceAllUsesWith - Replace all uses of the MDNode used by this

+/// type with the one in the passed descriptor.

+void DIType::replaceAllUsesWith(DIDescriptor &D) {

+

+  assert(DbgNode && "Trying to replace an unverified type!");

+

+  // Since we use a TrackingVH for the node, its easy for clients to manufacture

+  // legitimate situations where they want to replaceAllUsesWith() on something

+  // which, due to uniquing, has merged with the source. We shield clients from

+  // this detail by allowing a value to be replaced with replaceAllUsesWith()

+  // itself.

+  if (DbgNode != D) {

+    MDNode *Node = const_cast<MDNode*>(DbgNode);

+    const MDNode *DN = D;

+    const Value *V = cast_or_null<Value>(DN);

+    Node->replaceAllUsesWith(const_cast<Value*>(V));

+    MDNode::deleteTemporary(Node);

+  }

+}

+

+/// replaceAllUsesWith - Replace all uses of the MDNode used by this

+/// type with the one in D.

+void DIType::replaceAllUsesWith(MDNode *D) {

+

+  assert(DbgNode && "Trying to replace an unverified type!");

+

+  // Since we use a TrackingVH for the node, its easy for clients to manufacture

+  // legitimate situations where they want to replaceAllUsesWith() on something

+  // which, due to uniquing, has merged with the source. We shield clients from

+  // this detail by allowing a value to be replaced with replaceAllUsesWith()

+  // itself.

+  if (DbgNode != D) {

+    MDNode *Node = const_cast<MDNode*>(DbgNode);

+    const MDNode *DN = D;

+    const Value *V = cast_or_null<Value>(DN);

+    Node->replaceAllUsesWith(const_cast<Value*>(V));

+    MDNode::deleteTemporary(Node);

+  }

+}

+

+/// Verify - Verify that a compile unit is well formed.

+bool DICompileUnit::Verify() const {

+  if (!isCompileUnit())

+    return false;

+

+  // Don't bother verifying the compilation directory or producer string

+  // as those could be empty.

+  if (getFilename().empty())

+    return false;

+

+  return DbgNode->getNumOperands() == 13;

+}

+

+/// Verify - Verify that an ObjC property is well formed.

+bool DIObjCProperty::Verify() const {

+  if (!isObjCProperty())

+    return false;

+

+  // Don't worry about the rest of the strings for now.

+  return DbgNode->getNumOperands() == 8;

+}

+

+/// Check if a field at position Elt of a MDNode is a MDNode.

+/// We currently allow an empty string and an integer.

+/// But we don't allow a non-empty string in a MDNode field.

+static bool fieldIsMDNode(const MDNode *DbgNode, unsigned Elt) {

+  // FIXME: This function should return true, if the field is null or the field

+  // is indeed a MDNode: return !Fld || isa<MDNode>(Fld).

+  Value *Fld = getField(DbgNode, Elt);

+  if (Fld && isa<MDString>(Fld) &&

+      !cast<MDString>(Fld)->getString().empty())

+    return false;

+  return true;

+}

+

+/// Check if a field at position Elt of a MDNode is a MDString.

+static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) {

+  Value *Fld = getField(DbgNode, Elt);

+  return !Fld || isa<MDString>(Fld);

+}

+

+/// Check if a value can be a reference to a type.

+static bool isTypeRef(const Value *Val) {

+  return !Val ||

+         (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||

+         (isa<MDNode>(Val) && DIType(cast<MDNode>(Val)).isType());

+}

+

+/// Check if a field at position Elt of a MDNode can be a reference to a type.

+static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) {

+  Value *Fld = getField(DbgNode, Elt);

+  return isTypeRef(Fld);

+}

+

+/// Check if a value can be a ScopeRef.

+static bool isScopeRef(const Value *Val) {

+  return !Val ||

+         (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||

+         (isa<MDNode>(Val) && DIScope(cast<MDNode>(Val)).isScope());

+}

+

+/// Check if a field at position Elt of a MDNode can be a ScopeRef.

+static bool fieldIsScopeRef(const MDNode *DbgNode, unsigned Elt) {

+  Value *Fld = getField(DbgNode, Elt);

+  return isScopeRef(Fld);

+}

+

+/// Verify - Verify that a type descriptor is well formed.

+bool DIType::Verify() const {

+  if (!isType())

+    return false;

+  // Make sure Context @ field 2 is MDNode.

+  if (!fieldIsScopeRef(DbgNode, 2))

+    return false;

+

+  // FIXME: Sink this into the various subclass verifies.

+  uint16_t Tag = getTag();

+  if (!isBasicType() && Tag != dwarf::DW_TAG_const_type &&

+      Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_pointer_type &&

+      Tag != dwarf::DW_TAG_ptr_to_member_type &&

+      Tag != dwarf::DW_TAG_reference_type &&

+      Tag != dwarf::DW_TAG_rvalue_reference_type &&

+      Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_array_type &&

+      Tag != dwarf::DW_TAG_enumeration_type &&

+      Tag != dwarf::DW_TAG_subroutine_type &&

+      Tag != dwarf::DW_TAG_inheritance && Tag != dwarf::DW_TAG_friend &&

+      getFilename().empty())

+    return false;

+  // DIType is abstract, it should be a BasicType, a DerivedType or

+  // a CompositeType.

+  if (isBasicType())

+    DIBasicType(DbgNode).Verify();

+  else if (isCompositeType())

+    DICompositeType(DbgNode).Verify();

+  else if (isDerivedType())

+    DIDerivedType(DbgNode).Verify();

+  else

+    return false;

+  return true;

+}

+

+/// Verify - Verify that a basic type descriptor is well formed.

+bool DIBasicType::Verify() const {

+  return isBasicType() && DbgNode->getNumOperands() == 10;

+}

+

+/// Verify - Verify that a derived type descriptor is well formed.

+bool DIDerivedType::Verify() const {

+  // Make sure DerivedFrom @ field 9 is TypeRef.

+  if (!fieldIsTypeRef(DbgNode, 9))

+    return false;

+  if (getTag() == dwarf::DW_TAG_ptr_to_member_type)

+    // Make sure ClassType @ field 10 is a TypeRef.

+    if (!fieldIsTypeRef(DbgNode, 10))

+      return false;

+

+  return isDerivedType() && DbgNode->getNumOperands() >= 10 &&

+         DbgNode->getNumOperands() <= 14;

+}

+

+/// Verify - Verify that a composite type descriptor is well formed.

+bool DICompositeType::Verify() const {

+  if (!isCompositeType())

+    return false;

+

+  // Make sure DerivedFrom @ field 9 and ContainingType @ field 12 are TypeRef.

+  if (!fieldIsTypeRef(DbgNode, 9))

+    return false;

+  if (!fieldIsTypeRef(DbgNode, 12))

+    return false;

+

+  // Make sure the type identifier at field 14 is MDString, it can be null.

+  if (!fieldIsMDString(DbgNode, 14))

+    return false;

+

+  return DbgNode->getNumOperands() == 15;

+}

+

+/// Verify - Verify that a subprogram descriptor is well formed.

+bool DISubprogram::Verify() const {

+  if (!isSubprogram())

+    return false;

+

+  // Make sure context @ field 2 is a ScopeRef and type @ field 7 is a MDNode.

+  if (!fieldIsScopeRef(DbgNode, 2))

+    return false;

+  if (!fieldIsMDNode(DbgNode, 7))

+    return false;

+  // Containing type @ field 12.

+  if (!fieldIsTypeRef(DbgNode, 12))

+    return false;

+  return DbgNode->getNumOperands() == 20;

+}

+

+/// Verify - Verify that a global variable descriptor is well formed.

+bool DIGlobalVariable::Verify() const {

+  if (!isGlobalVariable())

+    return false;

+

+  if (getDisplayName().empty())

+    return false;

+  // Make sure context @ field 2 and type @ field 8 are MDNodes.

+  if (!fieldIsMDNode(DbgNode, 2))

+    return false;

+  if (!fieldIsMDNode(DbgNode, 8))

+    return false;

+  // Make sure StaticDataMemberDeclaration @ field 12 is MDNode.

+  if (!fieldIsMDNode(DbgNode, 12))

+    return false;

+

+  return DbgNode->getNumOperands() == 13;

+}

+

+/// Verify - Verify that a variable descriptor is well formed.

+bool DIVariable::Verify() const {

+  if (!isVariable())

+    return false;

+

+  // Make sure context @ field 1 and type @ field 5 are MDNodes.

+  if (!fieldIsMDNode(DbgNode, 1))

+    return false;

+  if (!fieldIsMDNode(DbgNode, 5))

+    return false;

+  return DbgNode->getNumOperands() >= 8;

+}

+

+/// Verify - Verify that a location descriptor is well formed.

+bool DILocation::Verify() const {

+  if (!DbgNode)

+    return false;

+

+  return DbgNode->getNumOperands() == 4;

+}

+

+/// Verify - Verify that a namespace descriptor is well formed.

+bool DINameSpace::Verify() const {

+  if (!isNameSpace())

+    return false;

+  return DbgNode->getNumOperands() == 5;

+}

+

+/// \brief Retrieve the MDNode for the directory/file pair.

+MDNode *DIFile::getFileNode() const {

+  return getNodeField(DbgNode, 1);

+}

+

+/// \brief Verify that the file descriptor is well formed.

+bool DIFile::Verify() const {

+  return isFile() && DbgNode->getNumOperands() == 2;

+}

+

+/// \brief Verify that the enumerator descriptor is well formed.

+bool DIEnumerator::Verify() const {

+  return isEnumerator() && DbgNode->getNumOperands() == 3;

+}

+

+/// \brief Verify that the subrange descriptor is well formed.

+bool DISubrange::Verify() const {

+  return isSubrange() && DbgNode->getNumOperands() == 3;

+}

+

+/// \brief Verify that the lexical block descriptor is well formed.

+bool DILexicalBlock::Verify() const {

+  return isLexicalBlock() && DbgNode->getNumOperands() == 6;

+}

+

+/// \brief Verify that the file-scoped lexical block descriptor is well formed.

+bool DILexicalBlockFile::Verify() const {

+  return isLexicalBlockFile() && DbgNode->getNumOperands() == 3;

+}

+

+/// \brief Verify that the template type parameter descriptor is well formed.

+bool DITemplateTypeParameter::Verify() const {

+  return isTemplateTypeParameter() && DbgNode->getNumOperands() == 7;

+}

+

+/// \brief Verify that the template value parameter descriptor is well formed.

+bool DITemplateValueParameter::Verify() const {

+  return isTemplateValueParameter() && DbgNode->getNumOperands() == 8;

+}

+

+/// \brief Verify that the imported module descriptor is well formed.

+bool DIImportedEntity::Verify() const {

+  return isImportedEntity() &&

+         (DbgNode->getNumOperands() == 4 || DbgNode->getNumOperands() == 5);

+}

+

+/// getObjCProperty - Return property node, if this ivar is associated with one.

+MDNode *DIDerivedType::getObjCProperty() const {

+  return getNodeField(DbgNode, 10);

+}

+

+MDString *DICompositeType::getIdentifier() const {

+  return cast_or_null<MDString>(getField(DbgNode, 14));

+}

+

+#ifndef NDEBUG

+static void VerifySubsetOf(const MDNode *LHS, const MDNode *RHS) {

+  for (unsigned i = 0; i != LHS->getNumOperands(); ++i) {

+    // Skip the 'empty' list (that's a single i32 0, rather than truly empty).

+    if (i == 0 && isa<ConstantInt>(LHS->getOperand(i)))

+      continue;

+    const MDNode *E = cast<MDNode>(LHS->getOperand(i));

+    bool found = false;

+    for (unsigned j = 0; !found && j != RHS->getNumOperands(); ++j)

+      found = E == RHS->getOperand(j);

+    assert(found && "Losing a member during member list replacement");

+  }

+}

+#endif

+

+/// \brief Set the array of member DITypes.

+void DICompositeType::setTypeArray(DIArray Elements, DIArray TParams) {

+  assert((!TParams || DbgNode->getNumOperands() == 15) &&

+         "If you're setting the template parameters this should include a slot "

+         "for that!");

+  TrackingVH<MDNode> N(*this);

+  if (Elements) {

+#ifndef NDEBUG

+    // Check that the new list of members contains all the old members as well.

+    if (const MDNode *El = cast_or_null<MDNode>(N->getOperand(10)))

+      VerifySubsetOf(El, Elements);

+#endif

+    N->replaceOperandWith(10, Elements);

+  }

+  if (TParams)

+    N->replaceOperandWith(13, TParams);

+  DbgNode = N;

+}

+

+void DICompositeType::addMember(DIDescriptor D) {

+  SmallVector<llvm::Value *, 16> M;

+  DIArray OrigM = getTypeArray();

+  unsigned Elements = OrigM.getNumElements();

+  if (Elements == 1 && !OrigM.getElement(0))

+    Elements = 0;

+  M.reserve(Elements + 1);

+  for (unsigned i = 0; i != Elements; ++i)

+    M.push_back(OrigM.getElement(i));

+  M.push_back(D);

+  setTypeArray(DIArray(MDNode::get(DbgNode->getContext(), M)));

+}

+

+/// Generate a reference to this DIType. Uses the type identifier instead

+/// of the actual MDNode if possible, to help type uniquing.

+DIScopeRef DIScope::getRef() const {

+  if (!isCompositeType())

+    return DIScopeRef(*this);

+  DICompositeType DTy(DbgNode);

+  if (!DTy.getIdentifier())

+    return DIScopeRef(*this);

+  return DIScopeRef(DTy.getIdentifier());

+}

+

+/// \brief Set the containing type.

+void DICompositeType::setContainingType(DICompositeType ContainingType) {

+  TrackingVH<MDNode> N(*this);

+  N->replaceOperandWith(12, ContainingType.getRef());

+  DbgNode = N;

+}

+

+/// isInlinedFnArgument - Return true if this variable provides debugging

+/// information for an inlined function arguments.

+bool DIVariable::isInlinedFnArgument(const Function *CurFn) {

+  assert(CurFn && "Invalid function");

+  if (!getContext().isSubprogram())

+    return false;

+  // This variable is not inlined function argument if its scope

+  // does not describe current function.

+  return !DISubprogram(getContext()).describes(CurFn);

+}

+

+/// describes - Return true if this subprogram provides debugging

+/// information for the function F.

+bool DISubprogram::describes(const Function *F) {

+  assert(F && "Invalid function");

+  if (F == getFunction())

+    return true;

+  StringRef Name = getLinkageName();

+  if (Name.empty())

+    Name = getName();

+  if (F->getName() == Name)

+    return true;

+  return false;

+}

+

+unsigned DISubprogram::isOptimized() const {

+  assert (DbgNode && "Invalid subprogram descriptor!");

+  if (DbgNode->getNumOperands() == 15)

+    return getUnsignedField(14);

+  return 0;

+}

+

+MDNode *DISubprogram::getVariablesNodes() const {

+  return getNodeField(DbgNode, 18);

+}

+

+DIArray DISubprogram::getVariables() const {

+  return DIArray(getNodeField(DbgNode, 18));

+}

+

+Value *DITemplateValueParameter::getValue() const {

+  return getField(DbgNode, 4);

+}

+

+// If the current node has a parent scope then return that,

+// else return an empty scope.

+DIScopeRef DIScope::getContext() const {

+

+  if (isType())

+    return DIType(DbgNode).getContext();

+

+  if (isSubprogram())

+    return DIScopeRef(DISubprogram(DbgNode).getContext());

+

+  if (isLexicalBlock())

+    return DIScopeRef(DILexicalBlock(DbgNode).getContext());

+

+  if (isLexicalBlockFile())

+    return DIScopeRef(DILexicalBlockFile(DbgNode).getContext());

+

+  if (isNameSpace())

+    return DIScopeRef(DINameSpace(DbgNode).getContext());

+

+  assert((isFile() || isCompileUnit()) && "Unhandled type of scope.");

+  return DIScopeRef(NULL);

+}

+

+// If the scope node has a name, return that, else return an empty string.

+StringRef DIScope::getName() const {

+  if (isType())

+    return DIType(DbgNode).getName();

+  if (isSubprogram())

+    return DISubprogram(DbgNode).getName();

+  if (isNameSpace())

+    return DINameSpace(DbgNode).getName();

+  assert((isLexicalBlock() || isLexicalBlockFile() || isFile() ||

+          isCompileUnit()) && "Unhandled type of scope.");

+  return StringRef();

+}

+

+StringRef DIScope::getFilename() const {

+  if (!DbgNode)

+    return StringRef();

+  return ::getStringField(getNodeField(DbgNode, 1), 0);

+}

+

+StringRef DIScope::getDirectory() const {

+  if (!DbgNode)

+    return StringRef();

+  return ::getStringField(getNodeField(DbgNode, 1), 1);

+}

+

+DIArray DICompileUnit::getEnumTypes() const {

+  if (!DbgNode || DbgNode->getNumOperands() < 13)

+    return DIArray();

+

+  return DIArray(getNodeField(DbgNode, 7));

+}

+

+DIArray DICompileUnit::getRetainedTypes() const {

+  if (!DbgNode || DbgNode->getNumOperands() < 13)

+    return DIArray();

+

+  return DIArray(getNodeField(DbgNode, 8));

+}

+

+DIArray DICompileUnit::getSubprograms() const {

+  if (!DbgNode || DbgNode->getNumOperands() < 13)

+    return DIArray();

+

+  return DIArray(getNodeField(DbgNode, 9));

+}

+

+

+DIArray DICompileUnit::getGlobalVariables() const {

+  if (!DbgNode || DbgNode->getNumOperands() < 13)

+    return DIArray();

+

+  return DIArray(getNodeField(DbgNode, 10));

+}

+

+DIArray DICompileUnit::getImportedEntities() const {

+  if (!DbgNode || DbgNode->getNumOperands() < 13)

+    return DIArray();

+

+  return DIArray(getNodeField(DbgNode, 11));

+}

+

+/// fixupSubprogramName - Replace contains special characters used

+/// in a typical Objective-C names with '.' in a given string.

+static void fixupSubprogramName(DISubprogram Fn, SmallVectorImpl<char> &Out) {

+  StringRef FName =

+      Fn.getFunction() ? Fn.getFunction()->getName() : Fn.getName();

+  FName = Function::getRealLinkageName(FName);

+

+  StringRef Prefix("llvm.dbg.lv.");

+  Out.reserve(FName.size() + Prefix.size());

+  Out.append(Prefix.begin(), Prefix.end());

+

+  bool isObjCLike = false;

+  for (size_t i = 0, e = FName.size(); i < e; ++i) {

+    char C = FName[i];

+    if (C == '[')

+      isObjCLike = true;

+

+    if (isObjCLike && (C == '[' || C == ']' || C == ' ' || C == ':' ||

+                       C == '+' || C == '(' || C == ')'))

+      Out.push_back('.');

+    else

+      Out.push_back(C);

+  }

+}

+

+/// getFnSpecificMDNode - Return a NameMDNode, if available, that is

+/// suitable to hold function specific information.

+NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, DISubprogram Fn) {

+  SmallString<32> Name;

+  fixupSubprogramName(Fn, Name);

+  return M.getNamedMetadata(Name.str());

+}

+

+/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable

+/// to hold function specific information.

+NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, DISubprogram Fn) {

+  SmallString<32> Name;

+  fixupSubprogramName(Fn, Name);

+  return M.getOrInsertNamedMetadata(Name.str());

+}

+

+/// createInlinedVariable - Create a new inlined variable based on current

+/// variable.

+/// @param DV            Current Variable.

+/// @param InlinedScope  Location at current variable is inlined.

+DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope,

+                                       LLVMContext &VMContext) {

+  SmallVector<Value *, 16> Elts;

+  // Insert inlined scope as 7th element.

+  for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i)

+    i == 7 ? Elts.push_back(InlinedScope) :

+             Elts.push_back(DV->getOperand(i));

+  return DIVariable(MDNode::get(VMContext, Elts));

+}

+

+/// cleanseInlinedVariable - Remove inlined scope from the variable.

+DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) {

+  SmallVector<Value *, 16> Elts;

+  // Insert inlined scope as 7th element.

+  for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i)

+    i == 7 ?

+      Elts.push_back(Constant::getNullValue(Type::getInt32Ty(VMContext))):

+      Elts.push_back(DV->getOperand(i));

+  return DIVariable(MDNode::get(VMContext, Elts));

+}

+

+/// getDISubprogram - Find subprogram that is enclosing this scope.

+DISubprogram llvm::getDISubprogram(const MDNode *Scope) {

+  DIDescriptor D(Scope);

+  if (D.isSubprogram())

+    return DISubprogram(Scope);

+

+  if (D.isLexicalBlockFile())

+    return getDISubprogram(DILexicalBlockFile(Scope).getContext());

+

+  if (D.isLexicalBlock())

+    return getDISubprogram(DILexicalBlock(Scope).getContext());

+

+  return DISubprogram();

+}

+

+/// getDICompositeType - Find underlying composite type.

+DICompositeType llvm::getDICompositeType(DIType T) {

+  if (T.isCompositeType())

+    return DICompositeType(T);

+

+  if (T.isDerivedType()) {

+    // This function is currently used by dragonegg and dragonegg does

+    // not generate identifier for types, so using an empty map to resolve

+    // DerivedFrom should be fine.

+    DITypeIdentifierMap EmptyMap;

+    return getDICompositeType(DIDerivedType(T).getTypeDerivedFrom()

+                                              .resolve(EmptyMap));

+  }

+

+  return DICompositeType();

+}

+

+/// Update DITypeIdentifierMap by going through retained types of each CU.

+DITypeIdentifierMap llvm::generateDITypeIdentifierMap(

+                              const NamedMDNode *CU_Nodes) {

+  DITypeIdentifierMap Map;

+  for (unsigned CUi = 0, CUe = CU_Nodes->getNumOperands(); CUi != CUe; ++CUi) {

+    DICompileUnit CU(CU_Nodes->getOperand(CUi));

+    DIArray Retain = CU.getRetainedTypes();

+    for (unsigned Ti = 0, Te = Retain.getNumElements(); Ti != Te; ++Ti) {

+      if (!Retain.getElement(Ti).isCompositeType())

+        continue;

+      DICompositeType Ty(Retain.getElement(Ti));

+      if (MDString *TypeId = Ty.getIdentifier()) {

+        // Definition has priority over declaration.

+        // Try to insert (TypeId, Ty) to Map.

+        std::pair<DITypeIdentifierMap::iterator, bool> P =

+            Map.insert(std::make_pair(TypeId, Ty));

+        // If TypeId already exists in Map and this is a definition, replace

+        // whatever we had (declaration or definition) with the definition.

+        if (!P.second && !Ty.isForwardDecl())

+          P.first->second = Ty;

+      }

+    }

+  }

+  return Map;

+}

+

+//===----------------------------------------------------------------------===//

+// DebugInfoFinder implementations.

+//===----------------------------------------------------------------------===//

+

+void DebugInfoFinder::reset() {

+  CUs.clear();

+  SPs.clear();

+  GVs.clear();

+  TYs.clear();

+  Scopes.clear();

+  NodesSeen.clear();

+  TypeIdentifierMap.clear();

+}

+

+/// processModule - Process entire module and collect debug info.

+void DebugInfoFinder::processModule(const Module &M) {

+  if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) {

+    TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);

+    for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {

+      DICompileUnit CU(CU_Nodes->getOperand(i));

+      addCompileUnit(CU);

+      DIArray GVs = CU.getGlobalVariables();

+      for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) {

+        DIGlobalVariable DIG(GVs.getElement(i));

+        if (addGlobalVariable(DIG)) {

+          processScope(DIG.getContext());

+          processType(DIG.getType());

+        }

+      }

+      DIArray SPs = CU.getSubprograms();

+      for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i)

+        processSubprogram(DISubprogram(SPs.getElement(i)));

+      DIArray EnumTypes = CU.getEnumTypes();

+      for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i)

+        processType(DIType(EnumTypes.getElement(i)));

+      DIArray RetainedTypes = CU.getRetainedTypes();

+      for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i)

+        processType(DIType(RetainedTypes.getElement(i)));

+      DIArray Imports = CU.getImportedEntities();

+      for (unsigned i = 0, e = Imports.getNumElements(); i != e; ++i) {

+        DIImportedEntity Import = DIImportedEntity(

+                                    Imports.getElement(i));

+        DIDescriptor Entity = Import.getEntity();

+        if (Entity.isType())

+          processType(DIType(Entity));

+        else if (Entity.isSubprogram())

+          processSubprogram(DISubprogram(Entity));

+        else if (Entity.isNameSpace())

+          processScope(DINameSpace(Entity).getContext());

+      }

+    }

+  }

+}

+

+/// processLocation - Process DILocation.

+void DebugInfoFinder::processLocation(DILocation Loc) {

+  if (!Loc) return;

+  processScope(Loc.getScope());

+  processLocation(Loc.getOrigLocation());

+}

+

+/// processType - Process DIType.

+void DebugInfoFinder::processType(DIType DT) {

+  if (!addType(DT))

+    return;

+  processScope(DT.getContext().resolve(TypeIdentifierMap));

+  if (DT.isCompositeType()) {

+    DICompositeType DCT(DT);

+    processType(DCT.getTypeDerivedFrom().resolve(TypeIdentifierMap));

+    DIArray DA = DCT.getTypeArray();

+    for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) {

+      DIDescriptor D = DA.getElement(i);

+      if (D.isType())

+        processType(DIType(D));

+      else if (D.isSubprogram())

+        processSubprogram(DISubprogram(D));

+    }

+  } else if (DT.isDerivedType()) {

+    DIDerivedType DDT(DT);

+    processType(DDT.getTypeDerivedFrom().resolve(TypeIdentifierMap));

+  }

+}

+

+void DebugInfoFinder::processScope(DIScope Scope) {

+  if (Scope.isType()) {

+    DIType Ty(Scope);

+    processType(Ty);

+    return;

+  }

+  if (Scope.isCompileUnit()) {

+    addCompileUnit(DICompileUnit(Scope));

+    return;

+  }

+  if (Scope.isSubprogram()) {

+    processSubprogram(DISubprogram(Scope));

+    return;

+  }

+  if (!addScope(Scope))

+    return;

+  if (Scope.isLexicalBlock()) {

+    DILexicalBlock LB(Scope);

+    processScope(LB.getContext());

+  } else if (Scope.isLexicalBlockFile()) {

+    DILexicalBlockFile LBF = DILexicalBlockFile(Scope);

+    processScope(LBF.getScope());

+  } else if (Scope.isNameSpace()) {

+    DINameSpace NS(Scope);

+    processScope(NS.getContext());

+  }

+}

+

+/// processLexicalBlock

+void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) {

+  DIScope Context = LB.getContext();

+  if (Context.isLexicalBlock())

+    return processLexicalBlock(DILexicalBlock(Context));

+  else if (Context.isLexicalBlockFile()) {

+    DILexicalBlockFile DBF = DILexicalBlockFile(Context);

+    return processLexicalBlock(DILexicalBlock(DBF.getScope()));

+  }

+  else

+    return processSubprogram(DISubprogram(Context));

+}

+

+/// processSubprogram - Process DISubprogram.

+void DebugInfoFinder::processSubprogram(DISubprogram SP) {

+  if (!addSubprogram(SP))

+    return;

+  processScope(SP.getContext().resolve(TypeIdentifierMap));

+  processType(SP.getType());

+  DIArray TParams = SP.getTemplateParams();

+  for (unsigned I = 0, E = TParams.getNumElements(); I != E; ++I) {

+    DIDescriptor Element = TParams.getElement(I);

+    if (Element.isTemplateTypeParameter()) {

+      DITemplateTypeParameter TType(Element);

+      processScope(TType.getContext().resolve(TypeIdentifierMap));

+      processType(TType.getType().resolve(TypeIdentifierMap));

+    } else if (Element.isTemplateValueParameter()) {

+      DITemplateValueParameter TVal(Element);

+      processScope(TVal.getContext().resolve(TypeIdentifierMap));

+      processType(TVal.getType().resolve(TypeIdentifierMap));

+    }

+  }

+}

+

+/// processDeclare - Process DbgDeclareInst.

+void DebugInfoFinder::processDeclare(const DbgDeclareInst *DDI) {

+  MDNode *N = dyn_cast<MDNode>(DDI->getVariable());

+  if (!N) return;

+

+  DIDescriptor DV(N);

+  if (!DV.isVariable())

+    return;

+

+  if (!NodesSeen.insert(DV))

+    return;

+  processScope(DIVariable(N).getContext());

+  processType(DIVariable(N).getType());

+}

+

+void DebugInfoFinder::processValue(const DbgValueInst *DVI) {

+  MDNode *N = dyn_cast<MDNode>(DVI->getVariable());

+  if (!N) return;

+

+  DIDescriptor DV(N);

+  if (!DV.isVariable())

+    return;

+

+  if (!NodesSeen.insert(DV))

+    return;

+  processScope(DIVariable(N).getContext());

+  processType(DIVariable(N).getType());

+}

+

+/// addType - Add type into Tys.

+bool DebugInfoFinder::addType(DIType DT) {

+  if (!DT)

+    return false;

+

+  if (!NodesSeen.insert(DT))

+    return false;

+

+  TYs.push_back(DT);

+  return true;

+}

+

+/// addCompileUnit - Add compile unit into CUs.

+bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) {

+  if (!CU)

+    return false;

+  if (!NodesSeen.insert(CU))

+    return false;

+

+  CUs.push_back(CU);

+  return true;

+}

+

+/// addGlobalVariable - Add global variable into GVs.

+bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) {

+  if (!DIG)

+    return false;

+

+  if (!NodesSeen.insert(DIG))

+    return false;

+

+  GVs.push_back(DIG);

+  return true;

+}

+

+// addSubprogram - Add subprgoram into SPs.

+bool DebugInfoFinder::addSubprogram(DISubprogram SP) {

+  if (!SP)

+    return false;

+

+  if (!NodesSeen.insert(SP))

+    return false;

+

+  SPs.push_back(SP);

+  return true;

+}

+

+bool DebugInfoFinder::addScope(DIScope Scope) {

+  if (!Scope)

+    return false;

+  // FIXME: Ocaml binding generates a scope with no content, we treat it

+  // as null for now.

+  if (Scope->getNumOperands() == 0)

+    return false;

+  if (!NodesSeen.insert(Scope))

+    return false;

+  Scopes.push_back(Scope);

+  return true;

+}

+

+//===----------------------------------------------------------------------===//

+// DIDescriptor: dump routines for all descriptors.

+//===----------------------------------------------------------------------===//

+

+/// dump - Print descriptor to dbgs() with a newline.

+void DIDescriptor::dump() const {

+  print(dbgs()); dbgs() << '\n';

+}

+

+/// print - Print descriptor.

+void DIDescriptor::print(raw_ostream &OS) const {

+  if (!DbgNode) return;

+

+  if (const char *Tag = dwarf::TagString(getTag()))

+    OS << "[ " << Tag << " ]";

+

+  if (this->isSubrange()) {

+    DISubrange(DbgNode).printInternal(OS);

+  } else if (this->isCompileUnit()) {

+    DICompileUnit(DbgNode).printInternal(OS);

+  } else if (this->isFile()) {

+    DIFile(DbgNode).printInternal(OS);

+  } else if (this->isEnumerator()) {

+    DIEnumerator(DbgNode).printInternal(OS);

+  } else if (this->isBasicType()) {

+    DIType(DbgNode).printInternal(OS);

+  } else if (this->isDerivedType()) {

+    DIDerivedType(DbgNode).printInternal(OS);

+  } else if (this->isCompositeType()) {

+    DICompositeType(DbgNode).printInternal(OS);

+  } else if (this->isSubprogram()) {

+    DISubprogram(DbgNode).printInternal(OS);

+  } else if (this->isGlobalVariable()) {

+    DIGlobalVariable(DbgNode).printInternal(OS);

+  } else if (this->isVariable()) {

+    DIVariable(DbgNode).printInternal(OS);

+  } else if (this->isObjCProperty()) {

+    DIObjCProperty(DbgNode).printInternal(OS);

+  } else if (this->isNameSpace()) {

+    DINameSpace(DbgNode).printInternal(OS);

+  } else if (this->isScope()) {

+    DIScope(DbgNode).printInternal(OS);

+  }

+}

+

+void DISubrange::printInternal(raw_ostream &OS) const {

+  int64_t Count = getCount();

+  if (Count != -1)

+    OS << " [" << getLo() << ", " << Count - 1 << ']';

+  else

+    OS << " [unbounded]";

+}

+

+void DIScope::printInternal(raw_ostream &OS) const {

+  OS << " [" << getDirectory() << "/" << getFilename() << ']';

+}

+

+void DICompileUnit::printInternal(raw_ostream &OS) const {

+  DIScope::printInternal(OS);

+  OS << " [";

+  unsigned Lang = getLanguage();

+  if (const char *LangStr = dwarf::LanguageString(Lang))

+    OS << LangStr;

+  else

+    (OS << "lang 0x").write_hex(Lang);

+  OS << ']';

+}

+

+void DIEnumerator::printInternal(raw_ostream &OS) const {

+  OS << " [" << getName() << " :: " << getEnumValue() << ']';

+}

+

+void DIType::printInternal(raw_ostream &OS) const {

+  if (!DbgNode) return;

+

+  StringRef Res = getName();

+  if (!Res.empty())

+    OS << " [" << Res << "]";

+

+  // TODO: Print context?

+

+  OS << " [line " << getLineNumber()

+     << ", size " << getSizeInBits()

+     << ", align " << getAlignInBits()

+     << ", offset " << getOffsetInBits();

+  if (isBasicType())

+    if (const char *Enc =

+        dwarf::AttributeEncodingString(DIBasicType(DbgNode).getEncoding()))

+      OS << ", enc " << Enc;

+  OS << "]";

+

+  if (isPrivate())

+    OS << " [private]";

+  else if (isProtected())

+    OS << " [protected]";

+

+  if (isArtificial())

+    OS << " [artificial]";

+

+  if (isForwardDecl())

+    OS << " [decl]";

+  else if (getTag() == dwarf::DW_TAG_structure_type ||

+           getTag() == dwarf::DW_TAG_union_type ||

+           getTag() == dwarf::DW_TAG_enumeration_type ||

+           getTag() == dwarf::DW_TAG_class_type)

+    OS << " [def]";

+  if (isVector())

+    OS << " [vector]";

+  if (isStaticMember())

+    OS << " [static]";

+}

+

+void DIDerivedType::printInternal(raw_ostream &OS) const {

+  DIType::printInternal(OS);

+  OS << " [from " << getTypeDerivedFrom().getName() << ']';

+}

+

+void DICompositeType::printInternal(raw_ostream &OS) const {

+  DIType::printInternal(OS);

+  DIArray A = getTypeArray();

+  OS << " [" << A.getNumElements() << " elements]";

+}

+

+void DINameSpace::printInternal(raw_ostream &OS) const {

+  StringRef Name = getName();

+  if (!Name.empty())

+    OS << " [" << Name << ']';

+

+  OS << " [line " << getLineNumber() << ']';

+}

+

+void DISubprogram::printInternal(raw_ostream &OS) const {

+  // TODO : Print context

+  OS << " [line " << getLineNumber() << ']';

+

+  if (isLocalToUnit())

+    OS << " [local]";

+

+  if (isDefinition())

+    OS << " [def]";

+

+  if (getScopeLineNumber() != getLineNumber())

+    OS << " [scope " << getScopeLineNumber() << "]";

+

+  if (isPrivate())

+    OS << " [private]";

+  else if (isProtected())

+    OS << " [protected]";

+

+  StringRef Res = getName();

+  if (!Res.empty())

+    OS << " [" << Res << ']';

+}

+

+void DIGlobalVariable::printInternal(raw_ostream &OS) const {

+  StringRef Res = getName();

+  if (!Res.empty())

+    OS << " [" << Res << ']';

+

+  OS << " [line " << getLineNumber() << ']';

+

+  // TODO : Print context

+

+  if (isLocalToUnit())

+    OS << " [local]";

+

+  if (isDefinition())

+    OS << " [def]";

+}

+

+void DIVariable::printInternal(raw_ostream &OS) const {

+  StringRef Res = getName();

+  if (!Res.empty())

+    OS << " [" << Res << ']';

+

+  OS << " [line " << getLineNumber() << ']';

+}

+

+void DIObjCProperty::printInternal(raw_ostream &OS) const {

+  StringRef Name = getObjCPropertyName();

+  if (!Name.empty())

+    OS << " [" << Name << ']';

+

+  OS << " [line " << getLineNumber()

+     << ", properties " << getUnsignedField(6) << ']';

+}

+

+static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS,

+                          const LLVMContext &Ctx) {

+  if (!DL.isUnknown()) {          // Print source line info.

+    DIScope Scope(DL.getScope(Ctx));

+    assert(Scope.isScope() &&

+      "Scope of a DebugLoc should be a DIScope.");

+    // Omit the directory, because it's likely to be long and uninteresting.

+    CommentOS << Scope.getFilename();

+    CommentOS << ':' << DL.getLine();

+    if (DL.getCol() != 0)

+      CommentOS << ':' << DL.getCol();

+    DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx));

+    if (!InlinedAtDL.isUnknown()) {

+      CommentOS << " @[ ";

+      printDebugLoc(InlinedAtDL, CommentOS, Ctx);

+      CommentOS << " ]";

+    }

+  }

+}

+

+void DIVariable::printExtendedName(raw_ostream &OS) const {

+  const LLVMContext &Ctx = DbgNode->getContext();

+  StringRef Res = getName();

+  if (!Res.empty())

+    OS << Res << "," << getLineNumber();

+  if (MDNode *InlinedAt = getInlinedAt()) {

+    DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt);

+    if (!InlinedAtDL.isUnknown()) {

+      OS << " @[";

+      printDebugLoc(InlinedAtDL, OS, Ctx);

+      OS << "]";

+    }

+  }

+}

+

+/// Specialize constructor to make sure it has the correct type.

+template <>

+DIRef<DIScope>::DIRef(const Value *V) : Val(V) {

+  assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode");

+}

+template <>

+DIRef<DIType>::DIRef(const Value *V) : Val(V) {

+  assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode");

+}

+

+/// Specialize getFieldAs to handle fields that are references to DIScopes.

+template <>

+DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const {

+  return DIScopeRef(getField(DbgNode, Elt));

+}

+/// Specialize getFieldAs to handle fields that are references to DITypes.

+template <>

+DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const {

+  return DITypeRef(getField(DbgNode, Elt));

+}