前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >clang 源码导读(7):编译器前端流程简介

clang 源码导读(7):编译器前端流程简介

作者头像
酷酷的哀殿
发布2021-04-09 12:55:54
2.9K0
发布2021-04-09 12:55:54
举报
文章被收录于专栏:酷酷的哀殿酷酷的哀殿

前言

clang 编译器前端负责从源码生成中间码,它通常由 clang 模块驱动,并通常包含以下几个步骤:

image

本文会先对 clang 编译器前端的流程进行简单的介绍,并会在后面的系列文章依次分享下面的几个库:

  1. clangLex :负责词法分析和预处理,处理宏、令牌和 pragma 构造
  2. clangAST:负责提供了构建、操作和遍历 AST 相关的功能
  3. clangParse:负责从词法分析的结果进行处理
  4. clangSema:负责语义分析
  5. clangCodeGen:负责生成 LLVM IR 代码

clang

clang 模块只包含 5 个可编译文件,大部分的功能都是依赖其它模块提供

clangdriver.cpp 是整个程序的入口。

image

clang 模块主要负责以下任务:

  1. main 函数检测输入的参数是否包含以 -cc1 开头的参数

image

  1. 通过 ExecuteCC1Tool 函数分发不同的 cc1类型。 clang 目前支持 3 种类型

image

  1. -cc1 : LLVM 'Clang' Compiler
  2. -cc1as : Clang Integrated Assembler
  3. -cc1gen-reproducer: Generate Libclang invocation reproducers

  1. cc1_main 函数负责初始化 CompilerInstanceDiagnosticIDs,并调用 CreateFromArgs 函数构建 CompilerInvocation

image

  1. CreateFromArgs 函数内部会非常多的函数对参数进行解析

image

  1. -emit-obj 参数传入时,ParseFrontendArgs 函数会将 frontend::EmitObj赋值给 ProgramAction 后面的 CreateFrontendBaseAction 函数会依赖依赖 ProgramAction

image对 -emit-objc 不熟悉的朋友,可以看看 clang driver 系列文章

  1. 调用 clangFrontendTool 模块的 ExecuteCompilerInvocation 函数执行编译任务

image

clangFrontendTool

clangFrontendTool 非常简单,目前只包含一个可编译文件 ExecuteCompilerInvocation.cpp

image

  1. ExecuteCompilerInvocation 会判断先是否存在 -h -v 等参数,如果存在,会执行对应的任务 值得注意的是,这里会尝试加载 plugin

image

  1. 经过一系列的判断后,才会通过 CreateFrontendAction 创建需要执行的编译器前端任务

image

  1. CreateFrontendAction 会先调用 CreateFrontendBaseAction 创建 FrontendAction 的子类

image

  1. CreateFrontendBaseAction 函数会因为前文提到的 EmitObj 参数创建 EmitObjAction 的实例

image

  1. 任务创建完成后,会调用 clangFrontend 模块的 ExecuteAction 函数执行编译任务

image

clangFrontend

clangFrontend 模块包含了很多重要的功能。

cc1_main 函数创建的 CompilerInstance 就是来自 clangFrontend

CompilerInstanceclangFrontend 中非常重要的一个类。它持有了诸如 preprocessorTargetAST 等属性

image

CompilerInstance 执行过程

CompilerInstance::ExecuteAction 会通过 Inputs 获取输入文件,并依次调用以下方法:

  1. Act.BeginSourceFile()
  2. Act.Execute()
  3. Act.EndSourceFile()

image

Ac 就是之前提到的 FrontendAction 的子类 EmitObjAction

Act.BeginSourceFile()

  1. Act.BeginSourceFile() 函数会通过懒加载方式创建 FileManagerSourceManager

imageFileManager 负责和文件系统交互,文件缓存、目录查找等任务

imageSourceManager 负责查找并将文件缓存到内存

image

  1. 通过 createPreprocessor 函数创建预处理器

image预处理器 初始化时,会构建一个包含各个语言的关键字列表IdentifierTable Identifiers;,方便后续词法分析使用

image

  1. 通过 createASTContext 创建 ASTContext

image

image

  1. 随后,会调用函数FrontendAction::CreateWrappedASTConsumer 创建 ASTConsumer

image

Act.Execute()

Act.Execute() 实际上是执行 EmitObjAction 继承自 FrontendActionExecute 函数

FrontendAction:Execute 随后会调用 CodeGenAction::ExecuteAction 函数

image

CodeGenAction::ExecuteAction 函数会调用ASTFrontendAction::ExecuteAction

image

ASTFrontendAction::ExecuteAction 会调用 CompilerInstancecreateSema 函数创建 Sema

image

Sema 后续会用于语义分析

image

各项准备工作结束后,就会调用 clangParse 模块的 clang::ParseAST 构建 abstract syntax tree

image

总结

本文对 clang 编译器前端入门知识进行了简单介绍。

下一篇文章,我们会开始分享 ParseAST 的第一个主要流程:词法分析 和 预处理指令

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-04-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 酷酷的哀殿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • clang
  • clangFrontendTool
  • clangFrontend
    • CompilerInstance 执行过程
      • Act.BeginSourceFile()
        • Act.Execute()
        • 总结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档