#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Debug.h"
Node->replaceAllUsesWith(D);
}
-bool DICompileUnit::Verify() const {
- if (!isCompileUnit())
- return false;
-
- // Don't bother verifying the compilation directory or producer string
- // as those could be empty.
- return !getFilename().empty();
-}
-
+bool DICompileUnit::Verify() const { return isCompileUnit(); }
bool DIObjCProperty::Verify() const { return isObjCProperty(); }
/// \brief Check if a value can be a reference to a type.
auto *N = dyn_cast_or_null<MDType>(DbgNode);
if (!N)
return false;
- if (!isScopeRef(N->getScope()))
- return false;
-
- // DIType is abstract, it should be a BasicType, a DerivedType or
- // a CompositeType.
- if (isBasicType())
- return DIBasicType(DbgNode).Verify();
-
- // FIXME: Sink this into the various subclass verifies.
- if (getFilename().empty()) {
- // Check whether the filename is allowed to be empty.
- uint16_t Tag = getTag();
- if (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 &&
- Tag != dwarf::DW_TAG_structure_type && Tag != dwarf::DW_TAG_member &&
- Tag != dwarf::DW_TAG_typedef)
- return false;
- }
if (isCompositeType())
return DICompositeType(DbgNode).Verify();
- if (isDerivedType())
- return DIDerivedType(DbgNode).Verify();
- return false;
+ return true;
}
-bool DIBasicType::Verify() const {
- return dyn_cast_or_null<MDBasicType>(DbgNode);
-}
-
-bool DIDerivedType::Verify() const {
- auto *N = dyn_cast_or_null<MDDerivedTypeBase>(DbgNode);
- if (!N)
- return false;
- if (getTag() == dwarf::DW_TAG_ptr_to_member_type) {
- auto *D = dyn_cast<MDDerivedType>(N);
- if (!D)
- return false;
- if (!isTypeRef(D->getExtraData()))
- return false;
- }
- return isTypeRef(N->getBaseType());
-}
+bool DIBasicType::Verify() const { return isBasicType(); }
+bool DIDerivedType::Verify() const { return isDerivedType(); }
bool DICompositeType::Verify() const {
auto *N = dyn_cast_or_null<MDCompositeTypeBase>(DbgNode);
- return N && isTypeRef(N->getBaseType()) && isTypeRef(N->getVTableHolder()) &&
- !(isLValueReference() && isRValueReference());
+ return N && !(isLValueReference() && isRValueReference());
}
bool DISubprogram::Verify() const {
if (!N)
return false;
- if (!isScopeRef(N->getScope()))
- return false;
-
- if (auto *Op = N->getType())
- if (!isa<MDNode>(Op))
- return false;
-
- if (!isTypeRef(getContainingType()))
- return false;
-
if (isLValueReference() && isRValueReference())
return false;
if (auto *F = getFunction()) {
for (auto &BB : *F) {
for (auto &I : BB) {
- DebugLoc DL = I.getDebugLoc();
- if (DL.isUnknown())
+ MDLocation *DL = I.getDebugLoc();
+ if (!DL)
continue;
- MDNode *Scope = nullptr;
- MDNode *IA = nullptr;
// walk the inlined-at scopes
- while ((IA = DL.getInlinedAt()))
- DL = DebugLoc::getFromDILocation(IA);
- DL.getScopeAndInlinedAt(Scope, IA);
+ MDScope *Scope = DL->getInlinedAtScope();
if (!Scope)
return false;
- assert(!IA);
- while (!DIDescriptor(Scope).isSubprogram()) {
- DILexicalBlockFile D(Scope);
- Scope = D.isLexicalBlockFile()
- ? D.getScope()
- : DebugLoc::getFromDILexicalBlock(Scope).getScope();
+ while (!isa<MDSubprogram>(Scope)) {
+ Scope = cast<MDLexicalBlockBase>(Scope)->getScope();
if (!Scope)
return false;
}
return true;
}
-bool DIGlobalVariable::Verify() const {
- auto *N = dyn_cast_or_null<MDGlobalVariable>(DbgNode);
-
- if (!N)
- return false;
-
- if (N->getDisplayName().empty())
- return false;
-
- if (auto *Op = N->getScope())
- if (!isa<MDNode>(Op))
- return false;
-
- if (auto *Op = N->getStaticDataMemberDeclaration())
- if (!isa<MDNode>(Op))
- return false;
-
- return isTypeRef(N->getType());
-}
-
-bool DIVariable::Verify() const {
- auto *N = dyn_cast_or_null<MDLocalVariable>(DbgNode);
-
- if (!N)
- return false;
-
- if (auto *Op = N->getScope())
- if (!isa<MDNode>(Op))
- return false;
-
- return isTypeRef(N->getType());
-}
+bool DIGlobalVariable::Verify() const { return isGlobalVariable(); }
+bool DIVariable::Verify() const { return isVariable(); }
bool DILocation::Verify() const {
return dyn_cast_or_null<MDLocation>(DbgNode);
// We look for the first instr that has a debug annotation leading back to F.
for (auto &BB : *F) {
auto Inst = std::find_if(BB.begin(), BB.end(), [](const Instruction &Inst) {
- return !Inst.getDebugLoc().isUnknown();
+ return Inst.getDebugLoc();
});
if (Inst == BB.end())
continue;
DebugLoc DLoc = Inst->getDebugLoc();
- const MDNode *Scope = DLoc.getScopeNode();
+ const MDNode *Scope = DLoc.getInlinedAtScope();
DISubprogram Subprogram = getDISubprogram(Scope);
return Subprogram.describes(F) ? Subprogram : DISubprogram();
}
static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS,
const LLVMContext &Ctx) {
- if (!DL.isUnknown()) { // Print source line info.
- DIScope Scope(DL.getScope(Ctx));
- assert(Scope.isScope() && "Scope of a DebugLoc should be a DIScope.");
- // Omit the directory, because it's likely to be long and uninteresting.
- CommentOS << Scope.getFilename();
- CommentOS << ':' << DL.getLine();
- if (DL.getCol() != 0)
- CommentOS << ':' << DL.getCol();
- DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx));
- if (!InlinedAtDL.isUnknown()) {
- CommentOS << " @[ ";
- printDebugLoc(InlinedAtDL, CommentOS, Ctx);
- CommentOS << " ]";
- }
- }
+ if (!DL)
+ return;
+
+ DIScope Scope(DL.getScope());
+ assert(Scope.isScope() && "Scope of a DebugLoc should be a DIScope.");
+ // Omit the directory, because it's likely to be long and uninteresting.
+ CommentOS << Scope.getFilename();
+ CommentOS << ':' << DL.getLine();
+ if (DL.getCol() != 0)
+ CommentOS << ':' << DL.getCol();
+
+ DebugLoc InlinedAtDL = DL.getInlinedAt();
+ if (!InlinedAtDL)
+ return;
+
+ CommentOS << " @[ ";
+ printDebugLoc(InlinedAtDL, CommentOS, Ctx);
+ CommentOS << " ]";
}
void DIVariable::printExtendedName(raw_ostream &OS) const {
StringRef Res = getName();
if (!Res.empty())
OS << Res << "," << getLineNumber();
- if (MDNode *InlinedAt = getInlinedAt()) {
- DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt);
- if (!InlinedAtDL.isUnknown()) {
+ if (auto *InlinedAt = get()->getInlinedAt()) {
+ if (DebugLoc InlinedAtDL = InlinedAt) {
OS << " @[";
printDebugLoc(InlinedAtDL, OS, Ctx);
OS << "]";
return DITypeRef(cast_or_null<Metadata>(getField(DbgNode, Elt)));
}
+bool llvm::stripDebugInfo(Function &F) {
+ bool Changed = false;
+ for (BasicBlock &BB : F) {
+ for (Instruction &I : BB) {
+ if (I.getDebugLoc()) {
+ Changed = true;
+ I.setDebugLoc(DebugLoc());
+ }
+ }
+ }
+ return Changed;
+}
+
bool llvm::StripDebugInfo(Module &M) {
bool Changed = false;
}
}
- for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
- for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE;
- ++FI)
- for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE;
- ++BI) {
- if (!BI->getDebugLoc().isUnknown()) {
- Changed = true;
- BI->setDebugLoc(DebugLoc());
- }
- }
+ for (Function &F : M)
+ Changed |= stripDebugInfo(F);
+
+ if ( GVMaterializer *Materializer = M.getMaterializer())
+ Materializer->setStripDebugInfo();
return Changed;
}