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