1 //===-- ModuleFileExtension.h - Module File Extensions ----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H 11 #define LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H 12 13 #include "llvm/ADT/IntrusiveRefCntPtr.h" 14 #include <memory> 15 #include <string> 16 17 namespace llvm { 18 class BitstreamCursor; 19 class BitstreamWriter; 20 class hash_code; 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 class ModuleFileExtension : public llvm::RefCountedBase<ModuleFileExtension> { 64 public: 65 virtual ~ModuleFileExtension(); 66 67 /// Retrieves the metadata for this module file extension. 68 virtual ModuleFileExtensionMetadata getExtensionMetadata() const = 0; 69 70 /// Hash information about the presence of this extension into the 71 /// module hash code. 72 /// 73 /// The module hash code is used to distinguish different variants 74 /// of a module that are incompatible. If the presence, absence, or 75 /// version of the module file extension should force the creation 76 /// of a separate set of module files, override this method to 77 /// combine that distinguishing information into the module hash 78 /// code. 79 /// 80 /// The default implementation of this function simply returns the 81 /// hash code as given, so the presence/absence of this extension 82 /// does not distinguish module files. 83 virtual llvm::hash_code hashExtension(llvm::hash_code c) const; 84 85 /// Create a new module file extension writer, which will be 86 /// responsible for writing the extension contents into a particular 87 /// module file. 88 virtual std::unique_ptr<ModuleFileExtensionWriter> 89 createExtensionWriter(ASTWriter &Writer) = 0; 90 91 /// Create a new module file extension reader, given the 92 /// metadata read from the block and the cursor into the extension 93 /// block. 94 /// 95 /// May return null to indicate that an extension block with the 96 /// given metadata cannot be read. 97 virtual std::unique_ptr<ModuleFileExtensionReader> 98 createExtensionReader(const ModuleFileExtensionMetadata &Metadata, 99 ASTReader &Reader, serialization::ModuleFile &Mod, 100 const llvm::BitstreamCursor &Stream) = 0; 101 }; 102 103 /// Abstract base class that writes a module file extension block into 104 /// a module file. 105 class ModuleFileExtensionWriter { 106 ModuleFileExtension *Extension; 107 108 protected: ModuleFileExtensionWriter(ModuleFileExtension * Extension)109 ModuleFileExtensionWriter(ModuleFileExtension *Extension) 110 : Extension(Extension) { } 111 112 public: 113 virtual ~ModuleFileExtensionWriter(); 114 115 /// Retrieve the module file extension with which this writer is 116 /// associated. getExtension()117 ModuleFileExtension *getExtension() const { return Extension; } 118 119 /// Write the contents of the extension block into the given bitstream. 120 /// 121 /// Responsible for writing the contents of the extension into the 122 /// given stream. All of the contents should be written into custom 123 /// records with IDs >= FIRST_EXTENSION_RECORD_ID. 124 virtual void writeExtensionContents(Sema &SemaRef, 125 llvm::BitstreamWriter &Stream) = 0; 126 }; 127 128 /// Abstract base class that reads a module file extension block from 129 /// a module file. 130 /// 131 /// Subclasses 132 class ModuleFileExtensionReader { 133 ModuleFileExtension *Extension; 134 135 protected: ModuleFileExtensionReader(ModuleFileExtension * Extension)136 ModuleFileExtensionReader(ModuleFileExtension *Extension) 137 : Extension(Extension) { } 138 139 public: 140 /// Retrieve the module file extension with which this reader is 141 /// associated. getExtension()142 ModuleFileExtension *getExtension() const { return Extension; } 143 144 virtual ~ModuleFileExtensionReader(); 145 }; 146 147 } // end namespace clang 148 149 #endif // LLVM_CLANG_FRONTEND_MODULEFILEEXTENSION_H 150