Files
swift-mirror/lib/AST/ConcreteDeclRef.cpp
Slava Pestov ac7a3030e3 Sema: Fix inheritance of designated initializers with default arguments in generic context
We were dropping the substitutions required to call the default
argument generator on the floor, when the correct solution is to
remap them to substitutions in terms of the base class signature.

Fixes <rdar://problem/29721571>.
2016-12-22 14:33:01 -05:00

103 lines
3.1 KiB
C++

//===--- ConcreteDeclRef.cpp - Reference to a concrete decl ---------------===//
//
// 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 https://swift.org/LICENSE.txt for license information
// See https://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) {
size_t size = totalSizeToAlloc<Substitution>(substitutions.size());
void *memory = ctx.Allocate(size, alignof(SpecializedDeclRef));
return new (memory) SpecializedDeclRef(decl, substitutions);
}
ConcreteDeclRef
ConcreteDeclRef::getOverriddenDecl(ASTContext &ctx,
LazyResolver *resolver) const {
auto *derivedDecl = getDecl();
auto *baseDecl = derivedDecl->getOverriddenDecl();
auto *baseSig = baseDecl->getInnermostDeclContext()
->getGenericSignatureOfContext();
auto *derivedSig = derivedDecl->getInnermostDeclContext()
->getGenericSignatureOfContext();
SmallVector<Substitution, 4> subs = {};
if (baseSig) {
SubstitutionMap subMap;
if (derivedSig)
derivedSig->getSubstitutionMap(getSubstitutions(), subMap);
subMap = SubstitutionMap::getOverrideSubstitutions(
baseDecl, derivedDecl, subMap, resolver);
baseSig->getSubstitutions(subMap, subs);
}
return ConcreteDeclRef(ctx, baseDecl, subs);
}
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.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());
}