-Function *DIDescriptor::getFunctionField(unsigned Elt) const {
- return dyn_cast_or_null<Function>(getConstantField(Elt));
-}
-
-void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) {
- if (!DbgNode)
- return;
-
- if (Elt < DbgNode->getNumOperands()) {
- MDNode *Node = const_cast<MDNode *>(DbgNode);
- Node->replaceOperandWith(Elt, F ? ConstantAsMetadata::get(F) : nullptr);
- }
-}
-
-static unsigned DIVariableInlinedAtIndex = 4;
-MDNode *DIVariable::getInlinedAt() const {
- return getNodeField(DbgNode, DIVariableInlinedAtIndex);
-}
-
-/// \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 (Ty.isDerivedType() && !Ty.getSizeInBits()) {
- DIDerivedType DT(&*Ty);
- Ty = DT.getTypeDerivedFrom().resolve(Map);
- }
- assert(Ty.getSizeInBits() && "type with size 0");
- return Ty.getSizeInBits();
-}
-
-uint64_t DIExpression::getElement(unsigned Idx) const {
- unsigned I = Idx + 1;
- assert(I < getNumHeaderFields() &&
- "non-existing complex address element requested");
- return getHeaderFieldAs<int64_t>(I);
-}
-
-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::begin() const {
- return DIExpression::iterator(*this);
-}
-
-DIExpression::iterator DIExpression::end() const {
- return DIExpression::iterator();
-}
-
-DIExpression::Operand DIExpression::Operand::getNext() const {
- iterator it(I);
- return *(++it);
-}
-
-//===----------------------------------------------------------------------===//
-// Predicates
-//===----------------------------------------------------------------------===//
-
-bool DIDescriptor::isSubroutineType() const {
- return DbgNode && getTag() == dwarf::DW_TAG_subroutine_type;
-}
-
-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;
- }
-}
-
-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();
- }
-}
-
-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;
- }
-}
-
-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;
- }
-}
-
-bool DIDescriptor::isType() const {
- return isBasicType() || isCompositeType() || isDerivedType();
-}
-
-bool DIDescriptor::isSubprogram() const {
- return DbgNode && getTag() == dwarf::DW_TAG_subprogram;
-}
-
-bool DIDescriptor::isGlobalVariable() const {
- return DbgNode && getTag() == dwarf::DW_TAG_variable;
-}
-
-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();
-}
-
-bool DIDescriptor::isTemplateTypeParameter() const {
- return DbgNode && getTag() == dwarf::DW_TAG_template_type_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);
-}
-
-bool DIDescriptor::isCompileUnit() const {
- return DbgNode && getTag() == dwarf::DW_TAG_compile_unit;
-}
-
-bool DIDescriptor::isFile() const {
- return DbgNode && getTag() == dwarf::DW_TAG_file_type;
-}
-
-bool DIDescriptor::isNameSpace() const {
- return DbgNode && getTag() == dwarf::DW_TAG_namespace;
-}
-
-bool DIDescriptor::isLexicalBlockFile() const {
- return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&
- DbgNode->getNumOperands() == 3 && getNumHeaderFields() == 2;
-}
-
-bool DIDescriptor::isLexicalBlock() const {
- // FIXME: There are always exactly 4 header fields in DILexicalBlock, but
- // something relies on this returning true for DILexicalBlockFile.
- return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&
- DbgNode->getNumOperands() == 3 &&
- (getNumHeaderFields() == 2 || getNumHeaderFields() == 4);
-}
-
-bool DIDescriptor::isSubrange() const {
- return DbgNode && getTag() == dwarf::DW_TAG_subrange_type;
-}
-
-bool DIDescriptor::isEnumerator() const {
- return DbgNode && getTag() == dwarf::DW_TAG_enumerator;
-}
-
-bool DIDescriptor::isObjCProperty() const {
- return DbgNode && getTag() == dwarf::DW_TAG_APPLE_property;
-}
-
-bool DIDescriptor::isImportedEntity() const {
- return DbgNode && (getTag() == dwarf::DW_TAG_imported_module ||
- getTag() == dwarf::DW_TAG_imported_declaration);
-}
-
-bool DIDescriptor::isExpression() const {
- return DbgNode && (getTag() == dwarf::DW_TAG_expression);
-}
-
-//===----------------------------------------------------------------------===//
-// Simple Descriptor Constructors and other Methods
-//===----------------------------------------------------------------------===//
-
-void DIDescriptor::replaceAllUsesWith(LLVMContext &VMContext, 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.
- const MDNode *DN = D;
- if (DbgNode == DN) {
- SmallVector<Metadata *, 10> Ops(DbgNode->getNumOperands());
- for (size_t i = 0; i != Ops.size(); ++i)
- Ops[i] = DbgNode->getOperand(i);
- DN = MDNode::get(VMContext, Ops);
- }
-
- assert(DbgNode->isTemporary() && "Expected temporary node");
- auto *Node = const_cast<MDNode *>(DbgNode);
- Node->replaceAllUsesWith(const_cast<MDNode *>(DN));
- MDNode::deleteTemporary(Node);
- DbgNode = DN;
-}
-
-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");
- auto *Node = const_cast<MDNode *>(DbgNode);
- Node->replaceAllUsesWith(D);
- MDNode::deleteTemporary(Node);
-}
-
-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() == 7 && getNumHeaderFields() == 8;
-}
-
-bool DIObjCProperty::Verify() const {
- if (!isObjCProperty())
- return false;
-
- // Don't worry about the rest of the strings for now.
- return DbgNode->getNumOperands() == 3 && getNumHeaderFields() == 6;
-}
-
-/// \brief 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).
- Metadata *Fld = getField(DbgNode, Elt);
- if (Fld && isa<MDString>(Fld) && !cast<MDString>(Fld)->getString().empty())
- return false;
- return true;
-}
-
-/// \brief Check if a field at position Elt of a MDNode is a MDString.
-static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) {
- Metadata *Fld = getField(DbgNode, Elt);
- return !Fld || isa<MDString>(Fld);
-}
-
-/// \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();
- if (auto *N = dyn_cast<MDNode>(MD))
- return DIType(N).isType();
- return false;
-}
-
-/// \brief Check if referenced field might be a type.
-static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) {
- return isTypeRef(dyn_cast_or_null<Metadata>(getField(DbgNode, Elt)));
-}
-
-/// \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<MDNode>(MD);
-}
-
-/// \brief Check if a field at position Elt of a MDNode can be a ScopeRef.
-static bool fieldIsScopeRef(const MDNode *DbgNode, unsigned Elt) {
- return isScopeRef(dyn_cast_or_null<Metadata>(getField(DbgNode, Elt)));
-}
-
-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())
- return DIBasicType(DbgNode).Verify();
- else if (isCompositeType())
- return DICompositeType(DbgNode).Verify();
- else if (isDerivedType())
- return DIDerivedType(DbgNode).Verify();
- else
- return false;
-}
-
-bool DIBasicType::Verify() const {
- return isBasicType() && DbgNode->getNumOperands() == 3 &&
- getNumHeaderFields() == 8;
-}
-
-bool DIDerivedType::Verify() const {
- // Make sure DerivedFrom @ field 3 is TypeRef.
- if (!fieldIsTypeRef(DbgNode, 3))
- return false;
- if (getTag() == dwarf::DW_TAG_ptr_to_member_type)
- // Make sure ClassType @ field 4 is a TypeRef.
- if (!fieldIsTypeRef(DbgNode, 4))
- return false;
-
- return isDerivedType() && DbgNode->getNumOperands() >= 4 &&
- DbgNode->getNumOperands() <= 8 && getNumHeaderFields() >= 7 &&
- getNumHeaderFields() <= 8;
-}
-
-bool DICompositeType::Verify() const {
- if (!isCompositeType())
- return false;
-
- // Make sure DerivedFrom @ field 3 and ContainingType @ field 5 are TypeRef.
- if (!fieldIsTypeRef(DbgNode, 3))
- return false;
- if (!fieldIsTypeRef(DbgNode, 5))
- return false;
-
- // Make sure the type identifier at field 7 is MDString, it can be null.
- if (!fieldIsMDString(DbgNode, 7))
- return false;
-
- // A subroutine type can't be both & and &&.
- if (isLValueReference() && isRValueReference())
- return false;
-
- return DbgNode->getNumOperands() == 8 && getNumHeaderFields() == 8;
-}
-
-bool DISubprogram::Verify() const {
- if (!isSubprogram())
- return false;
-
- // Make sure context @ field 2 is a ScopeRef and type @ field 3 is a MDNode.
- if (!fieldIsScopeRef(DbgNode, 2))
- return false;
- if (!fieldIsMDNode(DbgNode, 3))
- return false;
- // Containing type @ field 4.
- if (!fieldIsTypeRef(DbgNode, 4))
- return false;
-
- // A subprogram can't be both & and &&.
- if (isLValueReference() && isRValueReference())
- return false;
-
- // If a DISubprogram has an llvm::Function*, then scope chains from all
- // instructions within the function should lead to this DISubprogram.
- if (auto *F = getFunction()) {
- for (auto &BB : *F) {
- for (auto &I : BB) {
- DebugLoc DL = I.getDebugLoc();
- if (DL.isUnknown())
- continue;
-
- MDNode *Scope = nullptr;
- MDNode *IA = nullptr;
- // walk the inlined-at scopes
- while ((IA = DL.getInlinedAt()))
- DL = DebugLoc::getFromDILocation(IA);
- DL.getScopeAndInlinedAt(Scope, IA);
- if (!Scope)
- return false;
- assert(!IA);
- while (!DIDescriptor(Scope).isSubprogram()) {
- DILexicalBlockFile D(Scope);
- Scope = D.isLexicalBlockFile()
- ? D.getScope()
- : DebugLoc::getFromDILexicalBlock(Scope).getScope();
- if (!Scope)
- return false;
- }
- if (!DISubprogram(Scope).describes(F))
- return false;
- }
- }
- }
- return DbgNode->getNumOperands() == 9 && getNumHeaderFields() == 12;
-}
-
-bool DIGlobalVariable::Verify() const {
- if (!isGlobalVariable())
- return false;
-
- if (getDisplayName().empty())
- return false;
- // Make sure context @ field 1 is an MDNode.
- if (!fieldIsMDNode(DbgNode, 1))
- return false;
- // Make sure that type @ field 3 is a DITypeRef.
- if (!fieldIsTypeRef(DbgNode, 3))
- return false;
- // Make sure StaticDataMemberDeclaration @ field 5 is MDNode.
- if (!fieldIsMDNode(DbgNode, 5))
- return false;
-
- return DbgNode->getNumOperands() == 6 && getNumHeaderFields() == 7;
-}
-
-bool DIVariable::Verify() const {
- if (!isVariable())
- return false;
-
- // Make sure context @ field 1 is an MDNode.
- if (!fieldIsMDNode(DbgNode, 1))
- return false;
- // Make sure that type @ field 3 is a DITypeRef.
- if (!fieldIsTypeRef(DbgNode, 3))
- return false;
-
- // Check the number of header fields, which is common between complex and
- // simple variables.
- if (getNumHeaderFields() != 4)
- return false;
-
- // Variable without an inline location.
- if (DbgNode->getNumOperands() == 4)
- return true;
-
- // Variable with an inline location.
- return getInlinedAt() != nullptr && DbgNode->getNumOperands() == 5;
-}
-
-bool DIExpression::Verify() const {
- // Empty DIExpressions may be represented as a nullptr.
- if (!DbgNode)
- return true;
-
- if (!(isExpression() && DbgNode->getNumOperands() == 1))
- return false;
-
- for (auto Op : *this)
- switch (Op) {
- case DW_OP_bit_piece:
- // Must be the last element of the expression.
- return std::distance(Op.getBase(), DIHeaderFieldIterator()) == 3;
- case DW_OP_plus:
- if (std::distance(Op.getBase(), DIHeaderFieldIterator()) < 2)
- return false;
- break;
- case DW_OP_deref:
- break;
- default:
- // Other operators are not yet supported by the backend.
- return false;
- }
- return true;
-}
-
-bool DILocation::Verify() const {
- return DbgNode && isa<MDLocation>(DbgNode);
-}
-
-bool DINameSpace::Verify() const {
- if (!isNameSpace())
- return false;
- return DbgNode->getNumOperands() == 3 && getNumHeaderFields() == 3;
-}
-
-MDNode *DIFile::getFileNode() const { return getNodeField(DbgNode, 1); }
-
-bool DIFile::Verify() const {
- return isFile() && DbgNode->getNumOperands() == 2;
-}
-
-bool DIEnumerator::Verify() const {
- return isEnumerator() && DbgNode->getNumOperands() == 1 &&
- getNumHeaderFields() == 3;
-}
-
-bool DISubrange::Verify() const {
- return isSubrange() && DbgNode->getNumOperands() == 1 &&
- getNumHeaderFields() == 3;
-}
-
-bool DILexicalBlock::Verify() const {
- return isLexicalBlock() && DbgNode->getNumOperands() == 3 &&
- getNumHeaderFields() == 4;
-}
-
-bool DILexicalBlockFile::Verify() const {
- return isLexicalBlockFile() && DbgNode->getNumOperands() == 3 &&
- getNumHeaderFields() == 2;
-}
-
-bool DITemplateTypeParameter::Verify() const {
- return isTemplateTypeParameter() && DbgNode->getNumOperands() == 4 &&
- getNumHeaderFields() == 4;
-}
-
-bool DITemplateValueParameter::Verify() const {
- return isTemplateValueParameter() && DbgNode->getNumOperands() == 5 &&
- getNumHeaderFields() == 4;
-}
-
-bool DIImportedEntity::Verify() const {
- return isImportedEntity() && DbgNode->getNumOperands() == 3 &&
- getNumHeaderFields() == 3;
-}
-
-MDNode *DIDerivedType::getObjCProperty() const {
- return getNodeField(DbgNode, 4);
-}
-
-MDString *DICompositeType::getIdentifier() const {
- return cast_or_null<MDString>(getField(DbgNode, 7));
-}
-
-#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 && mdconst::hasa<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 == cast<MDNode>(RHS->getOperand(j)));
- assert(found && "Losing a member during member list replacement");
- }
-}
-#endif
-
-void DICompositeType::setArraysHelper(MDNode *Elements, MDNode *TParams) {
- TrackingMDNodeRef 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(4)))
- VerifySubsetOf(El, Elements);
-#endif
- N->replaceOperandWith(4, Elements);
- }
- if (TParams)
- N->replaceOperandWith(6, TParams);
- DbgNode = N;
-}
-
-DIScopeRef DIScope::getRef() const {
- if (!isCompositeType())
- return DIScopeRef(*this);
- DICompositeType DTy(DbgNode);
- if (!DTy.getIdentifier())
- return DIScopeRef(*this);
- return DIScopeRef(DTy.getIdentifier());
-}
-
-void DICompositeType::setContainingType(DICompositeType ContainingType) {
- TrackingMDNodeRef N(*this);
- N->replaceOperandWith(5, ContainingType.getRef());
- DbgNode = N;
-}
-
-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);
-}
-
-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;
-}
-
-MDNode *DISubprogram::getVariablesNodes() const {
- return getNodeField(DbgNode, 8);
-}
-
-DIArray DISubprogram::getVariables() const {
- return DIArray(getNodeField(DbgNode, 8));
-}
-
-Metadata *DITemplateValueParameter::getValue() const {
- return DbgNode->getOperand(3);
-}
-
-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(nullptr);
-}
-
-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() < 7)
- return DIArray();
-
- return DIArray(getNodeField(DbgNode, 2));
-}
-
-DIArray DICompileUnit::getRetainedTypes() const {
- if (!DbgNode || DbgNode->getNumOperands() < 7)
- return DIArray();
-
- return DIArray(getNodeField(DbgNode, 3));
-}
-
-DIArray DICompileUnit::getSubprograms() const {
- if (!DbgNode || DbgNode->getNumOperands() < 7)
- return DIArray();
-
- return DIArray(getNodeField(DbgNode, 4));
-}
-
-DIArray DICompileUnit::getGlobalVariables() const {
- if (!DbgNode || DbgNode->getNumOperands() < 7)
- return DIArray();
-
- return DIArray(getNodeField(DbgNode, 5));
-}
-
-DIArray DICompileUnit::getImportedEntities() const {
- if (!DbgNode || DbgNode->getNumOperands() < 7)
- return DIArray();
-
- return DIArray(getNodeField(DbgNode, 6));
-}
-
-void DICompileUnit::replaceSubprograms(DIArray Subprograms) {
- assert(Verify() && "Expected compile unit");
- if (Subprograms == getSubprograms())
- return;
-
- const_cast<MDNode *>(DbgNode)->replaceOperandWith(4, Subprograms);
-}
-
-void DICompileUnit::replaceGlobalVariables(DIArray GlobalVariables) {
- assert(Verify() && "Expected compile unit");
- if (GlobalVariables == getGlobalVariables())
- return;
-
- const_cast<MDNode *>(DbgNode)->replaceOperandWith(5, GlobalVariables);
-}
-
-DILocation DILocation::copyWithNewScope(LLVMContext &Ctx,
- DILexicalBlockFile NewScope) {
- assert(Verify());
- 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) {
- assert(DIVariable(DV).Verify() && "Expected a DIVariable");
- if (!InlinedScope)
- return cleanseInlinedVariable(DV, VMContext);
-
- // Insert inlined scope.
- SmallVector<Metadata *, 8> Elts;
- for (unsigned I = 0, E = DIVariableInlinedAtIndex; I != E; ++I)
- Elts.push_back(DV->getOperand(I));
- Elts.push_back(InlinedScope);
-
- DIVariable Inlined(MDNode::get(VMContext, Elts));
- assert(Inlined.Verify() && "Expected to create a DIVariable");
- return Inlined;
-}
-
-DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) {
- assert(DIVariable(DV).Verify() && "Expected a DIVariable");
- if (!DIVariable(DV).getInlinedAt())
- return DIVariable(DV);
-
- // Remove inlined scope.
- SmallVector<Metadata *, 8> Elts;
- for (unsigned I = 0, E = DIVariableInlinedAtIndex; I != E; ++I)
- Elts.push_back(DV->getOperand(I));
-
- DIVariable Cleansed(MDNode::get(VMContext, Elts));
- assert(Cleansed.Verify() && "Expected to create a DIVariable");
- return Cleansed;
-}
-
-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();
-}
-
-DISubprogram llvm::getDISubprogram(const Function *F) {