• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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