llvm-capstone/clang/lib/Frontend/TestModuleFileExtension.h
Jan Svoboda 4295ae96cd [clang][modules] Use extensible RTTI for ModuleFileExtension
Clang exposes an interface for extending the PCM/PCH file format: `ModuleFileExtension`.

Clang itself has only a single implementation of the interface: `TestModuleFileExtension` that can be instantiated via the `-ftest-module-file_extension=` command line argument (and is stored in `FrontendOptions::ModuleFileExtensions`).

Clients of the Clang library can extend the PCM/PCH file format by pushing an instance of their extension class to the `FrontendOptions::ModuleFileExtensions` vector.

When generating the `-ftest-module-file_extension=` command line argument from `FrontendOptions`, a downcast is used to distinguish between the Clang's testing extension and other (client) extensions.

This functionality is enabled by LLVM-style RTTI. However, this style of RTTI is hard to extend, as it requires patching Clang (adding new case to the `ModuleFileExtensionKind` enum).

This patch switches to the LLVM RTTI for open class hierarchies, which allows libClang users (e.g. Swift) to create implementations of `ModuleFileExtension` without patching Clang. (Documentation of the feature: https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html#rtti-for-open-class-hierarchies)

Reviewed By: artemcm

Differential Revision: https://reviews.llvm.org/D97702
2021-03-05 11:11:05 +01:00

74 lines
2.4 KiB
C++

//===-- TestModuleFileExtension.h - Module Extension Tester -----*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_FRONTEND_TESTMODULEFILEEXTENSION_H
#define LLVM_CLANG_FRONTEND_TESTMODULEFILEEXTENSION_H
#include "clang/Serialization/ModuleFileExtension.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Bitstream/BitstreamReader.h"
#include <string>
namespace clang {
/// A module file extension used for testing purposes.
class TestModuleFileExtension
: public llvm::RTTIExtends<TestModuleFileExtension, ModuleFileExtension> {
std::string BlockName;
unsigned MajorVersion;
unsigned MinorVersion;
bool Hashed;
std::string UserInfo;
class Writer : public ModuleFileExtensionWriter {
public:
Writer(ModuleFileExtension *Ext) : ModuleFileExtensionWriter(Ext) { }
~Writer() override;
void writeExtensionContents(Sema &SemaRef,
llvm::BitstreamWriter &Stream) override;
};
class Reader : public ModuleFileExtensionReader {
llvm::BitstreamCursor Stream;
public:
~Reader() override;
Reader(ModuleFileExtension *Ext, const llvm::BitstreamCursor &InStream);
};
public:
static char ID;
TestModuleFileExtension(StringRef BlockName, unsigned MajorVersion,
unsigned MinorVersion, bool Hashed,
StringRef UserInfo)
: BlockName(BlockName), MajorVersion(MajorVersion),
MinorVersion(MinorVersion), Hashed(Hashed), UserInfo(UserInfo) {}
~TestModuleFileExtension() override;
ModuleFileExtensionMetadata getExtensionMetadata() const override;
llvm::hash_code hashExtension(llvm::hash_code Code) const override;
std::unique_ptr<ModuleFileExtensionWriter>
createExtensionWriter(ASTWriter &Writer) override;
std::unique_ptr<ModuleFileExtensionReader>
createExtensionReader(const ModuleFileExtensionMetadata &Metadata,
ASTReader &Reader, serialization::ModuleFile &Mod,
const llvm::BitstreamCursor &Stream) override;
std::string str() const;
};
} // end namespace clang
#endif // LLVM_CLANG_FRONTEND_TESTMODULEFILEEXTENSION_H