How to access parsed C ++ 11 attributes using clang tools

This answer suggests that clang post version 165082 should store all parsed attributes in the AST.

At first, I realized that all attributes would be saved, but that doesn't seem to be the case:

$ clang++ -v Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) Target: x86_64-apple-darwin13.0.0 Thread model: posix $ cat att.cpp void f [[noreturn, foo]] () {} $ clang++ att.cpp -Xclang -ast-dump -fsyntax-only -std=c++11 att.cpp:1:20: warning: unknown attribute 'foo' ignored [-Wattributes] void f [[noreturn, foo]] () {} ^ att.cpp:1:30: warning: function declared 'noreturn' should not return [-Winvalid-noreturn] void f [[noreturn, foo]] () {} ^ TranslationUnitDecl 0x102021cd0 <<invalid sloc>> |-TypedefDecl 0x102022210 <<invalid sloc>> __int128_t '__int128' |-TypedefDecl 0x102022270 <<invalid sloc>> __uint128_t 'unsigned __int128' |-TypedefDecl 0x102022630 <<invalid sloc>> __builtin_va_list '__va_list_tag [1]' `-FunctionDecl 0x1020226d0 <att.cpp:1:1, col:30> f 'void (void)' |-CompoundStmt 0x1020227b0 <col:29, col:30> `-CXX11NoReturnAttr 0x102022770 <col:10> 2 warnings generated. 

In the above note, note that the "foo" attribute has indeed been ignored and is not in the AST, unlike the "noreturn" attribute.

Will the attribute β€œfoo” be stored in the AST at some point, or should all the attributes be part of the real compiler (defined in Attr.td, etc., as described in the clan’s Internal Documents Guide ), which should be stored in the AST?

+4
source share
1 answer

Attributes are stored in the AST only if they are already known by Clang, which are most of the GCC attributes and those defined by Clang. However, you can (kind of) add your own attributes using the hints from this link . This allows you to define any new attribute and then process it in ast as follows: For example, you took a line of code from the link above

 __attribute__((annotate("async"))) uint c; 

Then in your instance of RecursiveASTVisitor you can do the following:

  bool MyRecursiveASTVisitor::VisitVarDecl(VarDecl* v) { v->dump(); if(v->hasAttrs()){ clang::AttrVec vec = v->getAttrs(); printf("%s\n",vec[0]->getSpelling()); printf("%s\n", Lexer::getSourceText( CharSourceRange::getTokenRange( vec[0]->getRange()), compiler.getSourceManager(), langOpts).str().c_str()); } return true; } 

The first printf only prints "annotate", since it is the original attribute, to get the value that is interesting to use, we get the actual token from the lexer as a string.

Since we did not create a new attribute, we only get the attribute type append, but we can dig further and distinguish our new attribute. Not as elegant as the attribute just created (which may require changing the frog code itself), but it still works

+4
source

Source: https://habr.com/ru/post/926625/


All Articles