Path: blob/main/contrib/llvm-project/clang/lib/Serialization/GeneratePCH.cpp
35234 views
//===--- GeneratePCH.cpp - Sema Consumer for PCH Generation -----*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines the PCHGenerator, which as a SemaConsumer that generates9// a PCH file.10//11//===----------------------------------------------------------------------===//1213#include "clang/AST/ASTContext.h"14#include "clang/Frontend/FrontendDiagnostic.h"15#include "clang/Lex/HeaderSearch.h"16#include "clang/Lex/HeaderSearchOptions.h"17#include "clang/Lex/Preprocessor.h"18#include "clang/Sema/SemaConsumer.h"19#include "clang/Serialization/ASTWriter.h"20#include "llvm/Bitstream/BitstreamWriter.h"2122using namespace clang;2324PCHGenerator::PCHGenerator(25Preprocessor &PP, InMemoryModuleCache &ModuleCache, StringRef OutputFile,26StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,27ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,28bool AllowASTWithErrors, bool IncludeTimestamps,29bool BuildingImplicitModule, bool ShouldCacheASTInMemory,30bool GeneratingReducedBMI)31: PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),32SemaPtr(nullptr), Buffer(std::move(Buffer)), Stream(this->Buffer->Data),33Writer(Stream, this->Buffer->Data, ModuleCache, Extensions,34IncludeTimestamps, BuildingImplicitModule, GeneratingReducedBMI),35AllowASTWithErrors(AllowASTWithErrors),36ShouldCacheASTInMemory(ShouldCacheASTInMemory) {37this->Buffer->IsComplete = false;38}3940PCHGenerator::~PCHGenerator() {41}4243Module *PCHGenerator::getEmittingModule(ASTContext &) {44Module *M = nullptr;4546if (PP.getLangOpts().isCompilingModule()) {47M = PP.getHeaderSearchInfo().lookupModule(PP.getLangOpts().CurrentModule,48SourceLocation(),49/*AllowSearch*/ false);50if (!M)51assert(PP.getDiagnostics().hasErrorOccurred() &&52"emitting module but current module doesn't exist");53}5455return M;56}5758void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {59// Don't create a PCH if there were fatal failures during module loading.60if (PP.getModuleLoader().HadFatalFailure)61return;6263bool hasErrors = PP.getDiagnostics().hasErrorOccurred();64if (hasErrors && !AllowASTWithErrors)65return;6667Module *Module = getEmittingModule(Ctx);6869// Errors that do not prevent the PCH from being written should not cause the70// overall compilation to fail either.71if (AllowASTWithErrors)72PP.getDiagnostics().getClient()->clear();7374// Emit the PCH file to the Buffer.75assert(SemaPtr && "No Sema?");76Buffer->Signature = Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot,77ShouldCacheASTInMemory);7879Buffer->IsComplete = true;80}8182ASTMutationListener *PCHGenerator::GetASTMutationListener() {83return &Writer;84}8586ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() {87return &Writer;88}8990void PCHGenerator::anchor() {}9192CXX20ModulesGenerator::CXX20ModulesGenerator(Preprocessor &PP,93InMemoryModuleCache &ModuleCache,94StringRef OutputFile,95bool GeneratingReducedBMI)96: PCHGenerator(97PP, ModuleCache, OutputFile, llvm::StringRef(),98std::make_shared<PCHBuffer>(),99/*Extensions=*/ArrayRef<std::shared_ptr<ModuleFileExtension>>(),100/*AllowASTWithErrors*/ false, /*IncludeTimestamps=*/false,101/*BuildingImplicitModule=*/false, /*ShouldCacheASTInMemory=*/false,102GeneratingReducedBMI) {}103104Module *CXX20ModulesGenerator::getEmittingModule(ASTContext &Ctx) {105Module *M = Ctx.getCurrentNamedModule();106assert(M && M->isNamedModuleUnit() &&107"CXX20ModulesGenerator should only be used with C++20 Named modules.");108return M;109}110111void CXX20ModulesGenerator::HandleTranslationUnit(ASTContext &Ctx) {112// FIMXE: We'd better to wrap such options to a new class ASTWriterOptions113// since this is not about searching header really.114HeaderSearchOptions &HSOpts =115getPreprocessor().getHeaderSearchInfo().getHeaderSearchOpts();116HSOpts.ModulesSkipDiagnosticOptions = true;117HSOpts.ModulesSkipHeaderSearchPaths = true;118119PCHGenerator::HandleTranslationUnit(Ctx);120121if (!isComplete())122return;123124std::error_code EC;125auto OS = std::make_unique<llvm::raw_fd_ostream>(getOutputFile(), EC);126if (EC) {127getDiagnostics().Report(diag::err_fe_unable_to_open_output)128<< getOutputFile() << EC.message() << "\n";129return;130}131132*OS << getBufferPtr()->Data;133OS->flush();134}135136void CXX20ModulesGenerator::anchor() {}137138void ReducedBMIGenerator::anchor() {}139140141