我试图将Clang
语句打印到string
,以便打印语句的C / C ++代码。我通过以下方式执行此操作:
//Generate string and string ostream.
string stmt;
raw_string_ostream stream(stmt);
//Get statement from ASTMatcher and print to ostream.
auto* statement = result.Nodes.getNodeAs<clang::Expr>(types[VAR_STMT]);
statement->printPretty(stream, NULL, PrintingPolicy(LangOptions()));
//Flush ostream buffer.
stream.flush();
cout << statement << endl;
此代码编译并运行正常。但是,当我运行以下代码时,我会将statement
对象的地址打印到string
。例如,当我运行此代码时,我得到以下输出:
0x3ccd598
0x3ccd5b0
0x3ccd728
0x3ccdc88
0x3ccdd08
在printPretty(...)
的文档中没有关于Clang
的大量文档,那么打印{{1}代码的正确方式是什么? 1}}到一个字符串?
答案 0 :(得分:2)
我尝试使用此解决方案时发现的一个解决方案来自2013年的Clang developers post。
而不是:
//Generate string and string ostream.
string stmt;
raw_string_ostream stream(stmt);
//Get statement from ASTMatcher and print to ostream.
auto* statement = result.Nodes.getNodeAs<clang::Expr>(types[VAR_STMT]);
statement->printPretty(stream, NULL, PrintingPolicy(LangOptions()));
//Flush ostream buffer.
stream.flush();
cout << statement << endl;
我的代码现在是:
//Get the statement from the ASTMatcher
auto *statement = result.Nodes.getNodeAs<clang::Expr>(types[VAR_STMT]);
//Get the source range and manager.
SourceRange range = statement->getSourceRange();
const SourceManager *SM = result.SourceManager;
//Use LLVM's lexer to get source text.
llvm::StringRef ref = Lexer::getSourceText(CharSourceRange::getCharRange(range), *SM, LangOptions());
cout << ref.str() << endl;
虽然我不太确定任何潜在的缺点,但这种做法似乎确实有效。
答案 1 :(得分:1)
由于你的变量名称相似,你似乎很困惑自己。您有一个类型为stmt
的变量string
,并且您的变量statement
(大概)类型为clang::Stmt *
。 printPretty
调用正在修改stream
变量,该变量写入stmt
,而不是statement
。然后打印statement
,指向clang类型的指针。很自然地,对{1}}指针类型的调用会写入指针的地址。
更改cout
行以写出cout
,您就会得到您期望的内容。
答案 2 :(得分:1)
我刚刚发现可以使用 raw_string_ostream
将语句打印到字符串中:
// stmt is the statement you wish to print
string stmtToString(Stmt *stmt){
clang::LangOptions lo;
string out_str;
llvm::raw_string_ostream outstream(out_str);
stmt->printPretty(outstream, NULL, PrintingPolicy(lo));
return out_str;
}