xref: /freebsd/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h (revision 7ec1ec4fdb98d87602c8501dae9b9cbd24b7d22b)
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