18bd25b421f728cb7c33a3bcc21a4fc60e835c5e8Chandler Carruth//===--- GeneratePCH.cpp - Sema Consumer for PCH Generation -----*- C++ -*-===// 22cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 32cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// The LLVM Compiler Infrastructure 42cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 52cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// This file is distributed under the University of Illinois Open Source 62cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// License. See LICENSE.TXT for details. 72cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 82cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//===----------------------------------------------------------------------===// 92cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 108bd25b421f728cb7c33a3bcc21a4fc60e835c5e8Chandler Carruth// This file defines the PCHGenerator, which as a SemaConsumer that generates 118bd25b421f728cb7c33a3bcc21a4fc60e835c5e8Chandler Carruth// a PCH file. 122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// 132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//===----------------------------------------------------------------------===// 142cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 157faa2ec03a7ef120ac165bb45b6c70a8b20c9f1cSebastian Redl#include "clang/Serialization/ASTWriter.h" 162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/AST/ASTConsumer.h" 1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/ASTContext.h" 184fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor#include "clang/Basic/FileManager.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Preprocessor.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/SemaConsumer.h" 212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Bitcode/BitstreamWriter.h" 222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/Support/raw_ostream.h" 232cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include <string> 242cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 252cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorusing namespace clang; 262cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 271eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpPCHGenerator::PCHGenerator(const Preprocessor &PP, 28467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor StringRef OutputFile, 291a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor clang::Module *Module, 30832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor StringRef isysroot, 311f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis raw_ostream *OS, bool AllowASTWithErrors) 32a8cc6ce36e70e2afa22ab6b4340035cb3941c2ebDouglas Gregor : PP(PP), OutputFile(OutputFile), Module(Module), 337143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor isysroot(isysroot.str()), Out(OS), 346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SemaPtr(nullptr), Stream(Buffer), Writer(Stream), 351f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis AllowASTWithErrors(AllowASTWithErrors), 361f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis HasEmittedPCH(false) { 374947e25dd9f7ac1f2176d63262563ba3e96538feDouglas Gregor} 384947e25dd9f7ac1f2176d63262563ba3e96538feDouglas Gregor 394947e25dd9f7ac1f2176d63262563ba3e96538feDouglas GregorPCHGenerator::~PCHGenerator() { 404fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor} 414fed3f47f6b9e31d603c5c2d1f6d8ec2e1241e57Douglas Gregor 422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { 431f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis // Don't create a PCH if there were fatal failures during module loading. 441f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis if (PP.getModuleLoader().HadFatalFailure) 451f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis return; 461f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis 471f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis bool hasErrors = PP.getDiagnostics().hasErrorOccurred(); 481f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis if (hasErrors && !AllowASTWithErrors) 492cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor return; 5089d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // Emit the PCH file 52e7785040107266d01ebdcc066365f70b7ace371fDouglas Gregor assert(SemaPtr && "No Sema?"); 531f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot, hasErrors); 542cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // Write the generated bitstream to "Out". 5666d6f048471aad6daf67b3ea804b54fbea72a076Eli Friedman Out->write((char *)&Buffer.front(), Buffer.size()); 572cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 582cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // Make sure it hits disk now. 5966d6f048471aad6daf67b3ea804b54fbea72a076Eli Friedman Out->flush(); 6030c514c225342844700ed4640ec6d90ddf0e12b2Sebastian Redl 6130c514c225342844700ed4640ec6d90ddf0e12b2Sebastian Redl // Free up some memory, in case the process is kept alive. 6230c514c225342844700ed4640ec6d90ddf0e12b2Sebastian Redl Buffer.clear(); 631f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis 641f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis HasEmittedPCH = true; 652cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 662cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 677b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios KyrtzidisASTMutationListener *PCHGenerator::GetASTMutationListener() { 689293ba8e26fcba18505b273ecc9b66645133fcceDouglas Gregor return &Writer; 697b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis} 707b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis 71571db7f0cb31789737be92fce1c1b738e6dbe795Sebastian RedlASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() { 72ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl return &Writer; 73ffaab3e2bb13991bb3357e80f14bcae3745b2347Sebastian Redl} 74