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

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