深入研究Clang(六) Clang Lexer代码阅读笔记之Preprocesser

简介: 作者:史宁宁(snsn1984)clang/include/clang/Lex/Preprocesser.h这个文件是包含clang::Preprocesser类的定义的头文件。
clang/include/clang/Lex/Preprocesser.h
这个文件是包含clang::Preprocesser类的定义的头文件。它是类C语言(C、C++、Object C)的预处理的头文件。也就是说,类C语言的预处理都会用到此处的代码。
00082 /// \brief Context in which macro name is used.
00083 enum MacroUse {
00084   MU_Other  = 0,  // other than #define or #undef
00085   MU_Define = 1,  // macro name specified in #define
00086   MU_Undef  = 2   // macro name specified in #undef
00087 };
这个枚举很简单,就是通过枚举值来确定到底使用了哪些宏。除了define和undef之外,其他的都分类到MU_Other类别下边了。
00089 /// \brief Engages in a tight little dance with the lexer to efficiently
00090 /// preprocess tokens.
00091 ///
00092 /// Lexers know only about tokens within a single source file, and don't
00093 /// know anything about preprocessor-level issues like the \#include stack,
00094 /// token expansion, etc.
00095 class Preprocessor : public RefCountedBase<Preprocessor> {
00096   IntrusiveRefCntPtr<PreprocessorOptions> PPOpts;
00097   DiagnosticsEngine        *Diags;
00098   LangOptions       &LangOpts;
00099   const TargetInfo  *Target;
00100   FileManager       &FileMgr;
00101   SourceManager     &SourceMgr;
00102   std::unique_ptr<ScratchBuffer> ScratchBuf;
00103   HeaderSearch      &HeaderInfo;
00104   ModuleLoader      &TheModuleLoader;
这里可以看到Preprocessor的类的定义,而它是模板类RefCountedBase<Preprocessor>的子类。同时可以看看这几个类的几个成员变量,DiagnosticsEngine-诊断引擎,LangOptions-接收的编译选项,TargetInfo-存储目标信息,FileManager-文件管理器,SourceManager-源码管理器,ModuleLoader-module加载器。
00118   /// Identifiers for builtin macros and other builtins.
00119   IdentifierInfo *Ident__LINE__, *Ident__FILE__;   // __LINE__, __FILE__
00120   IdentifierInfo *Ident__DATE__, *Ident__TIME__;   // __DATE__, __TIME__
00121   IdentifierInfo *Ident__INCLUDE_LEVEL__;          // __INCLUDE_LEVEL__
00122   IdentifierInfo *Ident__BASE_FILE__;              // __BASE_FILE__
00123   IdentifierInfo *Ident__TIMESTAMP__;              // __TIMESTAMP__
00124   IdentifierInfo *Ident__COUNTER__;                // __COUNTER__
00125   IdentifierInfo *Ident_Pragma, *Ident__pragma;    // _Pragma, __pragma
00126   IdentifierInfo *Ident__identifier;               // __identifier
00127   IdentifierInfo *Ident__VA_ARGS__;                // __VA_ARGS__
00128   IdentifierInfo *Ident__has_feature;              // __has_feature
00129   IdentifierInfo *Ident__has_extension;            // __has_extension
00130   IdentifierInfo *Ident__has_builtin;              // __has_builtin
00131   IdentifierInfo *Ident__has_attribute;            // __has_attribute
00132   IdentifierInfo *Ident__has_include;              // __has_include
00133   IdentifierInfo *Ident__has_include_next;         // __has_include_next
00134   IdentifierInfo *Ident__has_warning;              // __has_warning
00135   IdentifierInfo *Ident__is_identifier;            // __is_identifier
00136   IdentifierInfo *Ident__building_module;          // __building_module
00137   IdentifierInfo *Ident__MODULE__;                 // __MODULE__
00138   IdentifierInfo *Ident__has_cpp_attribute;        // __has_cpp_attribute
另外Preprocesser类中包含了使用IdentifierInfo指针所保存的内建宏以及其他的内建的标示符。所以如果要修改或者扩展内建宏或者其他内建标示符,这里也是必须要修改的地方。
00148   // State that is set before the preprocessor begins.
00149   bool KeepComments : 1;
00150   bool KeepMacroComments : 1;
00151   bool SuppressIncludeNotFoundError : 1;
00152 
00153   // State that changes while the preprocessor runs:
00154   bool InMacroArgs : 1;            // True if parsing fn macro invocation args.
00155 
00156   /// Whether the preprocessor owns the header search object.
00157   bool OwnsHeaderSearch : 1;
00158 
00159   /// True if macro expansion is disabled.
00160   bool DisableMacroExpansion : 1;
00161 
00162   /// Temporarily disables DisableMacroExpansion (i.e. enables expansion)
00163   /// when parsing preprocessor directives.
00164   bool MacroExpansionInDirectivesOverride : 1;
00165 
00166   class ResetMacroExpansionHelper;
00167 
00168   /// \brief Whether we have already loaded macros from the external source.
00169   mutable bool ReadMacrosFromExternalSource : 1;
00170 
00171   /// \brief True if pragmas are enabled.
00172   bool PragmasEnabled : 1;
00173 
00174   /// \brief True if the current build action is a preprocessing action.
00175   bool PreprocessedOutput : 1;
另外在Preprocesser类中,还出现了一部分这样的代码,这种给成员变量制定位域的形式还是第一次见到,一度让我以为是要给成员变量赋值。这种使用位域节省空间的方式,在结构体中比在类中稍微常见点,为了节省空间,在这么大的类中使用还是第一次见。:后面的数字是为了指定一定的bit位去保存变量的值。其中,这里里面还有一个更特殊的一行代码:
00168   /// \brief Whether we have already loaded macros from the external source.
00169   mutable bool ReadMacrosFromExternalSource : 1;
这个成员变量,不仅仅用到了位域,还用到了mutable。一般使用mutable修饰变量,是为了在const成员函数中可以修改这个成员变量。






目录
相关文章
|
8月前
|
存储 自动驾驶 测试技术
Mastering Makefile:模块化编程技巧与经验分享
在Linux项目管理中,Makefile是一个强大的工具,它可以帮助我们自动化编译和测试过程。然而,随着项目的增长,Makefile可能会变得越来越复杂,难以管理。在这篇文章中,我将分享一些模块化编程的技巧和经验,帮助你更好地管理你的Makefile。 使用反斜杠进行换行
67 0
|
前端开发 C语言 iOS开发
基于LLVM的编译原理简明教程 (1) - 写编译器越来越容易了
跟学院派的厚书给大家的印象不同,其实用LLVM写个简单的编译器是件容易的事情,因为大部分事情LLVM都替我们做了。
8226 0
|
前端开发 IDE 编译器
LLVM编译器前端 Clang 简介
昨天晚上安装rails的开发环境,被ruby的编译搞的有点崩溃。下载的ruby的源码不能用系统自带的gcc -4.21编译,也不能用系统自带的clang进行编译,必须下载并使用gcc -4.2进行编译才能通过。今天稍微看看编译器的一些背景。
508 0
LLVM编译器前端 Clang 简介
|
编译器 iOS开发 Windows
带你读《LLVM编译器实战教程》之一:构建和安装LLVM
本书的前半部分将向您介绍怎么样去配置、构建、和安装LLVM的不同软件库、工具和外部项目。接下来,本书的后半部分将向您介绍LLVM的各种设计细节,并逐步地讲解LLVM的各个编译步骤:前段、中间表示(IR)、后端、即时编译(JIT)引擎、跨平台编译和插件接口。本书包含有大量翔实的示例和代码片段,以帮助读者平稳顺利的掌握LLVM的编译器开发环境。
19716 0
|
Unix
深入研究Clang(九) Clang代码阅读之打log读流程2
继续上一篇,同样的hello.c,同样的执行过程,只不过继续添加了一些log信息,而且对代码进行了更近一步的挖掘。先看输入和输出的log信息(前半部分): shining@shining-VirtualBox:~/llvm-3.
1424 0
深入研究Clang(八) Clang代码阅读之打log读流程1
这个过程简单的分为几步。 第一步:写一个简单的小程序,hello.c。内容如下: #includeint main() {  printf("Hello world!\n");} 第二步:找出如何在LLVM里面输出信息,最后选择采用llvm::errs(),等于采用了LLVM的错误机制。
1201 0
|
Web App开发 JavaScript
深入研究Clang(七) Clang Lexer代码阅读笔记之Lexer
作者:史宁宁(snsn1984) 源码位置:clang/lib/Lexer.cpp 源码网络地址:http://clang.llvm.org/doxygen/Lexer_8cpp_source.html Lexer.cpp这个文件,是Clang这个前端的词法分析器的主要文件,它的内容是对Lexer这个类的具体实现,原文件的注释中:“This file implements the Lexer and Token interfaces.” 这么解释这个文件的,但是Token只有两个简单函数的实现,剩下的都是Lexer的实现。
1576 0
|
前端开发 C语言 C++
LLVM和Clang背后的故事
LLVM是Apple官方支持的编译器,而该编译器的前端是Clang,这两个工具都被集成到了Xcode里面。
1774 0