| 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 | |