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 {
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 {
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();
97   void registerWriter(std::unique_ptr<PCHContainerWriter> Writer) {
98     Writers[Writer->getFormat()] = std::move(Writer);
99   }
100   void registerReader(std::unique_ptr<PCHContainerReader> Reader) {
101     Readers[Reader->getFormat()] = std::move(Reader);
102   }
103   const PCHContainerWriter *getWriterOrNull(llvm::StringRef Format) {
104     return Writers[Format].get();
105   }
106   const PCHContainerReader *getReaderOrNull(llvm::StringRef Format) {
107     return Readers[Format].get();
108   }
109   const PCHContainerReader &getRawReader() {
110     return *getReaderOrNull("raw");
111   }
112 };
113 
114 }
115 
116 #endif
117