libclang preprocessed code erroneous while clang++ -E preprocesses correctly

Hi,

I have been writing a code generator/parser for one of my projects with libclang+libtooling for the past couple of days. (https://github.com/inexor-game/code/tree/karo/tree-gen/inexor/rpc/gluegen)

In it I am using annotations like `__attribute__((annotate("Key=Value"))`.

Now since that syntax is a bit unpleasant, I am using macros to generate it:

  #if defined(__GNUC__) && !defined(COMPILER_ICC)
      #define INEXOR_ANNOT(...) __attribute__((annotate(#__VA_ARGS__)))
  #else
      #define INEXOR_ANNOT(...)
  #endif

  #define INEXOR_SHARED_TREE(...) INEXOR_ANNOT(SharedTree=__VA_ARGS__)

Invocation:

INEXOR_SHARED_TREE(/my/path/in/tree) int x = 42;

When I run this trough my application, the preprocessor does not expand the INEXOR_ANNOT macro correctly:

./gluegen ../../fpsgame/weapon.cpp -- -I../../../ -I/usr/include/SDL2 --std=c++14 -I/usr/lib/clang/3.7.0/include/ -I/usr/include/linux

I've added some debug output to my application; I am manually parsing the annotation to extract the key value pair; the code below is the attribute's SourceRange:

annotate(#__VA_ARGS__

The macro invocation being expanded here looks like

INEXOR_SHARED_TREE(settings/blood) ...

When I run this through gcc -E, cpp or clang -E the code expands quite fine:

  ```__attribute__((annotate("SharedTree=settings/blood"))) ...```

I've also tried running my tool against the already preprocessed file and then the annotation is parsed fine, so I think it might be a problem with the preprocesson invocation.

Any thoughts would be much appreciated!

Thank You,
Karolin Varner

Hi again,

I found the problem and was able to fix it, so this is just for reference in case anyone else runs into similar problems.

The libclang preprocessing was in fact very correct. I was assuming the SourceManager/SourceLocation APIs where referencing preprocessed output, but in fact, they where not. I saw the output I was getting simply because the SourceLocation was a reference *into* the macro definition.

Now I had to find another way to access the data, so I searched for a way to access the preprocessed code, but I could not find any.
Luckily I noticed that there is a class called AnnotateAttr that handles extracting the annotation quite nicely. Simply clang::cast the attr and use getAnnotation();

  clang::Attr *attr = ...;
  clang::AnnotateAttr *annot = clang::cast<clang::AnnotateAttr>(attr);
  if (attr) {
    llvm::StringRef text_ref = annot->getAnnotation();
    std::cout.write(text_ref.data(), text_ref.size());
  }

I couldn't find that class initially because it seems to be
not documented in the doxygen doc. I only found it by
searching through the clang code.

Is it correct that that class (and AttributeVisitor for
instance too) are undocumented?

Best,
Karolin Varner