xref: /aosp_15_r20/external/clang/lib/Frontend/TestModuleFileExtension.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===-- TestModuleFileExtension.cpp - Module Extension Tester -------------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li #include "TestModuleFileExtension.h"
10*67e74705SXin Li #include "clang/Frontend/FrontendDiagnostic.h"
11*67e74705SXin Li #include "clang/Serialization/ASTReader.h"
12*67e74705SXin Li #include "llvm/ADT/Hashing.h"
13*67e74705SXin Li #include "llvm/Bitcode/BitstreamWriter.h"
14*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
15*67e74705SXin Li #include <cstdio>
16*67e74705SXin Li using namespace clang;
17*67e74705SXin Li using namespace clang::serialization;
18*67e74705SXin Li 
~Writer()19*67e74705SXin Li TestModuleFileExtension::Writer::~Writer() { }
20*67e74705SXin Li 
writeExtensionContents(Sema & SemaRef,llvm::BitstreamWriter & Stream)21*67e74705SXin Li void TestModuleFileExtension::Writer::writeExtensionContents(
22*67e74705SXin Li        Sema &SemaRef,
23*67e74705SXin Li        llvm::BitstreamWriter &Stream) {
24*67e74705SXin Li   using namespace llvm;
25*67e74705SXin Li 
26*67e74705SXin Li   // Write an abbreviation for this record.
27*67e74705SXin Li   BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev();
28*67e74705SXin Li   Abv->Add(BitCodeAbbrevOp(FIRST_EXTENSION_RECORD_ID));
29*67e74705SXin Li   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of characters
30*67e74705SXin Li   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));   // message
31*67e74705SXin Li   auto Abbrev = Stream.EmitAbbrev(Abv);
32*67e74705SXin Li 
33*67e74705SXin Li   // Write a message into the extension block.
34*67e74705SXin Li   SmallString<64> Message;
35*67e74705SXin Li   {
36*67e74705SXin Li     auto Ext = static_cast<TestModuleFileExtension *>(getExtension());
37*67e74705SXin Li     raw_svector_ostream OS(Message);
38*67e74705SXin Li     OS << "Hello from " << Ext->BlockName << " v" << Ext->MajorVersion << "."
39*67e74705SXin Li        << Ext->MinorVersion;
40*67e74705SXin Li   }
41*67e74705SXin Li   uint64_t Record[] = {FIRST_EXTENSION_RECORD_ID, Message.size()};
42*67e74705SXin Li   Stream.EmitRecordWithBlob(Abbrev, Record, Message);
43*67e74705SXin Li }
44*67e74705SXin Li 
Reader(ModuleFileExtension * Ext,const llvm::BitstreamCursor & InStream)45*67e74705SXin Li TestModuleFileExtension::Reader::Reader(ModuleFileExtension *Ext,
46*67e74705SXin Li                                         const llvm::BitstreamCursor &InStream)
47*67e74705SXin Li   : ModuleFileExtensionReader(Ext), Stream(InStream)
48*67e74705SXin Li {
49*67e74705SXin Li   // Read the extension block.
50*67e74705SXin Li   SmallVector<uint64_t, 4> Record;
51*67e74705SXin Li   while (true) {
52*67e74705SXin Li     llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
53*67e74705SXin Li     switch (Entry.Kind) {
54*67e74705SXin Li     case llvm::BitstreamEntry::SubBlock:
55*67e74705SXin Li     case llvm::BitstreamEntry::EndBlock:
56*67e74705SXin Li     case llvm::BitstreamEntry::Error:
57*67e74705SXin Li       return;
58*67e74705SXin Li 
59*67e74705SXin Li     case llvm::BitstreamEntry::Record:
60*67e74705SXin Li       break;
61*67e74705SXin Li     }
62*67e74705SXin Li 
63*67e74705SXin Li     Record.clear();
64*67e74705SXin Li     StringRef Blob;
65*67e74705SXin Li     unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
66*67e74705SXin Li     switch (RecCode) {
67*67e74705SXin Li     case FIRST_EXTENSION_RECORD_ID: {
68*67e74705SXin Li       StringRef Message = Blob.substr(0, Record[0]);
69*67e74705SXin Li       fprintf(stderr, "Read extension block message: %s\n",
70*67e74705SXin Li               Message.str().c_str());
71*67e74705SXin Li       break;
72*67e74705SXin Li     }
73*67e74705SXin Li     }
74*67e74705SXin Li   }
75*67e74705SXin Li }
76*67e74705SXin Li 
~Reader()77*67e74705SXin Li TestModuleFileExtension::Reader::~Reader() { }
78*67e74705SXin Li 
~TestModuleFileExtension()79*67e74705SXin Li TestModuleFileExtension::~TestModuleFileExtension() { }
80*67e74705SXin Li 
81*67e74705SXin Li ModuleFileExtensionMetadata
getExtensionMetadata() const82*67e74705SXin Li TestModuleFileExtension::getExtensionMetadata() const {
83*67e74705SXin Li   return { BlockName, MajorVersion, MinorVersion, UserInfo };
84*67e74705SXin Li }
85*67e74705SXin Li 
hashExtension(llvm::hash_code Code) const86*67e74705SXin Li llvm::hash_code TestModuleFileExtension::hashExtension(
87*67e74705SXin Li                   llvm::hash_code Code) const {
88*67e74705SXin Li   if (Hashed) {
89*67e74705SXin Li     Code = llvm::hash_combine(Code, BlockName);
90*67e74705SXin Li     Code = llvm::hash_combine(Code, MajorVersion);
91*67e74705SXin Li     Code = llvm::hash_combine(Code, MinorVersion);
92*67e74705SXin Li     Code = llvm::hash_combine(Code, UserInfo);
93*67e74705SXin Li   }
94*67e74705SXin Li 
95*67e74705SXin Li   return Code;
96*67e74705SXin Li }
97*67e74705SXin Li 
98*67e74705SXin Li std::unique_ptr<ModuleFileExtensionWriter>
createExtensionWriter(ASTWriter &)99*67e74705SXin Li TestModuleFileExtension::createExtensionWriter(ASTWriter &) {
100*67e74705SXin Li   return std::unique_ptr<ModuleFileExtensionWriter>(new Writer(this));
101*67e74705SXin Li }
102*67e74705SXin Li 
103*67e74705SXin Li std::unique_ptr<ModuleFileExtensionReader>
createExtensionReader(const ModuleFileExtensionMetadata & Metadata,ASTReader & Reader,serialization::ModuleFile & Mod,const llvm::BitstreamCursor & Stream)104*67e74705SXin Li TestModuleFileExtension::createExtensionReader(
105*67e74705SXin Li   const ModuleFileExtensionMetadata &Metadata,
106*67e74705SXin Li   ASTReader &Reader, serialization::ModuleFile &Mod,
107*67e74705SXin Li   const llvm::BitstreamCursor &Stream)
108*67e74705SXin Li {
109*67e74705SXin Li   assert(Metadata.BlockName == BlockName && "Wrong block name");
110*67e74705SXin Li   if (std::make_pair(Metadata.MajorVersion, Metadata.MinorVersion) !=
111*67e74705SXin Li         std::make_pair(MajorVersion, MinorVersion)) {
112*67e74705SXin Li     Reader.getDiags().Report(Mod.ImportLoc,
113*67e74705SXin Li                              diag::err_test_module_file_extension_version)
114*67e74705SXin Li       << BlockName << Metadata.MajorVersion << Metadata.MinorVersion
115*67e74705SXin Li       << MajorVersion << MinorVersion;
116*67e74705SXin Li     return nullptr;
117*67e74705SXin Li   }
118*67e74705SXin Li 
119*67e74705SXin Li   return std::unique_ptr<ModuleFileExtensionReader>(
120*67e74705SXin Li                                                     new TestModuleFileExtension::Reader(this, Stream));
121*67e74705SXin Li }
122