[cfe-commits] Avoid clang::SourceManger's cache

Manuel Klimek klimek at google.com
Tue Apr 24 14:07:53 PDT 2012


On Mon, Apr 23, 2012 at 4:12 PM, Vassil Vassilev <vvasilev at cern.ch> wrote:
> Hi,
>   I am working on the following example:
> [cling]$ #include <iostream>
> [cling]$ #include <fstream>
> [cling]$ std::ofstream myfile;
> [cling]$ myfile.open("TmpClassDef.h");
> [cling]$ myfile << "class MyClass{};\n"
> [cling]$ myfile << "error_here;";
> [cling]$ myfile.close();
> [cling]$ #include "TmpClassDef.h" <--- issues error and recovers and
> continues:
>
> [cling]$ myfile.open("TmpClassDef.h");
> [cling]$ myfile << "class MyClass{ \n";
> [cling]$ myfile << "public: \n";
> [cling]$ myfile << "  int gimme12(){\n";
> [cling]$ myfile << "    return 12;\n"
> [cling]$ myfile << "  }\n"
> [cling]$ myfile << "};\n";
> [cling]$ myfile.close();
> [cling]$ #include "TmpClassDef.h" <--- no errors
>
>   However at the last line I hit the SourceManager's cache and it picks
> up the old
> file (containing the errors).
>   My general question is : Is there a way remove the file from the cache?
>
>   I am trying to override the TmpClassDef.h file by using:
> SourceManager::overrideFileContents.
> The issue is that actually I am overriding the same file with itself. So
> if I try to get the
> llvm::MemoryBuffer for the same FileID I'd get again the cached one.

Please note that what I'm saying is based on an incomplete
understanding, so somebody with more knowledge might chime in and
declare that I'm utterly wrong :)

That said, here's what I gathered so far:
The SourceManager is optimized for the use on a single translation
unit - it is explicitly not made to be used multiple times with
different files. When I do refactoring stuff, for that very reason I
create one SourceManager for each run on a TU, and then create an
extra one afterwards that handles my use case of applying all changes.

Now it looks like you're kind of defeating the whole TU concept that
is pretty deeply ingrained in C++ by your incremental approach. My
best guess is that you have two options:
1. hack up SourceManager to be able to satisfy the use cases you have
(and convince the powers that are that this is actually a good idea
xD)
2. make your compilations look more like translation units; for
example, you could have a set of virtual files in memory and every
time somebody enters a line in the interpreter, create a new
SourceManager, map all the files you have in the FileManager and run
clang; unfortunately I don't know enough about cling to judge whether
that's feasible for you

Cheers,
/Manuel




More information about the cfe-commits mailing list