[PM] [cleanup] Rename some of the Verifier's members, re-arrange them,

and tweak comments prior to more invasive surgery. Also clean up some
other non-doxygen comments, and run clang-format over the parts that are
going to change dramatically in subsequent commits so that those don't
get cluttered with formatting changes.

No functionality changed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199489 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2014-01-17 11:09:34 +00:00
parent bd2c711cdd
commit 825488c539
2 changed files with 276 additions and 277 deletions

View File

@ -36,9 +36,9 @@ class Function;
/// this enumeration as an argument provides a default value for it. The
/// actions are listed below.
enum VerifierFailureAction {
AbortProcessAction, ///< verifyModule will print to stderr and abort()
PrintMessageAction, ///< verifyModule will print to stderr and return true
ReturnStatusAction ///< verifyModule will just return true
AbortProcessAction, ///< verifyModule will print to stderr and abort()
PrintMessageAction, ///< verifyModule will print to stderr and return true
ReturnStatusAction ///< verifyModule will just return true
};
/// \brief Create a verifier pass.
@ -51,6 +51,9 @@ createVerifierPass(VerifierFailureAction action = AbortProcessAction);
/// \brief Check a function for errors, useful for use when debugging a
/// pass.
///
/// If there are no errors, the function returns false. If an error is found,
/// the action taken depends on the \p action parameter.
bool verifyFunction(const Function &F,
VerifierFailureAction action = AbortProcessAction);

View File

@ -80,293 +80,296 @@ static cl::opt<bool> DisableDebugInfoVerifier("disable-debug-info-verifier",
cl::init(true));
namespace {
struct Verifier : public FunctionPass, public InstVisitor<Verifier> {
static char ID; // Pass ID, replacement for typeid
bool Broken; // Is this module found to be broken?
VerifierFailureAction action;
// What to do if verification fails.
Module *Mod; // Module we are verifying right now
LLVMContext *Context; // Context within which we are verifying
DominatorTree DT;
const DataLayout *DL;
struct Verifier : public FunctionPass, public InstVisitor<Verifier> {
static char ID;
std::string Messages;
raw_string_ostream MessagesStr;
// What to do if verification fails.
VerifierFailureAction Action;
/// InstInThisBlock - when verifying a basic block, keep track of all of the
/// instructions we have seen so far. This allows us to do efficient
/// dominance checks for the case when an instruction has an operand that is
/// an instruction in the same block.
SmallPtrSet<Instruction*, 16> InstsInThisBlock;
Module *M;
LLVMContext *Context;
const DataLayout *DL;
DominatorTree DT;
/// MDNodes - keep track of the metadata nodes that have been checked
/// already.
SmallPtrSet<MDNode *, 32> MDNodes;
bool Broken;
std::string Messages;
raw_string_ostream MessagesStr;
/// PersonalityFn - The personality function referenced by the
/// LandingPadInsts. All LandingPadInsts within the same function must use
/// the same personality function.
const Value *PersonalityFn;
/// \brief When verifying a basic block, keep track of all of the
/// instructions we have seen so far.
///
/// This allows us to do efficient dominance checks for the case when an
/// instruction has an operand that is an instruction in the same block.
SmallPtrSet<Instruction *, 16> InstsInThisBlock;
/// Finder keeps track of all debug info MDNodes in a Module.
DebugInfoFinder Finder;
/// \brief Keep track of the metadata nodes that have been checked already.
SmallPtrSet<MDNode *, 32> MDNodes;
Verifier()
: FunctionPass(ID), Broken(false),
action(AbortProcessAction), Mod(0), Context(0), DL(0),
MessagesStr(Messages), PersonalityFn(0) {
initializeVerifierPass(*PassRegistry::getPassRegistry());
}
explicit Verifier(VerifierFailureAction ctn)
: FunctionPass(ID), Broken(false), action(ctn), Mod(0),
Context(0), DL(0), MessagesStr(Messages), PersonalityFn(0) {
initializeVerifierPass(*PassRegistry::getPassRegistry());
}
/// \brief The personality function referenced by the LandingPadInsts.
/// All LandingPadInsts within the same function must use the same
/// personality function.
const Value *PersonalityFn;
bool doInitialization(Module &M) {
Mod = &M;
Context = &M.getContext();
/// \brief Finder keeps track of all debug info MDNodes in a Module.
DebugInfoFinder Finder;
DL = getAnalysisIfAvailable<DataLayout>();
Verifier()
: FunctionPass(ID), Action(AbortProcessAction), M(0), Context(0), DL(0),
Broken(false), MessagesStr(Messages), PersonalityFn(0) {
initializeVerifierPass(*PassRegistry::getPassRegistry());
}
explicit Verifier(VerifierFailureAction Action)
: FunctionPass(ID), Action(Action), M(0), Context(0), DL(0),
Broken(false), MessagesStr(Messages), PersonalityFn(0) {
initializeVerifierPass(*PassRegistry::getPassRegistry());
}
// We must abort before returning back to the pass manager, or else the
// pass manager may try to run other passes on the broken module.
return abortIfBroken();
}
bool doInitialization(Module &M) {
this->M = &M;
Context = &M.getContext();
bool runOnFunction(Function &F) {
Broken = false;
DL = getAnalysisIfAvailable<DataLayout>();
// First ensure the function is well-enough formed to compute dominance
// information.
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
if (I->empty() || !I->back().isTerminator()) {
dbgs() << "Basic Block in function '" << F.getName()
<< "' does not have terminator!\n";
I->printAsOperand(dbgs(), true);
dbgs() << "\n";
Broken = true;
}
// We must abort before returning back to the pass manager, or else the
// pass manager may try to run other passes on the broken module.
return abortIfBroken();
}
bool runOnFunction(Function &F) {
Broken = false;
// First ensure the function is well-enough formed to compute dominance
// information.
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
if (I->empty() || !I->back().isTerminator()) {
dbgs() << "Basic Block in function '" << F.getName()
<< "' does not have terminator!\n";
I->printAsOperand(dbgs(), true);
dbgs() << "\n";
Broken = true;
}
if (Broken)
return abortIfBroken();
}
if (Broken)
return abortIfBroken();
// Now directly compute a dominance tree. We don't rely on the pass
// manager to provide this as it isolates us from a potentially
// out-of-date dominator tree and makes it significantly more complex to
// run this code outside of a pass manager.
DT.recalculate(F);
// Now directly compute a dominance tree. We don't rely on the pass
// manager to provide this as it isolates us from a potentially
// out-of-date dominator tree and makes it significantly more complex to
// run this code outside of a pass manager.
DT.recalculate(F);
Mod = F.getParent();
if (!Context) Context = &F.getContext();
M = F.getParent();
if (!Context)
Context = &F.getContext();
Finder.reset();
visit(F);
InstsInThisBlock.clear();
PersonalityFn = 0;
if (!DisableDebugInfoVerifier)
// Verify Debug Info.
verifyDebugInfo();
// We must abort before returning back to the pass manager, or else the
// pass manager may try to run other passes on the broken module.
return abortIfBroken();
}
bool doFinalization(Module &M) {
// Scan through, checking all of the external function's linkage now...
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
visitGlobalValue(*I);
// Check to make sure function prototypes are okay.
if (I->isDeclaration())
visitFunction(*I);
}
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I)
visitGlobalVariable(*I);
for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;
++I)
visitGlobalAlias(*I);
for (Module::named_metadata_iterator I = M.named_metadata_begin(),
E = M.named_metadata_end();
I != E; ++I)
visitNamedMDNode(*I);
visitModuleFlags(M);
visitModuleIdents(M);
if (!DisableDebugInfoVerifier) {
Finder.reset();
visit(F);
InstsInThisBlock.clear();
PersonalityFn = 0;
if (!DisableDebugInfoVerifier)
// Verify Debug Info.
verifyDebugInfo();
// We must abort before returning back to the pass manager, or else the
// pass manager may try to run other passes on the broken module.
return abortIfBroken();
Finder.processModule(M);
// Verify Debug Info.
verifyDebugInfo();
}
bool doFinalization(Module &M) {
// Scan through, checking all of the external function's linkage now...
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
visitGlobalValue(*I);
// If the module is broken, abort at this time.
return abortIfBroken();
}
// Check to make sure function prototypes are okay.
if (I->isDeclaration()) visitFunction(*I);
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I)
visitGlobalVariable(*I);
for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
I != E; ++I)
visitGlobalAlias(*I);
for (Module::named_metadata_iterator I = M.named_metadata_begin(),
E = M.named_metadata_end(); I != E; ++I)
visitNamedMDNode(*I);
visitModuleFlags(M);
visitModuleIdents(M);
if (!DisableDebugInfoVerifier) {
Finder.reset();
Finder.processModule(M);
// Verify Debug Info.
verifyDebugInfo();
}
// If the module is broken, abort at this time.
return abortIfBroken();
/// abortIfBroken - If the module is broken and we are supposed to abort on
/// this condition, do so.
///
bool abortIfBroken() {
if (!Broken)
return false;
MessagesStr << "Broken module found, ";
switch (Action) {
case AbortProcessAction:
MessagesStr << "compilation aborted!\n";
dbgs() << MessagesStr.str();
// Client should choose different reaction if abort is not desired
abort();
case PrintMessageAction:
MessagesStr << "verification continues.\n";
dbgs() << MessagesStr.str();
return false;
case ReturnStatusAction:
MessagesStr << "compilation terminated.\n";
return true;
}
llvm_unreachable("Invalid action");
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
// Verification methods...
void visitGlobalValue(GlobalValue &GV);
void visitGlobalVariable(GlobalVariable &GV);
void visitGlobalAlias(GlobalAlias &GA);
void visitNamedMDNode(NamedMDNode &NMD);
void visitMDNode(MDNode &MD, Function *F);
void visitModuleIdents(Module &M);
void visitModuleFlags(Module &M);
void visitModuleFlag(MDNode *Op, DenseMap<MDString *, MDNode *> &SeenIDs,
SmallVectorImpl<MDNode *> &Requirements);
void visitFunction(Function &F);
void visitBasicBlock(BasicBlock &BB);
using InstVisitor<Verifier>::visit;
void visit(Instruction &I);
void visitTruncInst(TruncInst &I);
void visitZExtInst(ZExtInst &I);
void visitSExtInst(SExtInst &I);
void visitFPTruncInst(FPTruncInst &I);
void visitFPExtInst(FPExtInst &I);
void visitFPToUIInst(FPToUIInst &I);
void visitFPToSIInst(FPToSIInst &I);
void visitUIToFPInst(UIToFPInst &I);
void visitSIToFPInst(SIToFPInst &I);
void visitIntToPtrInst(IntToPtrInst &I);
void visitPtrToIntInst(PtrToIntInst &I);
void visitBitCastInst(BitCastInst &I);
void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
void visitPHINode(PHINode &PN);
void visitBinaryOperator(BinaryOperator &B);
void visitICmpInst(ICmpInst &IC);
void visitFCmpInst(FCmpInst &FC);
void visitExtractElementInst(ExtractElementInst &EI);
void visitInsertElementInst(InsertElementInst &EI);
void visitShuffleVectorInst(ShuffleVectorInst &EI);
void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); }
void visitCallInst(CallInst &CI);
void visitInvokeInst(InvokeInst &II);
void visitGetElementPtrInst(GetElementPtrInst &GEP);
void visitLoadInst(LoadInst &LI);
void visitStoreInst(StoreInst &SI);
void verifyDominatesUse(Instruction &I, unsigned i);
void visitInstruction(Instruction &I);
void visitTerminatorInst(TerminatorInst &I);
void visitBranchInst(BranchInst &BI);
void visitReturnInst(ReturnInst &RI);
void visitSwitchInst(SwitchInst &SI);
void visitIndirectBrInst(IndirectBrInst &BI);
void visitSelectInst(SelectInst &SI);
void visitUserOp1(Instruction &I);
void visitUserOp2(Instruction &I) { visitUserOp1(I); }
void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI);
void visitAtomicRMWInst(AtomicRMWInst &RMWI);
void visitFenceInst(FenceInst &FI);
void visitAllocaInst(AllocaInst &AI);
void visitExtractValueInst(ExtractValueInst &EVI);
void visitInsertValueInst(InsertValueInst &IVI);
void visitLandingPadInst(LandingPadInst &LPI);
void VerifyCallSite(CallSite CS);
bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty, int VT,
unsigned ArgNo, std::string &Suffix);
bool VerifyIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
SmallVectorImpl<Type *> &ArgTys);
bool VerifyIntrinsicIsVarArg(bool isVarArg,
ArrayRef<Intrinsic::IITDescriptor> &Infos);
bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params);
void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, bool isFunction,
const Value *V);
void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
bool isReturnValue, const Value *V);
void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
const Value *V);
void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy);
void VerifyConstantExprBitcastType(const ConstantExpr *CE);
void verifyDebugInfo();
void WriteValue(const Value *V) {
if (!V)
return;
if (isa<Instruction>(V)) {
MessagesStr << *V << '\n';
} else {
V->printAsOperand(MessagesStr, true, M);
MessagesStr << '\n';
}
}
/// abortIfBroken - If the module is broken and we are supposed to abort on
/// this condition, do so.
///
bool abortIfBroken() {
if (!Broken) return false;
MessagesStr << "Broken module found, ";
switch (action) {
case AbortProcessAction:
MessagesStr << "compilation aborted!\n";
dbgs() << MessagesStr.str();
// Client should choose different reaction if abort is not desired
abort();
case PrintMessageAction:
MessagesStr << "verification continues.\n";
dbgs() << MessagesStr.str();
return false;
case ReturnStatusAction:
MessagesStr << "compilation terminated.\n";
return true;
}
llvm_unreachable("Invalid action");
}
void WriteType(Type *T) {
if (!T)
return;
MessagesStr << ' ' << *T;
}
// CheckFailed - A check failed, so print out the condition and the message
// that failed. This provides a nice place to put a breakpoint if you want
// to see why something is not correct.
void CheckFailed(const Twine &Message, const Value *V1 = 0,
const Value *V2 = 0, const Value *V3 = 0,
const Value *V4 = 0) {
MessagesStr << Message.str() << "\n";
WriteValue(V1);
WriteValue(V2);
WriteValue(V3);
WriteValue(V4);
Broken = true;
}
// Verification methods...
void visitGlobalValue(GlobalValue &GV);
void visitGlobalVariable(GlobalVariable &GV);
void visitGlobalAlias(GlobalAlias &GA);
void visitNamedMDNode(NamedMDNode &NMD);
void visitMDNode(MDNode &MD, Function *F);
void visitModuleIdents(Module &M);
void visitModuleFlags(Module &M);
void visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*> &SeenIDs,
SmallVectorImpl<MDNode*> &Requirements);
void visitFunction(Function &F);
void visitBasicBlock(BasicBlock &BB);
using InstVisitor<Verifier>::visit;
void CheckFailed(const Twine &Message, const Value *V1, Type *T2,
const Value *V3 = 0) {
MessagesStr << Message.str() << "\n";
WriteValue(V1);
WriteType(T2);
WriteValue(V3);
Broken = true;
}
void visit(Instruction &I);
void visitTruncInst(TruncInst &I);
void visitZExtInst(ZExtInst &I);
void visitSExtInst(SExtInst &I);
void visitFPTruncInst(FPTruncInst &I);
void visitFPExtInst(FPExtInst &I);
void visitFPToUIInst(FPToUIInst &I);
void visitFPToSIInst(FPToSIInst &I);
void visitUIToFPInst(UIToFPInst &I);
void visitSIToFPInst(SIToFPInst &I);
void visitIntToPtrInst(IntToPtrInst &I);
void visitPtrToIntInst(PtrToIntInst &I);
void visitBitCastInst(BitCastInst &I);
void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
void visitPHINode(PHINode &PN);
void visitBinaryOperator(BinaryOperator &B);
void visitICmpInst(ICmpInst &IC);
void visitFCmpInst(FCmpInst &FC);
void visitExtractElementInst(ExtractElementInst &EI);
void visitInsertElementInst(InsertElementInst &EI);
void visitShuffleVectorInst(ShuffleVectorInst &EI);
void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); }
void visitCallInst(CallInst &CI);
void visitInvokeInst(InvokeInst &II);
void visitGetElementPtrInst(GetElementPtrInst &GEP);
void visitLoadInst(LoadInst &LI);
void visitStoreInst(StoreInst &SI);
void verifyDominatesUse(Instruction &I, unsigned i);
void visitInstruction(Instruction &I);
void visitTerminatorInst(TerminatorInst &I);
void visitBranchInst(BranchInst &BI);
void visitReturnInst(ReturnInst &RI);
void visitSwitchInst(SwitchInst &SI);
void visitIndirectBrInst(IndirectBrInst &BI);
void visitSelectInst(SelectInst &SI);
void visitUserOp1(Instruction &I);
void visitUserOp2(Instruction &I) { visitUserOp1(I); }
void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI);
void visitAtomicRMWInst(AtomicRMWInst &RMWI);
void visitFenceInst(FenceInst &FI);
void visitAllocaInst(AllocaInst &AI);
void visitExtractValueInst(ExtractValueInst &EVI);
void visitInsertValueInst(InsertValueInst &IVI);
void visitLandingPadInst(LandingPadInst &LPI);
void VerifyCallSite(CallSite CS);
bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty,
int VT, unsigned ArgNo, std::string &Suffix);
bool VerifyIntrinsicType(Type *Ty,
ArrayRef<Intrinsic::IITDescriptor> &Infos,
SmallVectorImpl<Type*> &ArgTys);
bool VerifyIntrinsicIsVarArg(bool isVarArg,
ArrayRef<Intrinsic::IITDescriptor> &Infos);
bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params);
void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
bool isFunction, const Value *V);
void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
bool isReturnValue, const Value *V);
void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
const Value *V);
void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy);
void VerifyConstantExprBitcastType(const ConstantExpr *CE);
void verifyDebugInfo();
void WriteValue(const Value *V) {
if (!V) return;
if (isa<Instruction>(V)) {
MessagesStr << *V << '\n';
} else {
V->printAsOperand(MessagesStr, true, Mod);
MessagesStr << '\n';
}
}
void WriteType(Type *T) {
if (!T) return;
MessagesStr << ' ' << *T;
}
// CheckFailed - A check failed, so print out the condition and the message
// that failed. This provides a nice place to put a breakpoint if you want
// to see why something is not correct.
void CheckFailed(const Twine &Message,
const Value *V1 = 0, const Value *V2 = 0,
const Value *V3 = 0, const Value *V4 = 0) {
MessagesStr << Message.str() << "\n";
WriteValue(V1);
WriteValue(V2);
WriteValue(V3);
WriteValue(V4);
Broken = true;
}
void CheckFailed(const Twine &Message, const Value *V1,
Type *T2, const Value *V3 = 0) {
MessagesStr << Message.str() << "\n";
WriteValue(V1);
WriteType(T2);
WriteValue(V3);
Broken = true;
}
void CheckFailed(const Twine &Message, Type *T1,
Type *T2 = 0, Type *T3 = 0) {
MessagesStr << Message.str() << "\n";
WriteType(T1);
WriteType(T2);
WriteType(T3);
Broken = true;
}
};
void CheckFailed(const Twine &Message, Type *T1, Type *T2 = 0, Type *T3 = 0) {
MessagesStr << Message.str() << "\n";
WriteType(T1);
WriteType(T2);
WriteType(T3);
Broken = true;
}
};
} // End anonymous namespace
char Verifier::ID = 0;
@ -2064,7 +2067,7 @@ void Verifier::visitInstruction(Instruction &I) {
Assert1(!F->isIntrinsic() || isa<CallInst>(I) ||
F->getIntrinsicID() == Intrinsic::donothing,
"Cannot invoke an intrinsinc other than donothing", &I);
Assert1(F->getParent() == Mod, "Referencing function in another module!",
Assert1(F->getParent() == M, "Referencing function in another module!",
&I);
} else if (BasicBlock *OpBB = dyn_cast<BasicBlock>(I.getOperand(i))) {
Assert1(OpBB->getParent() == BB->getParent(),
@ -2073,7 +2076,7 @@ void Verifier::visitInstruction(Instruction &I) {
Assert1(OpArg->getParent() == BB->getParent(),
"Referring to an argument in another function!", &I);
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(I.getOperand(i))) {
Assert1(GV->getParent() == Mod, "Referencing global in another module!",
Assert1(GV->getParent() == M, "Referencing global in another module!",
&I);
} else if (isa<Instruction>(I.getOperand(i))) {
verifyDominatesUse(I, i);
@ -2124,7 +2127,7 @@ void Verifier::visitInstruction(Instruction &I) {
if (!DisableDebugInfoVerifier) {
MD = I.getMetadata(LLVMContext::MD_dbg);
Finder.processLocation(*Mod, DILocation(MD));
Finder.processLocation(*M, DILocation(MD));
}
InstsInThisBlock.insert(&I);
@ -2302,13 +2305,13 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
Assert1(MD->getNumOperands() == 1,
"invalid llvm.dbg.declare intrinsic call 2", &CI);
if (!DisableDebugInfoVerifier)
Finder.processDeclare(*Mod, cast<DbgDeclareInst>(&CI));
Finder.processDeclare(*M, cast<DbgDeclareInst>(&CI));
} break;
case Intrinsic::dbg_value: { //llvm.dbg.value
if (!DisableDebugInfoVerifier) {
Assert1(CI.getArgOperand(0) && isa<MDNode>(CI.getArgOperand(0)),
"invalid llvm.dbg.value intrinsic call 1", &CI);
Finder.processValue(*Mod, cast<DbgValueInst>(&CI));
Finder.processValue(*M, cast<DbgValueInst>(&CI));
}
break;
}
@ -2403,12 +2406,8 @@ FunctionPass *llvm::createVerifierPass(VerifierFailureAction action) {
return new Verifier(action);
}
/// verifyFunction - Check a function for errors, printing messages on stderr.
/// Return true if the function is corrupt.
///
bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) {
Function &F = const_cast<Function&>(f);
Function &F = const_cast<Function &>(f);
assert(!F.isDeclaration() && "Cannot verify external functions");
FunctionPassManager FPM(F.getParent());
@ -2419,15 +2418,12 @@ bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) {
return V->Broken;
}
/// verifyModule - Check a module for errors, printing messages on stderr.
/// Return true if the module is corrupt.
///
bool llvm::verifyModule(const Module &M, VerifierFailureAction action,
std::string *ErrorInfo) {
PassManager PM;
Verifier *V = new Verifier(action);
PM.add(V);
PM.run(const_cast<Module&>(M));
PM.run(const_cast<Module &>(M));
if (ErrorInfo && V->Broken)
*ErrorInfo = V->MessagesStr.str();