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