diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:49:41 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:49:41 +0000 | 
| commit | 45b533945f0851ec234ca846e1af5ee1e4df0b6e (patch) | |
| tree | 0a5b74c0b9ca73aded34df95c91fcaf3815230d8 /lib/Frontend/TestModuleFileExtension.cpp | |
| parent | 7e86edd64bfae4e324224452e4ea879b3371a4bd (diff) | |
Notes
Diffstat (limited to 'lib/Frontend/TestModuleFileExtension.cpp')
| -rw-r--r-- | lib/Frontend/TestModuleFileExtension.cpp | 123 | 
1 files changed, 123 insertions, 0 deletions
diff --git a/lib/Frontend/TestModuleFileExtension.cpp b/lib/Frontend/TestModuleFileExtension.cpp new file mode 100644 index 0000000000000..d1b20c4a80b34 --- /dev/null +++ b/lib/Frontend/TestModuleFileExtension.cpp @@ -0,0 +1,123 @@ +//===-- TestModuleFileExtension.cpp - Module Extension Tester -------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "TestModuleFileExtension.h" +#include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Serialization/ASTReader.h" +#include "llvm/ADT/Hashing.h" +#include "llvm/Bitcode/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. +  BitCodeAbbrev *Abv = new 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(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; +  } +  SmallVector<uint64_t, 4> Record; +  Record.push_back(FIRST_EXTENSION_RECORD_ID); +  Record.push_back(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::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); +    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; +    unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob); +    switch (RecCode) { +    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)); +}  | 
