我想用cast AST解析自定义标签。这是我的编译单元输入的简单说明。
#include <stdio.h>
int main() {
// \my-tags tag_A, tag_B
printf("helloworld");
return 0;
}
如何在
\my-tags
之后获得这些标签?阅读clang user manual之后,我意识到
-Wdocumentation
,-fparse-all-comments
甚至-fcomment-block-commands
可能满足我的要求。但是,当我在compile_commands.json
中添加这些标志之一时,ASTContext.Comments.empty()
仍会输出True
。我在下面附加compile_commands.json
和clang AST前端代码以供参考。// compile_commands.json
[
{
"directory": "/home/my/project/target/directory",
"arguments": ["/usr/local/bin/clang", "-c", "-std=c++14", "-Qunused-arguments", "-m64", "-fparse-all-comments", "-I/usr/include", "-I/usr/local/lib/clang/10.0.0/include", "-o", "build/.objs/input/linux/x86_64/release/target/target.cpp.o", "target/target.cpp"],
"file": "target/target.cpp"
}
]
// CommentParser.cpp
class MyPrinter : public MatchFinder::MatchCallback {
public:
virtual void run(const MatchFinder::MatchResult &Result) {
ASTContext *Context = Result.Context;
SourceManager& sm = Context->getSourceManager();
if (!Context->Comments.empty())
llvm::outs() << "There is no parsed comment\n";
}
};
int main(int argc, const char **argv) {
// CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
std::string err;
std::unique_ptr<CompilationDatabase> cd = CompilationDatabase::autoDetectFromSource("/home/my/project/target/directory/compile_commands.json", err);
ClangTool Tool(*cd, cd->getAllFiles());
MyPrinter Printer;
MatchFinder Finder;
StatementMatcher functionMatcher =
callExpr(callee(functionDecl(hasName("pthread_mutex_lock")))).bind("functions");
Finder.addMatcher(functionMatcher, &Printer);
return Tool.run(newFrontendActionFactory(&Finder).get());
}
最佳答案
我不确定clang是否可以以在AST中可见的方式解析注释,但是您可以尝试两种方法。一个是这样的:
How to extract comments and match to declaration with RecursiveASTVisitor in libclang c++?,它将使您获得声明上方的注释。
您可以尝试的另一件事是建立自己的自定义编译指示。因此,您可以拥有以下内容:
#include <stdio.h>
int main() {
#pragma mytag tagA
printf("helloworld");
return 0;
}
然后从AST中提取/识别标签。支持自定义编译指示需要稍微修改clang。这里是实现此目的的一些参考:
https://blog.quarkslab.com/implementing-a-custom-directive-handler-in-clang.html
https://git.scc.kit.edu/CES/clang-custom-pragma
过去,我在构建具有属性“reduce”的自定义实用程序“igen”时曾尝试过这种方法。它是这样的:
#pragma igen reduce
a = a + 1;
和生成的AST:-AttributedStmt 0xc792700 <<invalid sloc>, line:194:13>
|-IGenAttr 0xc7926e8 <line:193:13, col:24> Implicit Reduce
`-BinaryOperator 0xc7926c8 <line:194:5, col:13> 'int' '='
|-DeclRefExpr 0xc792630 <col:5> 'int' lvalue Var 0xc7924c0 'a' 'int'
`-BinaryOperator 0xc7926a8 <col:9, col:13> 'int' '+'
|-ImplicitCastExpr 0xc792690 <col:9> 'int' <LValueToRValue>
| `-DeclRefExpr 0xc792650 <col:9> 'int' lvalue Var 0xc7924c0 'a' 'int'
`-IntegerLiteral 0xc792670 <col:13> 'int' 1
从AST可以看出,#pragma指令在AST中生成和“AttributedStmt”节点。如果您确实需要为标签使用注释格式(即// \ my-tags tag_A),则始终可以制作一个小型python脚本来“预处理”您的源文件,在该脚本中,所有注释标签都将替换为#pragmas。这当然不是理想的,但仍然可能。
关于c++ - 使用CAST AST解析注释,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60763358/