[cfe-dev] Source rewrite

Abramo Bagnara abramobagnara at tin.it
Fri Dec 18 09:10:06 PST 2009


>> 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);
}





More information about the cfe-dev mailing list