Clang中字符串的漂亮打印语句

时间:2016-11-14 19:16:44

标签: c++ clang llvm

我试图将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}}到一个字符串?

3 个答案:

答案 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;
}