<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="text-align:left; direction:ltr;">
<div>Hello Ilya,</div>
<div><br>
</div>
<div>thank you for the fast reply. I do not know why I missed that.</div>
<div><br>
</div>
<div>Nevertheless, is the traversal order correct?</div>
<div><br>
</div>
<div>Cheers</div>
<div><br>
</div>
<div>Max</div>
<div><br>
</div>
<div>On Thu, 2019-07-18 at 09:40 +0200, Ilya Biryukov wrote:</div>
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
<div dir="ltr">Hi Max,
<div><br>
</div>
<div>You can get the attributes with Decl::attrs() method (also available for FunctionDecl).</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Thu, Jul 18, 2019 at 9:28 AM Max Sagebaum via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br>
</div>
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
<div style="text-align:left;direction:ltr">
<div>Hello @ all,</div>
<div><br>
</div>
<div>I want to annotate some function and generate some additional properties for the annotated functions in an xml document. My problem is, that the AST traversal seems to traverse the attributes of the function after the traversal of the function has been
 finished. I could not find any valuable resources on this topic by searching via google. So I am addressing my question here.</div>
<div><br>
</div>
<div>(Since I do not know if file attachments are allowed I provide the files as comments.)</div>
<div><br>
</div>
<div>My test files is: (attributeTest.cpp)</div>
<div><br>
</div>
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
<div>void func1()</div>
<div>__attribute((annotate(R"(Test)"))) {</div>
<div>  int a = 1 + 1;</div>
<div>}</div>
</blockquote>
<div><br>
</div>
<div>clang-check gives me the correct hierarchy: clang-check --ast-dump attributeTest.cpp</div>
<div></div>
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
<div>TranslationUnitDecl 0x559b4c7dc598 <<invalid sloc>> <invalid sloc></div>
<div>|-TypedefDecl 0x559b4c7dce70 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'</div>
<div>| `-BuiltinType 0x559b4c7dcb30 '__int128'</div>
<div>|-TypedefDecl 0x559b4c7dced8 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'</div>
<div>| `-BuiltinType 0x559b4c7dcb50 'unsigned __int128'</div>
<div>|-TypedefDecl 0x559b4c7dd208 <<invalid sloc>> <invalid sloc> implicit __NSConstantString '__NSConstantString_tag'</div>
<div>| `-RecordType 0x559b4c7dcfb0 '__NSConstantString_tag'</div>
<div>|   `-CXXRecord 0x559b4c7dcf28 '__NSConstantString_tag'</div>
<div>|-TypedefDecl 0x559b4c7dd2a0 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'</div>
<div>| `-PointerType 0x559b4c7dd260 'char *'</div>
<div>|   `-BuiltinType 0x559b4c7dc630 'char'</div>
<div>|-TypedefDecl 0x559b4c818958 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag [1]'</div>
<div>| `-ConstantArrayType 0x559b4c818900 '__va_list_tag [1]' 1 </div>
<div>|   `-RecordType 0x559b4c7dd380 '__va_list_tag'</div>
<div>|     `-CXXRecord 0x559b4c7dd2f0 '__va_list_tag'</div>
<div>`-FunctionDecl 0x559b4c818a98 </home/msagebaum/Kaiserslautern/Programms/adDSLParser/temp/attributeTest.cpp:1:1, line:4:1> line:1:6 func1 'void ()'</div>
<div>  |-CompoundStmt 0x559b4c818cb0 <line:2:36, line:4:1></div>
<div>  | `-DeclStmt 0x559b4c818c98 <line:3:3, col:16></div>
<div>  |   `-VarDecl 0x559b4c818bd8 <col:3, col:15> col:7 a 'int' cinit</div>
<div>  |     `-BinaryOperator 0x559b4c818c78 <col:11, col:15> 'int' '+'</div>
<div>  |       |-IntegerLiteral 0x559b4c818c38 <col:11> 'int' 1</div>
<div>  |       `-IntegerLiteral 0x559b4c818c58 <col:15> 'int' 1</div>
<div>  `-AnnotateAttr 0x559b4c818b30 <line:2:14, col:32> "Test"</div>
</blockquote>
<div><br>
</div>
<div>If I now run the file through my AST Visitor: (parserTest.cpp)</div>
<div><br>
</div>
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
<div>#include <iostream></div>
<div><br>
</div>
<div>#include "clang/AST/ASTConsumer.h"</div>
<div>#include "clang/AST/QualTypeNames.h"</div>
<div>#include "clang/AST/RecursiveASTVisitor.h"</div>
<div>#include "clang/Frontend/CompilerInstance.h"</div>
<div>#include "clang/Frontend/FrontendAction.h"</div>
<div>#include "clang/Tooling/CommonOptionsParser.h"</div>
<div>#include "clang/Tooling/Tooling.h"</div>
<div><br>
</div>
<div>#include <llvm/Support/CommandLine.h></div>
<div><br>
</div>
<div>using namespace llvm;</div>
<div>using namespace clang;</div>
<div>using namespace clang::tooling;</div>
<div><br>
</div>
<div>class XMLGenerator : public RecursiveASTVisitor<XMLGenerator> {</div>
<div>public:</div>
<div><br>
</div>
<div>  bool TraverseFunctionDecl(FunctionDecl *declaration) {</div>
<div><br>
</div>
<div>    std::cout << "Function start" << std::endl;</div>
<div><br>
</div>
<div>    RecursiveASTVisitor<XMLGenerator>::TraverseFunctionDecl(declaration);</div>
<div><br>
</div>
<div>    std::cout << "Function end" << std::endl;</div>
<div>    return true;</div>
<div>  }</div>
<div><br>
</div>
<div>  bool TraverseAnnotateAttr(AnnotateAttr *a) {</div>
<div>    std::cout << "Annotation start" << std::endl;</div>
<div><br>
</div>
<div>    RecursiveASTVisitor<XMLGenerator>::TraverseAnnotateAttr(a);</div>
<div><br>
</div>
<div>    std::cout << "Annotation end" << std::endl;</div>
<div>    return true;</div>
<div>  }</div>
<div>};</div>
<div><br>
</div>
<div>class XMLGeneratorClassConsumer : public clang::ASTConsumer {</div>
<div>public:</div>
<div>  explicit XMLGeneratorClassConsumer()</div>
<div>    : Visitor() {}</div>
<div><br>
</div>
<div>  virtual void HandleTranslationUnit(clang::ASTContext &Context) {</div>
<div>    Visitor.TraverseDecl(Context.getTranslationUnitDecl());</div>
<div>  }</div>
<div>private:</div>
<div>  XMLGenerator Visitor;</div>
<div>};</div>
<div><br>
</div>
<div>class XMLGeneratorClassAction : public clang::ASTFrontendAction {</div>
<div>public:</div>
<div>  virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(</div>
<div>    clang::CompilerInstance &Compiler, llvm::StringRef InFile) {</div>
<div>    return std::unique_ptr<clang::ASTConsumer>(</div>
<div>        new XMLGeneratorClassConsumer());</div>
<div>  }</div>
<div>};</div>
<div><br>
</div>
<div>static llvm::cl::OptionCategory MyToolCategory("my-tool options");</div>
<div><br>
</div>
<div>int main(int argc, const char **argv) {</div>
<div>  CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);</div>
<div>  ClangTool Tool(OptionsParser.getCompilations(),</div>
<div>                 OptionsParser.getSourcePathList());</div>
<div><br>
</div>
<div>  return Tool.run(newFrontendActionFactory<XMLGeneratorClassAction>().get());</div>
<div>}</div>
</blockquote>
<div><br>
</div>
<div>Compilation: (compile.sh)</div>
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
<div>g++ -g -O0 -Wall -pedantic -std=c++11 -fno-rtti -c parserTest.cpp -o parserTest.o -I/usr/include</div>
<div>g++ -g -O0 -Wall -pedantic -std=c++11 -fno-rtti -o parserTest.exe parserTest.o -L/usr/lib64  -Wl,--start-group -lclangAnalysis -lclangParse -lclangEdit -lclangSema -lclangTooling -lclangDriver -lclangSerialization -lclangFrontend -lclangBasic -lclangASTMatchers
 -lclangAST -lclangLex -lLLVM-8 -Wl,--end-group -lpthread -lz</div>
</blockquote>
<div><br>
</div>
<div>The result is:</div>
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
<div>Function start</div>
<div>Function end</div>
<div>Annotation start</div>
<div>Annotation end</div>
</blockquote>
<div><br>
</div>
<div>What I would expect is:</div>
<blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex">
<div>Function start</div>
<div>Annotation start</div>
<div>Annotation end</div>
<div>Function end</div>
</blockquote>
<div><br>
</div>
<div>My questions are now:</div>
<div>Is the order provided by my implementation the correct one or is the expected order the correct one?</div>
<div>Is there a way to change the visitor order such that attributes are visited inside of the function?</div>
<div>If not: Is there a way to get a list of attributes from 'FunctionDecl'? (Could not find any methods in the api <a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html" target="_blank">https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html</a>)</div>
<div><br>
</div>
<div>Thanks in advance for any help.</div>
<div><br>
</div>
<div>Cheers</div>
<div><br>
</div>
<div>Max</div>
</div>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote>
</div>
<br clear="all">
<div><br>
</div>
</blockquote>
<div><span>
<pre>-- <br></pre>
<div style="width: 71ch;">Dr. Max Sagebaum</div>
<div style="width: 71ch;"><br>
</div>
<div style="width: 71ch;">Chair for Scientific Computing,</div>
<div style="width: 71ch;">TU Kaiserslautern,</div>
<div style="width: 71ch;">Bldg/Geb 34, Paul-Ehrlich-Strasse,</div>
<div style="width: 71ch;">67663 Kaiserslautern, Germany</div>
<div style="width: 71ch;"><br>
</div>
<div style="width: 71ch;">Phone: +49 (0)631 205 5638</div>
<div style="width: 71ch;">Fax:   +49 (0)631 205 3056</div>
<div style="width: 71ch;">Email: <a href="mailto:max.sagebaum@scicomp.uni-kl.de">
max.sagebaum@scicomp.uni-kl.de</a></div>
<div style="width: 71ch;">URL:   <a href="www.scicomp.uni-kl.de">www.scicomp.uni-kl.de</a></div>
<div style="width: 71ch;"><br>
</div>
<div style="width: 71ch;"><br>
</div>
<div style="width: 71ch;"><br>
</div>
<div style="width: 71ch;"><br>
</div>
<div style="width: 71ch;"><br>
</div>
<div style="width: 71ch;"><br>
</div>
</span></div>
</body>
</html>