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