mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add MetadataSource classes
The compiler is generally free to not include pointers to metadata in heap boxes, which are used for closure captures, if it knows you can get to metadata through some other path. These MetadataSource classes will describe a sequence of steps to get to metadata at runtime. In the short term, this will be useful for describing the layout of function/closure capture contexts, which can vary depending on what is captured.
This commit is contained in:
141
include/swift/Reflection/MetadataSource.h
Normal file
141
include/swift/Reflection/MetadataSource.h
Normal file
@@ -0,0 +1,141 @@
|
||||
//===--- MetadataSource.cpp - Swift Metadata Sources for Reflection -------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See http://swift.org/LICENSE.txt for license information
|
||||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implements a description of a "metadata source": at runtime, emission of
|
||||
// metadata pointers that you can directly follow may be omitted as an
|
||||
// optimization, because the compiler knows you can get to metadata by some
|
||||
// other means. For example, all heap objects have a pointer to some metadata
|
||||
// describing it, so pointers to class instances can eventually lead to their
|
||||
// metadata. These nodes describe those kinds of paths to metadata at runtime.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_REFLECTION_METADATASOURCE_H
|
||||
#define SWIFT_REFLECTION_METADATASOURCE_H
|
||||
|
||||
#include "llvm/Support/Casting.h"
|
||||
|
||||
using llvm::cast;
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace swift {
|
||||
namespace reflection {
|
||||
|
||||
enum class MetadataSourceKind {
|
||||
#define METADATA_SOURCE(Id, Parent) Id,
|
||||
#include "swift/Reflection/MetadataSources.def"
|
||||
#undef METADATA_SOURCE
|
||||
};
|
||||
|
||||
class MetadataSource {
|
||||
MetadataSourceKind Kind;
|
||||
public:
|
||||
MetadataSource(MetadataSourceKind Kind) : Kind(Kind) {}
|
||||
|
||||
MetadataSourceKind getKind() const {
|
||||
return Kind;
|
||||
}
|
||||
|
||||
void dump() const;
|
||||
void dump(std::ostream &OS, unsigned Indent = 0) const;
|
||||
|
||||
virtual ~MetadataSource() = default;
|
||||
};
|
||||
|
||||
/// Represents a metadata pointer stashed in the "necessary bindings"
|
||||
/// structure at the head of a heap closure. These can be followed
|
||||
/// directly to some instantiated metadata.
|
||||
class ClosureBindingMetadataSource final : public MetadataSource {
|
||||
unsigned Index;
|
||||
|
||||
public:
|
||||
ClosureBindingMetadataSource(unsigned Index) :
|
||||
MetadataSource(MetadataSourceKind::ClosureBinding) {}
|
||||
|
||||
unsigned getIndex() const {
|
||||
return Index;
|
||||
}
|
||||
|
||||
static bool classof(const MetadataSource *MS) {
|
||||
return MS->getKind() == MetadataSourceKind::ClosureBinding;
|
||||
}
|
||||
};
|
||||
|
||||
/// Represents a capture of a reference to heap object. These can
|
||||
/// be followed to the heap instance's data, then its metadata pointer.
|
||||
class ReferenceCaptureMetadataSource final : public MetadataSource {
|
||||
unsigned Index;
|
||||
public:
|
||||
ReferenceCaptureMetadataSource(unsigned Index):
|
||||
MetadataSource(MetadataSourceKind::ReferenceCapture) {}
|
||||
|
||||
unsigned getIndex() const {
|
||||
return Index;
|
||||
}
|
||||
|
||||
static bool classof(const MetadataSource *MS) {
|
||||
return MS->getKind() == MetadataSourceKind::ReferenceCapture;
|
||||
}
|
||||
};
|
||||
|
||||
/// Represents the nth generic argument in some other source of instantiated
|
||||
/// metadata.
|
||||
///
|
||||
/// If you have a pointer to a class MyClass<T, U>, and you need the metadata
|
||||
/// for its `T`, you can follow the pointer to the instance data, then its
|
||||
/// metadata pointer at the start of the instance, and fetch its first
|
||||
/// generic argument.
|
||||
class GenericArgumentMetadataSource final : public MetadataSource {
|
||||
unsigned Index;
|
||||
const MetadataSource *Source;
|
||||
|
||||
public:
|
||||
GenericArgumentMetadataSource(unsigned Index,
|
||||
const MetadataSource *Source)
|
||||
: MetadataSource(MetadataSourceKind::GenericArgument),
|
||||
Index(Index),
|
||||
Source(Source) {}
|
||||
|
||||
unsigned getIndex() const {
|
||||
return Index;
|
||||
}
|
||||
|
||||
const MetadataSource *getSource() const {
|
||||
return Source;
|
||||
}
|
||||
|
||||
static bool classof(const MetadataSource *MS) {
|
||||
return MS->getKind() == MetadataSourceKind::GenericArgument;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ImplClass, typename RetTy = void, typename... Args>
|
||||
class MetadataSourceVisitor {
|
||||
public:
|
||||
|
||||
RetTy visit(const MetadataSource *MS, Args... args) {
|
||||
switch (MS->getKind()) {
|
||||
#define METADATA_SOURCE(Id, Parent) \
|
||||
case MetadataSourceKind::Id: \
|
||||
return static_cast<ImplClass*>(this) \
|
||||
->visit##Id##MetadataSource(cast<Id##MetadataSource>(MS), \
|
||||
::std::forward<Args>(args)...);
|
||||
#include "swift/Reflection/MetadataSources.def"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace reflection
|
||||
} // end namespace swift
|
||||
|
||||
#endif // SWIFT_REFLECTION_METADATASOURCE_H
|
||||
Reference in New Issue
Block a user