Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Frontend/TestModuleFileExtension.cpp
Line
Count
Source (jump to first uncovered line)
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/Bitstream/BitstreamWriter.h"
13
#include "llvm/Support/raw_ostream.h"
14
#include <cstdio>
15
using namespace clang;
16
using namespace clang::serialization;
17
18
char TestModuleFileExtension::ID = 0;
19
20
0
TestModuleFileExtension::Writer::~Writer() { }
21
22
void TestModuleFileExtension::Writer::writeExtensionContents(
23
       Sema &SemaRef,
24
0
       llvm::BitstreamWriter &Stream) {
25
0
  using namespace llvm;
26
27
  // Write an abbreviation for this record.
28
0
  auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
29
0
  Abv->Add(BitCodeAbbrevOp(FIRST_EXTENSION_RECORD_ID));
30
0
  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of characters
31
0
  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));   // message
32
0
  auto Abbrev = Stream.EmitAbbrev(std::move(Abv));
33
34
  // Write a message into the extension block.
35
0
  SmallString<64> Message;
36
0
  {
37
0
    auto Ext = static_cast<TestModuleFileExtension *>(getExtension());
38
0
    raw_svector_ostream OS(Message);
39
0
    OS << "Hello from " << Ext->BlockName << " v" << Ext->MajorVersion << "."
40
0
       << Ext->MinorVersion;
41
0
  }
42
0
  uint64_t Record[] = {FIRST_EXTENSION_RECORD_ID, Message.size()};
43
0
  Stream.EmitRecordWithBlob(Abbrev, Record, Message);
44
0
}
45
46
TestModuleFileExtension::Reader::Reader(ModuleFileExtension *Ext,
47
                                        const llvm::BitstreamCursor &InStream)
48
  : ModuleFileExtensionReader(Ext), Stream(InStream)
49
0
{
50
  // Read the extension block.
51
0
  SmallVector<uint64_t, 4> Record;
52
0
  while (true) {
53
0
    llvm::Expected<llvm::BitstreamEntry> MaybeEntry =
54
0
        Stream.advanceSkippingSubblocks();
55
0
    if (!MaybeEntry)
56
0
      (void)MaybeEntry.takeError();
57
0
    llvm::BitstreamEntry Entry = MaybeEntry.get();
58
59
0
    switch (Entry.Kind) {
60
0
    case llvm::BitstreamEntry::SubBlock:
61
0
    case llvm::BitstreamEntry::EndBlock:
62
0
    case llvm::BitstreamEntry::Error:
63
0
      return;
64
65
0
    case llvm::BitstreamEntry::Record:
66
0
      break;
67
0
    }
68
69
0
    Record.clear();
70
0
    StringRef Blob;
71
0
    Expected<unsigned> MaybeRecCode =
72
0
        Stream.readRecord(Entry.ID, Record, &Blob);
73
0
    if (!MaybeRecCode)
74
0
      fprintf(stderr, "Failed reading rec code: %s\n",
75
0
              toString(MaybeRecCode.takeError()).c_str());
76
0
    switch (MaybeRecCode.get()) {
77
0
    case FIRST_EXTENSION_RECORD_ID: {
78
0
      StringRef Message = Blob.substr(0, Record[0]);
79
0
      fprintf(stderr, "Read extension block message: %s\n",
80
0
              Message.str().c_str());
81
0
      break;
82
0
    }
83
0
    }
84
0
  }
85
0
}
86
87
0
TestModuleFileExtension::Reader::~Reader() { }
88
89
0
TestModuleFileExtension::~TestModuleFileExtension() { }
90
91
ModuleFileExtensionMetadata
92
0
TestModuleFileExtension::getExtensionMetadata() const {
93
0
  return { BlockName, MajorVersion, MinorVersion, UserInfo };
94
0
}
95
96
void TestModuleFileExtension::hashExtension(
97
0
    ExtensionHashBuilder &HBuilder) const {
98
0
  if (Hashed) {
99
0
    HBuilder.add(BlockName);
100
0
    HBuilder.add(MajorVersion);
101
0
    HBuilder.add(MinorVersion);
102
0
    HBuilder.add(UserInfo);
103
0
  }
104
0
}
105
106
std::unique_ptr<ModuleFileExtensionWriter>
107
0
TestModuleFileExtension::createExtensionWriter(ASTWriter &) {
108
0
  return std::unique_ptr<ModuleFileExtensionWriter>(new Writer(this));
109
0
}
110
111
std::unique_ptr<ModuleFileExtensionReader>
112
TestModuleFileExtension::createExtensionReader(
113
  const ModuleFileExtensionMetadata &Metadata,
114
  ASTReader &Reader, serialization::ModuleFile &Mod,
115
  const llvm::BitstreamCursor &Stream)
116
0
{
117
0
  assert(Metadata.BlockName == BlockName && "Wrong block name");
118
0
  if (std::make_pair(Metadata.MajorVersion, Metadata.MinorVersion) !=
119
0
        std::make_pair(MajorVersion, MinorVersion)) {
120
0
    Reader.getDiags().Report(Mod.ImportLoc,
121
0
                             diag::err_test_module_file_extension_version)
122
0
      << BlockName << Metadata.MajorVersion << Metadata.MinorVersion
123
0
      << MajorVersion << MinorVersion;
124
0
    return nullptr;
125
0
  }
126
127
0
  return std::unique_ptr<ModuleFileExtensionReader>(
128
0
                                                    new TestModuleFileExtension::Reader(this, Stream));
129
0
}
130
131
0
std::string TestModuleFileExtension::str() const {
132
0
  std::string Buffer;
133
0
  llvm::raw_string_ostream OS(Buffer);
134
0
  OS << BlockName << ":" << MajorVersion << ":" << MinorVersion << ":" << Hashed
135
0
     << ":" << UserInfo;
136
0
  return Buffer;
137
0
}