clang 01.clang简介

2023-11-11


前言

Clang的官方网站是 http://clang.llvm.org,它被认为是C家族的LLVM前端。

Clang可能指代三种不同的实体:

  1. 前端(由Clang程序库实现)。
  2. 编译器驱动器(由Clang命令和Clang驱动器程序库实现)。
  3. 实际的编译器(由clang -cc1 命令实现)。clang -cc1中的编译器不单用Clang程序库实现,还大量用到了LLVM程序库来实现编译器的中端和后端,还有集成的汇编器。

本章中主要将clang作为前端,并使用它的程序库构建自己的编译器


1. Clang的工作流程

前面我们说clang可能指代三种不同的实体:

  1. 它可以指代编译器前端是因为它实现了词法分析、语法分析、语义分析和中间代码生成这些步骤,并且把它们封装成libclang(模块化)。这些库是为clang外部用户设计的重要接口,可以单独使用,并将他们跟你的项目链接在一起。如下是相关的程序库:
  • libclangLex:这个库用于预处理和词法分析,处理宏、标记、pragma构造;
  • libclangAST:这个库提供编译、操作、遍历抽象语法树的功能;
  • libclangParse:这个库用于解析程序逻辑,利用此法阶段的结果;
  • libclangSema:这个库用于语义分析,为AST验证提供Action(动作)。
  • libclangAnalysis:这个库包含静态分析的资源;
  • libclangRewrite:这个库支持代码重写,为编译器代码重构工具提供基础设施(如LibTooling这个后面再参阅);
  • libclangBasic:这个库提供一系列实用工具-内存分配抽象、源代码位置、诊断,等。
  1. 编译器驱动器,该代码在clang/tools/driver/driver.cpp中实现,clang(这里指编译器前端)和llvm前后分离,编译器驱动器将命令行参数解析,并调用实际的编译器clang -cc1对source进行编译链接。
    clang hello.c -o hello就是调用编译器驱动器;
    clang hello.c -###,可以在驱动器命令行后面加-###来查看驱动器的调用清单;

    $ clang main.c -###
    clang version 15.0.7
    Target: x86_64-unknown-linux-gnu
    Thread model: posix
    InstalledDir: /usr/local/bin
     "/usr/local/bin/clang-15" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "--mrelax-relocations" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "main.c" "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie" "-mframe-pointer=all" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-funwind-tables=2" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-mllvm" "-treat-scalable-fixed-error-as-warning" "-debugger-tuning=gdb" "-fcoverage-compilation-dir=/home/zhimin/compiler/Clang-Learning/Lexer" "-resource-dir" "/usr/local/lib/clang/15.0.7" "-internal-isystem" "/usr/local/lib/clang/15.0.7/include" "-internal-isystem" "/usr/local/include" "-internal-isystem" "/usr/lib/gcc/x86_64-linux-gnu/9/../../../../x86_64-linux-gnu/include" "-internal-externc-isystem" "/usr/include/x86_64-linux-gnu" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdebug-compilation-dir=/home/zhimin/compiler/Clang-Learning/Lexer" "-ferror-limit" "19" "-fgnuc-version=4.2.1" "-fcolor-diagnostics" "-faddrsig" "-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o" "/tmp/main-2715fb.o" "-x" "c" "main.c"
     "/usr/bin/ld" "-pie" "-z" "relro" "--hash-style=gnu" "--eh-frame-hdr" "-m" "elf_x86_64" "-dynamic-linker" "/lib64/ld-linux-x86-64.so.2" "-o" "a.out" "/lib/x86_64-linux-gnu/Scrt1.o" "/lib/x86_64-linux-gnu/crti.o" "/usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o" "-L/usr/lib/gcc/x86_64-linux-gnu/9" "-L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib64" "-L/lib/x86_64-linux-gnu" "-L/lib/../lib64" "-L/usr/lib/x86_64-linux-gnu" "-L/usr/lib/../lib64" "-L/lib" "-L/usr/lib" "/tmp/main-2715fb.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "/usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o" "/lib/x86_64-linux-gnu/crtn.o"
    

    通过上述结果,编译驱动器调用实际的编译器clang -cc1将clang和llvm拼接起来实现了整个编译器(注意:ld这里还是使用GNU的,原因是llvm的链接器还没有集成进来,所以clang -cc1,将source code生成目标文件后就终止了)。

    当然也可以不通过驱动器来调用clang -cc1,结果就是需要自己手动指定系统头文件的位置,通过-I 选项。

    在编译驱动器中使用-Xclang <option>可以向这个工具输入具体的参数来激活clang -cc1中的某些隐藏技能。例如clang -cc1工具有一个特殊的选项,可以打印Clang抽象语法树(AST)。可以用clang -Xclang -ast-dump main.c来激活这个功能。当然也可以直接调用clang -cc1而不是驱动器:clang -cc1 -ast-dump main.c

  2. 实际的编译器:实际的编译器就是上述所说的clang -cc1,每次调用clang -cc1都是由一种主要前端Action来控制的。完整的Action集合定义在源文件clang/include/clang/FrontendOptions.h中,如下:描述了clang -cc1可能执行的不同任务:
    在这里插入图片描述
    在这里插入图片描述
    选项 -cc1触发cc1_main函数的执行(源代码文件:clang/tools/driver/cc1_main.cpp)。例如,当通过clang hello.c -o hello间接调用-cc1时,这个函数初始化目标特定的信息,建立诊断基础设施,执行EmitObj活动。这个活动由CodeGenAction(源代码文件:clang/CodeGen/CodeGenAction.h)实现,ASTFrontendAction的一个子类。此代码实例化了所有的clang和llvm组件,指挥它们生成目标文件 。
    在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

