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: 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. 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: 142 ModuleFileExtensionReader(ModuleFileExtension *Extension) 143 : Extension(Extension) { } 144 145 public: 146 /// Retrieve the module file extension with which this reader is 147 /// associated. 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