Files
swift-mirror/lib/IRGen/NominalMetadataVisitor.h
Slava Pestov 41aebf8e5a IRGen: Simplify NominalMetadataVisitor's treatment of generic requirements
We don't need to substitute the superclass type as we walk up a
class hierarchy, or look up the generic parameters and conformances
to check if they're concrete, since we're always just emitting
null pointers in place of the generic parameters and requirements,
to be filled at runtime.

Also, don't leave space for generic parameters and requirements from
Objective-C superclasses, since that's not how they're represented.
2018-08-14 00:20:12 -07:00

89 lines
2.6 KiB
C++

//===--- NominalMetadataVisitor.h - CRTP for metadata layout ----*- 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 helper class for visiting all of the fields in a nominal type
// metadata object.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_IRGEN_NOMINALMETADATAVISITOR_H
#define SWIFT_IRGEN_NOMINALMETADATAVISITOR_H
#include "llvm/ADT/SmallVector.h"
#include "swift/AST/Decl.h"
#include "swift/AST/SubstitutionMap.h"
#include "swift/SIL/TypeLowering.h"
#include "GenericRequirement.h"
#include "GenProto.h"
#include "IRGenModule.h"
namespace swift {
namespace irgen {
/// A CRTP class for laying out type metadata. Note that this does
/// *not* handle the metadata template stuff.
template <class Impl> class NominalMetadataVisitor {
protected:
Impl &asImpl() { return *static_cast<Impl*>(this); }
protected:
IRGenModule &IGM;
NominalMetadataVisitor(IRGenModule &IGM) : IGM(IGM) {}
public:
void layout() {
// Common fields.
asImpl().addValueWitnessTable();
asImpl().noteAddressPoint();
asImpl().addMetadataFlags();
}
/// This is the address point.
void noteAddressPoint() {}
/// Add fields related to the generics of this class declaration.
/// TODO: don't add new fields that are implied by the superclass
/// fields. e.g., if B<T> extends A<T>, the witness for T in A's
/// section should be enough.
template <class... T>
void addGenericFields(NominalTypeDecl *typeDecl, T &&...args) {
// The archetype order here needs to be consistent with
// NominalTypeDescriptorBase::addGenericParams.
// Note that we intentionally don't std::forward 'args'.
asImpl().noteStartOfGenericRequirements(args...);
GenericTypeRequirements requirements(IGM, typeDecl);
for (auto reqt : requirements.getRequirements()) {
if (reqt.Protocol) {
asImpl().addGenericWitnessTable(args...);
} else {
asImpl().addGenericArgument(args...);
}
}
asImpl().noteEndOfGenericRequirements(args...);
}
template <class... T>
void noteStartOfGenericRequirements(T &&...args) {}
template <class... T>
void noteEndOfGenericRequirements(T &&...args) {}
};
} // end namespace irgen
} // end namespace swift
#endif