clang  6.0.0svn
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  auto Abv = std::make_shared<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(std::move(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 
80 
83  return { BlockName, MajorVersion, MinorVersion, UserInfo };
84 }
85 
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>
100  return std::unique_ptr<ModuleFileExtensionWriter>(new Writer(this));
101 }
102 
103 std::unique_ptr<ModuleFileExtensionReader>
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 }
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:26
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1207
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:194
A module file extension used for testing purposes.
static void hash_combine(std::size_t &seed, const T &v)
The first record ID allocated to the extensions themselves.
Definition: ASTBitCodes.h:360
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:274
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:100
DiagnosticsEngine & getDiags() const
Definition: ASTReader.h:1477
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:358
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:104
An abstract superclass that describes a custom extension to the module/precompiled header file format...