Good to hear it confirmed that it *should* work! I must be doing something daft...
What would the full path name be? I want a directive like #include "remapped.h" to resolve to the contents of a preloaded buffer.
Tried 'faking it' with a path like /usr/local/remapped.h? -> error src line 10 col 10: 'remapped.h' file not found
Here's the relevant code (ModuleImpl is just a wrapper around llvm::Module) - if you see anything that looks awry, or out of order (literally), let me know!
bool compile(ModuleImpl * mImpl, std::string code) {
const char * src = code.data();
llvm::StringRef input_data(src);
llvm::StringRef buffer_name("src");
llvm::MemoryBuffer *buffer = llvm::MemoryBuffer::getMemBufferCopy(input_data, buffer_name);
if(!buffer) {
printf("couldn't create buffer\n");
}
CompilerInstance CI;
CI.createDiagnostics(0, NULL);
Diagnostic & Diags = CI.getDiagnostics();
TextDiagnosticBuffer * client = new TextDiagnosticBuffer;
Diags.setClient(client);
CompilerInvocation::CreateFromArgs(CI.getInvocation(), NULL, NULL, Diags);
LangOptions& lang = CI.getInvocation().getLangOpts();
lang.CPlusPlus = 1;
lang.Bool = 1;
lang.BCPLComment = 1;
lang.RTTI = 0;
lang.PICLevel = 1;
CI.createSourceManager();
CI.getSourceManager().createMainFileIDForMemBuffer(buffer);
CI.createFileManager();
// Create the target instance.
CI.setTarget(TargetInfo::CreateTargetInfo(CI.getDiagnostics(), CI.getTargetOpts()));
CI.createPreprocessor();
Preprocessor &PP = CI.getPreprocessor();
// Header paths:
HeaderSearchOptions& headeropts = CI.getHeaderSearchOpts();
for (unsigned int i=0; i<options.system_includes.size(); i++) {
headeropts.AddPath(options.system_includes[i], clang::frontend::Angled, true, false, false/* true ? */);
}
for (unsigned int i=0; i<options.user_includes.size(); i++) {
headeropts.AddPath(options.user_includes[i], clang::frontend::Quoted, true, false, false/* true ? */);
}
ApplyHeaderSearchOptions(PP.getHeaderSearchInfo(), headeropts, lang, CI.getTarget().getTriple());
/*
The goal is for clang to be able to resolve #include "remapped.h" (or <remapped.h> to the contents of the StringRef remapped_data.
*/
// add file remapping:
// (doesn't work)
llvm::StringRef remapped_name("remapped.h");
//llvm::StringRef remapped_name("/usr/include/remapped.h");
// some test code:
llvm::StringRef remapped_data("#include <stdio.h> \n void remapped() { printf(\"remapped!\\n\");");
llvm::MemoryBuffer * remapped_buffer = llvm::MemoryBuffer::getMemBufferCopy(remapped_data, remapped_name);
CI.getPreprocessorOpts().addRemappedFile(remapped_name, remapped_buffer);
PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), PP.getLangOptions().NoBuiltin);
CI.createASTContext();
CodeGenOptions CGO;
CodeGenerator * codegen = CreateLLVMCodeGen(Diags, "mymodule", CGO, mImpl->llvmContext );
ParseAST(CI.getPreprocessor(),
codegen,
CI.getASTContext(),
/* PrintState= */ false,
true,
0);
llvm::Module* module = codegen->ReleaseModule();
delete codegen;
/// etc.
}