Index: lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
index fa94733ef04fab95c98414bd97dc06e4b1e55837..ab8130f32ea5161998685a7b4bd156c99765795b 100644 |
--- a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
+++ b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp |
@@ -14,11 +14,11 @@ |
#include "llvm/Pass.h" |
#include "llvm/ADT/Twine.h" |
+#include "llvm/Analysis/NaCl.h" |
#include "llvm/IR/Function.h" |
#include "llvm/IR/Instructions.h" |
#include "llvm/IR/Metadata.h" |
#include "llvm/Support/raw_ostream.h" |
-#include "llvm/Analysis/NaCl.h" |
#include "PNaClABITypeChecker.h" |
using namespace llvm; |
@@ -30,22 +30,29 @@ namespace { |
class PNaClABIVerifyFunctions : public FunctionPass { |
public: |
static char ID; |
- PNaClABIVerifyFunctions() : FunctionPass(ID), Errors(ErrorsString) {} |
+ PNaClABIVerifyFunctions() : FunctionPass(ID), |
+ Reporter(new PNaClABIErrorReporter), |
+ ReporterIsOwned(true) {} |
+ explicit PNaClABIVerifyFunctions(PNaClABIErrorReporter *Reporter_) : |
+ FunctionPass(ID), |
+ Reporter(Reporter_), |
+ ReporterIsOwned(false) {} |
+ ~PNaClABIVerifyFunctions() { |
+ if (ReporterIsOwned) |
+ delete Reporter; |
+ } |
bool runOnFunction(Function &F); |
virtual void print(raw_ostream &O, const Module *M) const; |
private: |
PNaClABITypeChecker TC; |
- std::string ErrorsString; |
- raw_string_ostream Errors; |
+ PNaClABIErrorReporter *Reporter; |
+ bool ReporterIsOwned; |
}; |
} // and anonymous namespace |
bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
- // For now just start with new errors on each function; this may change |
- // once we want to do something with them other than just calling print() |
- ErrorsString.clear(); |
- // TODO: only report one error per instruction |
+ // TODO: only report one error per instruction? |
for (Function::const_iterator FI = F.begin(), FE = F.end(); |
FI != FE; ++FI) { |
for (BasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end(); |
@@ -59,7 +66,7 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
case Instruction::ExtractElement: |
case Instruction::InsertElement: |
case Instruction::ShuffleVector: |
- Errors << "Function " + F.getName() + |
+ Reporter->addError() << "Function " + F.getName() + |
" has disallowed instruction: " + |
BBI->getOpcodeName() + "\n"; |
break; |
@@ -126,7 +133,7 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
} |
// Check the types. First check the type of the instruction. |
if (!TC.isValidType(BBI->getType())) { |
- Errors << "Function " + F.getName() + |
+ Reporter->addError() << "Function " + F.getName() + |
" has instruction with disallowed type: " + |
PNaClABITypeChecker::getTypeName(BBI->getType()) + "\n"; |
} |
@@ -141,10 +148,11 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
OI != OE; OI++) { |
if (isa<Constant>(OI) && !isa<GlobalValue>(OI)) { |
Type *T = TC.checkTypesInConstant(cast<Constant>(*OI)); |
- if (T) |
- Errors << "Function " + F.getName() + |
+ if (T) { |
+ Reporter->addError() << "Function " + F.getName() + |
" has instruction operand with disallowed type: " + |
PNaClABITypeChecker::getTypeName(T) + "\n"; |
+ } |
} |
} |
@@ -153,21 +161,25 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
BBI->getAllMetadataOtherThanDebugLoc(MDForInst); |
for (unsigned i = 0, e = MDForInst.size(); i != e; i++) { |
Type *T = TC.checkTypesInMDNode(MDForInst[i].second); |
- if (T) |
- Errors << "Function " + F.getName() + |
+ if (T) { |
+ Reporter->addError() << "Function " + F.getName() + |
" has instruction metadata containing disallowed type: " + |
PNaClABITypeChecker::getTypeName(T) + "\n"; |
+ } |
} |
} |
} |
- Errors.flush(); |
return false; |
} |
+// This method exists so that the passes can easily be run with opt -analyze. |
+// In this case the default constructor is used and we want to reset the error |
+// messages after each print. |
void PNaClABIVerifyFunctions::print(llvm::raw_ostream &O, const Module *M) |
const { |
- O << ErrorsString; |
+ Reporter->printErrors(O); |
+ Reporter->reset(); |
} |
char PNaClABIVerifyFunctions::ID = 0; |
@@ -175,6 +187,7 @@ char PNaClABIVerifyFunctions::ID = 0; |
static RegisterPass<PNaClABIVerifyFunctions> X("verify-pnaclabi-functions", |
"Verify functions for PNaCl", false, false); |
-FunctionPass *llvm::createPNaClABIVerifyFunctionsPass() { |
- return new PNaClABIVerifyFunctions(); |
+FunctionPass *llvm::createPNaClABIVerifyFunctionsPass( |
+ PNaClABIErrorReporter *Reporter) { |
+ return new PNaClABIVerifyFunctions(Reporter); |
} |