clang  10.0.0svn
TestModuleFileExtension.cpp
Go to the documentation of this file.
1 //===-- TestModuleFileExtension.cpp - Module Extension Tester -------------===//
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 //===----------------------------------------------------------------------===//
11 #include "llvm/ADT/Hashing.h"
12 #include "llvm/Bitstream/BitstreamWriter.h"
13 #include "llvm/Support/raw_ostream.h"
14 #include <cstdio>
15 using namespace clang;
16 using namespace clang::serialization;
17 
18 TestModuleFileExtension::Writer::~Writer() { }
19 
20 void TestModuleFileExtension::Writer::writeExtensionContents(
21  Sema &SemaRef,
22  llvm::BitstreamWriter &Stream) {
23  using namespace llvm;
24 
25  // Write an abbreviation for this record.
26  auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
27  Abv->Add(BitCodeAbbrevOp(FIRST_EXTENSION_RECORD_ID));
28  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of characters
29  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // message
30  auto Abbrev = Stream.EmitAbbrev(std::move(Abv));
31 
32  // Write a message into the extension block.
33  SmallString<64> Message;
34  {
35  auto Ext = static_cast<TestModuleFileExtension *>(getExtension());
36  raw_svector_ostream OS(Message);
37  OS << "Hello from " << Ext->BlockName << " v" << Ext->MajorVersion << "."
38  << Ext->MinorVersion;
39  }
40  uint64_t Record[] = {FIRST_EXTENSION_RECORD_ID, Message.size()};
41  Stream.EmitRecordWithBlob(Abbrev, Record, Message);
42 }
43 
44 TestModuleFileExtension::Reader::Reader(ModuleFileExtension *Ext,
45  const llvm::BitstreamCursor &InStream)
46  : ModuleFileExtensionReader(Ext), Stream(InStream)
47 {
48  // Read the extension block.
50  while (true) {
52  Stream.advanceSkippingSubblocks();
53  if (!MaybeEntry)
54  (void)MaybeEntry.takeError();
55  llvm::BitstreamEntry Entry = MaybeEntry.get();
56 
57  switch (Entry.Kind) {
58  case llvm::BitstreamEntry::SubBlock:
59  case llvm::BitstreamEntry::EndBlock:
61  return;
62 
63  case llvm::BitstreamEntry::Record:
64  break;
65  }
66 
67  Record.clear();
68  StringRef Blob;
69  Expected<unsigned> MaybeRecCode =
70  Stream.readRecord(Entry.ID, Record, &Blob);
71  if (!MaybeRecCode)
72  fprintf(stderr, "Failed reading rec code: %s\n",
73  toString(MaybeRecCode.takeError()).c_str());
74  switch (MaybeRecCode.get()) {
76  StringRef Message = Blob.substr(0, Record[0]);
77  fprintf(stderr, "Read extension block message: %s\n",
78  Message.str().c_str());
79  break;
80  }
81  }
82  }
83 }
84 
85 TestModuleFileExtension::Reader::~Reader() { }
86 
88 
91  return { BlockName, MajorVersion, MinorVersion, UserInfo };
92 }
93 
95  llvm::hash_code Code) const {
96  if (Hashed) {
97  Code = llvm::hash_combine(Code, BlockName);
98  Code = llvm::hash_combine(Code, MajorVersion);
99  Code = llvm::hash_combine(Code, MinorVersion);
100  Code = llvm::hash_combine(Code, UserInfo);
101  }
102 
103  return Code;
104 }
105 
106 std::unique_ptr<ModuleFileExtensionWriter>
108  return std::unique_ptr<ModuleFileExtensionWriter>(new Writer(this));
109 }
110 
111 std::unique_ptr<ModuleFileExtensionReader>
113  const ModuleFileExtensionMetadata &Metadata,
114  ASTReader &Reader, serialization::ModuleFile &Mod,
115  const llvm::BitstreamCursor &Stream)
116 {
117  assert(Metadata.BlockName == BlockName && "Wrong block name");
118  if (std::make_pair(Metadata.MajorVersion, Metadata.MinorVersion) !=
119  std::make_pair(MajorVersion, MinorVersion)) {
120  Reader.getDiags().Report(Mod.ImportLoc,
121  diag::err_test_module_file_extension_version)
122  << BlockName << Metadata.MajorVersion << Metadata.MinorVersion
123  << MajorVersion << MinorVersion;
124  return nullptr;
125  }
126 
127  return std::unique_ptr<ModuleFileExtensionReader>(
128  new TestModuleFileExtension::Reader(this, Stream));
129 }
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
Definition: Dominators.h:30
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1290
std::unique_ptr< ModuleFileExtensionWriter > createExtensionWriter(ASTWriter &Writer) override
Create a new module file extension writer, which will be responsible for writing the extension conten...
SourceLocation ImportLoc
The source location where this module was first imported.
Definition: Module.h:204
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
A module file extension used for testing purposes.
static void hash_combine(std::size_t &seed, const T &v)
llvm::Error Error
The first record ID allocated to the extensions themselves.
Definition: ASTBitCodes.h:378
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:331
Abstract base class that reads a module file extension block from a module file.
std::unique_ptr< ModuleFileExtensionReader > createExtensionReader(const ModuleFileExtensionMetadata &Metadata, ASTReader &Reader, serialization::ModuleFile &Mod, const llvm::BitstreamCursor &Stream) override
Create a new module file extension reader, given the metadata read from the block and the cursor into...
llvm::hash_code hashExtension(llvm::hash_code Code) const override
Hash information about the presence of this extension into the module hash code.
ModuleFileExtensionMetadata getExtensionMetadata() const override
Retrieves the metadata for this module file extension.
Information about a module that has been loaded by the ASTReader.
Definition: Module.h:107
DiagnosticsEngine & getDiags() const
Definition: ASTReader.h:1504
unsigned MajorVersion
The major version of the extension data.
unsigned MinorVersion
The minor version of the extension data.
Dataflow Directional Tag Classes.
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:354
std::string BlockName
The name used to identify this particular extension block within the resulting module file...
Indicates that the tracking object is a descendant of a referenced-counted OSObject, used in the Darwin kernel.
Metadata for a module file extension.
Writes an AST file containing the contents of a translation unit.
Definition: ASTWriter.h:103
An abstract superclass that describes a custom extension to the module/precompiled header file format...