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