36#include <clang/Frontend/ASTUnit.h>
44 : QObject(parent), context_(context), fileManager_(fileManager) {
48 case clang::DiagnosticsEngine::Warning:
49 entry.level = LogLevel::Warning;
51 case clang::DiagnosticsEngine::Error:
52 case clang::DiagnosticsEngine::Fatal:
53 entry.level = LogLevel::Error;
55 case clang::DiagnosticsEngine::Remark:
56 case clang::DiagnosticsEngine::Note:
57 case clang::DiagnosticsEngine::Ignored:
59 entry.level = LogLevel::Debug;
63 QString message = QString::fromStdString(diag.message);
64 if (!diag.file.empty()) {
65 QString location = QString::fromStdString(diag.file);
67 location += QString(
":%1").arg(diag.line);
69 if (diag.column > 0) {
70 location += QString(
":%1").arg(diag.column);
72 message = QString(
"%1: %2").arg(location, message);
75 entry.source =
"acav-clang";
76 entry.message = message;
77 entry.timestamp = QDateTime::currentDateTime();
78 emit logMessage(entry);
82 astLoader_ = [
this](
const std::string &path, std::string &errorMsg,
83 const std::string &compilationDbPath,
84 const std::string &sourcePath)
85 -> std::unique_ptr<clang::ASTUnit> {
87 sourcePath, diagnosticCallback_);
94 : QObject(parent), context_(context), fileManager_(fileManager),
95 astLoader_(std::move(loader)) {}
97AstExtractorRunner::~AstExtractorRunner() =
default;
100 commentExtractionEnabled_.store(enabled);
104 const QStringList &tuFilePaths,
105 const QString &compilationDbPath) {
109 start_ = std::chrono::steady_clock::now();
110 emit started(astFilePath);
112 emit progress(QStringLiteral(
"Pre-registering files..."));
113 registerInputFiles(tuFilePaths);
115 emit progress(QStringLiteral(
"Loading AST from cache..."));
116 auto loadStart = std::chrono::steady_clock::now();
119 std::string sourcePath;
120 if (!tuFilePaths.isEmpty()) {
121 sourcePath = tuFilePaths.first().toStdString();
125 std::string stdError;
126 std::unique_ptr<clang::ASTUnit> astUnit =
127 astLoader_(astFilePath.toStdString(), stdError,
128 compilationDbPath.toStdString(), sourcePath);
131 QString errorMsg = stdError.empty() ? QStringLiteral(
"Failed to load AST")
132 : QString::fromStdString(stdError);
133 emit error(errorMsg);
137 auto loadEnd = std::chrono::steady_clock::now();
139 QString(
"Loaded AST: %1s")
140 .arg(std::chrono::duration<double>(loadEnd - loadStart).count(), 0,
146 emit progress(QStringLiteral(
"Building ACAV AST ..."));
147 auto buildStart = std::chrono::steady_clock::now();
149 AstViewNode *root = buildTreeFromASTUnit(*astUnit);
151 emit error(QStringLiteral(
"Failed to build AST"));
155 auto buildEnd = std::chrono::steady_clock::now();
157 QString(
"Built tree: %1s")
158 .arg(std::chrono::duration<double>(buildEnd - buildStart).count(), 0,
164#ifdef ACAV_ENABLE_STRING_STATS
165 InternedString::printStats(
"After AST extraction");
166 context_->printTypeDeduplicationStats(
"After AST extraction");
176 auto totalEnd = std::chrono::steady_clock::now();
178 QString(
"Total: %1s")
179 .arg(std::chrono::duration<double>(totalEnd - start_).count(), 0,
'f',
185void AstExtractorRunner::registerInputFiles(
const QStringList &tuFilePaths) {
186 for (
const QString &filePath : tuFilePaths) {
191AstViewNode *AstExtractorRunner::buildTreeFromASTUnit(clang::ASTUnit &astUnit) {
192 clang::ASTContext &ctx = astUnit.getASTContext();
193 clang::TranslationUnitDecl *tuDecl = ctx.getTranslationUnitDecl();
198 AstExtractionStats stats;
200 astUnit, context_, fileManager_, stats,
201 commentExtractionEnabled_.load());
203 emit statsUpdated(stats);
206 emit progress(QStringLiteral(
"Building location index..."));
207 auto indexStart = std::chrono::steady_clock::now();
208 buildLocationIndex(root);
209 context_->finalizeLocationIndex();
210 auto indexEnd = std::chrono::steady_clock::now();
212 QString(
"Index built: %1s")
213 .arg(std::chrono::duration<double>(indexEnd - indexStart).count(),
220void AstExtractorRunner::buildLocationIndex(
AstViewNode *node) {
225 context_->indexNode(node);
226 for (AstViewNode *child : node->getChildren()) {
227 buildLocationIndex(child);
Clang AST to ACAV AST transformation.
Utilities for interacting with Clang at runtime This includes runtime detection of Clang paths and AS...
std::unique_ptr< clang::ASTUnit > loadAstFromFile(const std::string &astFilePath, std::string &errorMessage, const std::string &compilationDbPath="", const std::string &sourcePath="", const DiagnosticCallback &diagnosticCallback=nullptr)
Load AST from local file.
Memory-efficient immutable string with automatic deduplication.
Cross-platform memory profiling utility.
Source code location representation.
static AstViewNode * buildFromASTUnit(clang::ASTUnit &astUnit, AstContext *context, FileManager &fileManager, AstExtractionStats &stats, bool extractComments=false)
Build ACAV AST from Clang ASTUnit.
Memory manager for AST nodes in a translation unit.
Represents node in AST tree hierarchy.
Centralized file registry providing path-to-FileID mapping.
FileID registerFile(std::string_view filePath)
Register a file and return its FileID.
static void checkpoint(const QString &label)
Log current memory usage with a label.
static void resetCache()
Reset internal caches (per extraction run).