mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
The main idea here is that we really, really want to be able to recover the protocol requirement of a conformance reference even if it's abstract due to the conforming type being abstract (e.g. an archetype). I've made the conversion from ProtocolConformance* explicit to discourage casual contamination of the Ref with a null value. As part of this change, always make conformance arrays in Substitutions fully parallel to the requirements, as opposed to occasionally being empty when the conformances are abstract. As another part of this, I've tried to proactively fix prospective bugs with partially-concrete conformances, which I believe can happen with concretely-bound archetypes. In addition to just giving us stronger invariants, this is progress towards the removal of the archetype from Substitution.
82 lines
2.4 KiB
C++
82 lines
2.4 KiB
C++
//===--- ConcreteDeclRef.cpp - Reference to a concrete decl -----*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the ConcreteDeclRef class, which provides a reference to
|
|
// a declaration that is potentially specialized.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "swift/AST/ASTContext.h"
|
|
#include "swift/AST/ConcreteDeclRef.h"
|
|
#include "swift/AST/Decl.h"
|
|
#include "swift/AST/Types.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
using namespace swift;
|
|
|
|
ConcreteDeclRef::SpecializedDeclRef *
|
|
ConcreteDeclRef::SpecializedDeclRef::create(
|
|
ASTContext &ctx, ValueDecl *decl,
|
|
ArrayRef<Substitution> substitutions) {
|
|
unsigned size = sizeof(SpecializedDeclRef)
|
|
+ sizeof(Substitution) * substitutions.size();
|
|
void *memory = ctx.Allocate(size, alignof(SpecializedDeclRef));
|
|
return new (memory) SpecializedDeclRef(decl, substitutions);
|
|
}
|
|
|
|
void ConcreteDeclRef::dump(raw_ostream &os) {
|
|
if (!getDecl()) {
|
|
os << "**NULL**";
|
|
return;
|
|
}
|
|
|
|
getDecl()->dumpRef(os);
|
|
|
|
// If specialized, dump the substitutions.
|
|
if (isSpecialized()) {
|
|
os << " [with ";
|
|
bool isFirst = true;
|
|
for (const auto &sub : getSubstitutions()) {
|
|
if (isFirst) {
|
|
isFirst = false;
|
|
} else {
|
|
os << ", ";
|
|
}
|
|
|
|
os << sub.getArchetype()->getFullName()
|
|
<< "=" << sub.getReplacement().getString();
|
|
|
|
if (sub.getConformances().size()) {
|
|
os << '[';
|
|
bool isFirst = true;
|
|
for (auto &c : sub.getConformances()) {
|
|
if (isFirst) {
|
|
isFirst = false;
|
|
} else {
|
|
os << ", ";
|
|
}
|
|
|
|
if (c.isConcrete()) {
|
|
c.getConcrete()->printName(os);
|
|
} else {
|
|
os << "abstract:" << c.getAbstract()->getName();
|
|
}
|
|
}
|
|
os << ']';
|
|
}
|
|
}
|
|
os << ']';
|
|
}
|
|
}
|
|
|
|
void ConcreteDeclRef::dump() {
|
|
dump(llvm::errs());
|
|
}
|