Index: lib/Analysis/NaCl/PNaClABIVerifyModule.cpp |
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp |
index 59addab087d0ae85ce6c9c53fa8b1c40fef60075..6b0243fbee59005003bd5fccb15979eb47ada2b8 100644 |
--- a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp |
+++ b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp |
@@ -14,8 +14,8 @@ |
//===----------------------------------------------------------------------===// |
#include "llvm/Pass.h" |
-#include "llvm/Analysis/NaCl.h" |
#include "llvm/ADT/Twine.h" |
+#include "llvm/Analysis/NaCl.h" |
#include "llvm/IR/DerivedTypes.h" |
#include "llvm/IR/Module.h" |
#include "llvm/Support/raw_ostream.h" |
@@ -28,13 +28,23 @@ namespace { |
class PNaClABIVerifyModule : public ModulePass { |
public: |
static char ID; |
- PNaClABIVerifyModule(); |
+ PNaClABIVerifyModule() : ModulePass(ID), |
+ Reporter(new PNaClABIErrorReporter), |
+ ReporterIsOwned(true) {} |
+ explicit PNaClABIVerifyModule(PNaClABIErrorReporter *Reporter_) : |
+ ModulePass(ID), |
+ Reporter(Reporter_), |
+ ReporterIsOwned(false) {} |
+ ~PNaClABIVerifyModule() { |
+ if (ReporterIsOwned) |
+ delete Reporter; |
+ } |
bool runOnModule(Module &M); |
virtual void print(raw_ostream &O, const Module *M) const; |
private: |
PNaClABITypeChecker TC; |
- std::string ErrorsString; |
- raw_string_ostream Errors; |
+ PNaClABIErrorReporter *Reporter; |
+ bool ReporterIsOwned; |
}; |
static const char *linkageName(GlobalValue::LinkageTypes LT) { |
@@ -65,26 +75,24 @@ static const char *linkageName(GlobalValue::LinkageTypes LT) { |
} // end anonymous namespace |
-PNaClABIVerifyModule::PNaClABIVerifyModule() : ModulePass(ID), |
- Errors(ErrorsString) {} |
- |
bool PNaClABIVerifyModule::runOnModule(Module &M) { |
for (Module::const_global_iterator MI = M.global_begin(), ME = M.global_end(); |
MI != ME; ++MI) { |
// Check types of global variables and their initializers |
if (!TC.isValidType(MI->getType())) { |
// GVs are pointers, so print the pointed-to type for clarity |
- Errors << "Variable " + MI->getName() + |
- " has disallowed type: " + |
+ Reporter->addError() << "Variable " << MI->getName() << |
+ " has disallowed type: " << |
PNaClABITypeChecker::getTypeName(MI->getType()->getContainedType(0)) |
+ "\n"; |
} else if (MI->hasInitializer()) { |
// If the type of the global is bad, no point in checking its initializer |
Type *T = TC.checkTypesInConstant(MI->getInitializer()); |
- if (T) |
- Errors << "Initializer for " + MI->getName() + |
- " has disallowed type: " + |
- PNaClABITypeChecker::getTypeName(T) + "\n"; |
+ if (T) { |
+ Reporter->addError() << "Initializer for " << MI->getName() << |
+ " has disallowed type: " << |
+ PNaClABITypeChecker::getTypeName(T) << "\n"; |
+ } |
} |
// Check GV linkage types |
@@ -95,28 +103,33 @@ bool PNaClABIVerifyModule::runOnModule(Module &M) { |
case GlobalValue::PrivateLinkage: |
break; |
default: |
- Errors << "Variable " + MI->getName() + |
- " has disallowed linkage type: " + |
- linkageName(MI->getLinkage()) + "\n"; |
+ Reporter->addError() << "Variable " << MI->getName() << |
+ " has disallowed linkage type: " << |
+ linkageName(MI->getLinkage()) << "\n"; |
} |
} |
// No aliases allowed for now. |
for (Module::alias_iterator MI = M.alias_begin(), |
- E = M.alias_end(); MI != E; ++MI) |
- Errors << "Variable " + MI->getName() + " is an alias (disallowed)\n"; |
+ E = M.alias_end(); MI != E; ++MI) { |
+ Reporter->addError() << "Variable " << MI->getName() << |
+ " is an alias (disallowed)\n"; |
+ } |
for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) { |
// Check types of functions and their arguments |
FunctionType *FT = MI->getFunctionType(); |
- if (!TC.isValidType(FT->getReturnType())) |
- Errors << "Function " + MI->getName() + " has disallowed return type: " + |
- PNaClABITypeChecker::getTypeName(FT->getReturnType()) + "\n"; |
+ if (!TC.isValidType(FT->getReturnType())) { |
+ Reporter->addError() << "Function " << MI->getName() << |
+ " has disallowed return type: " << |
+ PNaClABITypeChecker::getTypeName(FT->getReturnType()) << "\n"; |
+ } |
for (unsigned I = 0, E = FT->getNumParams(); I < E; ++I) { |
Type *PT = FT->getParamType(I); |
- if (!TC.isValidType(PT)) |
- Errors << "Function " << MI->getName() << " argument " << I + 1 << |
- " has disallowed type: " << |
- PNaClABITypeChecker::getTypeName(PT) + "\n"; |
+ if (!TC.isValidType(PT)) { |
+ Reporter->addError() << "Function " << MI->getName() << " argument " << |
+ I + 1 << " has disallowed type: " << |
+ PNaClABITypeChecker::getTypeName(PT) << "\n"; |
+ } |
} |
} |
@@ -124,18 +137,23 @@ bool PNaClABIVerifyModule::runOnModule(Module &M) { |
for (Module::const_named_metadata_iterator I = M.named_metadata_begin(), |
E = M.named_metadata_end(); I != E; ++I) { |
for (unsigned i = 0, e = I->getNumOperands(); i != e; i++) { |
- if (Type *T = TC.checkTypesInMDNode(I->getOperand(i))) |
- Errors << "Named metadata node " + I->getName() + |
- " refers to disallowed type: " + |
- PNaClABITypeChecker::getTypeName(T) + "\n"; |
+ if (Type *T = TC.checkTypesInMDNode(I->getOperand(i))) { |
+ Reporter->addError() << "Named metadata node " << I->getName() << |
+ " refers to 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 (this is more of an issue for the FunctionPass |
+// than the ModulePass) |
void PNaClABIVerifyModule::print(llvm::raw_ostream &O, const Module *M) const { |
- O << ErrorsString; |
+ Reporter->printErrors(O); |
+ Reporter->reset(); |
} |
char PNaClABIVerifyModule::ID = 0; |
@@ -143,6 +161,7 @@ char PNaClABIVerifyModule::ID = 0; |
static RegisterPass<PNaClABIVerifyModule> X("verify-pnaclabi-module", |
"Verify module for PNaCl", false, false); |
-ModulePass *llvm::createPNaClABIVerifyModulePass() { |
- return new PNaClABIVerifyModule(); |
+ModulePass *llvm::createPNaClABIVerifyModulePass( |
+ PNaClABIErrorReporter *Reporter) { |
+ return new PNaClABIVerifyModule(Reporter); |
} |