とりあえず日記

VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ→VIM→秀丸エディタ(いまここ🍄)

clangでC++をAST(XML-format)へ変換してみる

以下、試行錯誤とかエラー内容とか。(自分用メモ)

自分はllvm/clang初心者なので間違っている箇所があるかと思います。ご注意を。

環境

結論

AST を XML で出力するコマンドライン引数(-ast-print-xml)は LLVM2.9 で廃止された模様。
自力でASTを辿ってXMLを出力した方がよさそう。

  • ASTを辿るclangのサンプル
    • Driver/ASTConsumers.cpp

始めに

「clang/AST/XML」でググると下記コマンドラインが多数見つかります。

clang.exe -cc1 -ast-print-xml test1.cpp

「clangすげー」と鼻息荒くコマンドを打ち込むと、引数エラーで動かないんですよ・・・



試しにテストコードをコマンドラインからASTへ変換してみます。

テストコード

//test1.cpp
int max( int x, int y ) {
	if ( x > y ) {
		return x;
	} else {
		return y;
	}
}

clang.exe -cc1 -ast-print-xml test1.cpp

>clang.exe -cc1 -ast-print-xml test1.cpp
error: unknown argument: '-ast-print-xml'

引数エラー!


clang.exe test1.cpp -ast-print-xml

>clang.exe test1.cpp -ast-print-xml
clang: warning: argument unused during compilation: '-ast-print-xml'
clang: error: unable to execute command: program not executable
clang: error: linker command failed due to signal 1 (use -v to see invocation)

こちらも引数エラー!

clang -Xclang -ast-dump test1.cpp

>clang.exe -Xclang -ast-dump test1.cpp
class type_info;
typedef char *__builtin_va_list;
int max(int x, int y) (CompoundStmt 0xd76cd8 <test1.cpp:1:25, line:7:1>
  (IfStmt 0xd76cb8 <line:2:2, line:6:2>
    <<<NULL>>>
    (BinaryOperator 0xd76c00 <line:2:7, col:11> '_Bool' '>'
      (ImplicitCastExpr 0xd76be0 <col:7> 'int' <LValueToRValue>
        (DeclRefExpr 0xd76bb0 <col:7> 'int' lvalue ParmVar 0xd76a70 'x' 'int'))
      (ImplicitCastExpr 0xd76bf0 <col:11> 'int' <LValueToRValue>
        (DeclRefExpr 0xd76bc8 <col:11> 'int' lvalue ParmVar 0xd76ac0 'y' 'int')))
    (CompoundStmt 0xd76c50 <col:15, line:4:2>
      (ReturnStmt 0xd76c40 <line:3:3, col:10>
        (ImplicitCastExpr 0xd76c30 <col:10> 'int' <LValueToRValue>
          (DeclRefExpr 0xd76c18 <col:10> 'int' lvalue ParmVar 0xd76a70 'x' 'int'))))
    (CompoundStmt 0xd76ca0 <line:4:9, line:6:2>
      (ReturnStmt 0xd76c90 <line:5:3, col:10>
        (ImplicitCastExpr 0xd76c80 <col:10> 'int' <LValueToRValue>
          (DeclRefExpr 0xd76c64 <col:10> 'int' lvalue ParmVar 0xd76ac0 'y' 'int'))))))


clang: error: unable to execute command: program not executable
clang: error: linker command failed due to signal 1 (use -v to see invocation)

動作はしているがポインタ的な値が丸見え、本当にダンプ出力のようだ。


clang.exe -emit-ast test1.cpp

clang.exe -emit-ast test1.cpp

バイナリアイル(test1.ast)が出力される、どう使うのかは調査していないので不明。


clang.exe -cc1 -print-decl-contexts test1.cpp

clang.exe -cc1 -print-decl-contexts test1.cpp
[translation unit] 0xc65144
        <typedef> __builtin_va_list
        [function] max(x, y)
            <parameter> x
            <parameter> y

バイナリに比べればだいぶんXMLへ近づきましたが、引数xの型名(int)が表示されていない。


ASTのXML出力はLLVM2.9で廃止されたらしい

Can I get an XML AST dump of C/C++ code with clang without using the compiler? - Stack Overflow

For you information, the XML printer has been removed from the 2.9 version by Douglas Gregor (responsible of CLang FrontEnd).

まとめ

clang 2.9から -ast-print-xml オプションが廃止されたぽっい。
構文木を辿るサンプルがあるので自力でASTを辿ってXML出力した方が手っ取り早いかもしれない。
Driver/ASTConsumers.cpp
ASTDumper 関数内のダンプ
DeclCOntextPrinter (型)宣言のダンプ