Clang Basics

Posted Westwindrest

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Clang Basics相关的知识,希望对你有一定的参考价值。

参考:

Create a working compiler with the LLVM framework, Part 2

How to parse C programs with Clang: A tutorial

一、Preprocessor

前端由许多部分组成,其中第一部分通常是一个 lexer,clang 中 Preprocessor 类是 lexer 的 main interface。处于性能考虑,clang 没有独立的预处理器程序,而是在 lexing 的过程中进行预处理。

Preprocessor 的构造函数如下所示:

Preprocessor::Preprocessor(
        std::shared_ptr<PreprocessorOptions>    PPOpts, // constructor: PreprocessorOptions()
        DiagnosticsEngine&                      diags,  
        LangOptions&                            opts,   // constructor: LangOptions()
// Keep track of the various options that can be enabled,
// which controls the dialect of C or C++ that is accepted SourceManager
& SM, HeaderSearch& Headers, ModuleLoader& TheModuleLoader, IdentifierInfoLookup* IILookup = nullptr, bool OwnsHeaderSearch = false, TranslationUnitKind TUKind = TU_Complete )  

 DiagnosticsEngine : 用来给用户报告错误和警告信息。构造函数如下:

DiagnosticsEngine::DiagnosticsEngine(
        IntrusiveRefCntPtr<DiagnosticIDs>   Diags,        // constructor: DiagnosticIDs()
// used for handling and querying diagnostic IDs DiagnosticOptions
* DiagOpts, // constructor: DiagnosticOptions()
// Options for controlling the compiler diagnostics engine DiagnosticConsumer
* client = nullptr, bool ShouldOwnClient = true )

其中 DiagnosticConsumer 是一个抽象接口,由前端的 clients 实现,用来 formats and prints fully processed diagnostics。clang 内置一个 TextDiagnosticsConsumer 类,将错误和警告信息写到 console 上,clang binary 用的 DiagnosticConsumer 也是这个类。TextDiagnosticsConsumer 的构造函数如下:

TextDiagnosticPrinter::TextDiagnosticPrinter(
        raw_ostream&        os,        // llvm::outs() returns a reference to a raw_ostream for standard output
        DiagnosticOptions*  diags,
        bool                OwnsOutputStream = false  // within destructor:(OS is the member, initialized with os) 
                                                      // if (OwnsOutputStream) delete &OS
        )

 SourceManager :handles loading and caching of source files into memory。构造函数如下:

SourceManager::SourceManager(
        DiagnosticsEngine&  Diag,
        FileManager&        FileMgr,
        bool                UserFilesAreVolatile = false
        )

  FileManager :implements support for file system lookup, file system caching, and directory search management。构造函数如下:

FileManager::FileManager(
        const FileSystemOptions&            FileSystemOpts,  // use default constructor
        IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr
        )

 

  HeaderSearch :Encapsulates the information needed to find the file referenced by a #include or #include_next, (sub-)framework lookup, etc。构造函数如下:

HeaderSearch::HeaderSearch(
        std::shared_ptr<HeaderSearchOptions>    HSOpts,  // constructor: HeaderSearchOptions::HeaderSearchOptions(StringRef _Sysroot = "/")
        SourceManager&                          SourceMgr,
        DiagnosticsEngine&                      Diags,
        const LangOptions&                      LangOpts,
        const TargetInfo*                       Target
        )

 TargetInfo :Exposes information about the current target。 其构造函数为 protected,因此需要调用工厂函数 static TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr<TargetOptions>& Opts) ,其中 TargetOptions 类包含 target 的相关信息,如 CPU、ABI 等。类中有一个属性 Triple 用以定义 target 的架构。Triple 是一个 string,形如 i386-apple-darwin,通过 llvm::sys::getDefaultTargetTriple() 可以获得编译 llvm 的机器的 host triple。

ModuleLoader:描述了 module loader 的抽象接口。Module loader 负责解析一个 module name(如“std”),将其与实际的 module file 联系起来,并加载该 module。CompilerInstance 便是一个实现了该接口的 module loader

以上是关于Clang Basics的主要内容,如果未能解决你的问题,请参考以下文章

使用带有 NMake 样式 Makefile 的 clang-cl 无法回显

[arduino]-1-Basics代码解读

使用Clang格式化代码

PTBtutorials—The basics

用 g++ 编译的奇怪代码

Clang代码覆盖率检测(插桩技术)