blob: 486bee2d01b21768b3f96b7f6674b5ab32de617b [file] [log] [blame]
//===- SwiftAbstractBasicWriter.h - Clang serialization adapter -*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file provides an intermediate CRTP class which implements most of
// Clang's AbstractBasicWriter interface, allowing largely the same logic
// to be used for both the importer's "can this be serialized" checks and
// the serializer's actual serialization logic.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_CLANGIMPORTER_SWIFTABSTRACTBASICWRITER_H
#define SWIFT_CLANGIMPORTER_SWIFTABSTRACTBASICWRITER_H
#include "clang/AST/AbstractTypeWriter.h"
namespace swift {
/// An implementation of Clang's AbstractBasicWriter interface for a Swift
/// datastream-based reader. This is paired with the AbstractBasicReader
/// implementation in SwiftAbstractBasicReader.h. Note that the general
/// expectation is that the types and declarations involved will have passed
/// a serializability check when this is used for actual serialization.
/// The code in this class is also used when implementing that
/// serializability check and so must be a little more cautious.
///
/// The subclass must implement:
/// void writeUInt64(uint64_t value);
/// void writeIdentifier(const clang::IdentifierInfo *ident);
/// void writeStmtRef(const clang::Stmt *stmt);
/// void writeDeclRef(const clang::Decl *decl);
template <class Impl>
class DataStreamBasicWriter
: public clang::serialization::DataStreamBasicWriter<Impl> {
using super = clang::serialization::DataStreamBasicWriter<Impl>;
public:
using super::asImpl;
/// Perform all the calls necessary to write out the given type.
void writeTypeRef(const clang::Type *type) {
asImpl().writeUInt64(uint64_t(type->getTypeClass()));
clang::serialization::AbstractTypeWriter<Impl>(asImpl()).write(type);
}
void writeBool(bool value) {
asImpl().writeUInt64(uint64_t(value));
}
void writeUInt32(uint32_t value) {
asImpl().writeUInt64(uint64_t(value));
}
void writeSelector(clang::Selector selector) {
if (selector.isNull()) {
asImpl().writeUInt64(0);
return;
}
asImpl().writeUInt64(selector.getNumArgs() + 1);
for (unsigned i = 0, e = std::max(selector.getNumArgs(), 1U); i != e; ++i)
asImpl().writeIdentifier(selector.getIdentifierInfoForSlot(i));
}
void writeSourceLocation(clang::SourceLocation loc) {
// DataStreamBasicReader will always read null; the serializability
// check overrides this to complain about non-null source locations.
}
void writeQualType(clang::QualType type) {
assert(!type.isNull());
auto split = type.split();
asImpl().writeQualifiers(split.Quals);
// Just recursively visit the given type.
asImpl().writeTypeRef(split.Ty);
}
};
}
#endif