diff --git a/include/llvm/ModuleProvider.h b/include/llvm/ModuleProvider.h index 2f185e01d35..b42a5036e5c 100644 --- a/include/llvm/ModuleProvider.h +++ b/include/llvm/ModuleProvider.h @@ -18,6 +18,8 @@ #ifndef MODULEPROVIDER_H #define MODULEPROVIDER_H +#include + namespace llvm { class Function; @@ -35,22 +37,24 @@ public: /// Module* getModule() { return TheModule; } - /// materializeFunction - make sure the given function is fully read. Note - /// that this can throw an exception if the module is corrupt! + /// materializeFunction - make sure the given function is fully read. If the + /// module is corrupt, this returns true and fills in the optional string + /// with information about the problem. If successful, this returns false. /// - virtual void materializeFunction(Function *F) = 0; + virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0) = 0; /// materializeModule - make sure the entire Module has been completely read. - /// Note that this can throw an exception if the module is corrupt! + /// On error, return null and fill in the error string if specified. /// - virtual Module* materializeModule() = 0; + virtual Module* materializeModule(std::string *ErrInfo = 0) = 0; /// releaseModule - no longer delete the Module* when provider is destroyed. - /// Note that this can throw an exception if the module is corrupt! + /// On error, return null and fill in the error string if specified. /// - virtual Module* releaseModule() { + virtual Module* releaseModule(std::string *ErrInfo = 0) { // Since we're losing control of this Module, we must hand it back complete - materializeModule(); + if (materializeModule(ErrInfo)) + return 0; Module *tempM = TheModule; TheModule = 0; return tempM; @@ -66,8 +70,10 @@ struct ExistingModuleProvider : public ModuleProvider { ExistingModuleProvider(Module *M) { TheModule = M; } - void materializeFunction(Function *F) {} - Module* materializeModule() { return TheModule; } + bool materializeFunction(Function *F, std::string *ErrInfo = 0) { + return false; + } + Module* materializeModule(std::string *ErrInfo = 0) { return TheModule; } }; } // End llvm namespace diff --git a/lib/Bytecode/Reader/Reader.h b/lib/Bytecode/Reader/Reader.h index ffc251b64ef..9cecf52436f 100644 --- a/lib/Bytecode/Reader/Reader.h +++ b/lib/Bytecode/Reader/Reader.h @@ -153,18 +153,33 @@ public: /// implementation is identical to the ParseFunction method. /// @see ParseFunction /// @brief Make a specific function materialize. - virtual void materializeFunction(Function *F) { + virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0) { LazyFunctionMap::iterator Fi = LazyFunctionLoadMap.find(F); - if (Fi == LazyFunctionLoadMap.end()) return; - ParseFunction(F); + if (Fi == LazyFunctionLoadMap.end()) return false; + try { + ParseFunction(F); + } catch (std::string &ErrStr) { + if (ErrInfo) *ErrInfo = ErrStr; + return true; + } catch (...) { + return true; + } + return false; } /// This method is abstract in the parent ModuleProvider class. Its /// implementation is identical to ParseAllFunctionBodies. /// @see ParseAllFunctionBodies /// @brief Make the whole module materialize - virtual Module* materializeModule() { - ParseAllFunctionBodies(); + virtual Module* materializeModule(std::string *ErrInfo = 0) { + try { + ParseAllFunctionBodies(); + } catch (std::string &ErrStr) { + if (ErrInfo) *ErrInfo = ErrStr; + return 0; + } catch (...) { + return 0; + } return TheModule; } diff --git a/lib/Bytecode/Reader/ReaderWrappers.cpp b/lib/Bytecode/Reader/ReaderWrappers.cpp index 956d1ede696..b9e7cd29aac 100644 --- a/lib/Bytecode/Reader/ReaderWrappers.cpp +++ b/lib/Bytecode/Reader/ReaderWrappers.cpp @@ -170,7 +170,8 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) { // If we get to this point, we know that we have an old-style module. // Materialize the whole thing to perform the rewriting. - MP->materializeModule(); + if (MP->materializeModule() == 0) + return 0; if(Function* F = M->getNamedFunction("llvm.va_start")) { assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!"); @@ -376,22 +377,18 @@ static void getSymbols(Module*M, std::vector& symbols) { // Get just the externally visible defined symbols from the bytecode bool llvm::GetBytecodeSymbols(const sys::Path& fName, std::vector& symbols) { - try { - std::auto_ptr AMP( - getBytecodeModuleProvider(fName.toString())); + std::auto_ptr AMP( + getBytecodeModuleProvider(fName.toString())); - // Get the module from the provider - Module* M = AMP->materializeModule(); + // Get the module from the provider + Module* M = AMP->materializeModule(); + if (M == 0) return false; - // Get the symbols - getSymbols(M, symbols); + // Get the symbols + getSymbols(M, symbols); - // Done with the module - return true; - - } catch (...) { - return false; - } + // Done with the module + return true; } ModuleProvider* @@ -406,6 +403,7 @@ llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length, // Get the module from the provider Module* M = MP->materializeModule(); + if (M == 0) return 0; // Get the symbols getSymbols(M, symbols); diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index a7160f1f1ee..dc49ac6aeec 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -95,14 +95,10 @@ FunctionPassManager::~FunctionPassManager() { delete PM; } void FunctionPassManager::add(FunctionPass *P) { PM->add(P); } void FunctionPassManager::add(ImmutablePass *IP) { PM->add(IP); } bool FunctionPassManager::run(Function &F) { - try { - MP->materializeFunction(&F); - } catch (std::string& errstr) { + std::string errstr; + if (MP->materializeFunction(&F, &errstr)) { std::cerr << "Error reading bytecode file: " << errstr << "\n"; abort(); - } catch (...) { - std::cerr << "Error reading bytecode file!\n"; - abort(); } return PM->run(F); }