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