1 //===-- ModuleFileExtension.h - Module File Extensions ----------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H
10 #define LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H
12 #include "llvm/ADT/IntrusiveRefCntPtr.h"
17 class BitstreamCursor;
18 class BitstreamWriter;
29 namespace serialization {
31 } // end namespace serialization
33 /// Metadata for a module file extension.
34 struct ModuleFileExtensionMetadata {
35 /// The name used to identify this particular extension block within
36 /// the resulting module file. It should be unique to the particular
37 /// extension, because this name will be used to match the name of
38 /// an extension block to the appropriate reader.
39 std::string BlockName;
41 /// The major version of the extension data.
42 unsigned MajorVersion;
44 /// The minor version of the extension data.
45 unsigned MinorVersion;
47 /// A string containing additional user information that will be
48 /// stored with the metadata.
52 class ModuleFileExtensionReader;
53 class ModuleFileExtensionWriter;
55 /// An abstract superclass that describes a custom extension to the
56 /// module/precompiled header file format.
58 /// A module file extension can introduce additional information into
59 /// compiled module files (.pcm) and precompiled headers (.pch) via a
60 /// custom writer that can then be accessed via a custom reader when
61 /// the module file or precompiled header is loaded.
62 class ModuleFileExtension {
64 virtual ~ModuleFileExtension();
66 /// Retrieves the metadata for this module file extension.
67 virtual ModuleFileExtensionMetadata getExtensionMetadata() const = 0;
69 /// Hash information about the presence of this extension into the
72 /// The module hash code is used to distinguish different variants
73 /// of a module that are incompatible. If the presence, absence, or
74 /// version of the module file extension should force the creation
75 /// of a separate set of module files, override this method to
76 /// combine that distinguishing information into the module hash
79 /// The default implementation of this function simply returns the
80 /// hash code as given, so the presence/absence of this extension
81 /// does not distinguish module files.
82 virtual llvm::hash_code hashExtension(llvm::hash_code c) const;
84 /// Create a new module file extension writer, which will be
85 /// responsible for writing the extension contents into a particular
87 virtual std::unique_ptr<ModuleFileExtensionWriter>
88 createExtensionWriter(ASTWriter &Writer) = 0;
90 /// Create a new module file extension reader, given the
91 /// metadata read from the block and the cursor into the extension
94 /// May return null to indicate that an extension block with the
95 /// given metadata cannot be read.
96 virtual std::unique_ptr<ModuleFileExtensionReader>
97 createExtensionReader(const ModuleFileExtensionMetadata &Metadata,
98 ASTReader &Reader, serialization::ModuleFile &Mod,
99 const llvm::BitstreamCursor &Stream) = 0;
102 /// Abstract base class that writes a module file extension block into
104 class ModuleFileExtensionWriter {
105 ModuleFileExtension *Extension;
108 ModuleFileExtensionWriter(ModuleFileExtension *Extension)
109 : Extension(Extension) { }
112 virtual ~ModuleFileExtensionWriter();
114 /// Retrieve the module file extension with which this writer is
116 ModuleFileExtension *getExtension() const { return Extension; }
118 /// Write the contents of the extension block into the given bitstream.
120 /// Responsible for writing the contents of the extension into the
121 /// given stream. All of the contents should be written into custom
122 /// records with IDs >= FIRST_EXTENSION_RECORD_ID.
123 virtual void writeExtensionContents(Sema &SemaRef,
124 llvm::BitstreamWriter &Stream) = 0;
127 /// Abstract base class that reads a module file extension block from
131 class ModuleFileExtensionReader {
132 ModuleFileExtension *Extension;
135 ModuleFileExtensionReader(ModuleFileExtension *Extension)
136 : Extension(Extension) { }
139 /// Retrieve the module file extension with which this reader is
141 ModuleFileExtension *getExtension() const { return Extension; }
143 virtual ~ModuleFileExtensionReader();
146 } // end namespace clang
148 #endif // LLVM_CLANG_FRONTEND_MODULEFILEEXTENSION_H