1 //===--- Frontend/PCHContainerOperations.h - PCH Containers -----*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H 11 #define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H 12 13 #include "llvm/ADT/SmallVector.h" 14 #include "llvm/ADT/StringMap.h" 15 #include "llvm/Support/MemoryBuffer.h" 16 #include <memory> 17 18 namespace llvm { 19 class raw_pwrite_stream; 20 class BitstreamReader; 21 } 22 23 using llvm::StringRef; 24 25 namespace clang { 26 27 class ASTConsumer; 28 class CodeGenOptions; 29 class DiagnosticsEngine; 30 class CompilerInstance; 31 32 struct PCHBuffer { 33 uint64_t Signature; 34 llvm::SmallVector<char, 0> Data; 35 bool IsComplete; 36 }; 37 38 /// This abstract interface provides operations for creating 39 /// containers for serialized ASTs (precompiled headers and clang 40 /// modules). 41 class PCHContainerWriter { 42 public: 43 virtual ~PCHContainerWriter() = 0; 44 virtual StringRef getFormat() const = 0; 45 46 /// Return an ASTConsumer that can be chained with a 47 /// PCHGenerator that produces a wrapper file format containing a 48 /// serialized AST bitstream. 49 virtual std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( 50 CompilerInstance &CI, const std::string &MainFileName, 51 const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, 52 std::shared_ptr<PCHBuffer> Buffer) const = 0; 53 }; 54 55 /// This abstract interface provides operations for unwrapping 56 /// containers for serialized ASTs (precompiled headers and clang 57 /// modules). 58 class PCHContainerReader { 59 public: 60 virtual ~PCHContainerReader() = 0; 61 /// Equivalent to the format passed to -fmodule-format= 62 virtual StringRef getFormat() const = 0; 63 64 /// Initialize an llvm::BitstreamReader with the serialized AST inside 65 /// the PCH container Buffer. 66 virtual void ExtractPCH(llvm::MemoryBufferRef Buffer, 67 llvm::BitstreamReader &StreamFile) const = 0; 68 }; 69 70 /// Implements write operations for a raw pass-through PCH container. 71 class RawPCHContainerWriter : public PCHContainerWriter { getFormat()72 StringRef getFormat() const override { return "raw"; } 73 74 /// Return an ASTConsumer that can be chained with a 75 /// PCHGenerator that writes the module to a flat file. 76 std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( 77 CompilerInstance &CI, const std::string &MainFileName, 78 const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, 79 std::shared_ptr<PCHBuffer> Buffer) const override; 80 }; 81 82 /// Implements read operations for a raw pass-through PCH container. 83 class RawPCHContainerReader : public PCHContainerReader { getFormat()84 StringRef getFormat() const override { return "raw"; } 85 86 /// Initialize an llvm::BitstreamReader with Buffer. 87 void ExtractPCH(llvm::MemoryBufferRef Buffer, 88 llvm::BitstreamReader &StreamFile) const override; 89 }; 90 91 /// A registry of PCHContainerWriter and -Reader objects for different formats. 92 class PCHContainerOperations { 93 llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers; 94 llvm::StringMap<std::unique_ptr<PCHContainerReader>> Readers; 95 public: 96 /// Automatically registers a RawPCHContainerWriter and 97 /// RawPCHContainerReader. 98 PCHContainerOperations(); registerWriter(std::unique_ptr<PCHContainerWriter> Writer)99 void registerWriter(std::unique_ptr<PCHContainerWriter> Writer) { 100 Writers[Writer->getFormat()] = std::move(Writer); 101 } registerReader(std::unique_ptr<PCHContainerReader> Reader)102 void registerReader(std::unique_ptr<PCHContainerReader> Reader) { 103 Readers[Reader->getFormat()] = std::move(Reader); 104 } getWriterOrNull(StringRef Format)105 const PCHContainerWriter *getWriterOrNull(StringRef Format) { 106 return Writers[Format].get(); 107 } getReaderOrNull(StringRef Format)108 const PCHContainerReader *getReaderOrNull(StringRef Format) { 109 return Readers[Format].get(); 110 } getRawReader()111 const PCHContainerReader &getRawReader() { 112 return *getReaderOrNull("raw"); 113 } 114 }; 115 116 } 117 118 #endif 119