まえがき
LLVM/Clangに同梱されているlibclangの.NET(C#) Bindingライブラリ(ClangNet)を作成しました。
libclangはC/C++/Objective-Cソースコードの解析や自動補完機能を提供する高レベルのAPIで、オリジナルはC言語ベースのAPIが提供されています。
libclangのC# Bindingはいくつかありますが、最新のVer.8.0に対応したものがなかったので作ってみました。
なお、以下の環境でビルドおよび簡易的な動作確認を行っています。
- Visual Studio 2019 Community
- Visual Studio for Mac
※ すべての機能に対するテストは出来ていませんので、不具合等ありましたらご連絡いただければと思います。
ダウンロード先
GitHub
ClangNet本体、動作サンプルを含むソースコードはGitHubに置いてあります。
NuGet
ClangNetをプロジェクトに組み込んで使いたい場合は、NuGetからパッケージをインストールしてください。
libclang
libclang本体はプロジェクトに含まれていませんので、公式などから取得してください。
Windows版の組み込み方法は↓の動作サンプルの項で説明しています。
動作サンプル
ここでは、Windowsで動作させるための手順を紹介していきます。
MacやLinuxでも基本的には同じようにして動作させることができると思います。
(違うのはlibclangの準備くらいだと思います)
事前準備
LLVM/Clangインストール
libclang本体を入手するために、公式で配布されているインストーラを使ってLLVM/Clangをインストールします。
libclang本体もその中に含まれています。
- 公式から、最新Ver(現在は8.0.1)のWindows 64bit用のインストーラをダウンロードします
- ダウンロードしたインストーラ(LLVM-XX-Win64.exe)をダブルクリックし、インストーラを起動します
- インストールウィザードに従ってLLVM/Clangをインストールします(特に設定変更などは不要です)
インストールが完了すると、以下のパスにlibclang本体が格納されています。
C:\Program Files\LLVM\bin\libclang.dll
プロジェクト作成
- Visual StudioでC#プロジェクト1を作成します
- Visual StudioからNuGetパッケージマネージャでClangNetを検索してインストールします
- ↑でインストールしたlibclang.dllをVisual Studioプロジェクトディレクトリ内にコピーします
- libclang.dllのプロパティから「出力ディレクトリにコピー」を「常にコピーする」に変更します2
解析対象ソース
次に、解析対象となるC/C++のソースコードを準備します。
今回は、クラスや継承、テンプレートなどを使った↓のようなソースを準備しました。
※ 解析対象ソースの中身の説明については割愛します
ソースファイルは、実行ファイルと同じディレクトリのCodeディレクトリ配下に配置します。
libclangと同様に、プロジェクトディレクトリに配置して、「出力ディレクトリにコピー」を設定しておくと良いと思います。
#pragma once
#include <stdexcept>
using namespace std;
enum class Mode
{
Add,
Sub,
Mul,
Div,
Mod,
};
template<typename T>
class Calculator
{
public:
Calculator() {};
~Calculator() {};
T Calculate(T a, T b, Mode mode);
};
template<typename T>
T Calculator<T>::Calculate(T a, T b, Mode mode)
{
switch (mode)
{
case Mode::Add:
return a + b;
case Mode::Sub:
return a - b;
case Mode::Mul:
return a * b;
case Mode::Div:
return a / b;
case Mode::Mod:
return a % b;
default:
throw out_of_range("Operation Mode Out of Range!!");
}
}
#pragma once
#include "Calculator.h"
#include <string>
#include <map>
using namespace std;
class SuperClass
{
public:
SuperClass();
SuperClass(int a, int b);
virtual ~SuperClass();
inline void SetA(int a) { this->m_a = a; }
inline void SetB(int b) { this->m_b = b; }
inline int GetA() { return this->m_a; }
inline int GetB() { return this->m_b; }
int Calculate(string op);
private:
int m_a;
int m_b;
Calculator<int>* m_calc;
static map<string, Mode> m_ModeMap;
};
#include "SuperClass.h"
map<string, Mode> SuperClass::m_ModeMap =
{
{ "+", Mode::Add },
{ "-", Mode::Sub },
{ "*", Mode::Mul },
{ "/", Mode::Div },
{ "%", Mode::Mod },
};
SuperClass::SuperClass() : SuperClass(0, 0)
{
this->m_calc = new Calculator<int>();
}
SuperClass::SuperClass(int a, int b) : m_a(a), m_b(b), m_calc(nullptr)
{
this->m_calc = new Calculator<int>();
}
SuperClass::~SuperClass()
{
delete this->m_calc;
}
int SuperClass::Calculate(string op)
{
if (SuperClass::m_ModeMap.count(op) == 0)
{
return this->m_calc->Calculate(this->m_a, this->m_b, (Mode)-1);
}
else
{
auto mode = SuperClass::m_ModeMap[op];
return this->m_calc->Calculate(this->m_a, this->m_b, mode);
}
}
#pragma once
#include "SuperClass.h"
class SubClass : public SuperClass
{
public:
SubClass();
SubClass(int a, int b);
~SubClass();
void SetValue(int a, int b);
string GetExpression(string op);
};
#include "SubClass.h"
#include <sstream>
SubClass::SubClass() : SuperClass()
{
}
SubClass::SubClass(int a, int b) : SuperClass(a, b)
{
}
SubClass::~SubClass()
{
}
void SubClass::SetValue(int a, int b)
{
this->SetA(a);
this->SetB(b);
}
string SubClass::GetExpression(string op)
{
auto calc_result = this->Calculate(op);
ostringstream oss;
oss << this->GetA() << " " << op << " " << this->GetB() << " = " << calc_result;
return oss.str();
}
#include "SubClass.h"
#include <iostream>
using namespace std;
int main(void)
{
int a = 10;
int b = 3;
try
{
SubClass obj;
obj.SetValue(a, b);
cout << obj.GetExpression("+") << endl;
cout << obj.GetExpression("-") << endl;
cout << obj.GetExpression("*") << endl;
cout << obj.GetExpression("/") << endl;
cout << obj.GetExpression("%") << endl;
cout << obj.GetExpression("x") << endl;
}
catch (const exception& e)
{
cerr << e.what() << endl;
}
}
ClangNetによる解析コードサンプル
今回は、「main.cpp」ファイルを解析して、以下の情報を出力するサンプルを作成しました。
- 抽象構文木(Abstract Syntax Tree:AST)を再帰的にパースして、各要素の種類、名前、ソース位置情報を出力する
- インクルードしているヘッダファイルのパスと階層構造を出力する
using ClangNet;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ClangNetTest
{
public class ClangParser
{
/// <summary>
/// ソースファイル解析処理実行
/// </summary>
public void Execute()
{
/* ソースコード解析用設定 */
/* 解析対象ファイルパス */
var src_path = $"./Code/src/main.cpp";
/* インクルードファイルディレクトリパス */
var inc_dir = $"./Code/inc";
/* コンパイラに渡すコマンドラインオプション */
var command_line_args = new string[]
{
/* インクルードパスを-Iオプションで指定 */
$"-I{inc_dir}",
};
/* ダイアグ情報表示フラグ */
var display_diag = true;
/* ソース解析オプション */
var options = TranslationUnitFlags.None;
/* ソース解析処理 */
/* Clang Index(libclangのソース解析用インタフェース)生成 */
using (var index = Clang.CreateIndex(false, display_diag))
{
/* ソースファイルをパースし、Clang Translation Unit(コンパイラの変換単位)を生成 */
using (var tu = index.ParseTranslationUnit(src_path, command_line_args, new ClangUnsavedFile[0], options))
{
/* Translation Unitのカーソルを取得 */
/* カーソル : Translation Unit内の抽象構文木(Abstract Syntax Tree:AST)の要素を指し示す */
var cursor = tu.Cursor;
Console.WriteLine($"AST Dump:");
/* カーソル位置を探索 */
this.VisitCursor(cursor, null, 0);
Console.WriteLine();
Console.WriteLine($"Include Files Dump:");
/* インクルードファイルを再帰的に検索 */
tu.GetInclusions(this.InclusionVisitor, IntPtr.Zero);
}
}
}
/// <summary>
/// インクルードファイルの再帰的な検索
/// </summary>
/// <param name="file">インクルードファイル情報</param>
/// <param name="loc_stack">インクルード位置のスタック</param>
/// <param name="client_data">ユーザデータ(未使用)</param>
private void InclusionVisitor(ClangFile file, ClangSourceLocation[] loc_stack, IntPtr client_data)
{
/* インクルードファイルの階層 */
var depth = loc_stack.Length;
/* インクルードファイルのファイルパス('\'を'/'に変換) */
var file_name = file.FileName.Replace(@"\", "/");
/* 階層によるインデント */
var indent = new string(' ', depth * 2);
/* ファイルの絶対パス */
var file_full_path = Path.GetFullPath(file_name);
Console.WriteLine($"{indent}{file_full_path}");
}
/// <summary>
/// カーソル探索処理
/// </summary>
/// <param name="cursor">カーソル</param>
/// <param name="parent">親カーソル</param>
/// <param name="depth">ASTの深さ</param>
/// <returns>探索結果(継続、中断、再帰)</returns>
private ChildVisitResult CursorVisitor(ClangCursor cursor, ClangCursor parent, int depth)
{
/* カーソルのClang Location(論理的な位置情報)を取得 */
var loc = cursor.Location;
/* カーソル位置が解析対象ファイル(*.cpp)内 */
if (loc.IsFromMainFile)
{
/* カーソル位置を探索 */
this.VisitCursor(cursor, parent, depth);
}
/* カーソル位置が解析対象ファイル外(インクルードしているヘッダなど) */
else
{
/* カーソル位置がシステムヘッダ内(標準ヘッダなど) */
if (loc.IsInSystemHeader)
{
/* 何もしない */
}
/* カーソル位置がシステムヘッダ外(ユーザ定義ヘッダなど) */
else
{
/* カーソル位置を探索 */
this.VisitCursor(cursor, parent, depth);
}
}
/* 解析を継続 */
return ChildVisitResult.Continue;
}
/// <summary>
/// カーソル位置に対する処理
/// </summary>
/// <param name="cursor">カーソル</param>
/// <param name="parent">親カーソル</param>
/// <param name="depth">ASTの深さ</param>
private void VisitCursor(ClangCursor cursor, ClangCursor parent, int depth)
{
/* 階層によるインデント */
var indent = new string(' ', depth * 2);
/* カーソルが指す要素の種類 */
var kind = cursor.Kind;
/* カーソルがさす要素の表示名(クラス、関数、変数など) */
var name = cursor.DisplayName;
/* カーソル位置のファイル上の位置情報を取得 */
var loc = this.GetCursorLocationText(cursor.Location);
/* 表示名が空の場合 */
if (string.IsNullOrWhiteSpace(name))
{
Console.WriteLine($"{indent}[{kind}] @{loc}");
}
/* 表示名が空でない場合 */
else
{
Console.WriteLine($"{indent}[{kind}] {name} @{loc}");
}
/* ASTの子要素を探索 */
cursor.VisitChildren(this.CursorVisitor, depth + 1);
}
/// <summary>
/// カーソル位置のソースファイル上の位置情報を取得
/// </summary>
/// <param name="loc">カーソル位置</param>
/// <returns>ソースファイル上の位置情報</returns>
private string GetCursorLocationText(ClangSourceLocation loc)
{
/* カーソルのファイル上の物理的な位置情報 */
var floc = loc.FileLocation;
/* ファイル情報あり */
if (floc.File != null)
{
/* カーソル位置のファイルパス('\'を'/'に変換) */
var file = floc.File.FileName.Replace(@"\", "/");
/* カーソル位置のファイル行数 */
var line = floc.Line;
/* カーソル位置のファイル列数 */
var col = floc.Column;
/* カーソル位置情報 : <ファイルパス>[L.<行数>,C.<列数>] */
var result = $"{file}[L.{line},C.{col}]";
return result;
}
/* ファイル情報なし */
else
{
/* カーソル位置のファイル行数 */
var line = floc.Line;
/* カーソル位置のファイル列数 */
var col = floc.Column;
/* カーソル位置情報 : [L.<行数>,C.<列数>] */
var result = $"[L.{line},C.{col}]";
return result;
}
}
}
}
using System;
namespace ClangNetTest
{
class Program
{
static void Main(string[] args)
{
Execute();
}
static void Execute()
{
/* Clang Parserインスタンスを生成 */
ClangParser parser = new ClangParser();
/* ソース解析処理実行 */
parser.Execute();
}
}
}
実行結果
AST解析結果
AST Dump:
[TranslationUnit] ./Code/src/main.cpp @[L.0,C.0]
[UsingDirective] @./Code/inc/Calculator.h[L.4,C.17]
[NamespaceReference] std @./Code/inc/Calculator.h[L.4,C.17]
[EnumDeclaration] Mode @./Code/inc/Calculator.h[L.6,C.12]
[EnumConstantDeclaration] Add @./Code/inc/Calculator.h[L.8,C.5]
[EnumConstantDeclaration] Sub @./Code/inc/Calculator.h[L.9,C.5]
[EnumConstantDeclaration] Mul @./Code/inc/Calculator.h[L.10,C.5]
[EnumConstantDeclaration] Div @./Code/inc/Calculator.h[L.11,C.5]
[EnumConstantDeclaration] Mod @./Code/inc/Calculator.h[L.12,C.5]
[ClassTemplate] Calculator<T> @./Code/inc/Calculator.h[L.16,C.7]
[TemplateTypeParameter] T @./Code/inc/Calculator.h[L.15,C.19]
[CXXAccessSpecifier] @./Code/inc/Calculator.h[L.18,C.1]
[Constructor] Calculator<T>() @./Code/inc/Calculator.h[L.19,C.5]
[Destructor] ~Calculator<T>() @./Code/inc/Calculator.h[L.20,C.5]
[CXXMethod] Calculate(T, T, Mode) @./Code/inc/Calculator.h[L.22,C.7]
[TypeReference] T @./Code/inc/Calculator.h[L.22,C.5]
[ParmDeclaration] a @./Code/inc/Calculator.h[L.22,C.19]
[TypeReference] T @./Code/inc/Calculator.h[L.22,C.17]
[ParmDeclaration] b @./Code/inc/Calculator.h[L.22,C.24]
[TypeReference] T @./Code/inc/Calculator.h[L.22,C.22]
[ParmDeclaration] mode @./Code/inc/Calculator.h[L.22,C.32]
[TypeReference] enum Mode @./Code/inc/Calculator.h[L.22,C.27]
[CXXMethod] Calculate(T, T, Mode) @./Code/inc/Calculator.h[L.26,C.18]
[TemplateTypeParameter] T @./Code/inc/Calculator.h[L.25,C.19]
[TypeReference] T @./Code/inc/Calculator.h[L.26,C.1]
[TemplateReference] Calculator @./Code/inc/Calculator.h[L.26,C.3]
[TypeReference] T @./Code/inc/Calculator.h[L.26,C.14]
[ParmDeclaration] a @./Code/inc/Calculator.h[L.26,C.30]
[TypeReference] T @./Code/inc/Calculator.h[L.26,C.28]
[ParmDeclaration] b @./Code/inc/Calculator.h[L.26,C.35]
[TypeReference] T @./Code/inc/Calculator.h[L.26,C.33]
[ParmDeclaration] mode @./Code/inc/Calculator.h[L.26,C.43]
[TypeReference] enum Mode @./Code/inc/Calculator.h[L.26,C.38]
[UsingDirective] @./Code/inc/SuperClass.h[L.6,C.17]
[NamespaceReference] std @./Code/inc/SuperClass.h[L.6,C.17]
[ClassDeclaration] SuperClass @./Code/inc/SuperClass.h[L.8,C.7]
[CXXAccessSpecifier] @./Code/inc/SuperClass.h[L.10,C.1]
[Constructor] SuperClass() @./Code/inc/SuperClass.h[L.11,C.5]
[Constructor] SuperClass(int, int) @./Code/inc/SuperClass.h[L.12,C.5]
[ParmDeclaration] a @./Code/inc/SuperClass.h[L.12,C.20]
[ParmDeclaration] b @./Code/inc/SuperClass.h[L.12,C.27]
[Destructor] ~SuperClass() @./Code/inc/SuperClass.h[L.13,C.13]
[CXXMethod] SetA(int) @./Code/inc/SuperClass.h[L.15,C.17]
[ParmDeclaration] a @./Code/inc/SuperClass.h[L.15,C.26]
[CompoundStatement] @./Code/inc/SuperClass.h[L.15,C.29]
[BinaryOperator] @./Code/inc/SuperClass.h[L.15,C.31]
[MemberReferenceExpression] m_a @./Code/inc/SuperClass.h[L.15,C.37]
[CXXThisExpression] @./Code/inc/SuperClass.h[L.15,C.31]
[FirstExpression] a @./Code/inc/SuperClass.h[L.15,C.43]
[DeclarationReferenceExpression] a @./Code/inc/SuperClass.h[L.15,C.43]
[CXXMethod] SetB(int) @./Code/inc/SuperClass.h[L.16,C.17]
[ParmDeclaration] b @./Code/inc/SuperClass.h[L.16,C.26]
[CompoundStatement] @./Code/inc/SuperClass.h[L.16,C.29]
[BinaryOperator] @./Code/inc/SuperClass.h[L.16,C.31]
[MemberReferenceExpression] m_b @./Code/inc/SuperClass.h[L.16,C.37]
[CXXThisExpression] @./Code/inc/SuperClass.h[L.16,C.31]
[FirstExpression] b @./Code/inc/SuperClass.h[L.16,C.43]
[DeclarationReferenceExpression] b @./Code/inc/SuperClass.h[L.16,C.43]
[CXXMethod] GetA() @./Code/inc/SuperClass.h[L.18,C.16]
[CompoundStatement] @./Code/inc/SuperClass.h[L.18,C.23]
[ReturnStatement] @./Code/inc/SuperClass.h[L.18,C.25]
[FirstExpression] m_a @./Code/inc/SuperClass.h[L.18,C.38]
[MemberReferenceExpression] m_a @./Code/inc/SuperClass.h[L.18,C.38]
[CXXThisExpression] @./Code/inc/SuperClass.h[L.18,C.32]
[CXXMethod] GetB() @./Code/inc/SuperClass.h[L.19,C.16]
[CompoundStatement] @./Code/inc/SuperClass.h[L.19,C.23]
[ReturnStatement] @./Code/inc/SuperClass.h[L.19,C.25]
[FirstExpression] m_b @./Code/inc/SuperClass.h[L.19,C.38]
[MemberReferenceExpression] m_b @./Code/inc/SuperClass.h[L.19,C.38]
[CXXThisExpression] @./Code/inc/SuperClass.h[L.19,C.32]
[CXXMethod] Calculate(std::string) @./Code/inc/SuperClass.h[L.21,C.9]
[ParmDeclaration] op @./Code/inc/SuperClass.h[L.21,C.26]
[TypeReference] std::string @./Code/inc/SuperClass.h[L.21,C.19]
[CXXAccessSpecifier] @./Code/inc/SuperClass.h[L.23,C.1]
[FieldDeclaration] m_a @./Code/inc/SuperClass.h[L.24,C.9]
[FieldDeclaration] m_b @./Code/inc/SuperClass.h[L.25,C.9]
[FieldDeclaration] m_calc @./Code/inc/SuperClass.h[L.26,C.22]
[TemplateReference] Calculator @./Code/inc/SuperClass.h[L.26,C.5]
[VarDeclaration] m_ModeMap @./Code/inc/SuperClass.h[L.27,C.30]
[TemplateReference] map @./Code/inc/SuperClass.h[L.27,C.12]
[TypeReference] std::string @./Code/inc/SuperClass.h[L.27,C.16]
[TypeReference] enum Mode @./Code/inc/SuperClass.h[L.27,C.24]
[ClassDeclaration] SubClass @./Code/inc/SubClass.h[L.4,C.7]
[CXXBaseSpecifier] class SuperClass @./Code/inc/SubClass.h[L.4,C.25]
[TypeReference] class SuperClass @./Code/inc/SubClass.h[L.4,C.25]
[CXXAccessSpecifier] @./Code/inc/SubClass.h[L.6,C.1]
[Constructor] SubClass() @./Code/inc/SubClass.h[L.7,C.5]
[Constructor] SubClass(int, int) @./Code/inc/SubClass.h[L.8,C.5]
[ParmDeclaration] a @./Code/inc/SubClass.h[L.8,C.18]
[ParmDeclaration] b @./Code/inc/SubClass.h[L.8,C.25]
[Destructor] ~SubClass() @./Code/inc/SubClass.h[L.9,C.5]
[CXXMethod] SetValue(int, int) @./Code/inc/SubClass.h[L.11,C.10]
[ParmDeclaration] a @./Code/inc/SubClass.h[L.11,C.23]
[ParmDeclaration] b @./Code/inc/SubClass.h[L.11,C.30]
[CXXMethod] GetExpression(std::string) @./Code/inc/SubClass.h[L.13,C.12]
[TypeReference] std::string @./Code/inc/SubClass.h[L.13,C.5]
[ParmDeclaration] op @./Code/inc/SubClass.h[L.13,C.33]
[TypeReference] std::string @./Code/inc/SubClass.h[L.13,C.26]
[UsingDirective] @./Code/src/main.cpp[L.4,C.17]
[NamespaceReference] std @./Code/src/main.cpp[L.4,C.17]
[FunctionDeclaration] main() @./Code/src/main.cpp[L.6,C.5]
[CompoundStatement] @./Code/src/main.cpp[L.7,C.1]
[DeclarationStatement] @./Code/src/main.cpp[L.8,C.5]
[VarDeclaration] a @./Code/src/main.cpp[L.8,C.9]
[IntegerLiteral] @./Code/src/main.cpp[L.8,C.13]
[DeclarationStatement] @./Code/src/main.cpp[L.9,C.5]
[VarDeclaration] b @./Code/src/main.cpp[L.9,C.9]
[IntegerLiteral] @./Code/src/main.cpp[L.9,C.13]
[CXXTryStatement] @./Code/src/main.cpp[L.11,C.5]
[CompoundStatement] @./Code/src/main.cpp[L.12,C.5]
[DeclarationStatement] @./Code/src/main.cpp[L.13,C.9]
[VarDeclaration] obj @./Code/src/main.cpp[L.13,C.18]
[TypeReference] class SubClass @./Code/src/main.cpp[L.13,C.9]
[CallExpression] SubClass @./Code/src/main.cpp[L.13,C.18]
[CallExpression] SetValue @./Code/src/main.cpp[L.15,C.9]
[MemberReferenceExpression] SetValue @./Code/src/main.cpp[L.15,C.13]
[DeclarationReferenceExpression] obj @./Code/src/main.cpp[L.15,C.9]
[FirstExpression] a @./Code/src/main.cpp[L.15,C.22]
[DeclarationReferenceExpression] a @./Code/src/main.cpp[L.15,C.22]
[FirstExpression] b @./Code/src/main.cpp[L.15,C.25]
[DeclarationReferenceExpression] b @./Code/src/main.cpp[L.15,C.25]
[FirstExpression] @./Code/src/main.cpp[L.17,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.17,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.17,C.9]
[DeclarationReferenceExpression] cout @./Code/src/main.cpp[L.17,C.9]
[FirstExpression] operator<< @./Code/src/main.cpp[L.17,C.14]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.17,C.14]
[FirstExpression] @./Code/src/main.cpp[L.17,C.17]
[FirstExpression] @./Code/src/main.cpp[L.17,C.17]
[FirstExpression] @./Code/src/main.cpp[L.17,C.17]
[CallExpression] GetExpression @./Code/src/main.cpp[L.17,C.17]
[MemberReferenceExpression] GetExpression @./Code/src/main.cpp[L.17,C.21]
[DeclarationReferenceExpression] obj @./Code/src/main.cpp[L.17,C.17]
[FirstExpression] @./Code/src/main.cpp[L.17,C.35]
[CallExpression] @./Code/src/main.cpp[L.17,C.35]
[FirstExpression] @./Code/src/main.cpp[L.17,C.35]
[FirstExpression] @./Code/src/main.cpp[L.17,C.35]
[FirstExpression] basic_string @./Code/src/main.cpp[L.17,C.35]
[CallExpression] basic_string @./Code/src/main.cpp[L.17,C.35]
[FirstExpression] @./Code/src/main.cpp[L.17,C.35]
[StringLiteral] "+" @./Code/src/main.cpp[L.17,C.35]
[FirstExpression] operator<< @./Code/src/main.cpp[L.17,C.40]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.17,C.40]
[FirstExpression] endl @./Code/src/main.cpp[L.17,C.43]
[DeclarationReferenceExpression] endl @./Code/src/main.cpp[L.17,C.43]
[FirstExpression] @./Code/src/main.cpp[L.18,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.18,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.18,C.9]
[DeclarationReferenceExpression] cout @./Code/src/main.cpp[L.18,C.9]
[FirstExpression] operator<< @./Code/src/main.cpp[L.18,C.14]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.18,C.14]
[FirstExpression] @./Code/src/main.cpp[L.18,C.17]
[FirstExpression] @./Code/src/main.cpp[L.18,C.17]
[FirstExpression] @./Code/src/main.cpp[L.18,C.17]
[CallExpression] GetExpression @./Code/src/main.cpp[L.18,C.17]
[MemberReferenceExpression] GetExpression @./Code/src/main.cpp[L.18,C.21]
[DeclarationReferenceExpression] obj @./Code/src/main.cpp[L.18,C.17]
[FirstExpression] @./Code/src/main.cpp[L.18,C.35]
[CallExpression] @./Code/src/main.cpp[L.18,C.35]
[FirstExpression] @./Code/src/main.cpp[L.18,C.35]
[FirstExpression] @./Code/src/main.cpp[L.18,C.35]
[FirstExpression] basic_string @./Code/src/main.cpp[L.18,C.35]
[CallExpression] basic_string @./Code/src/main.cpp[L.18,C.35]
[FirstExpression] @./Code/src/main.cpp[L.18,C.35]
[StringLiteral] "-" @./Code/src/main.cpp[L.18,C.35]
[FirstExpression] operator<< @./Code/src/main.cpp[L.18,C.40]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.18,C.40]
[FirstExpression] endl @./Code/src/main.cpp[L.18,C.43]
[DeclarationReferenceExpression] endl @./Code/src/main.cpp[L.18,C.43]
[FirstExpression] @./Code/src/main.cpp[L.19,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.19,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.19,C.9]
[DeclarationReferenceExpression] cout @./Code/src/main.cpp[L.19,C.9]
[FirstExpression] operator<< @./Code/src/main.cpp[L.19,C.14]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.19,C.14]
[FirstExpression] @./Code/src/main.cpp[L.19,C.17]
[FirstExpression] @./Code/src/main.cpp[L.19,C.17]
[FirstExpression] @./Code/src/main.cpp[L.19,C.17]
[CallExpression] GetExpression @./Code/src/main.cpp[L.19,C.17]
[MemberReferenceExpression] GetExpression @./Code/src/main.cpp[L.19,C.21]
[DeclarationReferenceExpression] obj @./Code/src/main.cpp[L.19,C.17]
[FirstExpression] @./Code/src/main.cpp[L.19,C.35]
[CallExpression] @./Code/src/main.cpp[L.19,C.35]
[FirstExpression] @./Code/src/main.cpp[L.19,C.35]
[FirstExpression] @./Code/src/main.cpp[L.19,C.35]
[FirstExpression] basic_string @./Code/src/main.cpp[L.19,C.35]
[CallExpression] basic_string @./Code/src/main.cpp[L.19,C.35]
[FirstExpression] @./Code/src/main.cpp[L.19,C.35]
[StringLiteral] "*" @./Code/src/main.cpp[L.19,C.35]
[FirstExpression] operator<< @./Code/src/main.cpp[L.19,C.40]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.19,C.40]
[FirstExpression] endl @./Code/src/main.cpp[L.19,C.43]
[DeclarationReferenceExpression] endl @./Code/src/main.cpp[L.19,C.43]
[FirstExpression] @./Code/src/main.cpp[L.20,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.20,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.20,C.9]
[DeclarationReferenceExpression] cout @./Code/src/main.cpp[L.20,C.9]
[FirstExpression] operator<< @./Code/src/main.cpp[L.20,C.14]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.20,C.14]
[FirstExpression] @./Code/src/main.cpp[L.20,C.17]
[FirstExpression] @./Code/src/main.cpp[L.20,C.17]
[FirstExpression] @./Code/src/main.cpp[L.20,C.17]
[CallExpression] GetExpression @./Code/src/main.cpp[L.20,C.17]
[MemberReferenceExpression] GetExpression @./Code/src/main.cpp[L.20,C.21]
[DeclarationReferenceExpression] obj @./Code/src/main.cpp[L.20,C.17]
[FirstExpression] @./Code/src/main.cpp[L.20,C.35]
[CallExpression] @./Code/src/main.cpp[L.20,C.35]
[FirstExpression] @./Code/src/main.cpp[L.20,C.35]
[FirstExpression] @./Code/src/main.cpp[L.20,C.35]
[FirstExpression] basic_string @./Code/src/main.cpp[L.20,C.35]
[CallExpression] basic_string @./Code/src/main.cpp[L.20,C.35]
[FirstExpression] @./Code/src/main.cpp[L.20,C.35]
[StringLiteral] "/" @./Code/src/main.cpp[L.20,C.35]
[FirstExpression] operator<< @./Code/src/main.cpp[L.20,C.40]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.20,C.40]
[FirstExpression] endl @./Code/src/main.cpp[L.20,C.43]
[DeclarationReferenceExpression] endl @./Code/src/main.cpp[L.20,C.43]
[FirstExpression] @./Code/src/main.cpp[L.21,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.21,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.21,C.9]
[DeclarationReferenceExpression] cout @./Code/src/main.cpp[L.21,C.9]
[FirstExpression] operator<< @./Code/src/main.cpp[L.21,C.14]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.21,C.14]
[FirstExpression] @./Code/src/main.cpp[L.21,C.17]
[FirstExpression] @./Code/src/main.cpp[L.21,C.17]
[FirstExpression] @./Code/src/main.cpp[L.21,C.17]
[CallExpression] GetExpression @./Code/src/main.cpp[L.21,C.17]
[MemberReferenceExpression] GetExpression @./Code/src/main.cpp[L.21,C.21]
[DeclarationReferenceExpression] obj @./Code/src/main.cpp[L.21,C.17]
[FirstExpression] @./Code/src/main.cpp[L.21,C.35]
[CallExpression] @./Code/src/main.cpp[L.21,C.35]
[FirstExpression] @./Code/src/main.cpp[L.21,C.35]
[FirstExpression] @./Code/src/main.cpp[L.21,C.35]
[FirstExpression] basic_string @./Code/src/main.cpp[L.21,C.35]
[CallExpression] basic_string @./Code/src/main.cpp[L.21,C.35]
[FirstExpression] @./Code/src/main.cpp[L.21,C.35]
[StringLiteral] "%" @./Code/src/main.cpp[L.21,C.35]
[FirstExpression] operator<< @./Code/src/main.cpp[L.21,C.40]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.21,C.40]
[FirstExpression] endl @./Code/src/main.cpp[L.21,C.43]
[DeclarationReferenceExpression] endl @./Code/src/main.cpp[L.21,C.43]
[FirstExpression] @./Code/src/main.cpp[L.23,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.23,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.23,C.9]
[DeclarationReferenceExpression] cout @./Code/src/main.cpp[L.23,C.9]
[FirstExpression] operator<< @./Code/src/main.cpp[L.23,C.14]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.23,C.14]
[FirstExpression] @./Code/src/main.cpp[L.23,C.17]
[FirstExpression] @./Code/src/main.cpp[L.23,C.17]
[FirstExpression] @./Code/src/main.cpp[L.23,C.17]
[CallExpression] GetExpression @./Code/src/main.cpp[L.23,C.17]
[MemberReferenceExpression] GetExpression @./Code/src/main.cpp[L.23,C.21]
[DeclarationReferenceExpression] obj @./Code/src/main.cpp[L.23,C.17]
[FirstExpression] @./Code/src/main.cpp[L.23,C.35]
[CallExpression] @./Code/src/main.cpp[L.23,C.35]
[FirstExpression] @./Code/src/main.cpp[L.23,C.35]
[FirstExpression] @./Code/src/main.cpp[L.23,C.35]
[FirstExpression] basic_string @./Code/src/main.cpp[L.23,C.35]
[CallExpression] basic_string @./Code/src/main.cpp[L.23,C.35]
[FirstExpression] @./Code/src/main.cpp[L.23,C.35]
[StringLiteral] "x" @./Code/src/main.cpp[L.23,C.35]
[FirstExpression] operator<< @./Code/src/main.cpp[L.23,C.40]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.23,C.40]
[FirstExpression] endl @./Code/src/main.cpp[L.23,C.43]
[DeclarationReferenceExpression] endl @./Code/src/main.cpp[L.23,C.43]
[CXXCatchStatement] @./Code/src/main.cpp[L.25,C.5]
[VarDeclaration] e @./Code/src/main.cpp[L.25,C.29]
[TypeReference] class std::exception @./Code/src/main.cpp[L.25,C.18]
[CompoundStatement] @./Code/src/main.cpp[L.26,C.5]
[CallExpression] operator<< @./Code/src/main.cpp[L.27,C.9]
[CallExpression] operator<< @./Code/src/main.cpp[L.27,C.9]
[DeclarationReferenceExpression] cerr @./Code/src/main.cpp[L.27,C.9]
[FirstExpression] operator<< @./Code/src/main.cpp[L.27,C.14]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.27,C.14]
[CallExpression] what @./Code/src/main.cpp[L.27,C.17]
[MemberReferenceExpression] what @./Code/src/main.cpp[L.27,C.19]
[DeclarationReferenceExpression] e @./Code/src/main.cpp[L.27,C.17]
[FirstExpression] operator<< @./Code/src/main.cpp[L.27,C.26]
[DeclarationReferenceExpression] operator<< @./Code/src/main.cpp[L.27,C.26]
[FirstExpression] endl @./Code/src/main.cpp[L.27,C.29]
[DeclarationReferenceExpression] endl @./Code/src/main.cpp[L.27,C.29]
インクルードファイル検索結果
Include Files Dump:
C:\Works\ClangNetTest\ClangNetTest\bin\Debug\netcoreapp2.1\Code\src\main.cpp
C:\Works\ClangNetTest\ClangNetTest\bin\Debug\netcoreapp2.1\Code\inc\SubClass.h
C:\Works\ClangNetTest\ClangNetTest\bin\Debug\netcoreapp2.1\Code\inc\SuperClass.h
C:\Works\ClangNetTest\ClangNetTest\bin\Debug\netcoreapp2.1\Code\inc\Calculator.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\stdexcept
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\exception
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\yvals.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\yvals_core.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\crtdefs.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\vcruntime.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\sal.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\concurrencysal.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\vadefs.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xkeycheck.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\crtdbg.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\vcruntime_new_debug.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\vcruntime_new.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\use_ansi.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\type_traits
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xstddef
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\cstddef
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\stddef.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xtr1common
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\cstdlib
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\math.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_math.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\stdlib.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_malloc.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_search.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_wstdlib.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\limits.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\initializer_list
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\malloc.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\vcruntime_exception.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\eh.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_terminate.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xstring
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\iosfwd
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\cstdio
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\stdio.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_wstdio.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_stdio_config.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\cstring
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\string.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_memory.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_memcpy_s.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\errno.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\vcruntime_string.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_wstring.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\cwchar
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\wchar.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_wconio.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_wctype.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_wdirect.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_wio.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_share.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_wprocess.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_wtime.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\sys\stat.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\sys\types.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xmemory
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\cstdint
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\stdint.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\limits
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\cfloat
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\float.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\climits
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\new
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xatomic.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\intrin0.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xutility
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\utility
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\string
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\cctype
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\ctype.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\map
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\tuple
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xtree
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\iostream
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\istream
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\ostream
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\ios
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xlocnum
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\cmath
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xtgmath.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\streambuf
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xiosbase
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\share.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\system_error
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\cerrno
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xcall_once.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xerrc.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xlocale
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\memory
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\typeinfo
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\vcruntime_typeinfo.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xfacet
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xlocinfo
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\include\xlocinfo.h
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\locale.h
あとがき
気が向いたら、他の実用例のサンプルなども書いていきたいと思います。
- より詳しい情報の取得方法
- コールツリーの出力方法
- etc...