Fix a use-iterator-after-invalidate error
[oota-llvm.git] / include / llvm / IR / DebugInfo.h
index 44c9ddf803b8c923016dce213832147c2587bc47..d2e59752080a8f0342cbc75a224673660728691d 100644 (file)
@@ -132,26 +132,21 @@ public:
   /// The three accessibility flags are mutually exclusive and rolled together
   /// in the first two bits.
   enum {
-    FlagAccessibility     = 1 << 0 | 1 << 1,
-    FlagPrivate           = 1,
-    FlagProtected         = 2,
-    FlagPublic            = 3,
-
-    FlagFwdDecl           = 1 << 2,
-    FlagAppleBlock        = 1 << 3,
-    FlagBlockByrefStruct  = 1 << 4,
-    FlagVirtual           = 1 << 5,
-    FlagArtificial        = 1 << 6,
-    FlagExplicit          = 1 << 7,
-    FlagPrototyped        = 1 << 8,
-    FlagObjcClassComplete = 1 << 9,
-    FlagObjectPointer     = 1 << 10,
-    FlagVector            = 1 << 11,
-    FlagStaticMember      = 1 << 12,
-    FlagLValueReference   = 1 << 13,
-    FlagRValueReference   = 1 << 14
+#define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
+#include "llvm/IR/DebugInfoFlags.def"
+    FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic
   };
 
+  static unsigned getFlag(StringRef Flag);
+  static const char *getFlagString(unsigned Flag);
+
+  /// \brief Split up a flags bitfield.
+  ///
+  /// Split \c Flags into \c SplitFlags, a vector of its components.  Returns
+  /// any remaining (unrecognized) bits.
+  static unsigned splitFlags(unsigned Flags,
+                             SmallVectorImpl<unsigned> &SplitFlags);
+
 protected:
   const MDNode *DbgNode;
 
@@ -252,6 +247,19 @@ public:
   void replaceAllUsesWith(MDNode *D);
 };
 
+#define RETURN_FROM_RAW(VALID, DEFAULT)                                        \
+  do {                                                                         \
+    if (auto *N = getRaw())                                                    \
+      return VALID;                                                            \
+    return DEFAULT;                                                            \
+  } while (false)
+#define RETURN_DESCRIPTOR_FROM_RAW(DESC, VALID)                                \
+  do {                                                                         \
+    if (auto *N = getRaw())                                                    \
+      return DESC(dyn_cast_or_null<MDNode>(VALID));                            \
+    return DESC(static_cast<const MDNode *>(nullptr));                         \
+  } while (false)
+
 /// \brief This is used to represent ranges, for array bounds.
 class DISubrange : public DIDescriptor {
   friend class DIDescriptor;
@@ -732,7 +740,6 @@ public:
 
   StringRef getName() const { return getHeaderField(1); }
 
-  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); }
   DITypeRef getType() const { return getFieldAs<DITypeRef>(2); }
   bool Verify() const;
 };
@@ -745,7 +752,6 @@ public:
 
   StringRef getName() const { return getHeaderField(1); }
 
-  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); }
   DITypeRef getType() const { return getFieldAs<DITypeRef>(2); }
   Metadata *getValue() const;
   bool Verify() const;
@@ -930,28 +936,18 @@ public:
 ///
 /// This object is not associated with any DWARF tag.
 class DILocation : public DIDescriptor {
+  MDLocation *getRaw() const { return dyn_cast_or_null<MDLocation>(get()); }
+
 public:
   explicit DILocation(const MDNode *N) : DIDescriptor(N) {}
 
-  unsigned getLineNumber() const {
-    if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode))
-      return L->getLine();
-    return 0;
-  }
-  unsigned getColumnNumber() const {
-    if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode))
-      return L->getColumn();
-    return 0;
-  }
+  unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+  unsigned getColumnNumber() const { RETURN_FROM_RAW(N->getColumn(), 0); }
   DIScope getScope() const {
-    if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode))
-      return DIScope(dyn_cast_or_null<MDNode>(L->getScope()));
-    return DIScope(nullptr);
+    RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
   }
   DILocation getOrigLocation() const {
-    if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode))
-      return DILocation(dyn_cast_or_null<MDNode>(L->getInlinedAt()));
-    return DILocation(nullptr);
+    RETURN_DESCRIPTOR_FROM_RAW(DILocation, N->getInlinedAt());
   }
   StringRef getFilename() const { return getScope().getFilename(); }
   StringRef getDirectory() const { return getScope().getDirectory(); }
@@ -1034,6 +1030,7 @@ class DIImportedEntity : public DIDescriptor {
   void printInternal(raw_ostream &OS) const;
 
 public:
+  DIImportedEntity() = default;
   explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {}
   DIScope getContext() const { return getFieldAs<DIScope>(1); }
   DIDescriptorRef getEntity() const { return getFieldAs<DIDescriptorRef>(2); }
@@ -1042,6 +1039,9 @@ public:
   bool Verify() const;
 };
 
+#undef RETURN_FROM_RAW
+#undef RETURN_DESCRIPTOR_FROM_RAW
+
 /// \brief Find subprogram that is enclosing this scope.
 DISubprogram getDISubprogram(const MDNode *Scope);