-//===----------------------------------------------------------------------===//
-// DIDescriptor
-//===----------------------------------------------------------------------===//
-
-unsigned DIDescriptor::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 *DIDescriptor::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 DIDescriptor::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;
-}
-
-static Metadata *getField(const MDNode *DbgNode, unsigned Elt) {
- if (!DbgNode || Elt >= DbgNode->getNumOperands())
- return nullptr;
- return DbgNode->getOperand(Elt);
-}
-
-static MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) {
- return dyn_cast_or_null<MDNode>(getField(DbgNode, Elt));
-}
-
-DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const {
- MDNode *Field = getNodeField(DbgNode, Elt);
- return DIDescriptor(Field);
-}
-
-/// \brief Return the size reported by the variable's type.
-unsigned DIVariable::getSizeInBits(const DITypeIdentifierMap &Map) {
- DIType Ty = getType().resolve(Map);
- // Follow derived types until we reach a type that
- // reports back a size.
- while (isa<MDDerivedType>(Ty) && !Ty.getSizeInBits()) {
- DIDerivedType DT = cast<MDDerivedType>(Ty);
- Ty = DT.getTypeDerivedFrom().resolve(Map);
- }
- assert(Ty.getSizeInBits() && "type with size 0");
- return Ty.getSizeInBits();
-}
-
-bool DIExpression::isBitPiece() const {
- unsigned N = getNumElements();
- return N >=3 && getElement(N-3) == dwarf::DW_OP_bit_piece;
-}
-
-uint64_t DIExpression::getBitPieceOffset() const {
- assert(isBitPiece() && "not a piece");
- return getElement(getNumElements()-2);
-}
-
-uint64_t DIExpression::getBitPieceSize() const {
- assert(isBitPiece() && "not a piece");
- return getElement(getNumElements()-1);
-}
-
-DIExpression::iterator DIExpression::Operand::getNext() const {
- iterator it(I);
- return ++it;
-}
-
-//===----------------------------------------------------------------------===//
-// Simple Descriptor Constructors and other Methods
-//===----------------------------------------------------------------------===//
-
-void DIDescriptor::replaceAllUsesWith(LLVMContext &, DIDescriptor D) {
- assert(DbgNode && "Trying to replace an unverified type!");
- assert(DbgNode->isTemporary() && "Expected temporary node");
- TempMDNode Temp(get());
-
- // 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 (Temp.get() == D.get()) {
- DbgNode = MDNode::replaceWithUniqued(std::move(Temp));
- return;
- }
-
- Temp->replaceAllUsesWith(D.get());
- DbgNode = D.get();
-}
-
-void DIDescriptor::replaceAllUsesWith(MDNode *D) {
- assert(DbgNode && "Trying to replace an unverified type!");
- assert(DbgNode != D && "This replacement should always happen");
- assert(DbgNode->isTemporary() && "Expected temporary node");
- TempMDNode Node(get());
- Node->replaceAllUsesWith(D);
-}
-
-#ifndef NDEBUG
-/// \brief Check if a value can be a reference to a type.
-static bool isTypeRef(const Metadata *MD) {
- if (!MD)
- return true;
- if (auto *S = dyn_cast<MDString>(MD))
- return !S->getString().empty();
- return isa<MDType>(MD);
-}
-
-/// \brief Check if a value can be a ScopeRef.
-static bool isScopeRef(const Metadata *MD) {
- if (!MD)
- return true;
- if (auto *S = dyn_cast<MDString>(MD))
- return !S->getString().empty();
- return isa<MDScope>(MD);
-}
-
-/// \brief Check if a value can be a DescriptorRef.
-static bool isDescriptorRef(const Metadata *MD) {
- if (!MD)
- return true;
- if (auto *S = dyn_cast<MDString>(MD))
- return !S->getString().empty();
- return isa<MDNode>(MD);
-}
-#endif
-
-void DICompositeType::setArraysHelper(MDNode *Elements, MDNode *TParams) {
- TypedTrackingMDRef<MDCompositeTypeBase> N(get());
- if (Elements)
- N->replaceElements(cast<MDTuple>(Elements));
- if (TParams)
- N->replaceTemplateParams(cast<MDTuple>(TParams));
- DbgNode = N;
-}
-
-DIScopeRef DIScope::getRef() const { return MDScopeRef::get(get()); }
-
-void DICompositeType::setContainingType(DICompositeType ContainingType) {
- TypedTrackingMDRef<MDCompositeTypeBase> N(get());
- N->replaceVTableHolder(MDTypeRef::get(ContainingType));
- DbgNode = N;
-}
-
-bool DIVariable::isInlinedFnArgument(const Function *CurFn) {
- assert(CurFn && "Invalid function");
- DISubprogram SP = dyn_cast<MDSubprogram>(getContext());
- if (!SP)
- return false;
- // This variable is not inlined function argument if its scope
- // does not describe current function.
- return !SP.describes(CurFn);
-}
-
-Function *DISubprogram::getFunction() const {
- if (auto *N = get())
- if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getFunction()))
- return dyn_cast<Function>(C->getValue());
- return nullptr;
-}
-
-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;
-}
-
-GlobalVariable *DIGlobalVariable::getGlobal() const {
- return dyn_cast_or_null<GlobalVariable>(getConstant());
-}
-
-DIScopeRef DIScope::getContext() const {
- if (DIType T = dyn_cast<MDType>(*this))
- return T.getContext();
-
- if (DISubprogram SP = dyn_cast<MDSubprogram>(*this))
- return DIScopeRef(SP.getContext());
-
- if (DILexicalBlock LB = dyn_cast<MDLexicalBlockBase>(*this))
- return DIScopeRef(LB.getContext());
-
- if (DINameSpace NS = dyn_cast<MDNamespace>(*this))
- return DIScopeRef(NS.getContext());
-
- assert((isa<MDFile>(*this) || isa<MDCompileUnit>(*this)) &&
- "Unhandled type of scope.");
- return DIScopeRef(nullptr);
-}
-
-StringRef DIScope::getName() const {
- if (DIType T = dyn_cast<MDType>(*this))
- return T.getName();
- if (DISubprogram SP = dyn_cast<MDSubprogram>(*this))
- return SP.getName();
- if (DINameSpace NS = dyn_cast<MDNamespace>(*this))
- return NS.getName();
- assert((isa<MDLexicalBlockBase>(*this) || isa<MDFile>(*this) ||
- isa<MDCompileUnit>(*this)) &&
- "Unhandled type of scope.");
- return StringRef();
-}
-
-StringRef DIScope::getFilename() const {
- if (auto *N = get())
- if (auto *F = N->getFile())
- return F->getFilename();
- return "";
-}
-
-StringRef DIScope::getDirectory() const {
- if (auto *N = get())
- if (auto *F = N->getFile())
- return F->getDirectory();
- return "";
-}
-
-void DICompileUnit::replaceSubprograms(DIArray Subprograms) {
- get()->replaceSubprograms(cast_or_null<MDTuple>(Subprograms.get()));
-}
-
-void DICompileUnit::replaceGlobalVariables(DIArray GlobalVariables) {
- get()->replaceGlobalVariables(cast_or_null<MDTuple>(GlobalVariables.get()));
-}
-
-DILocation DILocation::copyWithNewScope(LLVMContext &Ctx,
- DILexicalBlockFile NewScope) {
- assert(NewScope && "Expected valid scope");
-
- const auto *Old = cast<MDLocation>(DbgNode);
- return DILocation(MDLocation::get(Ctx, Old->getLine(), Old->getColumn(),
- NewScope, Old->getInlinedAt()));
-}
-
-unsigned DILocation::computeNewDiscriminator(LLVMContext &Ctx) {
- std::pair<const char *, unsigned> Key(getFilename().data(), getLineNumber());
- return ++Ctx.pImpl->DiscriminatorTable[Key];
-}
-
-DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
- LLVMContext &VMContext) {
- return cast<MDLocalVariable>(DV)
- ->withInline(cast_or_null<MDLocation>(InlinedScope));
-}
-
-DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) {
- return cast<MDLocalVariable>(DV)->withoutInline();
-}
-
-DISubprogram llvm::getDISubprogram(const MDNode *Scope) {
- if (auto *LocalScope = dyn_cast_or_null<MDLocalScope>(Scope))