clang 01.clang简介 的相关文章

  • 如何编写 Hibernate HQL 查询来删除所有“孙子”元素?

    我有学校 里面有团体 里面有学生 我想删除特定学校的所有学生 在 SQL 中我可以编写以下查询 DELETE FROM students1 WHERE students1 group id IN SELECT id FROM group1
  • 透明平开窗

    我有一点JWindow上面有一个标志 用户可以将东西拖到上面 我主要在 OS X 上开发我的应用程序 为了获得我使用的透明窗口 setBackground new Color 0 0 0 0 在 Mac 上 这工作得很好 但在 Window
  • 如何在Java 8中实现Elvis运算符?

    我有一个经典的 Elvis 运算符 案例 其中我调用每个可能返回 null 的方法并将它们链接在一起 thing nullableMethod1 a nullableMethod2 b nullableMethod3 在 Java 8 中
  • 线程“main”java.lang.UnsatisfiedLinkError中出现异常:java.library.path中没有opencv_java249

    我目前正在尝试在我的 32 位笔记本电脑上设置 OpenCV 但我不断收到一条令我困惑的错误消息 Exception in thread main java lang UnsatisfiedLinkError no opencv java2
  • 静态方法的 Java 内存模型

    我来自操作系统和 C 语言背景 在代码编译时 世界很简单 需要处理和理解堆栈 堆文本部分等 当我开始学习 Java 时 我确实了解 JVM 和垃圾收集器 我对静态方法感到很有趣 根据我的理解 类的所有实例都会在堆中创建 然后被清理 但是 对
  • 使用 Spring Data REST 处理自定义异常 (i18n)

    我正在使用 Spring Boot 1 5 4 和 Spring JPA Spring Data REST HATEOAS 我正在寻找一种最佳实践 Spring 方式 来自定义异常 Spring Data REST 正在管理添加 i18n
  • 使用 jpql 和 jpa 从日期字段中提取年份

    我想从数据库中的一行中提取年份部分 以便将其与值进行比较 这是我的功能 public List
  • RSA SignatureException:签名长度不正确

    我在签署 rsa 签名时遇到问题 我有一个用私钥加密的签名 然而 当我尝试使用公钥验证它时遇到问题 我得到以下异常 java security SignatureException Signature length not correct
  • 初级 Java 计数器代码

    我的教授希望我这样做 使用下面的 Counter 接口写入多个可互换计数器 public interface Counter Current value of this counter int value Increment this co
  • 在 TestNG 中运行多个类

    我正在尝试自动化一个场景 其中我想登录一次应用程序 然后进行操作而无需再次重新登录 考虑一下 我有在特定类的 BeforeSuite 方法中登录应用程序的代码 public class TestNGClass1 public static
  • 如果基于 Spring 注解的控制器位于 jar 文件内,则该控制器无法工作

    我的子模块中有一些基于注释的控制器 这些模块作为 jar 文件部署 jar 文件中基于注释的控制器未加载到 spring 配置中 我使用 Eclipse 中的导出实用程序手动导出 jar 文件 有人遇到过这个问题吗 当您使用 Eclipse
  • 如何将自定义日志处理程序添加到 Google App Engine?

    我正在尝试向我的 java 应用程序添加自定义日志处理程序 我已经实现了一个扩展 java util Logging Handler 类的 InnerLogger 类 在我的logging properties中声明为处理程序 handle
  • Java 唤醒休眠线程

    我阅读了其他帖子 但没有找到我正在寻找的确切答案 所以我希望有人能给出一些澄清 我有一个将运行一段时间的程序 我有一些在后台运行的线程来执行各种任务 为了简单起见 让我们考虑 3 个线程 ThreadA每 10 秒执行一次任务 其中Thre
  • BlackBerry SQLite:将一个 SQLite 数据库连接到另一个

    我正在尝试使用 SQLite 将一个 SQLite 数据库附加到 BlackBerry 上的另一个数据库附加数据库 http www sqlite org lang attach html命令 Database d1 d2 Statemen
  • C# 中的协变和逆变

    首先我要说的是 我是一名正在学习 C 编程的 Java 开发人员 因此 我会将我所知道的与我正在学习的进行比较 我已经使用 C 泛型几个小时了 我已经能够在 C 中重现我在 Java 中知道的相同内容 除了几个使用协变和逆变的示例 我正在读
  • 如何制作无限的jscrollpane?

    我之前已经实现过拖动滚动 但是创建无限滚动窗格的最佳方法是什么 当然不会有任何滚动条 我将实现拖动滚动 我想做的是在无限表面上实现动态加载 EDIT 当然 它实际上不会是无限的 我想问如何伪造它 您可以执行以下操作 AdjustmentCl
  • 不要模拟值对象:过于通用的规则,没有解释

    以下是 Mockito 单元测试框架的引用 不要模拟值对象 为什么有人会想要这样做呢 因为实例化对象太痛苦了 gt 无效 原因 如果创造新的装置太困难 那就是一个迹象 代码可能需要一些认真的重构 另一种方法是创建 价值对象的构建者 有一些工
  • HTTP PUT 在 Java 中上传文件

    Edit 我想我已经弄清楚如何执行二进制数据部分 仔细检查代码 但我很确定我做对了 现在 当我尝试按照中所述完成上传时遇到新错误Vimeo API 文档 http vimeo com api docs upload streaming Ed
  • 是否可以为 azure blob 存储中的给定目录生成具有写入权限的 SAS(共享访问签名)

    我们的 blob 存储帐户结构 容器名称 simple 在这个容器内我们有 blob aa one zip aa two zip bb ss zip bb dd zip 是否可以生成对aa 目录 有写权限 但对bb 目录 没有访问权限的SA
  • java.io.EOFException:没有更多可用数据 - 预期结束标记 关闭开始标记

    我正在使用 xmpp 开发一个聊天应用程序 根据我们的要求 我们有三台服务器 Apache Tomcat 7 ejabbered 2 1 11 和 mysql 5 5 to run xmppbot on tomcat used below

