TestModuleFileExtension.cpp 4.5 KB

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