-
-
Save sheijk/b605641cd9744b4bc2ab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//===----------------------------------------------------------------------===// | |
// | |
// Small repro case to test how ParseAssemblyString will resolve references to | |
// types that are already defined in the module. | |
// | |
// If the parsed code uses a type foo_t that has been defined before in the | |
// module the parser will create a new opaque type foo_t.0 and use that | |
// instead. In contrast if foo_t gets defined inside the parsed code it will be | |
// used. (note: defining foo_t using the StructType::create has the same result | |
// as defining it using the parser). | |
// | |
// Change the variable `together' to true to see how the parser behaves when the | |
// type is defined at the same time as the code using it. | |
// | |
// I guess this change has been introduced during the changes to the type system | |
// in 3.0. Is there a way to use a type that has already been defined in the | |
// module before from code passed to ParseAssemblyString? | |
// | |
//===----------------------------------------------------------------------===// | |
// #include "llvm/Analysis/Verifier.h" | |
#include "llvm/AsmParser/Parser.h" | |
#include "llvm/ExecutionEngine/GenericValue.h" | |
#include "llvm/ExecutionEngine/Interpreter.h" | |
#include "llvm/ExecutionEngine/JIT.h" | |
#include "llvm/Support/SourceMgr.h" | |
#include "llvm/IR/Constants.h" | |
#include "llvm/IR/DerivedTypes.h" | |
#include "llvm/IR/Instructions.h" | |
#include "llvm/IR/LLVMContext.h" | |
#include "llvm/IR/Module.h" | |
#include "llvm/Support/TargetSelect.h" | |
#include "llvm/Support/raw_ostream.h" | |
#include <memory> | |
using namespace llvm; | |
/* Output with no args | |
---- Module after type: | |
; ModuleID = 'test' | |
%struct.foo_t = type { i32 } | |
declare void @dummy(%struct.foo_t) | |
---- module end | |
<string>:1:19: LLVM error: use of undefined type named 'struct.foo_t' | |
---- Module after func: | |
; ModuleID = 'test' | |
%struct.foo_t = type { i32 } | |
%struct.foo_t.0 = type opaque | |
declare void @dummy(%struct.foo_t) | |
declare void @func(%struct.foo_t.0*) | |
---- module end | |
*/ | |
/* Output with --combined | |
---- Module after type+func: | |
; ModuleID = 'test' | |
%struct.foo_t = type { i32 } | |
declare void @dummy(%struct.foo_t) | |
declare void @func(%struct.foo_t*) | |
---- module end | |
*/ | |
void ParseAndReport(LLVMContext& Context, Module& M, const char* action, const char* source) { | |
SMDiagnostic ErrorInfo; | |
Module *ParsedModule = ParseAssemblyString( source, &M, ErrorInfo, Context ); | |
if( !ErrorInfo.getMessage().empty() ) { | |
int line = ErrorInfo.getLineNo(); | |
fprintf( stderr, "%s:%d:%d: LLVM error: %s\n", | |
ErrorInfo.getFilename().data(), | |
line, | |
ErrorInfo.getColumnNo(), | |
ErrorInfo.getMessage().data() ); | |
} | |
errs() << "---- Module after " << action << ":\n" << M << "\n---- module end\n"; | |
} | |
int main(int argc, char **argv) { | |
bool combined = false; | |
if (argc <= 1) { | |
combined = false; | |
} | |
else if (argc == 2 && (argv[1] == std::string("--combined"))) { | |
combined = true; | |
} | |
else { | |
fprintf(stderr, "error: expected no args or --combined\n"); | |
exit(-1); | |
} | |
InitializeNativeTarget(); | |
LLVMContext Context; | |
// Create some module to put our function into it. | |
std::auto_ptr<Module> M(new Module("test", Context)); | |
// the dummy declaration is needed to keep the parser from omitting struct.foo_t | |
const char* CodeWithType = | |
"%struct.foo_t = type { i32 }\n" | |
"declare void @dummy(%struct.foo_t %p)\n"; | |
const char* CodeWithFunc = "declare void @func(%struct.foo_t* %ptr)\n"; | |
if(combined) { | |
std::string source = std::string(CodeWithType) + CodeWithFunc; | |
ParseAndReport(Context, *M.get(), "type+func", source.c_str()); | |
} | |
else { | |
ParseAndReport(Context, *M.get(), "type", CodeWithType); | |
ParseAndReport(Context, *M.get(), "func", CodeWithFunc); | |
} | |
return 0; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CXXFLAGS += -I $(LLVM_DIR)include | |
CXXFLAGS += $(shell $(LLVM_BIN_DIR)llvm-config --cxxflags) | |
llvm-parse: llvm-parse.o | |
$(CXX) $(shell $(LLVM_BIN_DIR)llvm-config --ldflags) $(shell $(LLVM_BIN_DIR)llvm-config --libs jit interpreter asmparser nativecodegen) -lz -lcurses $< -o $@ | |
llvm-parse.o: llvm-parse.cpp | |
$(CXX) -c $(CXXFLAGS) $< -o $@ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment