1//===--- Frontend/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_PCH_CONTAINER_OPERATIONS_H
11#define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
12
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;
20class BitstreamReader;
21}
22
23using llvm::StringRef;
24
25namespace clang {
26
27class ASTConsumer;
28class CodeGenOptions;
29class DiagnosticsEngine;
30class CompilerInstance;
31
32struct PCHBuffer {
33  uint64_t Signature;
34  llvm::SmallVector<char, 0> Data;
35  bool IsComplete;
36};
37
38/// This abstract interface provides operations for creating
39/// containers for serialized ASTs (precompiled headers and clang
40/// modules).
41class PCHContainerWriter {
42public:
43  virtual ~PCHContainerWriter() = 0;
44  virtual StringRef getFormat() const = 0;
45
46  /// Return an ASTConsumer that can be chained with a
47  /// PCHGenerator that produces a wrapper file format containing a
48  /// serialized AST bitstream.
49  virtual std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator(
50      CompilerInstance &CI, const std::string &MainFileName,
51      const std::string &OutputFileName, 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).
58class PCHContainerReader {
59public:
60  virtual ~PCHContainerReader() = 0;
61  /// Equivalent to the format passed to -fmodule-format=
62  virtual StringRef getFormat() const = 0;
63
64  /// Initialize an llvm::BitstreamReader with the serialized AST inside
65  /// the PCH container Buffer.
66  virtual void ExtractPCH(llvm::MemoryBufferRef Buffer,
67                          llvm::BitstreamReader &StreamFile) const = 0;
68};
69
70/// Implements write operations for a raw pass-through PCH container.
71class RawPCHContainerWriter : public PCHContainerWriter {
72  StringRef getFormat() const override { return "raw"; }
73
74  /// Return an ASTConsumer that can be chained with a
75  /// PCHGenerator that writes the module to a flat file.
76  std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator(
77      CompilerInstance &CI, const std::string &MainFileName,
78      const std::string &OutputFileName, 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.
83class RawPCHContainerReader : public PCHContainerReader {
84  StringRef getFormat() const override { return "raw"; }
85
86  /// Initialize an llvm::BitstreamReader with Buffer.
87  void ExtractPCH(llvm::MemoryBufferRef Buffer,
88                  llvm::BitstreamReader &StreamFile) const override;
89};
90
91/// A registry of PCHContainerWriter and -Reader objects for different formats.
92class PCHContainerOperations {
93  llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers;
94  llvm::StringMap<std::unique_ptr<PCHContainerReader>> Readers;
95public:
96  /// Automatically registers a RawPCHContainerWriter and
97  /// RawPCHContainerReader.
98  PCHContainerOperations();
99  void registerWriter(std::unique_ptr<PCHContainerWriter> Writer) {
100    Writers[Writer->getFormat()] = std::move(Writer);
101  }
102  void registerReader(std::unique_ptr<PCHContainerReader> Reader) {
103    Readers[Reader->getFormat()] = std::move(Reader);
104  }
105  const PCHContainerWriter *getWriterOrNull(StringRef Format) {
106    return Writers[Format].get();
107  }
108  const PCHContainerReader *getReaderOrNull(StringRef Format) {
109    return Readers[Format].get();
110  }
111  const PCHContainerReader &getRawReader() {
112    return *getReaderOrNull("raw");
113  }
114};
115
116}
117
118#endif
119