- 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);
- assert(Scope && "debug location has no scope");
- assert(!IA);
- while (!DIDescriptor(Scope).isSubprogram()) {
- DILexicalBlockFile D(Scope);
- Scope = D.isLexicalBlockFile()
- ? D.getScope()
- : DebugLoc::getFromDILexicalBlock(Scope).getScope();
- if (!Scope)
- llvm_unreachable("lexical block file has no scope");
- }
- 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;
-
- return isExpression() && DbgNode->getNumOperands() == 1;
-}
-
-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;