TestModuleFileExtension.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. //===-- TestModuleFileExtension.cpp - Module Extension Tester -------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "TestModuleFileExtension.h"
  10. #include "clang/Frontend/FrontendDiagnostic.h"
  11. #include "clang/Serialization/ASTReader.h"
  12. #include "llvm/ADT/Hashing.h"
  13. #include "llvm/Bitcode/BitstreamWriter.h"
  14. #include "llvm/Support/raw_ostream.h"
  15. #include <cstdio>
  16. using namespace clang;
  17. using namespace clang::serialization;
  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::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
  48. switch (Entry.Kind) {
  49. case llvm::BitstreamEntry::SubBlock:
  50. case llvm::BitstreamEntry::EndBlock:
  51. case llvm::BitstreamEntry::Error:
  52. return;
  53. case llvm::BitstreamEntry::Record:
  54. break;
  55. }
  56. Record.clear();
  57. StringRef Blob;
  58. unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
  59. switch (RecCode) {
  60. case FIRST_EXTENSION_RECORD_ID: {
  61. StringRef Message = Blob.substr(0, Record[0]);
  62. fprintf(stderr, "Read extension block message: %s\n",
  63. Message.str().c_str());
  64. break;
  65. }
  66. }
  67. }
  68. }
  69. TestModuleFileExtension::Reader::~Reader() { }
  70. TestModuleFileExtension::~TestModuleFileExtension() { }
  71. ModuleFileExtensionMetadata
  72. TestModuleFileExtension::getExtensionMetadata() const {
  73. return { BlockName, MajorVersion, MinorVersion, UserInfo };
  74. }
  75. llvm::hash_code TestModuleFileExtension::hashExtension(
  76. llvm::hash_code Code) const {
  77. if (Hashed) {
  78. Code = llvm::hash_combine(Code, BlockName);
  79. Code = llvm::hash_combine(Code, MajorVersion);
  80. Code = llvm::hash_combine(Code, MinorVersion);
  81. Code = llvm::hash_combine(Code, UserInfo);
  82. }
  83. return Code;
  84. }
  85. std::unique_ptr<ModuleFileExtensionWriter>
  86. TestModuleFileExtension::createExtensionWriter(ASTWriter &) {
  87. return std::unique_ptr<ModuleFileExtensionWriter>(new Writer(this));
  88. }
  89. std::unique_ptr<ModuleFileExtensionReader>
  90. TestModuleFileExtension::createExtensionReader(
  91. const ModuleFileExtensionMetadata &Metadata,
  92. ASTReader &Reader, serialization::ModuleFile &Mod,
  93. const llvm::BitstreamCursor &Stream)
  94. {
  95. assert(Metadata.BlockName == BlockName && "Wrong block name");
  96. if (std::make_pair(Metadata.MajorVersion, Metadata.MinorVersion) !=
  97. std::make_pair(MajorVersion, MinorVersion)) {
  98. Reader.getDiags().Report(Mod.ImportLoc,
  99. diag::err_test_module_file_extension_version)
  100. << BlockName << Metadata.MajorVersion << Metadata.MinorVersion
  101. << MajorVersion << MinorVersion;
  102. return nullptr;
  103. }
  104. return std::unique_ptr<ModuleFileExtensionReader>(
  105. new TestModuleFileExtension::Reader(this, Stream));
  106. }