+ DILocation(Context, Storage, Line, Column, Ops),
+ Storage, Context.pImpl->DILocations);
+}
+
+unsigned DILocation::computeNewDiscriminator() const {
+ // FIXME: This seems completely wrong.
+ //
+ // 1. If two modules are generated in the same context, then the second
+ // Module will get different discriminators than it would have if it were
+ // generated in its own context.
+ // 2. If this function is called after round-tripping to bitcode instead of
+ // before, it will give a different (and potentially incorrect!) return.
+ //
+ // The discriminator should instead be calculated from local information
+ // where it's actually needed. This logic should be moved to
+ // AddDiscriminators::runOnFunction(), where it doesn't pollute the
+ // LLVMContext.
+ std::pair<const char *, unsigned> Key(getFilename().data(), getLine());
+ return ++getContext().pImpl->DiscriminatorTable[Key];
+}
+
+unsigned DINode::getFlag(StringRef Flag) {
+ return StringSwitch<unsigned>(Flag)
+#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)
+#include "llvm/IR/DebugInfoFlags.def"
+ .Default(0);
+}
+
+const char *DINode::getFlagString(unsigned Flag) {
+ switch (Flag) {
+ default:
+ return "";
+#define HANDLE_DI_FLAG(ID, NAME) \
+ case Flag##NAME: \
+ return "DIFlag" #NAME;
+#include "llvm/IR/DebugInfoFlags.def"
+ }
+}
+
+unsigned DINode::splitFlags(unsigned Flags,
+ SmallVectorImpl<unsigned> &SplitFlags) {
+ // Accessibility flags need to be specially handled, since they're packed
+ // together.
+ if (unsigned A = Flags & FlagAccessibility) {
+ if (A == FlagPrivate)
+ SplitFlags.push_back(FlagPrivate);
+ else if (A == FlagProtected)
+ SplitFlags.push_back(FlagProtected);
+ else
+ SplitFlags.push_back(FlagPublic);
+ Flags &= ~A;
+ }
+
+#define HANDLE_DI_FLAG(ID, NAME) \
+ if (unsigned Bit = Flags & ID) { \
+ SplitFlags.push_back(Bit); \
+ Flags &= ~Bit; \
+ }
+#include "llvm/IR/DebugInfoFlags.def"
+
+ return Flags;
+}
+
+DIScopeRef DIScope::getScope() const {
+ if (auto *T = dyn_cast<DIType>(this))
+ return T->getScope();
+
+ if (auto *SP = dyn_cast<DISubprogram>(this))
+ return SP->getScope();
+
+ if (auto *LB = dyn_cast<DILexicalBlockBase>(this))
+ return DIScopeRef(LB->getScope());
+
+ if (auto *NS = dyn_cast<DINamespace>(this))
+ return DIScopeRef(NS->getScope());
+
+ if (auto *M = dyn_cast<DIModule>(this))
+ return DIScopeRef(M->getScope());
+
+ assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) &&
+ "Unhandled type of scope.");
+ return nullptr;
+}
+
+StringRef DIScope::getName() const {
+ if (auto *T = dyn_cast<DIType>(this))
+ return T->getName();
+ if (auto *SP = dyn_cast<DISubprogram>(this))
+ return SP->getName();
+ if (auto *NS = dyn_cast<DINamespace>(this))
+ return NS->getName();
+ if (auto *M = dyn_cast<DIModule>(this))
+ return M->getName();
+ assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) ||
+ isa<DICompileUnit>(this)) &&
+ "Unhandled type of scope.");
+ return "";