Files
swift-mirror/tools/libStaticMirror/libStaticMirror.cpp

474 lines
18 KiB
C++

//===------------ DependencyScanImpl.cpp - Swift Compiler -----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 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
//
//===----------------------------------------------------------------------===//
//
// Implementation of the dependency scanning C API
//
//===----------------------------------------------------------------------===//
#include "swift/Basic/LLVMInitialize.h"
#include "swift/DependencyScan/StringUtils.h"
#include "swift/StaticMirror/BinaryScanImpl.h"
#include "swift/StaticMirror/BinaryScanningTool.h"
// FIXME: Code duplication with StringUtils.cpp
namespace swift {
namespace c_string_utils {
swiftscan_string_ref_t create_null() {
swiftscan_string_ref_t str;
str.data = nullptr;
str.length = 0;
return str;
}
swiftscan_string_ref_t create_clone(const char *string) {
if (!string)
return create_null();
if (string[0] == '\0')
return create_null();
swiftscan_string_ref_t str;
str.data = strdup(string);
str.length = strlen(string);
return str;
}
swiftscan_string_set_t *create_set(const std::vector<std::string> &strings) {
swiftscan_string_set_t *set = new swiftscan_string_set_t;
set->count = strings.size();
set->strings = new swiftscan_string_ref_t[set->count];
for (unsigned SI = 0, SE = set->count; SI < SE; ++SI)
set->strings[SI] = create_clone(strings[SI].c_str());
return set;
}
} // namespace c_string_utils
} // namespace swift
using namespace swift::static_mirror;
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BinaryScanningTool, swift_static_mirror_t)
//=== Private Cleanup Functions -------------------------------------------===//
/// Free the given string.
void swift_static_mirror_string_dispose(
swift_static_mirror_string_ref_t string) {
if (string.data)
free(const_cast<void *>(string.data));
}
//=== Static Mirror Scan Functions ---------------------------------------===//
swift_static_mirror_t swift_static_mirror_create(int num_binaries,
const char **binary_paths,
const char *arch) {
// INITIALIZE_LLVM();
std::vector<std::string> inputBinaryPaths;
for (unsigned SI = 0, SE = num_binaries; SI < SE; ++SI)
inputBinaryPaths.push_back(binary_paths[SI]);
return wrap(new BinaryScanningTool(inputBinaryPaths, arch));
}
void swift_static_mirror_dispose(swift_static_mirror_t c_static_mirror) {
delete unwrap(c_static_mirror);
}
swift_static_mirror_conformances_set_t *
swift_static_mirror_conformances_set_create(swift_static_mirror_t static_mirror,
int num_protocols,
const char **protocol_names) {
std::vector<std::string> protocols;
for (unsigned SI = 0, SE = num_protocols; SI < SE; ++SI)
protocols.push_back(protocol_names[SI]);
BinaryScanningTool *scanTool = unwrap(static_mirror);
auto scanResult = scanTool->collectConformances(protocols);
// Bridge to the C interface
swift_static_mirror_conformances_set_t *conformanceSet =
new swift_static_mirror_conformances_set_t;
conformanceSet->count = scanResult.Conformances.size();
conformanceSet->conformances =
new swift_static_mirror_conformance_info_t[conformanceSet->count];
size_t idx = 0;
for (auto &conformance : scanResult.Conformances) {
swift_static_mirror_conformance_info_s *conformanceInfo =
new swift_static_mirror_conformance_info_s;
conformanceSet->conformances[idx] = conformanceInfo;
conformanceInfo->type_name =
swift::c_string_utils::create_clone(conformance.TypeName.c_str());
conformanceInfo->mangled_type_name = swift::c_string_utils::create_clone(
conformance.MangledTypeName.c_str());
conformanceInfo->protocol_name =
swift::c_string_utils::create_clone(conformance.ProtocolName.c_str());
idx += 1;
}
return conformanceSet;
}
swift_static_mirror_string_ref_t
swift_static_mirror_conformance_info_get_type_name(
swift_static_mirror_conformance_info_t info) {
return info->type_name;
}
swift_static_mirror_string_ref_t
swift_static_mirror_conformance_info_get_protocol_name(
swift_static_mirror_conformance_info_t info) {
return info->protocol_name;
}
swift_static_mirror_string_ref_t
swift_static_mirror_conformance_info_get_mangled_type_name(
swift_static_mirror_conformance_info_t info) {
return info->mangled_type_name;
}
void swift_static_mirror_conformance_info_dispose(
swift_static_mirror_conformance_info_t info) {
swift_static_mirror_conformance_info_s *info_impl = info;
swift_static_mirror_string_dispose(info_impl->type_name);
swift_static_mirror_string_dispose(info_impl->mangled_type_name);
swift_static_mirror_string_dispose(info_impl->protocol_name);
}
void swift_static_mirror_conformances_set_dispose(
swift_static_mirror_conformances_set_t *set) {
for (size_t i = 0; i < set->count; ++i) {
swift_static_mirror_conformance_info_dispose(set->conformances[i]);
}
delete[] set->conformances;
delete set;
}
static swift_static_mirror_associated_type_info_set_t *
convertAssociatedTypeQueryResult(
const swift::reflection::AssociatedTypeCollectionResult &scanResult) {
swift_static_mirror_associated_type_info_set_t *result =
new swift_static_mirror_associated_type_info_set_t;
result->count = scanResult.AssociatedTypeInfos.size();
result->associated_type_infos = new swift_static_mirror_associated_type_info_t
[scanResult.AssociatedTypeInfos.size()];
int associatedTypeInfoIndex = 0;
for (const auto &assocTypeInfo : scanResult.AssociatedTypeInfos) {
swift_static_mirror_associated_type_info_s *info =
new swift_static_mirror_associated_type_info_s;
info->mangled_type_name = swift::c_string_utils::create_clone(
assocTypeInfo.MangledTypeName.c_str());
info->type_alias_set = new swift_static_mirror_type_alias_set_t;
info->type_alias_set->count = assocTypeInfo.AssociatedTypes.size();
info->type_alias_set->type_aliases =
new swift_static_mirror_type_alias_t[assocTypeInfo.AssociatedTypes
.size()];
int typealiasIndex = 0;
for (const auto &typeAliasInfo : assocTypeInfo.AssociatedTypes) {
swift_static_mirror_type_alias_s *typeAliasDetails =
new swift_static_mirror_type_alias_s;
typeAliasDetails->type_alias_name = swift::c_string_utils::create_clone(
typeAliasInfo.SubstitutionInfo.TypeAliasName.c_str());
typeAliasDetails->substituted_type_name =
swift::c_string_utils::create_clone(
typeAliasInfo.SubstitutionInfo.SubstitutedTypeFullyQualifiedName.c_str());
typeAliasDetails->substituted_type_mangled_name =
swift::c_string_utils::create_clone(
typeAliasInfo.SubstitutionInfo.SubstitutedTypeMangledName.c_str());
// Opaque type's protocol conformance requirements
typeAliasDetails->opaque_protocol_requirements_set =
swift::c_string_utils::create_set(
typeAliasInfo.OpaqueTypeProtocolConformanceRequirements);
// Opaque type's same-type requirements
typeAliasDetails->opaque_same_type_requirements_set =
new swift_static_mirror_type_alias_set_t;
typeAliasDetails->opaque_same_type_requirements_set->count =
typeAliasInfo.OpaqueTypeSameTypeRequirements.size();
typeAliasDetails->opaque_same_type_requirements_set->type_aliases =
new swift_static_mirror_type_alias_t
[typeAliasInfo.OpaqueTypeSameTypeRequirements.size()];
int sameTypeReqIndex = 0;
for (const auto &sameTypeReq :
typeAliasInfo.OpaqueTypeSameTypeRequirements) {
swift_static_mirror_type_alias_s *sameTypeReqDetails =
new swift_static_mirror_type_alias_s;
sameTypeReqDetails->type_alias_name =
swift::c_string_utils::create_clone(
sameTypeReq.TypeAliasName.c_str());
sameTypeReqDetails->substituted_type_mangled_name =
swift::c_string_utils::create_clone(
sameTypeReq.SubstitutedTypeMangledName.c_str());
sameTypeReqDetails->substituted_type_name =
swift::c_string_utils::create_clone(
sameTypeReq.SubstitutedTypeFullyQualifiedName.c_str());
typeAliasDetails->opaque_same_type_requirements_set
->type_aliases[sameTypeReqIndex] = sameTypeReqDetails;
sameTypeReqIndex += 1;
}
info->type_alias_set->type_aliases[typealiasIndex] = typeAliasDetails;
typealiasIndex += 1;
}
result->associated_type_infos[associatedTypeInfoIndex] = info;
associatedTypeInfoIndex += 1;
}
return result;
}
static swift_static_mirror_field_info_set_t *convertFieldTypeQueryResult(
const swift::reflection::FieldTypeCollectionResult &scanResult) {
swift_static_mirror_field_info_set_t *result =
new swift_static_mirror_field_info_set_t;
result->count = scanResult.FieldInfos.size();
result->field_infos =
new swift_static_mirror_field_info_t[scanResult.FieldInfos.size()];
int fieldInfoIndex = 0;
for (const auto &fieldInfo : scanResult.FieldInfos) {
swift_static_mirror_field_info_s *info =
new swift_static_mirror_field_info_s;
info->mangled_type_name =
swift::c_string_utils::create_clone(fieldInfo.MangledTypeName.c_str());
info->property_set = new swift_static_mirror_property_info_set_t;
info->property_set->count = fieldInfo.Properties.size();
info->property_set->properties =
new swift_static_mirror_property_info_t[fieldInfo.Properties.size()];
info->enum_case_set = new swift_static_mirror_enum_case_info_set_t;
info->enum_case_set->count = fieldInfo.EnumCases.size();
info->enum_case_set->enum_cases =
new swift_static_mirror_enum_case_info_t[fieldInfo.EnumCases.size()];
int propertyIndex = 0;
for (const auto &propertyInfo : fieldInfo.Properties) {
swift_static_mirror_property_info_s *propertyDetails =
new swift_static_mirror_property_info_s;
propertyDetails->label =
swift::c_string_utils::create_clone(propertyInfo.Label.c_str());
propertyDetails->type_name = swift::c_string_utils::create_clone(
propertyInfo.TypeFullyQualifiedName.c_str());
propertyDetails->mangled_type_name = swift::c_string_utils::create_clone(
propertyInfo.TypeMangledName.c_str());
info->property_set->properties[propertyIndex] = propertyDetails;
propertyIndex += 1;
}
int enumCaseIndex = 0;
for (const auto &enumCaseInfo : fieldInfo.EnumCases) {
swift_static_mirror_enum_case_info_s *enumCaseDetails =
new swift_static_mirror_enum_case_info_s;
enumCaseDetails->label =
swift::c_string_utils::create_clone(enumCaseInfo.Label.c_str());
info->enum_case_set->enum_cases[enumCaseIndex] = enumCaseDetails;
enumCaseIndex += 1;
}
result->field_infos[fieldInfoIndex] = info;
fieldInfoIndex += 1;
}
return result;
}
swift_static_mirror_associated_type_info_set_t *
swift_static_mirror_associated_type_info_set_create(
swift_static_mirror_t static_mirror, const char *forTypeName) {
BinaryScanningTool *scanTool = unwrap(static_mirror);
auto scanResult = scanTool->collectAssociatedTypes(forTypeName);
return convertAssociatedTypeQueryResult(scanResult);
}
/// Identify and collect associated types of all discovered types.
swift_static_mirror_associated_type_info_set_t *
swift_static_mirror_all_associated_type_info_set_create(
swift_static_mirror_t static_mirror) {
BinaryScanningTool *scanTool = unwrap(static_mirror);
auto scanResult = scanTool->collectAllAssociatedTypes();
return convertAssociatedTypeQueryResult(scanResult);
}
// swift_static_mirror_associated_type query methods
swift_static_mirror_string_ref_t
swift_static_mirror_type_alias_get_type_alias_name(
swift_static_mirror_type_alias_t type_alias) {
return type_alias->type_alias_name;
}
swift_static_mirror_string_ref_t
swift_static_mirror_type_alias_get_substituted_type_name(
swift_static_mirror_type_alias_t type_alias) {
return type_alias->substituted_type_name;
}
swift_static_mirror_string_ref_t
swift_static_mirror_type_alias_get_substituted_type_mangled_name(
swift_static_mirror_type_alias_t type_alias) {
return type_alias->substituted_type_mangled_name;
}
swiftscan_string_set_t *
swift_static_mirror_type_alias_get_opaque_type_protocol_requirements(
swift_static_mirror_type_alias_t type_alias) {
return type_alias->opaque_protocol_requirements_set;
}
swift_static_mirror_type_alias_set_t *
swift_static_mirror_type_alias_get_opaque_type_same_type_requirements(
swift_static_mirror_type_alias_t type_alias) {
return type_alias->opaque_same_type_requirements_set;
}
// swift_static_mirror_associated_type_info query methods
swift_static_mirror_string_ref_t
swift_static_mirror_associated_type_info_get_mangled_type_name(
swift_static_mirror_associated_type_info_t associated_type_info) {
return associated_type_info->mangled_type_name;
}
swift_static_mirror_type_alias_set_t *
swift_static_mirror_associated_type_info_get_type_alias_set(
swift_static_mirror_associated_type_info_t associated_type_info) {
return associated_type_info->type_alias_set;
}
void swift_static_mirror_type_alias_dispose(
swift_static_mirror_type_alias_t type_alias) {
swift_static_mirror_string_dispose(type_alias->substituted_type_mangled_name);
swift_static_mirror_string_dispose(type_alias->substituted_type_name);
swift_static_mirror_string_dispose(type_alias->type_alias_name);
delete type_alias;
}
void swift_static_mirror_type_alias_set_dispose(
swift_static_mirror_type_alias_set_t *type_alias_set) {
for (size_t i = 0; i < type_alias_set->count; ++i) {
swift_static_mirror_type_alias_dispose(type_alias_set->type_aliases[i]);
}
delete[] type_alias_set->type_aliases;
delete type_alias_set;
}
void swift_static_mirror_associated_type_info_dispose(
swift_static_mirror_associated_type_info_t associated_type_info) {
swift_static_mirror_string_dispose(associated_type_info->mangled_type_name);
swift_static_mirror_type_alias_set_dispose(
associated_type_info->type_alias_set);
}
void swift_static_mirror_associated_type_info_set_dispose(
swift_static_mirror_associated_type_info_set_t *associated_type_info_set) {
for (size_t i = 0; i < associated_type_info_set->count; ++i) {
swift_static_mirror_associated_type_info_dispose(
associated_type_info_set->associated_type_infos[i]);
}
delete[] associated_type_info_set->associated_type_infos;
delete associated_type_info_set;
}
swift_static_mirror_string_ref_t
swift_static_mirror_field_info_get_mangled_type_name(
swift_static_mirror_field_info_t field_info) {
return field_info->mangled_type_name;
}
swift_static_mirror_property_info_set_t *
swift_static_mirror_field_info_get_property_info_set(
swift_static_mirror_field_info_t field_info) {
return field_info->property_set;
}
swift_static_mirror_enum_case_info_set_t *
swift_static_mirror_field_info_get_enum_case_info_set(
swift_static_mirror_field_info_t field_info) {
return field_info->enum_case_set;
}
swift_static_mirror_string_ref_t swift_static_mirror_property_info_get_label(
swift_static_mirror_property_info_t property_info) {
return property_info->label;
}
swift_static_mirror_string_ref_t
swift_static_mirror_property_info_get_type_name(
swift_static_mirror_property_info_t property_info) {
return property_info->type_name;
}
swift_static_mirror_string_ref_t
swift_static_mirror_property_info_get_mangled_type_name(
swift_static_mirror_property_info_t property_info) {
return property_info->mangled_type_name;
}
swift_static_mirror_string_ref_t swift_static_mirror_enum_case_info_get_label(
swift_static_mirror_enum_case_info_t enum_case_info) {
return enum_case_info->label;
}
swift_static_mirror_field_info_set_t *
swift_static_mirror_field_info_set_create(swift_static_mirror_t static_mirror,
const char *mangled_name) {
BinaryScanningTool *scanTool = unwrap(static_mirror);
auto scanResult = scanTool->collectFieldTypes(mangled_name);
return convertFieldTypeQueryResult(scanResult);
}
swift_static_mirror_field_info_set_t *
swift_static_mirror_all_field_info_set_create(
swift_static_mirror_t static_mirror) {
BinaryScanningTool *scanTool = unwrap(static_mirror);
auto scanResult = scanTool->collectAllFieldTypes();
return convertFieldTypeQueryResult(scanResult);
}
void swift_static_mirror_property_info_dispose(
swift_static_mirror_property_info_t property_info) {
swift_static_mirror_string_dispose(property_info->mangled_type_name);
swift_static_mirror_string_dispose(property_info->type_name);
swift_static_mirror_string_dispose(property_info->label);
delete property_info;
}
void swift_static_mirror_property_info_set_dispose(
swift_static_mirror_property_info_set_t *property_set) {
for (size_t i = 0; i < property_set->count; ++i) {
swift_static_mirror_property_info_dispose(property_set->properties[i]);
}
delete[] property_set->properties;
delete property_set;
}
void swift_static_mirror_enum_case_info_dispose(
swift_static_mirror_enum_case_info_t enum_case_info) {
swift_static_mirror_string_dispose(enum_case_info->label);
delete enum_case_info;
}
void swift_static_mirror_enum_case_info_set_dispose(
swift_static_mirror_enum_case_info_set_t *enum_case_set) {
for (size_t i = 0; i < enum_case_set->count; ++i) {
swift_static_mirror_enum_case_info_dispose(enum_case_set->enum_cases[i]);
}
delete[] enum_case_set->enum_cases;
delete enum_case_set;
}
void swift_static_mirror_field_info_dispose(
swift_static_mirror_field_info_t field_info) {
swift_static_mirror_string_dispose(field_info->mangled_type_name);
swift_static_mirror_property_info_set_dispose(field_info->property_set);
swift_static_mirror_enum_case_info_set_dispose(field_info->enum_case_set);
}
void swift_static_mirror_field_info_set_dispose(
swift_static_mirror_field_info_set_t *field_info_set) {
for (size_t i = 0; i < field_info_set->count; ++i) {
swift_static_mirror_field_info_dispose(field_info_set->field_infos[i]);
}
delete[] field_info_set->field_infos;
delete field_info_set;
}