- MDNode *Node = const_cast<MDNode *>(DbgNode);
- const MDNode *DN = D;
- const Value *V = cast_or_null<Value>(DN);
- Node->replaceAllUsesWith(const_cast<Value *>(V));
- 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;
-}
-
-/// 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).
- Value *Fld = getField(DbgNode, Elt);
- if (Fld && isa<MDString>(Fld) && !cast<MDString>(Fld)->getString().empty())
- return false;
- return true;
-}
-
-/// Check if a field at position Elt of a MDNode is a MDString.
-static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) {
- Value *Fld = getField(DbgNode, Elt);
- return !Fld || isa<MDString>(Fld);
-}
-
-/// Check if a value can be a reference to a type.
-static bool isTypeRef(const Value *Val) {
- return !Val ||
- (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||
- (isa<MDNode>(Val) && DIType(cast<MDNode>(Val)).isType());
-}
-
-/// Check if a field at position Elt of a MDNode can be a reference to a type.
-static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) {
- Value *Fld = getField(DbgNode, Elt);
- return isTypeRef(Fld);
-}
-
-/// Check if a value can be a ScopeRef.
-static bool isScopeRef(const Value *Val) {
- return !Val ||
- (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||
- // Not checking for Val->isScope() here, because it would work
- // only for lexical scopes and not all subclasses of DIScope.
- isa<MDNode>(Val);
-}
-
-/// Check if a field at position Elt of a MDNode can be a ScopeRef.
-static bool fieldIsScopeRef(const MDNode *DbgNode, unsigned Elt) {
- Value *Fld = getField(DbgNode, Elt);
- return isScopeRef(Fld);
-}
-
-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;
-}
-
-/// Verify - Verify that a basic type descriptor is well formed.
-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()) {
- LLVMContext &Ctxt = F->getContext();
- 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 (DL.getScopeAndInlinedAt(Scope, IA, F->getContext()), IA)
- DL = DebugLoc::getFromDILocation(IA);
- DL.getScopeAndInlinedAt(Scope, IA, Ctxt);
- assert(!IA);
- while (!DIDescriptor(Scope).isSubprogram()) {
- DILexicalBlockFile D(Scope);
- Scope = D.isLexicalBlockFile()
- ? D.getScope()
- : DebugLoc::getFromDILexicalBlock(Scope).getScope(Ctxt);
- }
- if (!DISubprogram(Scope).describes(F))
- return false;
- }
- }
- }
- return DbgNode->getNumOperands() == 9 && getNumHeaderFields() == 12;