summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Frontend/TestModuleFileExtension.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend/TestModuleFileExtension.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Frontend/TestModuleFileExtension.cpp123
1 files changed, 123 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/TestModuleFileExtension.cpp b/contrib/llvm/tools/clang/lib/Frontend/TestModuleFileExtension.cpp
new file mode 100644
index 0000000..d1b20c4
--- /dev/null
+++ b/contrib/llvm/tools/clang/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));
+}
OpenPOWER on IntegriCloud