mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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
99 lines
3.5 KiB
C++
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;
|
|
}
|
|
}
|
|
}
|