mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Change the "metadata base offset" variable into a "class metadata bounds"
variable that contains the base offset and the +/- bounds on the class.
Link this variable from the class descriptor when the class has a resilient
superclass; otherwise, store the +/- bounds there. Use this variable to
compute the immediate-members offset for various runtime queries. Teach the
runtime to fill it in lazily and remove the code to compute it from the
generated code for instantiation. Identify generic arguments with the start
of the immediate class metadata members / end of the {struct,enum} metadata
header and remove the generic-arguments offset from generic type descriptors.
98 lines
2.8 KiB
C++
98 lines
2.8 KiB
C++
//===--- StructMetadataVisitor.h - CRTP for struct metadata ------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// A CRTP class useful for laying out struct metadata.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_IRGEN_STRUCTMETADATALAYOUT_H
|
|
#define SWIFT_IRGEN_STRUCTMETADATALAYOUT_H
|
|
|
|
#include "NominalMetadataVisitor.h"
|
|
|
|
namespace swift {
|
|
namespace irgen {
|
|
|
|
/// A CRTP class for laying out struct metadata.
|
|
///
|
|
/// This produces an object corresponding to the StructMetadata type.
|
|
/// It does not itself doing anything special for metadata templates.
|
|
template <class Impl> class StructMetadataVisitor
|
|
: public NominalMetadataVisitor<Impl> {
|
|
using super = NominalMetadataVisitor<Impl>;
|
|
|
|
protected:
|
|
using super::IGM;
|
|
using super::asImpl;
|
|
|
|
/// The struct.
|
|
StructDecl *const Target;
|
|
|
|
StructMetadataVisitor(IRGenModule &IGM, StructDecl *target)
|
|
: super(IGM), Target(target) {}
|
|
|
|
public:
|
|
void layout() {
|
|
// Metadata header.
|
|
super::layout();
|
|
|
|
// StructMetadata header.
|
|
asImpl().addNominalTypeDescriptor();
|
|
|
|
// Instantiation-specific.
|
|
|
|
// Generic arguments.
|
|
// This must always be the first piece of trailing data.
|
|
asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext());
|
|
|
|
// Struct field offsets.
|
|
asImpl().noteStartOfFieldOffsets();
|
|
for (VarDecl *prop : Target->getStoredProperties())
|
|
asImpl().addFieldOffset(prop);
|
|
}
|
|
|
|
// Note the start of the field offset vector.
|
|
void noteStartOfFieldOffsets() {}
|
|
};
|
|
|
|
/// An "implementation" of StructMetadataVisitor that just scans through
|
|
/// the metadata layout, maintaining the offset of the next field.
|
|
template <class Impl>
|
|
class StructMetadataScanner : public StructMetadataVisitor<Impl> {
|
|
typedef StructMetadataVisitor<Impl> super;
|
|
protected:
|
|
Size NextOffset = Size(0);
|
|
|
|
StructMetadataScanner(IRGenModule &IGM, StructDecl *target)
|
|
: super(IGM, target) {}
|
|
|
|
public:
|
|
void addMetadataFlags() { addPointer(); }
|
|
void addValueWitnessTable() { addPointer(); }
|
|
void addNominalTypeDescriptor() { addPointer(); }
|
|
void addFieldOffset(VarDecl*) { addPointer(); }
|
|
void addGenericArgument(CanType argument) { addPointer(); }
|
|
void addGenericWitnessTable(CanType argument, ProtocolConformanceRef conf) {
|
|
addPointer();
|
|
}
|
|
|
|
private:
|
|
void addPointer() {
|
|
NextOffset += super::IGM.getPointerSize();
|
|
}
|
|
};
|
|
|
|
} // end namespace irgen
|
|
} // end namespace swift
|
|
|
|
#endif
|