forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			130 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- TestModuleFileExtension.cpp - Module Extension Tester -------------===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
#include "TestModuleFileExtension.h"
 | 
						|
#include "clang/Frontend/FrontendDiagnostic.h"
 | 
						|
#include "clang/Serialization/ASTReader.h"
 | 
						|
#include "llvm/ADT/Hashing.h"
 | 
						|
#include "llvm/Bitstream/BitstreamWriter.h"
 | 
						|
#include "llvm/Support/raw_ostream.h"
 | 
						|
#include <cstdio>
 | 
						|
using namespace clang;
 | 
						|
using namespace clang::serialization;
 | 
						|
 | 
						|
TestModuleFileExtension::Writer::~Writer() { }
 | 
						|
 | 
						|
void TestModuleFileExtension::Writer::writeExtensionContents(
 | 
						|
       Sema &SemaRef,
 | 
						|
       llvm::BitstreamWriter &Stream) {
 | 
						|
  using namespace llvm;
 | 
						|
 | 
						|
  // Write an abbreviation for this record.
 | 
						|
  auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
 | 
						|
  Abv->Add(BitCodeAbbrevOp(FIRST_EXTENSION_RECORD_ID));
 | 
						|
  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of characters
 | 
						|
  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));   // message
 | 
						|
  auto Abbrev = Stream.EmitAbbrev(std::move(Abv));
 | 
						|
 | 
						|
  // Write a message into the extension block.
 | 
						|
  SmallString<64> Message;
 | 
						|
  {
 | 
						|
    auto Ext = static_cast<TestModuleFileExtension *>(getExtension());
 | 
						|
    raw_svector_ostream OS(Message);
 | 
						|
    OS << "Hello from " << Ext->BlockName << " v" << Ext->MajorVersion << "."
 | 
						|
       << Ext->MinorVersion;
 | 
						|
  }
 | 
						|
  uint64_t Record[] = {FIRST_EXTENSION_RECORD_ID, Message.size()};
 | 
						|
  Stream.EmitRecordWithBlob(Abbrev, Record, Message);
 | 
						|
}
 | 
						|
 | 
						|
TestModuleFileExtension::Reader::Reader(ModuleFileExtension *Ext,
 | 
						|
                                        const llvm::BitstreamCursor &InStream)
 | 
						|
  : ModuleFileExtensionReader(Ext), Stream(InStream)
 | 
						|
{
 | 
						|
  // Read the extension block.
 | 
						|
  SmallVector<uint64_t, 4> Record;
 | 
						|
  while (true) {
 | 
						|
    llvm::Expected<llvm::BitstreamEntry> MaybeEntry =
 | 
						|
        Stream.advanceSkippingSubblocks();
 | 
						|
    if (!MaybeEntry)
 | 
						|
      (void)MaybeEntry.takeError();
 | 
						|
    llvm::BitstreamEntry Entry = MaybeEntry.get();
 | 
						|
 | 
						|
    switch (Entry.Kind) {
 | 
						|
    case llvm::BitstreamEntry::SubBlock:
 | 
						|
    case llvm::BitstreamEntry::EndBlock:
 | 
						|
    case llvm::BitstreamEntry::Error:
 | 
						|
      return;
 | 
						|
 | 
						|
    case llvm::BitstreamEntry::Record:
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    Record.clear();
 | 
						|
    StringRef Blob;
 | 
						|
    Expected<unsigned> MaybeRecCode =
 | 
						|
        Stream.readRecord(Entry.ID, Record, &Blob);
 | 
						|
    if (!MaybeRecCode)
 | 
						|
      fprintf(stderr, "Failed reading rec code: %s\n",
 | 
						|
              toString(MaybeRecCode.takeError()).c_str());
 | 
						|
    switch (MaybeRecCode.get()) {
 | 
						|
    case FIRST_EXTENSION_RECORD_ID: {
 | 
						|
      StringRef Message = Blob.substr(0, Record[0]);
 | 
						|
      fprintf(stderr, "Read extension block message: %s\n",
 | 
						|
              Message.str().c_str());
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TestModuleFileExtension::Reader::~Reader() { }
 | 
						|
 | 
						|
TestModuleFileExtension::~TestModuleFileExtension() { }
 | 
						|
 | 
						|
ModuleFileExtensionMetadata
 | 
						|
TestModuleFileExtension::getExtensionMetadata() const {
 | 
						|
  return { BlockName, MajorVersion, MinorVersion, UserInfo };
 | 
						|
}
 | 
						|
 | 
						|
llvm::hash_code TestModuleFileExtension::hashExtension(
 | 
						|
                  llvm::hash_code Code) const {
 | 
						|
  if (Hashed) {
 | 
						|
    Code = llvm::hash_combine(Code, BlockName);
 | 
						|
    Code = llvm::hash_combine(Code, MajorVersion);
 | 
						|
    Code = llvm::hash_combine(Code, MinorVersion);
 | 
						|
    Code = llvm::hash_combine(Code, UserInfo);
 | 
						|
  }
 | 
						|
 | 
						|
  return Code;
 | 
						|
}
 | 
						|
 | 
						|
std::unique_ptr<ModuleFileExtensionWriter>
 | 
						|
TestModuleFileExtension::createExtensionWriter(ASTWriter &) {
 | 
						|
  return std::unique_ptr<ModuleFileExtensionWriter>(new Writer(this));
 | 
						|
}
 | 
						|
 | 
						|
std::unique_ptr<ModuleFileExtensionReader>
 | 
						|
TestModuleFileExtension::createExtensionReader(
 | 
						|
  const ModuleFileExtensionMetadata &Metadata,
 | 
						|
  ASTReader &Reader, serialization::ModuleFile &Mod,
 | 
						|
  const llvm::BitstreamCursor &Stream)
 | 
						|
{
 | 
						|
  assert(Metadata.BlockName == BlockName && "Wrong block name");
 | 
						|
  if (std::make_pair(Metadata.MajorVersion, Metadata.MinorVersion) !=
 | 
						|
        std::make_pair(MajorVersion, MinorVersion)) {
 | 
						|
    Reader.getDiags().Report(Mod.ImportLoc,
 | 
						|
                             diag::err_test_module_file_extension_version)
 | 
						|
      << BlockName << Metadata.MajorVersion << Metadata.MinorVersion
 | 
						|
      << MajorVersion << MinorVersion;
 | 
						|
    return nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  return std::unique_ptr<ModuleFileExtensionReader>(
 | 
						|
                                                    new TestModuleFileExtension::Reader(this, Stream));
 | 
						|
}
 |