Files
swift-mirror/lib/SIL/SILWitnessTable.cpp
Michael Gottesman 5b88963e78 [SIL] Implement external SIL Witness Table declarations.
This will help with ensuring that we do not create multiple witness
table "definitions" one of which is null. That situtation yields an
IRGen assertion to be hit since the external declaration (in the guise
of a definition) has a different type from the actual deserialized
definition.

Swift SVN r14999
2014-03-13 19:52:59 +00:00

99 lines
3.5 KiB
C++

//===--- SILWitnessTable.h - Defines the SILWitnessTable class ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 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 defines the SILWitnessTable class, which is used to map a protocol
// conformance for a type to its implementing SILFunctions. This information is
// (FIXME will be) used by IRGen to create witness tables for protocol dispatch.
// It can also be used by generic specialization and existential
// devirtualization passes to promote witness_method and protocol_method
// instructions to static function_refs.
//
//===----------------------------------------------------------------------===//
#include "swift/SIL/SILWitnessTable.h"
#include "swift/SIL/SILModule.h"
using namespace swift;
SILWitnessTable *
SILWitnessTable::create(SILModule &M,
SILLinkage Linkage,
NormalProtocolConformance *Conformance,
ArrayRef<SILWitnessTable::Entry> entries) {
void *buf = M.allocate(sizeof(SILWitnessTable),
alignof(SILWitnessTable));
SILWitnessTable *wt = ::new (buf) SILWitnessTable(M, Linkage, Conformance,
entries);
M.witnessTables.push_back(wt);
return wt;
}
SILWitnessTable *
SILWitnessTable::create(SILModule &M,
SILLinkage Linkage,
NormalProtocolConformance *Conformance) {
void *buf = M.allocate(sizeof(SILWitnessTable), alignof(SILWitnessTable));
SILWitnessTable *wt = ::new (buf) SILWitnessTable(M, Linkage, Conformance);
M.witnessTables.push_back(wt);
return wt;
}
SILWitnessTable::SILWitnessTable(SILModule &M,
SILLinkage Linkage,
NormalProtocolConformance *Conformance,
ArrayRef<Entry> entries)
: Linkage(Linkage), Conformance(Conformance), Entries(), IsDeclaration(false)
{
void *buf = M.allocate(sizeof(Entry)*entries.size(), alignof(Entry));
memcpy(buf, entries.begin(), sizeof(Entry)*entries.size());
Entries = ArrayRef<Entry>(static_cast<Entry*>(buf), entries.size());
// Bump the reference count of witness functions referenced by this table.
for (auto entry : getEntries()) {
switch (entry.getKind()) {
case Method:
entry.getMethodWitness().Witness->RefCount++;
break;
case AssociatedType:
case AssociatedTypeProtocol:
case BaseProtocol:
case Invalid:
break;
}
}
}
SILWitnessTable::SILWitnessTable(SILModule &M,
SILLinkage Linkage,
NormalProtocolConformance *Conformance)
: Linkage(Linkage), Conformance(Conformance), Entries(), IsDeclaration(true)
{}
SILWitnessTable::~SILWitnessTable() {
if (isDeclaration())
return;
// Drop the reference count of witness functions referenced by this table.
for (auto entry : getEntries()) {
switch (entry.getKind()) {
case Method:
entry.getMethodWitness().Witness->RefCount--;
break;
case AssociatedType:
case AssociatedTypeProtocol:
case BaseProtocol:
case Invalid:
break;
}
}
}