mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
As part of this, we have to change the type export rules to prevent `@convention(c)` function types from being used in exported interfaces if they aren't serializable. This is a more conservative version of the original rule I had, which was to import such function-pointer types as opaque pointers. That rule would've completely prevented importing function-pointer types defined in bridging headers and so simply doesn't work, so we're left trying to catch the unsupportable cases retroactively. This has the unfortunate consequence that we can't necessarily serialize the internal state of the compiler, but that was already true due to normal type uses of aggregate types from bridging headers; if we can teach the compiler to reliably serialize such types, we should be able to use the same mechanisms for function types. This PR doesn't flip the switch to use Clang function types by default, so many of the clang-function-type-serialization FIXMEs are still in place.
91 lines
3.1 KiB
C++
91 lines
3.1 KiB
C++
//===- 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
|