1 //===-- 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/MemoryBufferRef.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::ArrayRef<llvm::StringRef> getFormats() 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 { 81 llvm::ArrayRef<llvm::StringRef> getFormats() const override; 82 /// Simply returns the buffer contained in Buffer. 83 llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override; 84 }; 85 86 /// A registry of PCHContainerWriter and -Reader objects for different formats. 87 class PCHContainerOperations { 88 llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers; 89 llvm::StringMap<PCHContainerReader *> Readers; 90 llvm::SmallVector<std::unique_ptr<PCHContainerReader>> OwnedReaders; 91 92 public: 93 /// Automatically registers a RawPCHContainerWriter and 94 /// RawPCHContainerReader. 95 PCHContainerOperations(); registerWriter(std::unique_ptr<PCHContainerWriter> Writer)96 void registerWriter(std::unique_ptr<PCHContainerWriter> Writer) { 97 Writers[Writer->getFormat()] = std::move(Writer); 98 } registerReader(std::unique_ptr<PCHContainerReader> Reader)99 void registerReader(std::unique_ptr<PCHContainerReader> Reader) { 100 assert(!Reader->getFormats().empty() && 101 "PCHContainerReader must handle >=1 format"); 102 for (llvm::StringRef Fmt : Reader->getFormats()) 103 Readers[Fmt] = Reader.get(); 104 OwnedReaders.push_back(std::move(Reader)); 105 } getWriterOrNull(llvm::StringRef Format)106 const PCHContainerWriter *getWriterOrNull(llvm::StringRef Format) { 107 return Writers[Format].get(); 108 } getReaderOrNull(llvm::StringRef Format)109 const PCHContainerReader *getReaderOrNull(llvm::StringRef Format) { 110 return Readers[Format]; 111 } getRawReader()112 const PCHContainerReader &getRawReader() { 113 return *getReaderOrNull("raw"); 114 } 115 }; 116 117 } 118 119 #endif 120