forked from OSchip/llvm-project
Change the ModuleProvider interface to not throw exceptions.
llvm-svn: 29024
This commit is contained in:
parent
0e316b4dbf
commit
3d40daa474
|
@ -18,6 +18,8 @@
|
||||||
#ifndef MODULEPROVIDER_H
|
#ifndef MODULEPROVIDER_H
|
||||||
#define MODULEPROVIDER_H
|
#define MODULEPROVIDER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class Function;
|
class Function;
|
||||||
|
@ -35,22 +37,24 @@ public:
|
||||||
///
|
///
|
||||||
Module* getModule() { return TheModule; }
|
Module* getModule() { return TheModule; }
|
||||||
|
|
||||||
/// materializeFunction - make sure the given function is fully read. Note
|
/// materializeFunction - make sure the given function is fully read. If the
|
||||||
/// that this can throw an exception if the module is corrupt!
|
/// 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
|
||||||
materializeModule();
|
if (materializeModule(ErrInfo))
|
||||||
|
return 0;
|
||||||
Module *tempM = TheModule;
|
Module *tempM = TheModule;
|
||||||
TheModule = 0;
|
TheModule = 0;
|
||||||
return tempM;
|
return tempM;
|
||||||
|
@ -66,8 +70,10 @@ struct ExistingModuleProvider : public ModuleProvider {
|
||||||
ExistingModuleProvider(Module *M) {
|
ExistingModuleProvider(Module *M) {
|
||||||
TheModule = M;
|
TheModule = M;
|
||||||
}
|
}
|
||||||
void materializeFunction(Function *F) {}
|
bool materializeFunction(Function *F, std::string *ErrInfo = 0) {
|
||||||
Module* materializeModule() { return TheModule; }
|
return false;
|
||||||
|
}
|
||||||
|
Module* materializeModule(std::string *ErrInfo = 0) { return TheModule; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
|
@ -153,18 +153,33 @@ public:
|
||||||
/// implementation is identical to the ParseFunction method.
|
/// implementation is identical to the ParseFunction method.
|
||||||
/// @see ParseFunction
|
/// @see ParseFunction
|
||||||
/// @brief Make a specific function materialize.
|
/// @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;
|
if (Fi == LazyFunctionLoadMap.end()) return false;
|
||||||
ParseFunction(F);
|
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
|
/// This method is abstract in the parent ModuleProvider class. Its
|
||||||
/// implementation is identical to ParseAllFunctionBodies.
|
/// implementation is identical to ParseAllFunctionBodies.
|
||||||
/// @see ParseAllFunctionBodies
|
/// @see ParseAllFunctionBodies
|
||||||
/// @brief Make the whole module materialize
|
/// @brief Make the whole module materialize
|
||||||
virtual Module* materializeModule() {
|
virtual Module* materializeModule(std::string *ErrInfo = 0) {
|
||||||
ParseAllFunctionBodies();
|
try {
|
||||||
|
ParseAllFunctionBodies();
|
||||||
|
} catch (std::string &ErrStr) {
|
||||||
|
if (ErrInfo) *ErrInfo = ErrStr;
|
||||||
|
return 0;
|
||||||
|
} catch (...) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return TheModule;
|
return TheModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,8 @@ static ModuleProvider* CheckVarargs(ModuleProvider* MP) {
|
||||||
|
|
||||||
// If we get to this point, we know that we have an old-style module.
|
// If we get to this point, we know that we have an old-style module.
|
||||||
// Materialize the whole thing to perform the rewriting.
|
// Materialize the whole thing to perform the rewriting.
|
||||||
MP->materializeModule();
|
if (MP->materializeModule() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if(Function* F = M->getNamedFunction("llvm.va_start")) {
|
if(Function* F = M->getNamedFunction("llvm.va_start")) {
|
||||||
assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!");
|
assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!");
|
||||||
|
@ -376,22 +377,18 @@ static void getSymbols(Module*M, std::vector<std::string>& symbols) {
|
||||||
// Get just the externally visible defined symbols from the bytecode
|
// Get just the externally visible defined symbols from the bytecode
|
||||||
bool llvm::GetBytecodeSymbols(const sys::Path& fName,
|
bool llvm::GetBytecodeSymbols(const sys::Path& fName,
|
||||||
std::vector<std::string>& symbols) {
|
std::vector<std::string>& symbols) {
|
||||||
try {
|
std::auto_ptr<ModuleProvider> AMP(
|
||||||
std::auto_ptr<ModuleProvider> AMP(
|
getBytecodeModuleProvider(fName.toString()));
|
||||||
getBytecodeModuleProvider(fName.toString()));
|
|
||||||
|
|
||||||
// Get the module from the provider
|
// Get the module from the provider
|
||||||
Module* M = AMP->materializeModule();
|
Module* M = AMP->materializeModule();
|
||||||
|
if (M == 0) return false;
|
||||||
|
|
||||||
// Get the symbols
|
// Get the symbols
|
||||||
getSymbols(M, symbols);
|
getSymbols(M, symbols);
|
||||||
|
|
||||||
// Done with the module
|
// Done with the module
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} catch (...) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleProvider*
|
ModuleProvider*
|
||||||
|
@ -406,6 +403,7 @@ llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length,
|
||||||
|
|
||||||
// Get the module from the provider
|
// Get the module from the provider
|
||||||
Module* M = MP->materializeModule();
|
Module* M = MP->materializeModule();
|
||||||
|
if (M == 0) return 0;
|
||||||
|
|
||||||
// Get the symbols
|
// Get the symbols
|
||||||
getSymbols(M, symbols);
|
getSymbols(M, symbols);
|
||||||
|
|
|
@ -95,14 +95,10 @@ FunctionPassManager::~FunctionPassManager() { delete PM; }
|
||||||
void FunctionPassManager::add(FunctionPass *P) { PM->add(P); }
|
void FunctionPassManager::add(FunctionPass *P) { PM->add(P); }
|
||||||
void FunctionPassManager::add(ImmutablePass *IP) { PM->add(IP); }
|
void FunctionPassManager::add(ImmutablePass *IP) { PM->add(IP); }
|
||||||
bool FunctionPassManager::run(Function &F) {
|
bool FunctionPassManager::run(Function &F) {
|
||||||
try {
|
std::string errstr;
|
||||||
MP->materializeFunction(&F);
|
if (MP->materializeFunction(&F, &errstr)) {
|
||||||
} catch (std::string& errstr) {
|
|
||||||
std::cerr << "Error reading bytecode file: " << errstr << "\n";
|
std::cerr << "Error reading bytecode file: " << errstr << "\n";
|
||||||
abort();
|
abort();
|
||||||
} catch (...) {
|
|
||||||
std::cerr << "Error reading bytecode file!\n";
|
|
||||||
abort();
|
|
||||||
}
|
}
|
||||||
return PM->run(F);
|
return PM->run(F);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue