Clang Project

clang_source_code/lib/Frontend/TestModuleFileExtension.cpp
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//===----------------------------------------------------------------------===//
8#include "TestModuleFileExtension.h"
9#include "clang/Frontend/FrontendDiagnostic.h"
10#include "clang/Serialization/ASTReader.h"
11#include "llvm/ADT/Hashing.h"
12#include "llvm/Bitcode/BitstreamWriter.h"
13#include "llvm/Support/raw_ostream.h"
14#include <cstdio>
15using namespace clang;
16using namespace clang::serialization;
17
18TestModuleFileExtension::Writer::~Writer() { }
19
20void 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<64Message;
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
44TestModuleFileExtension::Reader::Reader(ModuleFileExtension *Ext,
45                                        const llvm::BitstreamCursor &InStream)
46  : ModuleFileExtensionReader(Ext), Stream(InStream)
47{
48  // Read the extension block.
49  SmallVector<uint64_t4Record;
50  while (true) {
51    llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
52    switch (Entry.Kind) {
53    case llvm::BitstreamEntry::SubBlock:
54    case llvm::BitstreamEntry::EndBlock:
55    case llvm::BitstreamEntry::Error:
56      return;
57
58    case llvm::BitstreamEntry::Record:
59      break;
60    }
61
62    Record.clear();
63    StringRef Blob;
64    unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
65    switch (RecCode) {
66    case FIRST_EXTENSION_RECORD_ID: {
67      StringRef Message = Blob.substr(0, Record[0]);
68      fprintf(stderr"Read extension block message: %s\n",
69              Message.str().c_str());
70      break;
71    }
72    }
73  }
74}
75
76TestModuleFileExtension::Reader::~Reader() { }
77
78TestModuleFileExtension::~TestModuleFileExtension() { }
79
80ModuleFileExtensionMetadata
81TestModuleFileExtension::getExtensionMetadata() const {
82  return { BlockNameMajorVersionMinorVersionUserInfo };
83}
84
85llvm::hash_code TestModuleFileExtension::hashExtension(
86                  llvm::hash_code Codeconst {
87  if (Hashed) {
88    Code = llvm::hash_combine(Code, BlockName);
89    Code = llvm::hash_combine(Code, MajorVersion);
90    Code = llvm::hash_combine(Code, MinorVersion);
91    Code = llvm::hash_combine(Code, UserInfo);
92  }
93
94  return Code;
95}
96
97std::unique_ptr<ModuleFileExtensionWriter>
98TestModuleFileExtension::createExtensionWriter(ASTWriter &) {
99  return std::unique_ptr<ModuleFileExtensionWriter>(new Writer(this));
100}
101
102std::unique_ptr<ModuleFileExtensionReader>
103TestModuleFileExtension::createExtensionReader(
104  const ModuleFileExtensionMetadata &Metadata,
105  ASTReader &Readerserialization::ModuleFile &Mod,
106  const llvm::BitstreamCursor &Stream)
107{
108   (0) . __assert_fail ("Metadata.BlockName == BlockName && \"Wrong block name\"", "/home/seafit/code_projects/clang_source/clang/lib/Frontend/TestModuleFileExtension.cpp", 108, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Metadata.BlockName == BlockName && "Wrong block name");
109  if (std::make_pair(Metadata.MajorVersionMetadata.MinorVersion) !=
110        std::make_pair(MajorVersionMinorVersion)) {
111    Reader.getDiags().Report(Mod.ImportLoc,
112                             diag::err_test_module_file_extension_version)
113      << BlockName << Metadata.MajorVersion << Metadata.MinorVersion
114      << MajorVersion << MinorVersion;
115    return nullptr;
116  }
117
118  return std::unique_ptr<ModuleFileExtensionReader>(
119                                                    new TestModuleFileExtension::Reader(thisStream));
120}
121
clang::TestModuleFileExtension::Writer::writeExtensionContents
clang::TestModuleFileExtension::getExtensionMetadata
clang::TestModuleFileExtension::hashExtension
clang::TestModuleFileExtension::createExtensionWriter
clang::TestModuleFileExtension::createExtensionReader