1 //===--- Serialization/PCHContainerOperations.h - PCH Containers --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_CLANG_SERIALIZATION_PCHCONTAINEROPERATIONS_H
11 #define LLVM_CLANG_SERIALIZATION_PCHCONTAINEROPERATIONS_H
12 
13 #include "clang/Basic/Module.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringMap.h"
16 #include "llvm/Support/MemoryBuffer.h"
17 #include <memory>
18 
19 namespace llvm {
20 class raw_pwrite_stream;
21 }
22 
23 namespace clang {
24 
25 class ASTConsumer;
26 class CodeGenOptions;
27 class DiagnosticsEngine;
28 class CompilerInstance;
29 
30 struct PCHBuffer {
31   ASTFileSignature Signature;
32   llvm::SmallVector<char, 0> Data;
33   bool IsComplete;
34 };
35 
36 /// This abstract interface provides operations for creating
37 /// containers for serialized ASTs (precompiled headers and clang
38 /// modules).
39 class PCHContainerWriter {
40 public:
41   virtual ~PCHContainerWriter() = 0;
42   virtual llvm::StringRef getFormat() const = 0;
43 
44   /// Return an ASTConsumer that can be chained with a
45   /// PCHGenerator that produces a wrapper file format containing a
46   /// serialized AST bitstream.
47   virtual std::unique_ptr<ASTConsumer>
48   CreatePCHContainerGenerator(CompilerInstance &CI,
49                               const std::string &MainFileName,
50                               const std::string &OutputFileName,
51                               std::unique_ptr<llvm::raw_pwrite_stream> OS,
52                               std::shared_ptr<PCHBuffer> Buffer) const = 0;
53 };
54 
55 /// This abstract interface provides operations for unwrapping
56 /// containers for serialized ASTs (precompiled headers and clang
57 /// modules).
58 class PCHContainerReader {
59 public:
60   virtual ~PCHContainerReader() = 0;
61   /// Equivalent to the format passed to -fmodule-format=
62   virtual llvm::StringRef getFormat() const = 0;
63 
64   /// Returns the serialized AST inside the PCH container Buffer.
65   virtual llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const = 0;
66 };
67 
68 /// Implements write operations for a raw pass-through PCH container.
69 class RawPCHContainerWriter : public PCHContainerWriter {
getFormat()70   llvm::StringRef getFormat() const override { return "raw"; }
71 
72   /// Return an ASTConsumer that can be chained with a
73   /// PCHGenerator that writes the module to a flat file.
74   std::unique_ptr<ASTConsumer>
75   CreatePCHContainerGenerator(CompilerInstance &CI,
76                               const std::string &MainFileName,
77                               const std::string &OutputFileName,
78                               std::unique_ptr<llvm::raw_pwrite_stream> OS,
79                               std::shared_ptr<PCHBuffer> Buffer) const override;
80 };
81 
82 /// Implements read operations for a raw pass-through PCH container.
83 class RawPCHContainerReader : public PCHContainerReader {
getFormat()84   llvm::StringRef getFormat() const override { return "raw"; }
85 
86   /// Simply returns the buffer contained in Buffer.
87   llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
88 };
89 
90 /// A registry of PCHContainerWriter and -Reader objects for different formats.
91 class PCHContainerOperations {
92   llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers;
93   llvm::StringMap<std::unique_ptr<PCHContainerReader>> Readers;
94 public:
95   /// Automatically registers a RawPCHContainerWriter and
96   /// RawPCHContainerReader.
97   PCHContainerOperations();
registerWriter(std::unique_ptr<PCHContainerWriter> Writer)98   void registerWriter(std::unique_ptr<PCHContainerWriter> Writer) {
99     Writers[Writer->getFormat()] = std::move(Writer);
100   }
registerReader(std::unique_ptr<PCHContainerReader> Reader)101   void registerReader(std::unique_ptr<PCHContainerReader> Reader) {
102     Readers[Reader->getFormat()] = std::move(Reader);
103   }
getWriterOrNull(llvm::StringRef Format)104   const PCHContainerWriter *getWriterOrNull(llvm::StringRef Format) {
105     return Writers[Format].get();
106   }
getReaderOrNull(llvm::StringRef Format)107   const PCHContainerReader *getReaderOrNull(llvm::StringRef Format) {
108     return Readers[Format].get();
109   }
getRawReader()110   const PCHContainerReader &getRawReader() {
111     return *getReaderOrNull("raw");
112   }
113 };
114 
115 }
116 
117 #endif
118