Module extract:compiler
Summary
extract:compiler 模块负责加载、解析和归一化编译数据库(如 compile_commands``.json),并提供对单个编译条目进行标准化处理的核心流程。它公开定义了 CompileEntry、CompilationDatabase 和 CompDbError 等数据结构,用于表示编译命令、数据库及错误信息。模块的公开函数涵盖从文件路径加载数据库(load_compdb)、在数据库中按源文件查找条目(lookup)、标准化条目中的文件路径与参数(normalize_entry_file、normalize_argument_path、sanitize_driver_arguments、sanitize_tool_arguments)、生成唯一编译签名与缓存键(build_compile_signature、ensure_cache_key)、缓存工具链查询结果(query_toolchain_cached)以及最终基于归一化后的条目创建编译器实例(create_compiler_instance)等关键操作,为后续代码提取与分析提供稳定可重复的编译上下文。
Imports
stdsupport
Imported By
Types
clore::extract::CompDbError
Declaration: extract/compiler.cppm:38
Definition: extract/compiler.cppm:38
Declaration: Namespace clore::extract
clore::extract::CompDbError 是一个简单的错误类型,内部仅包含一个 std::string 类型的 message 成员。该结构体没有自定义构造函数、析构函数或赋值运算符,完全依赖编译器生成的默认版本,因此它作为平凡可复制且可移动的类型。其唯一的不变性是 message 在逻辑上应表示一条无歧义的错误信息,但该结构体自身不对此施加任何校验或约束,所有错误文本的构建与解释均由上层调用代码负责。message 成员使用标准字符串存储,使得该类型能够自然地参与异常抛出或值返回的错误处理流程。
Invariants
- The
messagemember is always default-constructible and movable.
Key Members
message
Usage Patterns
- Caught or checked by callers of
clore::extractfunctions that may fail.
clore::extract::CompilationDatabase
Declaration: extract/compiler.cppm:31
Definition: extract/compiler.cppm:31
Declaration: Namespace clore::extract
内部结构由两个主要数据容器构成:entries 是一个 std::vector<CompileEntry>,用于存储编译数据库中的所有编译条目;toolchain_cache 是一个 std::unordered_map<std::string, std::vector<std::string>>,作为缓存层,将工具链标识符(字符串)映射到其对应的编译标志序列,从而避免重复解析相同的工具链配置。两个容器之间没有显式的约束,但缓存的设计预期与 entries 中的工具链引用保持一致。
has_cached_toolchain 方法的实现直接检查 toolchain_cache 是否非空,返回 true 表示缓存中至少包含一组解析后的工具链数据,否则返回 false。由于该方法不带参数且为 const 限定,它仅反映缓存整体的填充状态,而不针对特定工具链标识符进行查询。该实现作为轻量级门卫函数,允许调用方在需要填充或重用缓存前快速判断是否已有缓存数据。
Member Functions
clore::extract::CompilationDatabase::has_cached_toolchain
Declaration: extract/compiler.cppm:35
Definition: extract/compiler.cppm:229
Declaration: Namespace clore::extract
Implementation
auto CompilationDatabase::has_cached_toolchain() const -> bool {
return !toolchain_cache.empty();
}clore::extract::CompileEntry
Declaration: extract/compiler.cppm:21
Definition: extract/compiler.cppm:21
Declaration: Namespace clore::extract
结构体 clore::extract::CompileEntry 直接容纳从编译数据库记录中解析出的四个原始字段:file、directory、arguments 和可选的 source_hash。其中 file 存储源文件相对路径,directory 记录编译命令的工作目录,arguments 保留完整的命令行参数列表。normalized_file 与 compile_signature 是两个派生字段,分别代表规范化后的文件路径和根据规范化文件与参数计算出的 64 位编译签名,用于唯一标识该编译条目。cache_key 则是一个字符串,通常由 compile_signature 和 source_hash 联合构成,为后续缓存查找提供快速索引。
所有成员均在默认构造函数中初始化为空字符串或零值。在加载条目时,normalized_file、compile_signature 和 cache_key 会依次计算并赋值,确保它们在后续使用前已正确填充。source_hash 仅当源文件内容被访问时才记录哈希值,因此其类型为 std::optional,允许未赋值状态。这些字段共同构成了一个紧凑的编译单元描述,供提取流程下游步骤(如去重、缓存或分析)直接使用。
Invariants
- 字段的默认值为空字符串、空向量、零或
std::nullopt,表示使用前应被填充。
Key Members
filedirectoryargumentsnormalized_filecompile_signaturesource_hashcache_key
Usage Patterns
- 用于表示从编译数据库或构建系统中提取的单个编译条目。
- 可能用于编译缓存或重新执行的输入。
Functions
clore::extract::build_compile_signature
Declaration: extract/compiler.cppm:58
Definition: extract/compiler.cppm:110
Declaration: Namespace clore::extract
clore::extract::build_compile_signature 首先检查 entry 的 normalized_file 是否非空且 compile_signature 字段非零:若成立则直接返回缓存的签名,避免重复计算。否则,它会确保 normalized_file 可用——若 entry.normalized_file 为空则调用 normalize_entry_file 生成它,否则直接复用已有值——然后委托给命名空间内的 build_compile_signature_impl 执行实际签名计算。
该函数的核心设计是通过预检查缓存短路后续开销,并统一规范化文件路径。其依赖关系局限于 normalize_entry_file(用于解析 CompileEntry 的文件路径)以及 build_compile_signature_impl(内部实现签名算法),后者负责解析编译参数、加载编译数据库、实例化编译器调用等更复杂的流程。
Side Effects
No observable side effects are evident from the extracted code.
Reads From
entry.normalized_fileentry.compile_signatureclore::extract::normalize_entry_file(readsentry)
Usage Patterns
- Used to obtain a stable identifier for a compile entry.
- Likely used for caching or detecting changes in compile configurations.
clore::extract::create_compiler_instance
Declaration: extract/compiler.cppm:65
Definition: extract/compiler.cppm:297
Declaration: Namespace clore::extract
create_compiler_instance 首先调用 sanitize_driver_arguments 清理传入的 CompileEntry 以生成有效的 driver_args。若 driver_args 为空则直接返回 nullptr。接着创建一个物理文件系统 vfs,并基于 DiagnosticOptions 和 IgnoringDiagConsumer 初始化一个 DiagnosticsEngine。随后调用 parse_compiler_invocation 解析 driver_args、entry.file、vfs 和 diagnostics,尝试构造 CompilerInvocation;若解析失败或 FrontendOptions::Inputs 为空,均返回 nullptr。成功获得 invocation 后,会设置其 DisableFree 为 false 并将 WorkingDir 设为 entry.directory。最终使用该 invocation 构造 CompilerInstance,依次设置 vfs、创建诊断器与文件管理器,并通过 createTarget 检查目标是否可用;任意步骤失败则返回 nullptr,否则返回构建好的实例。
该函数依赖 sanitize_driver_arguments、parse_compiler_invocation 以及 clang 与 llvm::vfs 的基础设施,通过组装一个完整的编译器实例为后续的提取工作提供执行环境。
Side Effects
- Allocates memory for a
clang::CompilerInstanceand associated objects - Accesses the file system via physical VFS creation and target creation
Reads From
- entry (const
CompileEntry&): reads entry.fileand entry.directory
Usage Patterns
- Typically called by extraction pipeline to obtain a compiler instance for parsing source files
clore::extract::ensure_cache_key
Declaration: extract/compiler.cppm:60
Definition: extract/compiler.cppm:225
Declaration: Namespace clore::extract
Implementation: Implementation
函数 clore::extract::ensure_cache_key 完全委托给内部的 ensure_cache_key_impl,后者负责为给定的 CompileEntry 计算并设置 cache_key 字段。实现流程首先调用 normalize_entry_file 获取规范化路径,然后通过 sanitize_driver_arguments 清理参数列表,并尝试用 parse_compiler_invocation 解析出 CompilerInvocation,从中提取 frontend_inputs 并调用 try_hash_source_file 计算 source_hash。接着利用 build_compile_signature(内部委托给 build_compile_signature_impl)生成最终的签名值,此过程还会查询 toolchain_cache(通过 query_toolchain_cached)并可能加载编译数据库(load_compdb)以补充缺失上下文,最终将签名写入 entry.cache_key 以确保每个条目拥有唯一的缓存标识。
Side Effects
- Modifies the
CompileEntryby setting its cache key.
Reads From
- Parameter
entry(reference toCompileEntry).
Writes To
- Parameter
entry(theCompileEntryobject is mutated).
Usage Patterns
- Called by
query_toolchain_cachedbefore attempting to use cached toolchain information to ensure the entry has a valid cache key.
clore::extract::ensure_cache_key_impl
Declaration: extract/compiler.cppm:119
Definition: extract/compiler.cppm:119
Declaration: Namespace clore::extract
Implementation: Implementation
ensure_cache_key_impl 通过依次填充 CompileEntry 的四个关键字段来构造缓存键。它首先调用 normalize_entry_file 将条目的源文件路径规范化,结果写入 entry.normalized_file。然后调用 build_compile_signature_impl 基于该规范化路径生成编译签名,存入 entry.compile_signature。接着用 try_hash_source_file 尝试哈希源文件,结果存入 entry.source_hash;该调用可能返回空,但函数在此处不检查其结果——缓存键的最终构建依赖 clore::support::build_cache_key,它仅使用规范化路径和编译签名组成 entry.cache_key。
整个流程是线性的,无分支或错误处理;它假定所有被调用的辅助函数均能成功完成,并将结果直接赋值给传入的 CompileEntry。该函数是 ensure_cache_key 的内部实现,将缓存键的构造分解为独立的子步骤,便于测试和复用。
Side Effects
- Modifies the fields of the passed
CompileEntry& - Reads the source file for hashing via
try_hash_source_file
Reads From
- The
CompileEntryparameterentry - The file system via
normalize_entry_fileandtry_hash_source_file
Writes To
entry.normalized_fileentry.compile_signatureentry.source_hashentry.cache_key
Usage Patterns
- Called by
clore::extract::ensure_cache_key
clore::extract::load_compdb
Declaration: extract/compiler.cppm:42
Definition: extract/compiler.cppm:127
Declaration: Namespace clore::extract
该函数首先检查输入路径对应的文件是否存在,若不存在则返回一个 CompDbError。接着调用 clang::tooling::JSONCompilationDatabase::loadFromFile 解析 JSON 数据库,解析失败同样返回错误。成功时遍历所有编译命令,为每个命令构造一个 CompileEntry,依次填充其 file、directory 和 arguments 字段,并对每个 entry 调用 ensure_cache_key 生成缓存键,最后将 entry 移入 CompilationDatabase 的 entries 向量。此过程依赖 clang::tooling 的 JSON 解析能力,以及内部辅助函数 ensure_cache_key 对每个条目进行键值计算,最终以日志记录加载的条目数量并返回数据库对象。
Side Effects
- Reads file system to check existence and read
compile_commands.json - Allocates memory for the returned
CompilationDatabaseand its entries - Calls
ensure_cache_keywhich may modify eachCompileEntry - Outputs a log message via
logging::info
Reads From
pathparameter (std::string_view)- File system:
compile_commands.jsonat the givenpath entry.file,entry.directory,entry.argumentsfrom each parsed compile command
Writes To
- Returned
std::expected<CompilationDatabase, CompDbError>(includesCompilationDatabaseon success) - Each
CompileEntrypassed toensure_cache_key(cache key field) - Log output via
logging::info
Usage Patterns
- Typically invoked at the start of the extraction pipeline to obtain the compilation database
- Used in conjunction with other extraction functions like
query_toolchain_cachedorextract_project_async
clore::extract::lookup
Declaration: extract/compiler.cppm:44
Definition: extract/compiler.cppm:164
Declaration: Namespace clore::extract
函数 clore::extract::lookup 遍历 CompilationDatabase 的 entries 容器,对每个 CompileEntry 执行两步路径标准化:首先通过 normalize_argument_path 将查询的文件路径 file 与当前条目的 directory 合并得到候选路径 candidate;然后利用 normalize_entry_file 将条目的 file 字段转换为绝对路径(若 normalized_file 已缓存则直接使用)。最后使用 std::filesystem::path 的相等比较判断 candidate 与 normalized_entry 是否匹配,将所有匹配的条目指针收集到 std::vector<const CompileEntry*> 中并返回。
该函数依赖于 normalize_argument_path 和 normalize_entry_file 两个辅助函数,后者会调用 std::filesystem::weakly_canonical 完成路径解析。内部控制流为简单的线性扫描,未涉及缓存或提前退出,时间复杂度为 O(n)。
Side Effects
No observable side effects are evident from the extracted code.
Reads From
db.entriesentry.directoryentry.normalized_file
Usage Patterns
- Lookup compile entries for a specific source file
clore::extract::normalize_argument_path
Declaration: extract/compiler.cppm:49
Definition: extract/compiler.cppm:188
Declaration: Namespace clore::extract
该函数将传入的 path 与 directory 组合并解析为绝对、规范的文件系统路径。算法首先判断 path 是否为相对路径:若是,则将其与 directory 拼接;接着通过 std::filesystem::absolute 转换为绝对路径(忽略错误),再调用 lexically_normal 进行词法规范化。最后尝试使用 weakly_canonical 获取强规范形式——此步骤依赖底层文件系统判断是否存在符号链接或目录问题,若失败则直接返回词法规范化后的结果。整个流程依赖 std::filesystem 提供的路径操作与错误处理机制。
Side Effects
- Accesses the filesystem via
std::filesystem::weakly_canonicalto resolve symlinks and verify path existence.
Reads From
std::string_view pathparameterstd::string_view directoryparameter- Filesystem state (for symlink resolution and existence checks)
Usage Patterns
- Normalizes file paths from compilation database entries
- Standardizes paths before comparison or indexing in extraction pipeline
clore::extract::normalize_entry_file
Declaration: extract/compiler.cppm:56
Definition: extract/compiler.cppm:91
Declaration: Namespace clore::extract
Implementation: Implementation
函数 clore::extract::normalize_entry_file 通过组合 std::filesystem 操作将 entry.file 规范化为绝对路径并解析链接依赖。首先检查路径是否为相对路径,若是则与 entry.directory 拼接;接着调用 std::filesystem::absolute 生成绝对形式,然后通过 lexically_normal 做词法上的规范化。为处理符号链接,进一步尝试 weakly_canonical:若失败(如路径不存在或权限不足)则回退到词法规范化结果,最终以 Unix 风格返回 generic_string。
该函数主要依赖 std::filesystem::path 及其错误处理(通过 std::error_code),不涉及外部文件系统缓存或其他模块。控制流简洁:仅处理相对路径分支和回退分支,确保在无法解析真实路径时仍返回格式一致的结果。
Side Effects
No observable side effects are evident from the extracted code.
Reads From
entry.fileentry.directory
Usage Patterns
- Used by
build_compile_signatureto create a stable file key - Used by
ensure_cache_key_implto normalize the file path before caching
clore::extract::query_toolchain_cached
Declaration: extract/compiler.cppm:62
Definition: extract/compiler.cppm:233
Declaration: Namespace clore::extract
函数 clore::extract::query_toolchain_cached 通过缓存机制返回与给定 CompileEntry 关联的工具链参数。它首先检查 entry.arguments 是否为空,若为空则直接返回空向量。否则,使用 entry.cache_key 作为查找键;若该键为空,则复制 entry 并调用 ensure_cache_key 生成缓存键。随后在 db.toolchain_cache 中查找该键,若命中则返回对应的已缓存 std::vector<std::string>。
若缓存未命中,函数调用 sanitize_tool_arguments 对原始 entry 进行清理,将结果存入 db.toolchain_cache(键为步骤中确定的 key),并返回该结果。该实现依赖于 ensure_cache_key(用于保证缓存键的一致性)和 sanitize_tool_arguments(负责实际的参数规范化与提取)。
Side Effects
- Modifies the toolchain cache of the
CompilationDatabaseobject
Reads From
- entry
.arguments - entry
.cache_key - db
.toolchain_cache
Writes To
- db
.toolchain_cache
Usage Patterns
- Caching sanitized tool arguments for compile entries
- Avoiding repeated sanitization of tool arguments
clore::extract::sanitize_driver_arguments
Declaration: extract/compiler.cppm:52
Definition: extract/compiler.cppm:207
Declaration: Namespace clore::extract
该函数首先通过 normalize_argument_path 规范化 entry.file 与 entry.directory 得到 source_path,然后对 entry.arguments 执行 std::erase_if,移除那些非空、不以 - 开头且经相同规范化后与 source_path 相等的参数。这一过滤逻辑用于剔除与输入文件自身路径重复的参数(如显式传递的源文件名),保留编译选项和标志。核心依赖是 normalize_argument_path,它负责将相对路径或混合路径转换为统一的绝对形式以进行精确比较;内部不涉及复杂的状态或异常处理,仅依赖标准库容器算法和路径规范化工具。
Side Effects
No observable side effects are evident from the extracted code.
Reads From
entry.argumentsentry.fileentry.directory
Usage Patterns
- used to clean up compiler argument lists before invoking the driver
- called to avoid duplicate source file arguments
clore::extract::sanitize_tool_arguments
Declaration: extract/compiler.cppm:54
Definition: extract/compiler.cppm:221
Declaration: Namespace clore::extract
clore::extract::sanitize_tool_arguments 的实现完全依赖于委托:它将接收到的 CompileEntry 引用传递给 sanitize_driver_arguments,再将结果直接传入 strip_compiler_path。内部控制流是线性的,没有分支、循环或错误处理;唯一的数据流是参数向量经过两次转换后的返回值。这两个被调用的函数分别承担了清理编译器特定参数和剥离可执行路径的核心工作,共同构成了整个函数的计算逻辑。
Side Effects
No observable side effects are evident from the extracted code.
Reads From
- const
CompileEntry&entry
Usage Patterns
- Used in the extraction pipeline to normalize compile commands before parsing or analysis
clore::extract::strip_compiler_path
Declaration: extract/compiler.cppm:47
Definition: extract/compiler.cppm:181
Declaration: Namespace clore::extract
该函数接收一个代表编译器调用的参数向量,并返回移除了第一个元素(即编译器可执行路径)后的剩余参数。若输入参数不足两个元素(即没有后续参数),则返回一个空向量。控制流仅包含一个长度检查与一次向量切片操作,不依赖外部函数或数据结构,算法复杂度为线性复制。
Side Effects
No observable side effects are evident from the extracted code.
Reads From
argsparameter
Usage Patterns
- Used to extract compiler flags from a compilation command, e.g., when processing
CompileEntryarguments.
Internal Structure
模块 extract:compiler 围绕编译数据库的加载、条目规范化及编译器调用实例化进行分解。核心公开类型包括 CompileEntry(存储源文件、编译目录、参数列表及缓存字段)和 CompilationDatabase(维护条目列表与工具链缓存)。公开函数从 load_compdb 开始,逐层处理:先通过 normalize_entry_file 与 sanitize_driver_arguments 完成路径和参数的标准化,再通过 ensure_cache_key 建立唯一缓存标识,最后由 query_toolchain_cached 和 create_compiler_instance 将清理后的输入转化为可复用的编译器实例。内部处于匿名命名空间的辅助函数(如 parse_compiler_invocation、try_hash_source_file、build_compile_signature_impl)负责底层的路径哈希、参数解析与签名计算,确保公开接口的职责清晰且可测试。该模块仅导入 std 与 support 模块,依赖后者提供的文件 I/O、路径归一化及缓存键构造能力,自身则专注于编译器调用相关的解析、去重与实例化逻辑,形成从原始编译数据库到可用编译器实例的完整转换流水线。