xref: /freebsd/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h (revision 19261079b74319502c6ffa1249920079f0f69a72)
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 <memory>
14 #include <string>
15 
16 namespace llvm {
17 class BitstreamCursor;
18 class BitstreamWriter;
19 class hash_code;
20 class raw_ostream;
21 }
22 
23 namespace clang {
24 
25 class ASTReader;
26 class ASTWriter;
27 class Sema;
28 
29 namespace serialization {
30   class ModuleFile;
31 } // end namespace serialization
32 
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;
40 
41   /// The major version of the extension data.
42   unsigned MajorVersion;
43 
44   /// The minor version of the extension data.
45   unsigned MinorVersion;
46 
47   /// A string containing additional user information that will be
48   /// stored with the metadata.
49   std::string UserInfo;
50 };
51 
52 class ModuleFileExtensionReader;
53 class ModuleFileExtensionWriter;
54 
55 /// An abstract superclass that describes a custom extension to the
56 /// module/precompiled header file format.
57 ///
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 {
63 public:
64   virtual ~ModuleFileExtension();
65 
66   /// Retrieves the metadata for this module file extension.
67   virtual ModuleFileExtensionMetadata getExtensionMetadata() const = 0;
68 
69   /// Hash information about the presence of this extension into the
70   /// module hash code.
71   ///
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
77   /// code.
78   ///
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;
83 
84   /// Create a new module file extension writer, which will be
85   /// responsible for writing the extension contents into a particular
86   /// module file.
87   virtual std::unique_ptr<ModuleFileExtensionWriter>
88   createExtensionWriter(ASTWriter &Writer) = 0;
89 
90   /// Create a new module file extension reader, given the
91   /// metadata read from the block and the cursor into the extension
92   /// block.
93   ///
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;
100 };
101 
102 /// Abstract base class that writes a module file extension block into
103 /// a module file.
104 class ModuleFileExtensionWriter {
105   ModuleFileExtension *Extension;
106 
107 protected:
108   ModuleFileExtensionWriter(ModuleFileExtension *Extension)
109     : Extension(Extension) { }
110 
111 public:
112   virtual ~ModuleFileExtensionWriter();
113 
114   /// Retrieve the module file extension with which this writer is
115   /// associated.
116   ModuleFileExtension *getExtension() const { return Extension; }
117 
118   /// Write the contents of the extension block into the given bitstream.
119   ///
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;
125 };
126 
127 /// Abstract base class that reads a module file extension block from
128 /// a module file.
129 ///
130 /// Subclasses
131 class ModuleFileExtensionReader {
132   ModuleFileExtension *Extension;
133 
134 protected:
135   ModuleFileExtensionReader(ModuleFileExtension *Extension)
136     : Extension(Extension) { }
137 
138 public:
139   /// Retrieve the module file extension with which this reader is
140   /// associated.
141   ModuleFileExtension *getExtension() const { return Extension; }
142 
143   virtual ~ModuleFileExtensionReader();
144 };
145 
146 } // end namespace clang
147 
148 #endif // LLVM_CLANG_FRONTEND_MODULEFILEEXTENSION_H
149