1//===-- ModuleFileExtension.h - Module File Extensions ----------*- 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_MODULEFILEEXTENSION_H
10#define LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H
11
12#include "llvm/Support/ExtensibleRTTI.h"
13#include "llvm/Support/HashBuilder.h"
14#include "llvm/Support/MD5.h"
15#include <memory>
16#include <string>
17
18namespace llvm {
19class BitstreamCursor;
20class BitstreamWriter;
21class raw_ostream;
22}
23
24namespace clang {
25
26class ASTReader;
27class ASTWriter;
28class Sema;
29
30namespace serialization {
31 class ModuleFile;
32} // end namespace serialization
33
34/// Metadata for a module file extension.
35struct ModuleFileExtensionMetadata {
36 /// The name used to identify this particular extension block within
37 /// the resulting module file. It should be unique to the particular
38 /// extension, because this name will be used to match the name of
39 /// an extension block to the appropriate reader.
40 std::string BlockName;
41
42 /// The major version of the extension data.
43 unsigned MajorVersion;
44
45 /// The minor version of the extension data.
46 unsigned MinorVersion;
47
48 /// A string containing additional user information that will be
49 /// stored with the metadata.
50 std::string UserInfo;
51};
52
53class ModuleFileExtensionReader;
54class ModuleFileExtensionWriter;
55
56/// An abstract superclass that describes a custom extension to the
57/// module/precompiled header file format.
58///
59/// A module file extension can introduce additional information into
60/// compiled module files (.pcm) and precompiled headers (.pch) via a
61/// custom writer that can then be accessed via a custom reader when
62/// the module file or precompiled header is loaded.
63///
64/// Subclasses must use LLVM RTTI for open class hierarchies.
65class ModuleFileExtension
66 : public llvm::RTTIExtends<ModuleFileExtension, llvm::RTTIRoot> {
67public:
68 /// Discriminator for LLVM RTTI.
69 static char ID;
70
71 virtual ~ModuleFileExtension();
72
73 /// Retrieves the metadata for this module file extension.
74 virtual ModuleFileExtensionMetadata getExtensionMetadata() const = 0;
75
76 /// Hash information about the presence of this extension into the
77 /// module hash.
78 ///
79 /// The module hash is used to distinguish different variants of a module that
80 /// are incompatible. If the presence, absence, or version of the module file
81 /// extension should force the creation of a separate set of module files,
82 /// override this method to combine that distinguishing information into the
83 /// module hash.
84 ///
85 /// The default implementation of this function simply does nothing, so the
86 /// presence/absence of this extension does not distinguish module files.
87 using ExtensionHashBuilder =
88 llvm::HashBuilder<llvm::MD5, llvm::endianness::native>;
89 virtual void hashExtension(ExtensionHashBuilder &HBuilder) const;
90
91 /// Create a new module file extension writer, which will be
92 /// responsible for writing the extension contents into a particular
93 /// module file.
94 virtual std::unique_ptr<ModuleFileExtensionWriter>
95 createExtensionWriter(ASTWriter &Writer) = 0;
96
97 /// Create a new module file extension reader, given the
98 /// metadata read from the block and the cursor into the extension
99 /// block.
100 ///
101 /// May return null to indicate that an extension block with the
102 /// given metadata cannot be read.
103 virtual std::unique_ptr<ModuleFileExtensionReader>
104 createExtensionReader(const ModuleFileExtensionMetadata &Metadata,
105 ASTReader &Reader, serialization::ModuleFile &Mod,
106 const llvm::BitstreamCursor &Stream) = 0;
107};
108
109/// Abstract base class that writes a module file extension block into
110/// a module file.
111class ModuleFileExtensionWriter {
112 ModuleFileExtension *Extension;
113
114protected:
115 ModuleFileExtensionWriter(ModuleFileExtension *Extension)
116 : Extension(Extension) { }
117
118public:
119 virtual ~ModuleFileExtensionWriter();
120
121 /// Retrieve the module file extension with which this writer is
122 /// associated.
123 ModuleFileExtension *getExtension() const { return Extension; }
124
125 /// Write the contents of the extension block into the given bitstream.
126 ///
127 /// Responsible for writing the contents of the extension into the
128 /// given stream. All of the contents should be written into custom
129 /// records with IDs >= FIRST_EXTENSION_RECORD_ID.
130 virtual void writeExtensionContents(Sema &SemaRef,
131 llvm::BitstreamWriter &Stream) = 0;
132};
133
134/// Abstract base class that reads a module file extension block from
135/// a module file.
136///
137/// Subclasses
138class ModuleFileExtensionReader {
139 ModuleFileExtension *Extension;
140
141protected:
142 ModuleFileExtensionReader(ModuleFileExtension *Extension)
143 : Extension(Extension) { }
144
145public:
146 /// Retrieve the module file extension with which this reader is
147 /// associated.
148 ModuleFileExtension *getExtension() const { return Extension; }
149
150 virtual ~ModuleFileExtensionReader();
151};
152
153} // end namespace clang
154
155#endif // LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H
156

source code of clang/include/clang/Serialization/ModuleFileExtension.h