xref: /freebsd/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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  
18  namespace llvm {
19  class BitstreamCursor;
20  class BitstreamWriter;
21  class raw_ostream;
22  }
23  
24  namespace clang {
25  
26  class ASTReader;
27  class ASTWriter;
28  class Sema;
29  
30  namespace serialization {
31    class ModuleFile;
32  } // end namespace serialization
33  
34  /// Metadata for a module file extension.
35  struct 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  
53  class ModuleFileExtensionReader;
54  class 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.
65  class ModuleFileExtension
66      : public llvm::RTTIExtends<ModuleFileExtension, llvm::RTTIRoot> {
67  public:
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.
111  class ModuleFileExtensionWriter {
112    ModuleFileExtension *Extension;
113  
114  protected:
ModuleFileExtensionWriter(ModuleFileExtension * Extension)115    ModuleFileExtensionWriter(ModuleFileExtension *Extension)
116      : Extension(Extension) { }
117  
118  public:
119    virtual ~ModuleFileExtensionWriter();
120  
121    /// Retrieve the module file extension with which this writer is
122    /// associated.
getExtension()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
138  class ModuleFileExtensionReader {
139    ModuleFileExtension *Extension;
140  
141  protected:
ModuleFileExtensionReader(ModuleFileExtension * Extension)142    ModuleFileExtensionReader(ModuleFileExtension *Extension)
143      : Extension(Extension) { }
144  
145  public:
146    /// Retrieve the module file extension with which this reader is
147    /// associated.
getExtension()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