<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;
mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:#0563C1;
text-decoration:underline;}
code
{mso-style-priority:99;
font-family:"Courier New";}
pre
{mso-style-priority:99;
mso-style-link:"HTML Preformatted Char";
margin:0cm;
font-size:10.0pt;
font-family:"Courier New";}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri",sans-serif;
color:windowtext;}
span.HTMLPreformattedChar
{mso-style-name:"HTML Preformatted Char";
mso-style-priority:99;
mso-style-link:"HTML Preformatted";
font-family:"Courier New";
mso-fareast-language:EN-GB;}
span.hljs-string
{mso-style-name:hljs-string;}
span.hljs-keyword
{mso-style-name:hljs-keyword;}
span.hljs-function
{mso-style-name:hljs-function;}
span.hljs-title
{mso-style-name:hljs-title;}
span.hljs-params
{mso-style-name:hljs-params;}
span.hljs-literal
{mso-style-name:hljs-literal;}
span.hljs-comment
{mso-style-name:hljs-comment;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri",sans-serif;
mso-fareast-language:EN-US;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style>
</head>
<body lang="EN-GB" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Hi,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I am trying to move up the AST from a CallExpr. I am using Recursive Visitors to match on the target CallExpr I am interested in.
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The function AST I am trying to recurse upwards from looks like this<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">|-FunctionDecl 0x564865171688 prev 0x56486516d948 <line:101:1, line:110:1> line:101:6 used print_json_array 'void (json_t *, int)'<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| |-ParmVarDecl 0x564865171580 <col:23, col:31> col:31 used element 'json_t *'<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| |-ParmVarDecl 0x5648651715f8 <col:40, col:44> col:44 used indent 'int'<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| `-CompoundStmt 0x564865172048 <col:52, line:110:1><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| |-DeclStmt 0x5648651717c0 <line:102:5, col:13><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| | `-VarDecl 0x564865171748 <col:5, col:12> col:12 used i 'size_t':'unsigned long'<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| |-DeclStmt 0x564865171910 <line:103:5, col:43><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| | `-VarDecl 0x5648651717e8 <col:5, col:42> col:12 used size 'size_t':'unsigned long' cinit<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| | `-CallExpr 0x5648651718b0 <col:19, col:42> 'size_t':'unsigned long'<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| | |-ImplicitCastExpr 0x564865171898 <col:19> 'size_t (*)(const json_t *)' <FunctionToPointerDecay><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| | | `-DeclRefExpr 0x564865171848 <col:19> 'size_t (const json_t *)' Function 0x564865161cd8 'json_array_size' 'size_t (const json_t *)'<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| | `-ImplicitCastExpr 0x5648651718f8 <col:35> 'const json_t *' <BitCast><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| | `-ImplicitCastExpr 0x5648651718e0 <col:35> 'json_t *' <LValueToRValue><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New";mso-fareast-language:EN-GB">| | `-DeclRefExpr 0x564865171870 <col:35> 'json_t *' lvalue ParmVar 0x564865171580 'element' 'json_t *'<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p>I am following the suggestion here <a href="http://clang-developers.42468.n3.nabble.com/acquiring-all-the-ancestors-or-descendants-of-a-matched-node-td4052601.html">
http://clang-developers.42468.n3.nabble.com/acquiring-all-the-ancestors-or-descendants-of-a-matched-node-td4052601.html</a> to get the functiondecl of the CallExpr.<o:p></o:p></p>
<p>This is what the upwards traversal looks like<o:p></o:p></p>
<pre><span class="hljs-keyword">const</span><span class="hljs-function"> FunctionDecl* </span><span class="hljs-title">Visitor::getParentFunctionDecl</span><span class="hljs-params">(</span><span class="hljs-keyword">const</span><span class="hljs-params"> clang::Stmt& stmt)</span><code>{<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">auto</span><code> it = astContext.getParents(stmt).begin();<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">if</span><code>(it == astContext.getParents(stmt).end()) </code><span class="hljs-keyword">return</span><code> </code><span class="hljs-literal">nullptr</span><code>;<o:p></o:p></code></pre>
<pre><code><o:p> </o:p></code></pre>
<pre><code> outs() << </code><span class="hljs-string">"Current Node Kind: "</span><code> << it->getNodeKind().asStringRef() << </code><span class="hljs-string">"\n"</span><code>;<o:p></o:p></code></pre>
<pre><code><o:p> </o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">const</span><code> FunctionDecl *fDecl = it->get<FunctionDecl>();<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">if</span><code>(fDecl){<o:p></o:p></code></pre>
<pre><code> outs() << </code><span class="hljs-string">"Got function Decl!\n"</span><code> ;<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">return</span><code> fDecl;<o:p></o:p></code></pre>
<pre><code> }<o:p></o:p></code></pre>
<pre><code><o:p> </o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">const</span><code> Stmt *aStmt = it->get<Stmt>();<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">if</span><code>(aStmt){<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">return</span><code> getParentFunctionDecl(*aStmt);<o:p></o:p></code></pre>
<pre><code> }<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-comment">//nothing worked</span><code><o:p></o:p></code></pre>
<pre><code> errs() << </code><span class="hljs-string">"Nothing worked\n"</span><code>;<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">return</span><code> </code><span class="hljs-literal">nullptr</span><code>;<o:p></o:p></code></pre>
<pre><code>}</code><o:p></o:p></pre>
<p>The problem I am running into is getting the parent of the VarDecl which is the DeclStmt in my function.<o:p></o:p></p>
<p>I tried something like<o:p></o:p></p>
<pre><code> </code><span class="hljs-keyword">const</span><code> VarDecl *var = it->get<VarDecl>();<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">if</span><code>(var){<o:p></o:p></code></pre>
<pre><code> outs() << </code><span class="hljs-string">"Got a VarDecl\n"</span><code>;<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">auto</span><code> decl = astContext.getParents(dyn_cast<Decl>(var)).begin();<o:p></o:p></code></pre>
<pre><code> outs() << </code><span class="hljs-string">"Parent of VarDecl: "</span><code> << decl->getNodeKind().asStringRef() << </code><span class="hljs-string">"\n"</span><code>;<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">const</span><code> DeclStmt *declStmt = decl->get<DeclStmt>();<o:p></o:p></code></pre>
<pre><code> </code><span class="hljs-keyword">return</span><code> getParentFunctionDecl(dyn_cast<Stmt>(decl));<o:p></o:p></code></pre>
<pre><code> }</code><o:p></o:p></pre>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-GB">But I get problem with the creation of a Decl from a DynTypedNode.<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-GB">An idea how can I move upwards from a VarDecl ?<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">What I am trying to achieve is if I find an interesting callexpr I want to check all declstmts and declrefexprs before the callexpr that reference the arguments of the call.
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>