blob: 40688ba9f4246e7f3fecf58a25e0c3b3ae1781bd [file] [log] [blame]
//===--- SILDefaultWitnessTable.cpp ---------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file defines the SILDefaultWitnessTable class, which is used to provide
// default implementations of protocol requirements for resilient protocols,
// allowing IRGen to generate the appropriate metadata so that the runtime can
// insert those requirements to witness tables that were emitted prior to the
// requirement being added.
//
//===----------------------------------------------------------------------===//
#include "swift/AST/ASTMangler.h"
#include "swift/SIL/SILDefaultWitnessTable.h"
#include "swift/SIL/SILModule.h"
#include "llvm/ADT/SmallString.h"
using namespace swift;
void SILDefaultWitnessTable::addDefaultWitnessTable() {
// Make sure we have not seen this witness table yet.
assert(Mod.DefaultWitnessTableMap.find(Protocol) ==
Mod.DefaultWitnessTableMap.end() && "Attempting to create duplicate "
"default witness table.");
Mod.DefaultWitnessTableMap[Protocol] = this;
Mod.defaultWitnessTables.push_back(this);
}
SILDefaultWitnessTable *
SILDefaultWitnessTable::create(SILModule &M, SILLinkage Linkage,
const ProtocolDecl *Protocol,
ArrayRef<SILDefaultWitnessTable::Entry> entries){
// Allocate the witness table and initialize it.
auto *buf = M.allocate<SILDefaultWitnessTable>(1);
SILDefaultWitnessTable *wt =
::new (buf) SILDefaultWitnessTable(M, Linkage, Protocol, entries);
wt->addDefaultWitnessTable();
// Return the resulting default witness table.
return wt;
}
SILDefaultWitnessTable *
SILDefaultWitnessTable::create(SILModule &M, SILLinkage Linkage,
const ProtocolDecl *Protocol) {
// Allocate the witness table and initialize it.
auto *buf = M.allocate<SILDefaultWitnessTable>(1);
SILDefaultWitnessTable *wt =
::new (buf) SILDefaultWitnessTable(M, Linkage, Protocol);
wt->addDefaultWitnessTable();
// Return the resulting default witness table.
return wt;
}
SILDefaultWitnessTable::
SILDefaultWitnessTable(SILModule &M,
SILLinkage Linkage,
const ProtocolDecl *Protocol,
ArrayRef<Entry> entries)
: Mod(M), Linkage(Linkage), Protocol(Protocol), Entries(),
IsDeclaration(true) {
convertToDefinition(entries);
}
SILDefaultWitnessTable::SILDefaultWitnessTable(SILModule &M,
SILLinkage Linkage,
const ProtocolDecl *Protocol)
: Mod(M), Linkage(Linkage), Protocol(Protocol), Entries(),
IsDeclaration(true) {}
void SILDefaultWitnessTable::
convertToDefinition(ArrayRef<Entry> entries) {
assert(IsDeclaration);
IsDeclaration = false;
Entries = Mod.allocateCopy(entries);
// Bump the reference count of witness functions referenced by this table.
for (auto entry : getEntries()) {
if (entry.isValid() && entry.getKind() == SILWitnessTable::Method) {
entry.getMethodWitness().Witness->incrementRefCount();
}
}
}
std::string SILDefaultWitnessTable::getUniqueName() const {
Mangle::ASTMangler Mangler;
return Mangler.mangleTypeWithoutPrefix(getProtocol()->getDeclaredType());
}
SILDefaultWitnessTable::~SILDefaultWitnessTable() {
// Drop the reference count of witness functions referenced by this table.
for (auto entry : getEntries()) {
if (entry.isValid() && entry.getKind() == SILWitnessTable::Method) {
entry.getMethodWitness().Witness->decrementRefCount();
}
}
}