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