1 | |
2 | |
3 | |
4 | |
5 | |
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> |
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 | |
26 | auto Abv = std::make_shared<llvm::BitCodeAbbrev>(); |
27 | Abv->Add(BitCodeAbbrevOp(FIRST_EXTENSION_RECORD_ID)); |
28 | Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); |
29 | Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); |
30 | auto Abbrev = Stream.EmitAbbrev(std::move(Abv)); |
31 | |
32 | |
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 | |
49 | SmallVector<uint64_t, 4> Record; |
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 | |
76 | TestModuleFileExtension::Reader::~Reader() { } |
77 | |
78 | TestModuleFileExtension::~TestModuleFileExtension() { } |
79 | |
80 | ModuleFileExtensionMetadata |
81 | TestModuleFileExtension::getExtensionMetadata() const { |
82 | return { BlockName, MajorVersion, MinorVersion, UserInfo }; |
83 | } |
84 | |
85 | llvm::hash_code TestModuleFileExtension::hashExtension( |
86 | llvm::hash_code Code) const { |
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 | |
97 | std::unique_ptr<ModuleFileExtensionWriter> |
98 | TestModuleFileExtension::createExtensionWriter(ASTWriter &) { |
99 | return std::unique_ptr<ModuleFileExtensionWriter>(new Writer(this)); |
100 | } |
101 | |
102 | std::unique_ptr<ModuleFileExtensionReader> |
103 | TestModuleFileExtension::createExtensionReader( |
104 | const ModuleFileExtensionMetadata &Metadata, |
105 | ASTReader &Reader, serialization::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.MajorVersion, Metadata.MinorVersion) != |
110 | std::make_pair(MajorVersion, MinorVersion)) { |
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(this, Stream)); |
120 | } |
121 | |