I am using antlr to translate a custom language to C++ code.
In this language, user can embed C++ code snippets between $code...$endcode
directives, that gets inserted into the translated C++code as-is.
I have the following problem: When there is an error in the code snippet I would like the compiler to point to the source file rather than the translated C++ code.
I tried using line directives as follows, but it didn't work:
"foo.custom_laguage"
1 $code
2 ...some c++ code...
3 $endcode
gets translated to
"auto-generated.cpp"
42 #line 2 "foo.custom_language"
43 ...some c++ code...
44 #line __LINE__ __FILE__
This doesn't work, I think because #line directive modifies what gets written by the __LINE__
macro later. How can I set line number back to the actual line number in the translated C++ code? How does antlr do this?
Here is what I want the auto-generated code to look like:
"auto-generated.cpp"
42 #line 2 "foo.custom_language"
43 ...some c++ code...
44 #line 44 "auto-generated.cpp" //actual line in this file
45 ..some more C++ code ...
edit: I just found out that there is a way to do this in C# language by using a #line default
directive:
http://msdn.microsoft.com/en-us/library/34dk387t.aspx
But couldn't find anything similar for C++
It's not clear from the question, but you're generating the #line
directives yourself given source-line
and source-file
? I'm sorry, I'm not familiar with Antlr.
Indeed, #line __LINE__ __FILE__
does nothing but assign the __LINE__
macro to itself.
Because of the evaluation semantics of the preprocessor, you can't easily assign the numeric value of __LINE__
to a macro. (You can only define a new macro to map to the macro __LINE__
literally, returning its current value.) But why do you need that? Unless Antlr itself uses the __LINE__
macro, you don't need to restore it to its previous value.
If it is an issue, the most straightforward solution would be to put the raw C++ code in separate include
files and forgo the inline embedding. To prevent proliferation of header files, you could use a construct like
$code
#define USE_SNIPPET_FOO
#include "snippets.h"
$endcode
$code
#define USE_SNIPPET_BAR
#include "snippets.h"
$endcode
and in the header, a kind of reverse header guard:
#ifdef USE_SNIPPET_FOO
#undef USE_SNIPPET_FOO
class foo {};
#elif defined USE_SNIPPET_BAR
#undef USE_SNIPPET_BAR
class bar {};
#else
#error no snippet selected
#endif
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With