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 18namespace llvm { 19class raw_pwrite_stream; 20} 21 22namespace clang { 23 24class ASTConsumer; 25class CompilerInstance; 26 27struct 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). 36class PCHContainerWriter { 37public: 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). 55class PCHContainerReader { 56public: 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. 66class RawPCHContainerWriter : public PCHContainerWriter { 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. 80class 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. 87class PCHContainerOperations { 88 llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers; 89 llvm::StringMap<PCHContainerReader *> Readers; 90 llvm::SmallVector<std::unique_ptr<PCHContainerReader>> OwnedReaders; 91 92public: 93 /// Automatically registers a RawPCHContainerWriter and 94 /// RawPCHContainerReader. 95 PCHContainerOperations(); 96 void registerWriter(std::unique_ptr<PCHContainerWriter> Writer) { 97 Writers[Writer->getFormat()] = std::move(Writer); 98 } 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 } 106 const PCHContainerWriter *getWriterOrNull(llvm::StringRef Format) { 107 return Writers[Format].get(); 108 } 109 const PCHContainerReader *getReaderOrNull(llvm::StringRef Format) { 110 return Readers[Format]; 111 } 112 const PCHContainerReader &getRawReader() { 113 return *getReaderOrNull("raw"); 114 } 115}; 116 117} 118 119#endif 120