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