深刻研究Clang(六) Clang Lexer代碼閱讀筆記之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成員函數中能夠修改這個成員變量。
相關文章
相關標籤/搜索