Mengeksplorasi AST Clang dengan clang -ast-dump, memahami ASTContext dan hierarki Decl/Stmt, serta membangun clang-tidy check dan refactoring tool sendiri menggunakan libTooling, ASTMatchers, dan ClangTool driver.

Setelah di episode 14 kita menambahkan debug information ke mini language, pada episode ini kita beralih ke dunia Clang AST dan libTooling — ekosistem LLVM untuk menganalisis, memeriksa, dan mentransformasi kode C/C++ secara programatik.
Clang AST (Abstract Syntax Tree) adalah representasi struktural kode sumber C/C++ yang dihasilkan oleh parser Clang. libTooling memungkinkan kalian menulis tool yang membaca AST ini, mencocokkan pola tertentu (anti-pattern, bug, gaya coding), dan bahkan melakukan auto-fix — persis seperti yang dilakukan clang-tidy dan clang-format.
Gunakan clang -ast-dump untuk melihat AST dari kode C/C++:
echo "int add(int a, int b) { return a + b; }" | \
clang -Xclang -ast-dump -fsyntax-only -Output menunjukkan hierarki AST:
TranslationUnitDecl
└─FunctionDecl 0x... <line:1:1, line:1:40> line:1:5 used add 'int (int, int)'
├─ParmVarDecl 0x... <col:9, col:13> col:13 used a 'int'
├─ParmVarDecl 0x... <col:16, col:20> col:20 used b 'int'
└─CompoundStmt 0x...
└─ReturnStmt 0x...
└─BinaryOperator 0x... <col:26, col:35> 'int' '+'
├─ImplicitCastExpr ... 'int' <LValueToRValue>
│ └─DeclRefExpr ... 'int' lvalue ParmVar 'a'
└─ImplicitCastExpr ... 'int' <LValueToRValue>
└─DeclRefExpr ... 'int' lvalue ParmVar 'b'ASTContext adalah container untuk seluruh AST dari satu translation unit. Ia menyimpan semua type info, identifier table, dan source location manager.
Semua deklarasi mewarisi dari Decl:
| Kelas | Contoh |
|---|---|
FunctionDecl | Deklarasi fungsi |
VarDecl | Deklarasi variabel |
ParmVarDecl | Parameter fungsi |
RecordDecl | Struct/class definition |
Semua pernyataan mewarisi dari Stmt:
| Kelas | Contoh |
|---|---|
CompoundStmt | Blok kode { ... } |
IfStmt | Pernyataan if |
ForStmt | Loop for |
ReturnStmt | Return |
my-tool/
├── CMakeLists.txt
└── MyTool.cpp#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
using namespace clang::tooling;
using namespace clang::ast_matchers;
static llvm::cl::OptionCategory MyToolCategory("my-tool");
// Callback untuk match
class LoopPrinter : public MatchFinder::MatchCallback {
public:
void run(const MatchFinder::MatchResult &Result) override {
const auto *FS = Result.Nodes.getNodeAs<clang::ForStmt>("forLoop");
if (FS) {
llvm::outs() << "Found for loop at: "
<< FS->getBeginLoc().printToString(
Result.Context->getSourceManager())
<< "\n";
}
}
};
int main(int argc, const char **argv) {
auto ExpectedParser = CommonOptionsParser::create(argc, argv, MyToolCategory);
ClangTool Tool(ExpectedParser->getCompilations(),
ExpectedParser->getSourcePathList());
LoopPrinter Printer;
MatchFinder Finder;
Finder.addMatcher(forStmt().bind("forLoop"), &Printer);
return Tool.run(newFrontendActionFactory(&Finder).get());
}ASTMatchers memungkinkan kalian mendeskripsikan pola AST secara deklaratif:
// Cari semua pemanggilan printf
Finder.addMatcher(
callExpr(callee(functionDecl(hasName("printf")))).bind("printfCall"),
&Printer);
// Cari semua variabel yang tidak dipakai
Finder.addMatcher(
varDecl(unless(hasAncestor(functionDecl(hasBody(stmt()))))).bind("unused"),
&Printer);
// Cari semua pointer yang tidak di-null-check
Finder.addMatcher(
binaryOperator(
hasOperatorName("="),
hasLHS(declRefExpr(to(varDecl(hasType(pointerType())))))
).bind("pointerAssign"),
&Printer);clang-tidy adalah tool analysis yang menggunakan libTooling. Menulis custom check berguna untuk enforce coding standard khusus perusahaan:
class NoRawPointerCheck : public ast_matchers::MatchFinder::MatchCallback {
public:
void run(const ast_matchers::MatchFinder::MatchResult &Result) override {
const auto *VD = Result.Nodes.getNodeAs<clang::VarDecl>("var");
if (VD && VD->getType()->isPointerType() &&
!VD->getType()->isConstPointerType()) {
diag(VD->getLocation(),
"Use smart pointer instead of raw pointer");
}
}
};Tip
clang-tidy menyediakan framework lengkap untuk custom checks: registrasi, diagnostics, auto-fix hints, dan suppression pragmas. Gunakan clang-tidy --list-checks untuk melihat semua checks yang tersedia, dan pelajari checks yang ada sebagai referensi menulis check sendiri.
Inti yang harus dibawa pulang:
clang -ast-dump menampilkan AST dari kode C/C++ — tool debugging fundamental.Di episode 16 selanjutnya kita akan memasuki Fase 4: Backend & Advanced Codegen — backend architecture (IR → SelectionDAG/GlobalISel → MachineInstr → MCInst → object file), TableGen, dan praktik membaca deskripsi target RISC-V/X86. Sampai jumpa di episode 16!