clang
编译器前端负责从源码生成中间码,它通常由 clang
模块驱动,并通常包含以下几个步骤:
image
本文会先对 clang
编译器前端的流程进行简单的介绍,并会在后面的系列文章依次分享下面的几个库:
clang
模块只包含 5
个可编译文件,大部分的功能都是依赖其它模块提供
clang
库 的driver.cpp
是整个程序的入口。
image
clang
模块主要负责以下任务:
main
函数检测输入的参数是否包含以 -cc1
开头的参数
image
ExecuteCC1Tool
函数分发不同的 cc1
类型。
clang
目前支持 3 种类型
image
-cc1
: LLVM 'Clang' Compiler-cc1as
: Clang Integrated Assembler-cc1gen-reproducer
: Generate Libclang invocation reproducerscc1_main
函数负责初始化 CompilerInstance
、DiagnosticIDs
,并调用 CreateFromArgs
函数构建 CompilerInvocation
image
CreateFromArgs
函数内部会非常多的函数对参数进行解析
image
-emit-obj
参数传入时,ParseFrontendArgs
函数会将 frontend::EmitObj
赋值给 ProgramAction
后面的 CreateFrontendBaseAction
函数会依赖依赖 ProgramAction
image对 -emit-objc
不熟悉的朋友,可以看看 clang driver
系列文章
clangFrontendTool
模块的 ExecuteCompilerInvocation
函数执行编译任务
image
clangFrontendTool
非常简单,目前只包含一个可编译文件 ExecuteCompilerInvocation.cpp
image
ExecuteCompilerInvocation
会判断先是否存在 -h
-v
等参数,如果存在,会执行对应的任务
值得注意的是,这里会尝试加载 plugin
image
CreateFrontendAction
创建需要执行的编译器前端任务
image
CreateFrontendAction
会先调用 CreateFrontendBaseAction
创建 FrontendAction
的子类
image
CreateFrontendBaseAction
函数会因为前文提到的 EmitObj
参数创建 EmitObjAction
的实例
image
ExecuteAction
函数执行编译任务
image
clangFrontend
模块包含了很多重要的功能。
cc1_main
函数创建的 CompilerInstance
就是来自 clangFrontend
CompilerInstance
是 clangFrontend
中非常重要的一个类。它持有了诸如 preprocessor
、Target
、AST
等属性
image
CompilerInstance::ExecuteAction
会通过 Inputs
获取输入文件,并依次调用以下方法:
Act.BeginSourceFile()
Act.Execute()
Act.EndSourceFile()
image
Ac
就是之前提到的FrontendAction
的子类EmitObjAction
Act.BeginSourceFile()
函数会通过懒加载方式创建 FileManager
和 SourceManager
imageFileManager
负责和文件系统交互,文件缓存、目录查找等任务
imageSourceManager
负责查找并将文件缓存到内存
image
createPreprocessor
函数创建预处理器
image预处理器 初始化时,会构建一个包含各个语言的关键字列表IdentifierTable Identifiers;
,方便后续词法分析使用
image
createASTContext
创建 ASTContext
image
image
FrontendAction::CreateWrappedASTConsumer
创建 ASTConsumer
image
Act.Execute()
实际上是执行 EmitObjAction
继承自 FrontendAction
的 Execute
函数
FrontendAction:Execute
随后会调用 CodeGenAction::ExecuteAction
函数
image
CodeGenAction::ExecuteAction
函数会调用ASTFrontendAction::ExecuteAction
image
ASTFrontendAction::ExecuteAction
会调用 CompilerInstance
的 createSema
函数创建 Sema
image
Sema
后续会用于语义分析
image
各项准备工作结束后,就会调用 clangParse
模块的 clang::ParseAST
构建 abstract syntax tree
image
本文对 clang 编译器前端入门知识进行了简单介绍。
下一篇文章,我们会开始分享 ParseAST
的第一个主要流程:词法分析 和 预处理指令