clang  3.9.0
TestModuleFileExtension.cpp
Go to the documentation of this file.
1 //===-- TestModuleFileExtension.cpp - Module Extension Tester -------------===//
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 //===----------------------------------------------------------------------===//
12 #include "llvm/ADT/Hashing.h"
13 #include "llvm/Bitcode/BitstreamWriter.h"
14 #include "llvm/Support/raw_ostream.h"
15 #include <cstdio>
16 using namespace clang;
17 using namespace clang::serialization;
18 
19 TestModuleFileExtension::Writer::~Writer() { }
20 
21 void TestModuleFileExtension::Writer::writeExtensionContents(
22  Sema &SemaRef,
23  llvm::BitstreamWriter &Stream) {
24  using namespace llvm;
25 
26  // Write an abbreviation for this record.
27  BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev();
28  Abv->Add(BitCodeAbbrevOp(FIRST_EXTENSION_RECORD_ID));
29  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of characters
30  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // message
31  auto Abbrev = Stream.EmitAbbrev(Abv);
32 
33  // Write a message into the extension block.
34  SmallString<64> Message;
35  {
36  auto Ext = static_cast<TestModuleFileExtension *>(getExtension());
37  raw_svector_ostream OS(Message);
38  OS << "Hello from " << Ext->BlockName << " v" << Ext->MajorVersion << "."
39  << Ext->MinorVersion;
40  }
41  uint64_t Record[] = {FIRST_EXTENSION_RECORD_ID, Message.size()};
42  Stream.EmitRecordWithBlob(Abbrev, Record, Message);
43 }
44 
45 TestModuleFileExtension::Reader::Reader(ModuleFileExtension *Ext,
46  const llvm::BitstreamCursor &InStream)
47  : ModuleFileExtensionReader(Ext), Stream(InStream)
48 {
49  // Read the extension block.
51  while (true) {
52  llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
53  switch (Entry.Kind) {
54  case llvm::BitstreamEntry::SubBlock:
55  case llvm::BitstreamEntry::EndBlock:
57  return;
58 
59  case llvm::BitstreamEntry::Record:
60  break;
61  }
62 
63  Record.clear();
64  StringRef Blob;
65  unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
66  switch (RecCode) {
68  StringRef Message = Blob.substr(0, Record[0]);
69  fprintf(stderr, "Read extension block message: %s\n",
70  Message.str().c_str());
71  break;
72  }
73  }
74  }
75 }
76 
77 TestModuleFileExtension::Reader::~Reader() { }
78 
79 TestModuleFileExtension::~TestModuleFileExtension() { }
80 
82 TestModuleFileExtension::getExtensionMetadata() const {
83  return { BlockName, MajorVersion, MinorVersion, UserInfo };
84 }
85 
86 llvm::hash_code TestModuleFileExtension::hashExtension(
87  llvm::hash_code Code) const {
88  if (Hashed) {
89  Code = llvm::hash_combine(Code, BlockName);
90  Code = llvm::hash_combine(Code, MajorVersion);
91  Code = llvm::hash_combine(Code, MinorVersion);
92  Code = llvm::hash_combine(Code, UserInfo);
93  }
94 
95  return Code;
96 }
97 
98 std::unique_ptr<ModuleFileExtensionWriter>
99 TestModuleFileExtension::createExtensionWriter(ASTWriter &) {
100  return std::unique_ptr<ModuleFileExtensionWriter>(new Writer(this));
101 }
102 
103 std::unique_ptr<ModuleFileExtensionReader>
104 TestModuleFileExtension::createExtensionReader(
105  const ModuleFileExtensionMetadata &Metadata,
106  ASTReader &Reader, serialization::ModuleFile &Mod,
107  const llvm::BitstreamCursor &Stream)
108 {
109  assert(Metadata.BlockName == BlockName && "Wrong block name");
110  if (std::make_pair(Metadata.MajorVersion, Metadata.MinorVersion) !=
111  std::make_pair(MajorVersion, MinorVersion)) {
112  Reader.getDiags().Report(Mod.ImportLoc,
113  diag::err_test_module_file_extension_version)
114  << BlockName << Metadata.MajorVersion << Metadata.MinorVersion
115  << MajorVersion << MinorVersion;
116  return nullptr;
117  }
118 
119  return std::unique_ptr<ModuleFileExtensionReader>(
120  new TestModuleFileExtension::Reader(this, Stream));
121 }
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1124
SourceLocation ImportLoc
The source location where this module was first imported.
A module file extension used for testing purposes.
DiagnosticsEngine & getDiags() const
Definition: ASTReader.h:1351
The first record ID allocated to the extensions themselves.
Definition: ASTBitCodes.h:331
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:263
Abstract base class that reads a module file extension block from a module file.
Information about a module that has been loaded by the ASTReader.
unsigned MajorVersion
The major version of the extension data.
unsigned MinorVersion
The minor version of the extension data.
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:312
std::string BlockName
The name used to identify this particular extension block within the resulting module file...
Metadata for a module file extension.
Writes an AST file containing the contents of a translation unit.
Definition: ASTWriter.h:84
An abstract superclass that describes a custom extension to the module/precompiled header file format...