[cfe-dev] Source rewrite

ether zhhb etherzhhb at gmail.com
Mon Dec 21 19:23:46 PST 2009


hi,

its there any simple example that shows us how to rewrite the source
code that clang just parsed?

best regards

--ether

On Sat, Dec 19, 2009 at 1:10 AM, Abramo Bagnara <abramobagnara at tin.it> wrote:
>>> As I write above, what I need is that the AST built from:
>>>
>>> int p() {
>>>  int a = 3;
>>>  /* #instrument(a)# */
>>> }
>>>
>>> is as if the source read was:
>>>
>>> int p() {
>>>  int a = 3;
>>>  instrument(a);
>>> }
>>
>>
>> Oh, interesting. You'll probably need to each the preprocessor how to
>> parse inside these comments. One option might be to treat such comments
>> similarly to macro expansion, so that processing the comment
>>
>>   /* #instrument(a)# */
>>
>> consumes the comment and then pushes a new lexer that will point into a
>> buffer containing
>>
>>   instrument(a)
>>
>> just like processing
>>
>>   FOO
>>
>> where there is a macro definition
>>
>>   #define FOO instrument(a)
>>
>> will create a new lexer pointing into a buffer containing
>>
>>   instrument(a)
>
> I've done it and it "almost" works...
>
> The problem I see is that the pushed TokenLexer is used only *after* the
> first token after the comment is Lexed and not just after the skipped
> comment (because usually the comment is not a token to return).
>
> This means that:
>
> int x /* = 0 */;
> int z;
>
> is lexed as:
>
> int x; = 0 int z;
>
> instead of the wished way.
>
> Now I'm stuck...
>
> There is a way to cope with that?
>
> My CommentHandler is written in this way:
>
> void Comment_Converter::HandleComment(clang::Preprocessor &PP,
>                                      clang::SourceRange Comment) {
>  const clang::SourceManager &sm = PP.getSourceManager();
>  const clang::LangOptions &lo = PP.getLangOptions();
>  clang::SourceLocation begin = Comment.getBegin();
>  clang::FileID fid = sm.getFileID(begin);
>  const char* start = sm.getCharacterData(begin);
>  const char* end = sm.getCharacterData(Comment.getEnd());
>  if (start[1] == '*')
>    end -= 2;
>  start += 2;
>  char saved = *end;
>  *const_cast<char*>(end) = 0;
>  clang::Lexer lexer(sm.getLocForStartOfFile(fid), lo,
>                     sm.getBufferData(fid).first,
>                     start, end);
>  static std::vector<clang::Token> tokens;
>  tokens.clear();
>  clang::Token tok;
>  while (1) {
>    lexer.LexFromRawLexer(tok);
>    if (tok.is(clang::tok::eof))
>      break;
>    if (tok.is(clang::tok::identifier))
>      tok.setKind(PP.LookUpIdentifierInfo(tok)->getTokenID());
>    tokens.push_back(tok);
>  }
>  *const_cast<char*>(end) = saved;
>  PP.EnterTokenStream(tokens.data(), tokens.size(), false, false);
> }
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>




More information about the cfe-dev mailing list