#ifndef MODULEPROVIDER_H
#define MODULEPROVIDER_H
#ifndef MODULEPROVIDER_H
#define MODULEPROVIDER_H
namespace llvm {
class Function;
namespace llvm {
class Function;
///
Module* getModule() { return TheModule; }
///
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.
/// 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.
/// 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
// Since we're losing control of this Module, we must hand it back complete
+ if (materializeModule(ErrInfo))
+ return 0;
Module *tempM = TheModule;
TheModule = 0;
return tempM;
Module *tempM = TheModule;
TheModule = 0;
return tempM;
ExistingModuleProvider(Module *M) {
TheModule = M;
}
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
};
} // End llvm namespace
/// implementation is identical to the ParseFunction method.
/// @see ParseFunction
/// @brief Make a specific function materialize.
/// 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);
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
}
/// 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;
+ }
// If we get to this point, we know that we have an old-style module.
// Materialize the whole thing to perform the rewriting.
// 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!");
if(Function* F = M->getNamedFunction("llvm.va_start")) {
assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!");
// Get just the externally visible defined symbols from the bytecode
bool llvm::GetBytecodeSymbols(const sys::Path& fName,
std::vector<std::string>& symbols) {
// Get just the externally visible defined symbols from the bytecode
bool llvm::GetBytecodeSymbols(const sys::Path& fName,
std::vector<std::string>& symbols) {
- try {
- std::auto_ptr<ModuleProvider> AMP(
- getBytecodeModuleProvider(fName.toString()));
+ std::auto_ptr<ModuleProvider> 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;
// Get the module from the provider
Module* M = MP->materializeModule();
// Get the module from the provider
Module* M = MP->materializeModule();
// Get the symbols
getSymbols(M, symbols);
// Get the symbols
getSymbols(M, symbols);
void FunctionPassManager::add(FunctionPass *P) { PM->add(P); }
void FunctionPassManager::add(ImmutablePass *IP) { PM->add(IP); }
bool FunctionPassManager::run(Function &F) {
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();
std::cerr << "Error reading bytecode file: " << errstr << "\n";
abort();
- } catch (...) {
- std::cerr << "Error reading bytecode file!\n";
- abort();