随机推荐

  • Android studio Gradle 7.0+ 版本的.aar引入方式说明

    新建的Androidi项目编译错误 莫名其妙的错误 踩坑了 记录一下 各位大神指正 1 buildg radle中引入 aar错误 android repositories flatDir 引入libs目录下的aar dirs libs A
  • linux命令打印消息自动保存,Linux基本命令(2)

    1 如果在任何命令的后面加上一个 gt 和文件名 不一定事先存在 那么这个命令的执行结果就被送至该文件中 如 ls usr bin gt unknown 如果该文件已经存在 则ls命令的输出结果将会覆盖原来的文件内容 如果用csh和tcsh
  • Python time strftime() 方法

    描述 Python time strftime 函数用于格式化时间 返回以可读字符串表示的当地时间 格式由参数 format 决定 语法 strftime 方法语法 time strftime format t 参数 format 格式字符
  • SpringBoot项目配置跨域报错When allowCredentials is true, allowedOrigins cannot contain the special value

    项目配置允许跨域访问后 报When allowCredentials is true allowedOrigins cannot contain the special value错误 解决办法找到配置允许跨域访问配置的地方 找到如下配置
  • 二叉搜索树 BST

    文章目录 一 判断 BST 的合法性 Q98 迭代写法见提交记录 使用stack 二 在 BST 中搜索一个数 Q700 三 在 BST 中插入一个数 Q701 四 在 BST 中删除一个数 Q450 最后总结 原文 https mp we
  • A优秀的springcloud项目部署及代码。

    在线演示地址 http 114 115 178 160 8082 index 演示服务器内存宽带比较小 可能导致演示系统比较卡 第一次加载可能要20秒 为防止人为恶意删除我演示系统数据库演示系统将禁止修改数据库 敬请谅解 在这个社会上总有一
  • 【Java】jdk5.0、jdk7、jdk8、jdk11、jdk17新特性

    文章目录 前言 一 jdk5 0新特性 二 jdk7新特性 三 jdk8新特性 四 jdk11新特性 五 jdk17新特性 前言 了解jdk新特性 一 jdk5 0新特性 泛型 允许类型或方法对各种类型的对象进行操作 同时提供编译时类型安全
  • 华为OD机试-高性能AI处理器-2022Q4 A卷-Py/Java/JS

    某公司研发了一款高性能AI处理器 每台物理设备具备8颗AI处理器 编号分别为0 1 2 3 4 5 6 7 编号0 3的处理器处于同一个链路中 编号4 7的处理器处于另外一个链路中 不同链路中的处理器不能通信 现给定服务器可用的处理器编号数
  • Opencascade之STL可视化与选取渲染风格

    在Opencascade中 STL模型可以的可视化有两种方式 一 STL模型加载为Shape对象 再可视化 1 1 STL模型加载为Shape对象 TopoDS Shape aShape try StlAPI Reader reader r
  • LeetCode两个数组的交集

    两个数组的交集 给定两个数组 nums1 和 nums2 返回 它们的交集 输出结果中的每个元素一定是 唯一 的 我们可以 不考虑输出结果的顺序 输入 nums1 1 2 2 1 nums2 2 2 输出 2 输入 nums1 4 9 5
  • Maven —— Plugin execution not covered by lifecycle configuration 错误

    转载自 https blog csdn net lmxmimihuhu article details 34436205 一 错误描述 Eclipse 导入已存在的Maven 后 pom xml 文件的execution 节点报错 错误位置
  • 网络安全的方向好就业吗

    一些网络安全专业方向的同学难免会有疑问 这个方向好就业吗 我能做些什么呢 今天就业老师就给大家解答一下相关的问题 网络安全是目前为止比较容易就业的一个方向 现今我国是被黑客攻击 信息丢失最严重的的国家之一 因此在市场需求和政策引导的共同推动
  • 微信小程序-0.11.122100版本更新问题

    官方更新了122100版本 一共有90几处改动 这里先不一一列举了 一 redirectTo和navigateTo不能再跳转到带有tab选项卡的页面 小程序新增了一个接口wx switchTab 这个接口是专门用来跳转到带有tabbar的页
  • 1.平台介绍:FISCO BCOS 区块链

    引言 区块链技术作为一种分布式 安全可信的数据记录和交互方式 正逐渐在各行各业展现出巨大潜力 然而 公共区块链的隐私性和性能限制使得企业更倾向于采用联盟链或私有链解决方案 FISCO BCOS Blockchain Open Consort
  • wildfly(JBOSS)启动报错

    报错内容 15 07 50 724 ERROR org jboss as controller management operation Controller Boot Thread WFLYCTL0013 Operation add fa
  • Delphi 判断fast report 是否存在未定义对象

    Assigned fastreport 对象 Boolean 返回 sql Fields i FieldName 获取列名 sql select from table tmp ADOQuery DLLMan Exe server Query
  • ansys选择一个面上所有节点_ANSYS选中无序关键点、节点并得到其编号

    看样子选中无序关键点 节点并得到其编号不可能的 在ANSYS中 有时我们需要采用APDL命令流选中一堆无序的关键点或节点 也就是这堆关键点或节点的编号完全是任意不连续的 因此无法采用根据编号来选中这堆无序的关键点或节点 而且假如最不利情况下
  • dockerfile创建lnmp镜像

    目录 一 创建lnmp的相关镜像 1 1 dockerfile创建php7 2 16镜像 1 2 dockerfile创建nginx 1 15 7镜像 1 3 mysql镜像是直接在docker仓库上pull 二 通过dockerpose
  • 串口服务器网页进不去怎么办,路由器登录入口进不去怎么办?

    问 路由器登录入口进不去怎么办 答 如果在设置路由器的时候 进不去路由器的登录入口 无法对路由器进行设置 这多半是用户自己操作有误导致的 也可能是路由器或者其它客观原因引起的 具体的解决办法如下 温馨提示 1 如果是用手机设置路由器时 手机
  • clang 01.clang简介

    文章目录 前言 1 Clang的工作流程 前言 Clang的官方网站是 http clang llvm org 它被认为是C家族的LLVM前端 Clang可能指代三种不同的实体 前端 由Clang程序库实现 编译器驱动器 由Clang命令和