Debug Info: Use identifier to reference DIType in base type field of
[oota-llvm.git] / include / llvm / DebugInfo.h
index 87ccac10dd253bbb376b0a7e62108162860b4946..997d01e9946290f737538bde2fe9bef3e2fabd58 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef LLVM_DEBUGINFO_H
 #define LLVM_DEBUGINFO_H
 
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
@@ -45,12 +46,19 @@ namespace llvm {
   class DILexicalBlockFile;
   class DIVariable;
   class DIType;
+  class DITypeRef;
   class DIObjCProperty;
 
+  /// Maps from type identifier to the actual MDNode.
+  typedef DenseMap<const MDString *, MDNode*> DITypeIdentifierMap;
+
   /// DIDescriptor - A thin wraper around MDNode to access encoded debug info.
   /// This should not be stored in a container, because the underlying MDNode
   /// may change in certain situations.
   class DIDescriptor {
+    // Befriends DITypeRef so DITypeRef can befriend the protected member
+    // function: getFieldAs<DITypeRef>.
+    friend class DITypeRef;
   public:
     enum {
       FlagPrivate            = 1 << 0,
@@ -143,6 +151,23 @@ namespace llvm {
     void dump() const;
   };
 
+  /// Specialize getFieldAs to handle fields that are references to DITypes.
+  template <>
+  DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const;
+
+  /// Represents reference to a DIType, abstracts over direct and
+  /// identifier-based metadata type references.
+  class DITypeRef {
+    friend DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const;
+
+    /// TypeVal can be either a MDNode or a MDString, in the latter,
+    /// MDString specifies the type identifier.
+    const Value *TypeVal;
+    explicit DITypeRef(const Value *V);
+  public:
+    DIType resolve(const DITypeIdentifierMap &Map) const;
+  };
+
   /// DISubrange - This is used to represent ranges, for array bounds.
   class DISubrange : public DIDescriptor {
     friend class DIDescriptor;
@@ -296,9 +321,9 @@ namespace llvm {
     /// associated with one.
     MDNode *getObjCProperty() const;
 
-    DIType getClassType() const {
+    DITypeRef getClassType() const {
       assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
-      return getFieldAs<DIType>(10);
+      return getFieldAs<DITypeRef>(10);
     }
 
     Constant *getConstant() const {
@@ -720,6 +745,9 @@ namespace llvm {
   /// cleanseInlinedVariable - Remove inlined scope from the variable.
   DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
 
+  /// Construct DITypeIdentifierMap by going through retained types of each CU.
+  DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);
+
   /// DebugInfoFinder tries to list all debug info MDNodes used in a module. To
   /// list debug info MDNodes used by an instruction, DebugInfoFinder uses
   /// processDeclare, processValue and processLocation to handle DbgDeclareInst,