Files
swift-mirror/lib/IRGen/StructMetadataVisitor.h
Slava Pestov 3ab5b6fa19 IRGen/Runtime: Remove parent field from type metadata
We no longer need this for anything, so remove it from metadata
altogether. This simplifies logic for emitting type metadata and
makes type metadata smaller.

We still pass the parent metadata pointer to type constructors;
removing that is a separate change.
2017-09-25 15:45:17 -07:00

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();
// If changing this layout, you must update the magic number in
// emitParentMetadataRef.
// Struct field offsets.
asImpl().noteStartOfFieldOffsets();
for (VarDecl *prop : Target->getStoredProperties())
asImpl().addFieldOffset(prop);
// Instantiation-specific.
asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext());
}
// 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