<div dir="ltr">Hi everyone,<div><br></div><div>I want to add some extra parameters for all CUDA kernel functions (any function that has the __global__ attribute) inside a CUDA source file. For example, I have a function called matrixAddCUDA which was originally declared like this:</div><div><br></div><div><div>__global__ void</div><div>matrixAddCUDA(float *C, float *A, float *B, int w, int h)</div><div>{</div></div><div>    // code inside the function......</div><div>}</div><div><br></div><div>I want to use the Rewriter to add some extra parameters so that the function will be like this:</div><div><br></div><div><div>__global__ void</div><div>matrixAddCUDA(float *C, float *A, float *B, int w, int h, <b>int extra1, int extra2, int extra3</b>)</div><div>{</div></div><div>    // code inside the function</div><div>}</div><div><br></div><div><br></div><div>My current implementation is:</div><div><div><div>#include <iostream></div><div>#include <string></div><div><br></div><div>#include "clang/AST/AST.h"</div><div>#include "clang/AST/ASTConsumer.h"</div><div>#include "clang/ASTMatchers/ASTMatchFinder.h"</div><div>#include "clang/ASTMatchers/ASTMatchers.h"</div><div>#include "clang/Frontend/CompilerInstance.h"</div><div>#include "clang/Frontend/FrontendActions.h"</div><div>#include "clang/Rewrite/Core/Rewriter.h"</div><div>#include "clang/Tooling/CommonOptionsParser.h"</div><div>#include "clang/Tooling/Tooling.h"</div><div>#include "llvm/Support/raw_ostream.h"</div><div><br></div><div>using namespace clang::tooling;</div><div>using namespace llvm;</div><div>using namespace clang;</div><div>using namespace clang::ast_matchers;</div><div><br></div><div><br></div><div>// Apply a custom category to all command-line options so that they are the</div><div>// only ones displayed.</div><div>static llvm::cl::OptionCategory MyToolCategory("my-tool options");</div><div><br></div><div>// CommonOptionsParser declares HelpMessage with a description of the common</div><div>// command-line options related to the compilation database and input files.</div><div>// It's nice to have this help message in all tools.</div><div>static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);</div><div><br></div><div>// A help message for this specific tool can be added afterwards.</div><div>static cl::extrahelp MoreHelp("\nMore help text...");</div><div><br></div><div><br></div><div>class MyASTConsumer: public ASTConsumer {</div><div>public:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>Rewriter &TheRewriter;</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>MyASTConsumer (Rewriter &R) : TheRewriter(R){}</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>void HandleTranslationUnit(ASTContext &Context) override {</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">         </span>// Run the matchers when we have the whole TU parsed.</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>Finder.matchAST(Context);</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">              </span></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">               </span>for(DeclContext::decl_iterator D = Context.getTranslationUnitDecl()->decls_begin(), DEnd = Context.getTranslationUnitDecl()->decls_end(); D!=DEnd; ++D){</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                 </span>FunctionDecl* FD; </div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                    </span>if((FD=dyn_cast<FunctionDecl> (*D)) != 0){</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                               </span>if(FD->hasAttr<CUDAGlobalAttr>()){ </div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                  </span>std::cout << "found " << FD->getNameAsString() << " fun decl\n";</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                      </span>TypeSourceInfo *TI = FD->getTypeSourceInfo();</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                       </span>TypeLoc TL = TI->getTypeLoc();</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                      </span>FunctionTypeLoc FTL = TL.getAsAdjusted<FunctionTypeLoc>();</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                       </span>TheRewriter.insertText(FTL.getRParenLoc(), "int extra1, int extra2, int extra3", true, true);</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                </span>}</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>}</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">             </span>}</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">              </span></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>}</div><div><br></div><div>private:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>MatchFinder Finder;</div><div>};</div><div><br></div><div>// For each source file provided to the tool, a new FrontendAction is created.</div><div>class MyFrontendAction : public ASTFrontendAction {</div><div>public:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>MyFrontendAction() {}</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>void EndSourceFileAction() override {</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>TheRewriter.getEditBuffer(TheRewriter.getSourceMgr().getMainFileID())</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>.write(llvm::outs());</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>}</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>StringRef file) override {</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">             </span>TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">             </span>return llvm::make_unique<MyASTConsumer>(TheRewriter);</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">    </span>}</div><div><br></div><div>private:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>Rewriter TheRewriter;</div><div>};</div><div><br></div><div><br></div><div>int main(int argc, const char **argv) {</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>ClangTool Tool(OptionsParser.getCompilations(),</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>OptionsParser.getSourcePathList());</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>return Tool.run(newFrontendActionFactory<MyFrontendAction>().get());</div><div>}</div></div></div><div><br></div><div><br></div><div>It can successfully print out the CUDA kernel function, but cannot add extra parameters. I think there must be some problems with the Rewriter, but I don't know where.</div><div><br></div><div>Thanks in advance!</div><div><br></div><div>Patrick</div></div>