1234353Sdim//===--- GeneratePCH.cpp - Sema Consumer for PCH Generation -----*- C++ -*-===// 2212795Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6212795Sdim// 7212795Sdim//===----------------------------------------------------------------------===// 8212795Sdim// 9234353Sdim// This file defines the PCHGenerator, which as a SemaConsumer that generates 10234353Sdim// a PCH file. 11212795Sdim// 12212795Sdim//===----------------------------------------------------------------------===// 13212795Sdim 14212795Sdim#include "clang/AST/ASTContext.h" 15314564Sdim#include "clang/Lex/HeaderSearch.h" 16212795Sdim#include "clang/Lex/Preprocessor.h" 17249423Sdim#include "clang/Sema/SemaConsumer.h" 18314564Sdim#include "clang/Serialization/ASTWriter.h" 19353358Sdim#include "llvm/Bitstream/BitstreamWriter.h" 20212795Sdim 21212795Sdimusing namespace clang; 22212795Sdim 23296417SdimPCHGenerator::PCHGenerator( 24353358Sdim const Preprocessor &PP, InMemoryModuleCache &ModuleCache, 25353358Sdim StringRef OutputFile, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer, 26314564Sdim ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, 27353358Sdim bool AllowASTWithErrors, bool IncludeTimestamps, 28353358Sdim bool ShouldCacheASTInMemory) 29314564Sdim : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()), 30321369Sdim SemaPtr(nullptr), Buffer(std::move(Buffer)), Stream(this->Buffer->Data), 31353358Sdim Writer(Stream, this->Buffer->Data, ModuleCache, Extensions, 32321369Sdim IncludeTimestamps), 33353358Sdim AllowASTWithErrors(AllowASTWithErrors), 34353358Sdim ShouldCacheASTInMemory(ShouldCacheASTInMemory) { 35321369Sdim this->Buffer->IsComplete = false; 36212795Sdim} 37212795Sdim 38226633SdimPCHGenerator::~PCHGenerator() { 39226633Sdim} 40226633Sdim 41212795Sdimvoid PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { 42261991Sdim // Don't create a PCH if there were fatal failures during module loading. 43261991Sdim if (PP.getModuleLoader().HadFatalFailure) 44212795Sdim return; 45261991Sdim 46261991Sdim bool hasErrors = PP.getDiagnostics().hasErrorOccurred(); 47261991Sdim if (hasErrors && !AllowASTWithErrors) 48261991Sdim return; 49288943Sdim 50314564Sdim Module *Module = nullptr; 51314564Sdim if (PP.getLangOpts().isCompilingModule()) { 52314564Sdim Module = PP.getHeaderSearchInfo().lookupModule( 53314564Sdim PP.getLangOpts().CurrentModule, /*AllowSearch*/ false); 54314564Sdim if (!Module) { 55314564Sdim assert(hasErrors && "emitting module but current module doesn't exist"); 56314564Sdim return; 57314564Sdim } 58314564Sdim } 59314564Sdim 60288943Sdim // Emit the PCH file to the Buffer. 61212795Sdim assert(SemaPtr && "No Sema?"); 62296417Sdim Buffer->Signature = 63309124Sdim Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot, 64309124Sdim // For serialization we are lenient if the errors were 65309124Sdim // only warn-as-error kind. 66353358Sdim PP.getDiagnostics().hasUncompilableErrorOccurred(), 67353358Sdim ShouldCacheASTInMemory); 68212795Sdim 69288943Sdim Buffer->IsComplete = true; 70212795Sdim} 71212795Sdim 72218893SdimASTMutationListener *PCHGenerator::GetASTMutationListener() { 73226633Sdim return &Writer; 74218893Sdim} 75218893Sdim 76212795SdimASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() { 77212795Sdim return &Writer; 78212795Sdim} 79