Merge pull request #12433 from github/alexdenisov+redsun82/tuple-mangling

Swift: properly identify types and declarations in trap files via mangling
This commit is contained in:
Paolo Tranquilli 2023-08-03 13:27:07 +02:00 коммит произвёл GitHub
Родитель 48048d6f38 0dafe2d757
Коммит 67cd25184a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
23 изменённых файлов: 767 добавлений и 186 удалений

Просмотреть файл

@ -14,7 +14,6 @@
#include "swift/extractor/infra/file/Path.h"
#include "swift/extractor/infra/SwiftLocationExtractor.h"
#include "swift/extractor/infra/SwiftBodyEmissionStrategy.h"
#include "swift/extractor/mangler/SwiftMangler.h"
#include "swift/logging/SwiftAssert.h"
using namespace codeql;
@ -49,24 +48,20 @@ static void archiveFile(const SwiftExtractorConfiguration& config, swift::Source
}
}
// TODO: This should be factored out/replaced with simplified version of custom mangling
static std::string mangledDeclName(const swift::ValueDecl& decl) {
std::string_view moduleName = decl.getModuleContext()->getRealName().str();
// ASTMangler::mangleAnyDecl crashes when called on `ModuleDecl`
if (decl.getKind() == swift::DeclKind::Module) {
return std::string{moduleName};
static std::string mangledDeclName(const swift::Decl& decl) {
// SwiftRecursiveMangler mangled name cannot be used directly as it can be too long for file names
// so we build some minimal human readable info for debuggability and append a hash
auto ret = decl.getModuleContext()->getRealName().str().str();
ret += '/';
ret += swift::Decl::getKindName(decl.getKind());
ret += '_';
if (auto valueDecl = llvm::dyn_cast<swift::ValueDecl>(&decl); valueDecl && valueDecl->hasName()) {
ret += valueDecl->getBaseName().userFacingName();
ret += '_';
}
swift::Mangle::ASTMangler mangler;
if (decl.getKind() == swift::DeclKind::TypeAlias) {
// In cases like this (when coming from PCM)
// typealias CFXMLTree = CFTree
// typealias CFXMLTreeRef = CFXMLTree
// mangleAnyDecl mangles both CFXMLTree and CFXMLTreeRef into 'So12CFXMLTreeRefa'
// which is not correct and causes inconsistencies. mangleEntity makes these two distinct
// prefix adds a couple of special symbols, we don't necessary need them
return mangler.mangleEntity(&decl);
}
return mangler.mangleAnyDecl(&decl, /* prefix = */ false);
SwiftRecursiveMangler mangler;
ret += mangler.mangleDecl(decl).hash();
return ret;
}
static fs::path getFilename(swift::ModuleDecl& module,
@ -76,20 +71,7 @@ static fs::path getFilename(swift::ModuleDecl& module,
return resolvePath(primaryFile->getFilename());
}
if (lazyDeclaration) {
// this code will be thrown away in the near future
auto decl = llvm::dyn_cast<swift::ValueDecl>(lazyDeclaration);
CODEQL_ASSERT(decl, "not a ValueDecl");
auto mangled = mangledDeclName(*decl);
// mangled name can be too long to use as a file name, so we can't use it directly
mangled = picosha2::hash256_hex_string(mangled);
std::string ret;
ret += module.getRealName().str();
ret += '_';
ret += decl->getBaseName().userFacingName();
ret += '_';
// half a SHA2 is enough
ret += std::string_view(mangled).substr(0, mangled.size() / 2);
return ret;
return mangledDeclName(*lazyDeclaration);
}
// PCM clang module
if (module.isNonSwiftModule()) {

Просмотреть файл

@ -11,5 +11,6 @@ swift_cc_library(
"//swift/extractor/trap",
"//swift/logging",
"//swift/third_party/swift-llvm-support",
"@picosha2",
],
)

Просмотреть файл

@ -25,8 +25,8 @@ void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sour
entry.file = fetchFileLabel(file);
std::tie(entry.start_line, entry.start_column) = sourceManager.getLineAndColumnInBuffer(start);
std::tie(entry.end_line, entry.end_column) = sourceManager.getLineAndColumnInBuffer(end);
SwiftMangledName locName{{"loc", entry.file, ":", entry.start_line, ":", entry.start_column, ":",
entry.end_line, ":", entry.end_column}};
SwiftMangledName locName{"loc", entry.file, ':', entry.start_line, ':', entry.start_column,
':', entry.end_line, ':', entry.end_column};
entry.id = trap.createTypedLabel<DbLocationTag>(locName);
trap.emit(entry);
trap.emit(LocatableLocationsTrap{locatableLabel, entry.id});
@ -99,7 +99,7 @@ TrapLabel<FileTag> SwiftLocationExtractor::fetchFileLabel(const std::filesystem:
}
DbFile entry({});
entry.id = trap.createTypedLabel<DbFileTag>({{"file_", file.string()}});
entry.id = trap.createTypedLabel<DbFileTag>({"file_", file.string()});
entry.name = file.string();
trap.emit(entry);
store[file] = entry.id;

Просмотреть файл

@ -1,29 +1,25 @@
#include "swift/extractor/infra/SwiftMangledName.h"
#include "absl/strings/str_cat.h"
#include <picosha2.h>
namespace codeql {
namespace {
void appendPart(std::string& out, const std::string& prefix) {
out += prefix;
std::string SwiftMangledName::hash() const {
auto ret = picosha2::hash256_hex_string(value);
// half a hash is already enough for disambuiguation
ret.resize(ret.size() / 2);
return ret;
}
void appendPart(std::string& out, UntypedTrapLabel label) {
absl::StrAppend(&out, "{", label.str(), "}");
SwiftMangledName& SwiftMangledName::operator<<(UntypedTrapLabel label) & {
absl::StrAppend(&value, "{", label.str(), "}");
return *this;
}
void appendPart(std::string& out, unsigned index) {
absl::StrAppend(&out, index);
}
} // namespace
std::string SwiftMangledName::str() const {
std::string out;
for (const auto& part : parts) {
std::visit([&](const auto& contents) { appendPart(out, contents); }, part);
}
return out;
SwiftMangledName& SwiftMangledName::operator<<(unsigned int i) & {
absl::StrAppend(&value, i);
return *this;
}
} // namespace codeql

Просмотреть файл

@ -9,37 +9,52 @@
namespace codeql {
struct SwiftMangledName {
class SwiftMangledName {
public:
using Part = std::variant<UntypedTrapLabel, std::string, unsigned>;
std::vector<Part> parts;
explicit operator bool() const { return !value.empty(); }
explicit operator bool() const { return !parts.empty(); }
const std::string& str() const { return value; }
operator std::string_view() const { return value; }
std::string str() const;
std::string hash() const;
// streaming labels or ints into a SwiftMangledName just appends them
template <typename Tag>
SwiftMangledName& operator<<(TrapLabel<Tag> label) {
parts.emplace_back(label);
return *this;
// let's avoid copying as long as we don't need it
SwiftMangledName() = default;
SwiftMangledName(const SwiftMangledName&) = delete;
SwiftMangledName& operator=(const SwiftMangledName&) = delete;
SwiftMangledName(SwiftMangledName&&) = default;
SwiftMangledName& operator=(SwiftMangledName&&) = default;
template <typename... Args>
SwiftMangledName(Args&&... args) {
(operator<<(std::forward<Args>(args)), ...);
}
SwiftMangledName& operator<<(unsigned i) {
parts.emplace_back(i);
return *this;
SwiftMangledName& operator<<(UntypedTrapLabel label) &;
SwiftMangledName& operator<<(unsigned i) &;
template <typename Tag>
SwiftMangledName& operator<<(TrapLabel<Tag> label) & {
return operator<<(static_cast<UntypedTrapLabel>(label));
}
// streaming string-like stuff will add a new part it only if strictly required, otherwise it will
// append to the last part if it is a string
template <typename T>
SwiftMangledName& operator<<(T&& arg) {
if (parts.empty() || !std::holds_alternative<std::string>(parts.back())) {
parts.emplace_back("");
}
std::get<std::string>(parts.back()) += std::forward<T>(arg);
SwiftMangledName& operator<<(T&& arg) & {
value += arg;
return *this;
}
template <typename T>
SwiftMangledName&& operator<<(T&& arg) && {
return std::move(operator<<(std::forward<T>(arg)));
}
private:
std::string value;
};
} // namespace codeql

Просмотреть файл

@ -1,89 +1,403 @@
#include "swift/extractor/mangler/SwiftMangler.h"
#include "swift/extractor/infra/SwiftDispatcher.h"
#include "swift/extractor/trap/generated/decl/TrapClasses.h"
#include "swift/logging/SwiftLogging.h"
#include <swift/AST/Module.h>
#include <swift/AST/ParameterList.h>
#include <swift/AST/ASTContext.h>
#include <swift/AST/GenericParamList.h>
#include <sstream>
using namespace codeql;
namespace {
SwiftMangledName initMangled(const swift::TypeBase* type) {
Logger& logger() {
static Logger ret{"mangler"};
return ret;
}
const swift::Decl* getParent(const swift::Decl* decl) {
auto context = decl->getDeclContext();
if (context->getContextKind() == swift::DeclContextKind::FileUnit) {
return decl->getModuleContext();
}
return context->getAsDecl();
}
std::string_view getTypeKindStr(const swift::TypeBase* type) {
switch (type->getKind()) {
#define TYPE(ID, PARENT) \
case swift::TypeKind::ID: \
return {{#ID "Type_"}};
return #ID "Type";
#include <swift/AST/TypeNodes.def>
default:
return {};
}
}
SwiftMangledName initMangled(const swift::Decl* decl) {
SwiftMangledName ret;
ret << swift::Decl::getKindName(decl->getKind()) << "Decl_";
return ret;
}
} // namespace
SwiftMangledName SwiftMangler::initMangled(const swift::TypeBase* type) {
return {getTypeKindStr(type), '_'};
}
SwiftMangledName SwiftMangler::initMangled(const swift::Decl* decl) {
return {swift::Decl::getKindName(decl->getKind()), "Decl_", fetch(getParent(decl))};
}
SwiftMangledName SwiftMangler::mangleModuleName(std::string_view name) {
SwiftMangledName ret = {{"ModuleDecl_"}};
ret << name;
return ret;
return {"ModuleDecl_", name};
}
SwiftMangledName SwiftMangler::mangleDecl(const swift::Decl& decl) {
if (!llvm::isa<swift::ValueDecl>(decl)) {
return {};
}
// We do not deduplicate local variables, but for the moment also non-local vars from non-swift
// (PCM, clang modules) modules as the mangler crashes sometimes
if (decl.getKind() == swift::DeclKind::Var &&
(decl.getDeclContext()->isLocalContext() || decl.getModuleContext()->isNonSwiftModule())) {
return {};
}
// we do not deduplicate GenericTypeParamDecl, as their mangling is ambiguous in the presence of
// extensions
if (decl.getKind() == swift::DeclKind::GenericTypeParam) {
return {};
}
if (decl.getKind() == swift::DeclKind::Module) {
return mangleModuleName(llvm::cast<swift::ModuleDecl>(decl).getRealName().str());
}
auto ret = initMangled(&decl);
const auto& valueDecl = llvm::cast<swift::ValueDecl>(decl);
// stamp all declarations with an id-ref of the containing module
auto moduleLabel = dispatcher.fetchLabel(decl.getModuleContext());
ret << moduleLabel;
if (decl.getKind() == swift::DeclKind::TypeAlias) {
// In cases like this (when coming from PCM)
// typealias CFXMLTree = CFTree
// typealias CFXMLTreeRef = CFXMLTree
// mangleAnyDecl mangles both CFXMLTree and CFXMLTreeRef into 'So12CFXMLTreeRefa'
// which is not correct and causes inconsistencies. mangleEntity makes these two distinct
// prefix adds a couple of special symbols, we don't necessary need them
ret << mangler.mangleEntity(&valueDecl);
} else {
// prefix adds a couple of special symbols, we don't necessary need them
ret << mangler.mangleAnyDecl(&valueDecl, /* prefix = */ false);
}
return ret;
}
SwiftMangledName SwiftMangler::visitModuleType(const swift::ModuleType* type) {
auto ret = initMangled(type);
ret << type->getModule()->getRealName().str();
if (type->getModule()->isNonSwiftModule()) {
SwiftMangledName SwiftMangler::visitModuleDecl(const swift::ModuleDecl* decl) {
auto ret = mangleModuleName(decl->getRealName().str());
if (decl->isNonSwiftModule()) {
ret << "|clang";
}
return ret;
}
SwiftMangledName SwiftMangler::visitBuiltinType(const swift::BuiltinType* type) {
auto ret = initMangled(type);
llvm::SmallString<32> buffer;
ret << type->getTypeName(buffer, /* prependBuiltinNamespace= */ false);
SwiftMangledName SwiftMangler::visitValueDecl(const swift::ValueDecl* decl, bool force) {
if (!force && (!decl->hasName() || decl->getDeclContext()->isLocalContext())) {
return {};
}
auto ret = initMangled(decl);
std::string name;
llvm::raw_string_ostream oss{name};
decl->getName().print(oss);
ret << name;
if (decl->isStatic()) {
ret << "|static";
}
return ret;
}
SwiftMangledName SwiftMangler::visitTypeDiscriminatedValueDecl(const swift::ValueDecl* decl) {
if (auto ret = visitValueDecl(decl)) {
ret << fetch(decl->getInterfaceType()->getCanonicalType());
return ret;
}
return {};
}
SwiftMangledName SwiftMangler::visitAbstractFunctionDecl(const swift::AbstractFunctionDecl* decl) {
return visitTypeDiscriminatedValueDecl(decl);
}
SwiftMangledName SwiftMangler::visitSubscriptDecl(const swift::SubscriptDecl* decl) {
return visitTypeDiscriminatedValueDecl(decl);
}
SwiftMangledName SwiftMangler::visitVarDecl(const swift::VarDecl* decl) {
return visitTypeDiscriminatedValueDecl(decl);
}
SwiftMangledName SwiftMangler::visitExtensionDecl(const swift::ExtensionDecl* decl) {
if (decl->getDeclContext()->isLocalContext()) {
return {};
}
auto parent = getParent(decl);
return initMangled(decl) << fetch(parent) << getExtensionIndex(decl, parent);
}
unsigned SwiftMangler::getExtensionIndex(const swift::ExtensionDecl* decl,
const swift::Decl* parent) {
// to avoid iterating multiple times on the parent of multiple extensions, we preload extension
// indexes once for each encountered parent into the `preloadedExtensionIndexes` mapping.
// Because we mangle declarations only once in a given trap/dispatcher context, we can safely
// discard preloaded indexes on use
if (auto found = preloadedExtensionIndexes.extract(decl)) {
return found.mapped();
}
if (auto parentModule = llvm::dyn_cast<swift::ModuleDecl>(parent)) {
llvm::SmallVector<swift::Decl*> siblings;
parentModule->getTopLevelDecls(siblings);
indexExtensions(siblings);
} else if (auto iterableParent = llvm::dyn_cast<swift::IterableDeclContext>(parent)) {
indexExtensions(iterableParent->getAllMembers());
} else {
// TODO use a generic logging handle for Swift entities here, once it's available
CODEQL_ASSERT(false, "non-local context must be module or iterable decl context");
}
auto found = preloadedExtensionIndexes.extract(decl);
// TODO use a generic logging handle for Swift entities here, once it's available
CODEQL_ASSERT(found, "extension not found within parent");
return found.mapped();
}
void SwiftMangler::indexExtensions(llvm::ArrayRef<swift::Decl*> siblings) {
auto index = 0u;
for (auto sibling : siblings) {
if (sibling->getKind() == swift::DeclKind::Extension) {
preloadedExtensionIndexes.emplace(sibling, index);
}
++index;
}
}
SwiftMangledName SwiftMangler::visitGenericTypeParamDecl(const swift::GenericTypeParamDecl* decl) {
return visitValueDecl(decl, /*force=*/true) << '_' << decl->getDepth() << '_' << decl->getIndex();
}
SwiftMangledName SwiftMangler::visitAssociatedTypeDecl(const swift::AssociatedTypeDecl* decl) {
return visitValueDecl(decl, /*force=*/true);
}
SwiftMangledName SwiftMangler::visitModuleType(const swift::ModuleType* type) {
return initMangled(type) << fetch(type->getModule());
}
SwiftMangledName SwiftMangler::visitTupleType(const swift::TupleType* type) {
auto ret = initMangled(type);
for (const auto& element : type->getElements()) {
if (element.hasName()) {
ret << element.getName().str();
}
ret << fetch(element.getType());
}
return ret;
}
SwiftMangledName SwiftMangler::visitBuiltinType(const swift::BuiltinType* type) {
llvm::SmallString<32> buffer;
return initMangled(type) << type->getTypeName(buffer, /* prependBuiltinNamespace= */ false);
}
SwiftMangledName SwiftMangler::visitAnyGenericType(const swift::AnyGenericType* type) {
auto ret = initMangled(type);
auto decl = type->getDecl();
ret << fetch(decl);
if (auto parent = type->getParent()) {
ret << fetch(parent);
}
return ret;
}
SwiftMangledName SwiftMangler::visitType(const swift::TypeBase* type) {
LOG_WARNING("encountered {} for which we give no name", getTypeKindStr(type));
return {};
}
SwiftMangledName SwiftMangler::visitBoundGenericType(const swift::BoundGenericType* type) {
auto ret = visitAnyGenericType(type);
for (const auto param : type->getGenericArgs()) {
ret << fetch(param);
}
return ret;
}
SwiftMangledName SwiftMangler::visitAnyFunctionType(const swift::AnyFunctionType* type) {
auto ret = initMangled(type);
for (const auto& param : type->getParams()) {
ret << fetch(param.getPlainType());
if (param.isInOut()) {
ret << "_inout";
}
if (param.isOwned()) {
ret << "_owned";
}
if (param.isShared()) {
ret << "_shared";
}
if (param.isIsolated()) {
ret << "_isolated";
}
if (param.isVariadic()) {
ret << "...";
}
}
ret << "->" << fetch(type->getResult());
if (type->isAsync()) {
ret << "_async";
}
if (type->isThrowing()) {
ret << "_throws";
}
if (type->isSendable()) {
ret << "_sendable";
}
if (type->isNoEscape()) {
ret << "_noescape";
}
if (type->hasGlobalActor()) {
ret << "_actor" << fetch(type->getGlobalActor());
}
// TODO: see if this needs to be used in identifying types, if not it needs to be removed from
// type printing in the Swift compiler code
assert(type->hasExtInfo() && "type must have ext info");
auto info = type->getExtInfo();
auto convention = info.getSILRepresentation();
if (convention != swift::SILFunctionTypeRepresentation::Thick) {
ret << "_convention" << static_cast<unsigned>(convention);
}
return ret;
}
SwiftMangledName SwiftMangler::visitGenericFunctionType(const swift::GenericFunctionType* type) {
auto ret = visitAnyFunctionType(type);
ret << '<';
for (auto paramType : type->getGenericParams()) {
ret << fetch(paramType);
}
ret << '>';
if (!type->getRequirements().empty()) {
ret << "where_";
for (const auto& req : type->getRequirements()) {
ret << fetch(req.getFirstType().getPointer());
ret << (req.getKind() == swift::RequirementKind::SameType ? '=' : ':');
if (req.getKind() == swift::RequirementKind::Layout) {
ret << '(' << req.getLayoutConstraint().getString() << ')';
} else {
ret << fetch(req.getSecondType());
}
}
}
return ret;
}
SwiftMangledName SwiftMangler::visitGenericTypeParamType(const swift::GenericTypeParamType* type) {
auto ret = initMangled(type);
if (auto decl = type->getDecl()) {
ret << fetch(decl);
} else {
// type parameter is canonicalized to a depth/index coordinate
ret << type->getDepth() << '_' << type->getIndex();
}
return ret;
}
SwiftMangledName SwiftMangler::visitAnyMetatypeType(const swift::AnyMetatypeType* type) {
return initMangled(type) << fetch(type->getInstanceType());
}
SwiftMangledName SwiftMangler::visitDependentMemberType(const swift::DependentMemberType* type) {
return initMangled(type) << fetch(type->getBase()) << fetch(type->getAssocType());
}
SwiftMangledName SwiftMangler::visitInOutType(const swift::InOutType* type) {
return initMangled(type) << fetch(type->getObjectType());
}
SwiftMangledName SwiftMangler::visitExistentialType(const swift::ExistentialType* type) {
return initMangled(type) << fetch(type->getConstraintType());
}
SwiftMangledName SwiftMangler::visitUnarySyntaxSugarType(const swift::UnarySyntaxSugarType* type) {
return initMangled(type) << fetch(type->getBaseType());
}
SwiftMangledName SwiftMangler::visitDictionaryType(const swift::DictionaryType* type) {
return initMangled(type) << fetch(type->getKeyType()) << fetch(type->getValueType());
}
SwiftMangledName SwiftMangler::visitTypeAliasType(const swift::TypeAliasType* type) {
auto ret = initMangled(type);
ret << fetch(type->getDecl());
if (auto parent = type->getParent()) {
ret << fetch(parent);
}
ret << '<';
for (auto replacement : type->getSubstitutionMap().getReplacementTypes()) {
ret << fetch(replacement);
}
ret << '>';
return ret;
}
SwiftMangledName SwiftMangler::visitArchetypeType(const swift::ArchetypeType* type) {
auto ret = initMangled(type) << fetch(type->getInterfaceType());
if (const auto super = type->getSuperclass()) {
ret << ':' << fetch(super);
}
for (const auto* protocol : type->getConformsTo()) {
// Including the protocols in the mangled name allows us to distinguish the "same" type in
// different extensions, where it might have different constraints. Mangling the context (i.e.
// which ExtensionDecl or ValueDecl it's mentioned in) might be more robust, but there doesn't
// seem to be a clean way to get it.
ret << ':' << fetch(protocol);
}
return ret;
}
SwiftMangledName SwiftMangler::visitOpaqueTypeArchetypeType(
const swift::OpaqueTypeArchetypeType* type) {
return visitArchetypeType(type) << fetch(type->getDecl());
}
SwiftMangledName SwiftMangler::visitOpenedArchetypeType(const swift::OpenedArchetypeType* type) {
llvm::SmallVector<char> uuid;
type->getOpenedExistentialID().toString(uuid);
return visitArchetypeType(type) << std::string_view(uuid.data(), uuid.size());
}
SwiftMangledName SwiftMangler::visitProtocolCompositionType(
const swift::ProtocolCompositionType* type) {
auto ret = initMangled(type);
for (auto composed : type->getMembers()) {
ret << fetch(composed);
}
if (type->hasExplicitAnyObject()) {
ret << "&AnyObject";
}
return ret;
}
SwiftMangledName SwiftMangler::visitParenType(const swift::ParenType* type) {
return initMangled(type) << fetch(type->getUnderlyingType());
}
SwiftMangledName SwiftMangler::visitLValueType(const swift::LValueType* type) {
return initMangled(type) << fetch(type->getObjectType());
}
SwiftMangledName SwiftMangler::visitDynamicSelfType(const swift::DynamicSelfType* type) {
return initMangled(type) << fetch(type->getSelfType());
}
SwiftMangledName SwiftMangler::visitUnboundGenericType(const swift::UnboundGenericType* type) {
return initMangled(type) << fetch(type->getDecl());
}
SwiftMangledName SwiftMangler::visitReferenceStorageType(const swift::ReferenceStorageType* type) {
return initMangled(type) << fetch(type->getReferentType());
}
SwiftMangledName SwiftMangler::visitParametrizedProtocolType(
const swift::ParameterizedProtocolType* type) {
auto ret = initMangled(type);
ret << fetch(type->getBaseType());
ret << '<';
for (auto arg : type->getArgs()) {
ret << fetch(arg);
}
ret << '>';
return ret;
}
namespace {
template <typename E>
UntypedTrapLabel fetchLabel(SwiftDispatcher& dispatcher, const E* e) {
auto ret = dispatcher.fetchLabel(e);
// TODO use a generic logging handle for Swift entities here, once it's available
CODEQL_ASSERT(ret.valid(), "using an undefined label in mangling");
return ret;
}
} // namespace
SwiftMangledName SwiftTrapMangler::fetch(const swift::Decl* decl) {
return {fetchLabel(dispatcher, decl)};
}
SwiftMangledName SwiftTrapMangler::fetch(const swift::TypeBase* type) {
return {fetchLabel(dispatcher, type)};
}
SwiftMangledName SwiftRecursiveMangler::fetch(const swift::Decl* decl) {
return mangleDecl(*decl).hash();
}
SwiftMangledName SwiftRecursiveMangler::fetch(const swift::TypeBase* type) {
return mangleType(*type).hash();
}

Просмотреть файл

@ -11,39 +11,132 @@
#include "swift/extractor/infra/SwiftMangledName.h"
#include <optional>
#include <unordered_map>
namespace codeql {
class SwiftDispatcher;
class SwiftMangler : private swift::TypeVisitor<SwiftMangler, SwiftMangledName> {
// This class is tasked with assigning unique names to entities that need it (non-local
// declarations and types), to be used as trap keys.
// This uses the Template Method design pattern (or Non-Virtual Interface). The actual behavior
// when the identity depends on some other entity (like the parent of a declaration, or the
// declaration introducing a user type) depends on a private virtual fetch method. See below for
// the specific implementations.
//
// * all names are prefixed with the name of the entity class (for example `ParamDecl_`)
// * declarations usually use a fetch of their declaration context as first element, followed
// by whatever distinguishes them within that context (the name, or the signature for function)
// * user defined types have a name that is a simple wrapper around a fetch of their declaration
class SwiftMangler : private swift::TypeVisitor<SwiftMangler, SwiftMangledName>,
private swift::DeclVisitor<SwiftMangler, SwiftMangledName> {
using TypeVisitor = swift::TypeVisitor<SwiftMangler, SwiftMangledName>;
using DeclVisitor = swift::DeclVisitor<SwiftMangler, SwiftMangledName>;
public:
explicit SwiftMangler(SwiftDispatcher& dispatcher) : dispatcher(dispatcher) {}
virtual ~SwiftMangler() = default;
static SwiftMangledName mangleModuleName(std::string_view name);
// TODO actual visit
SwiftMangledName mangleDecl(const swift::Decl& decl);
SwiftMangledName mangleDecl(const swift::Decl& decl) {
return DeclVisitor::visit(const_cast<swift::Decl*>(&decl));
}
SwiftMangledName mangleType(const swift::TypeBase& type) {
return visit(const_cast<swift::TypeBase*>(&type));
return TypeVisitor::visit(const_cast<swift::TypeBase*>(&type));
}
private:
friend class swift::TypeVisitor<SwiftMangler, SwiftMangledName>;
friend TypeVisitor;
friend DeclVisitor;
// default fallback for not yet mangled types. This should never be called in normal situations
// will just spawn a random name
// TODO: make it assert once we mangle all types
static SwiftMangledName visitType(const swift::TypeBase* type) { return {}; }
// assign no name by default
static SwiftMangledName visitDecl(const swift::Decl* decl) { return {}; }
// current default, falling back to internal mangling
SwiftMangledName visitValueDecl(const swift::ValueDecl* decl, bool force = false);
SwiftMangledName visitModuleDecl(const swift::ModuleDecl* decl);
SwiftMangledName visitExtensionDecl(const swift::ExtensionDecl* decl);
SwiftMangledName visitAbstractFunctionDecl(const swift::AbstractFunctionDecl* decl);
SwiftMangledName visitSubscriptDecl(const swift::SubscriptDecl* decl);
SwiftMangledName visitVarDecl(const swift::VarDecl* decl);
SwiftMangledName visitGenericTypeParamDecl(const swift::GenericTypeParamDecl* decl);
SwiftMangledName visitAssociatedTypeDecl(const swift::AssociatedTypeDecl* decl);
// default fallback for non mangled types. This covers types that should not appear in normal
// successful extractor runs, like ErrorType
SwiftMangledName visitType(const swift::TypeBase* type);
SwiftMangledName visitModuleType(const swift::ModuleType* type);
SwiftMangledName visitTupleType(const swift::TupleType* type);
SwiftMangledName visitBuiltinType(const swift::BuiltinType* type);
SwiftMangledName visitAnyGenericType(const swift::AnyGenericType* type);
// shouldn't be required, but they forgot to link `NominalType` to its direct superclass
// in swift/AST/TypeNodes.def, so we need to chain the call manually
SwiftMangledName visitNominalType(const swift::NominalType* type) {
return visitAnyGenericType(type);
}
SwiftMangledName visitBoundGenericType(const swift::BoundGenericType* type);
SwiftMangledName visitAnyFunctionType(const swift::AnyFunctionType* type);
SwiftMangledName visitGenericFunctionType(const swift::GenericFunctionType* type);
SwiftMangledName visitGenericTypeParamType(const swift::GenericTypeParamType* type);
SwiftMangledName visitAnyMetatypeType(const swift::AnyMetatypeType* type);
SwiftMangledName visitDependentMemberType(const swift::DependentMemberType* type);
SwiftMangledName visitInOutType(const swift::InOutType* type);
SwiftMangledName visitExistentialType(const swift::ExistentialType* type);
SwiftMangledName visitUnarySyntaxSugarType(const swift::UnarySyntaxSugarType* type);
SwiftMangledName visitDictionaryType(const swift::DictionaryType* type);
SwiftMangledName visitTypeAliasType(const swift::TypeAliasType* type);
SwiftMangledName visitArchetypeType(const swift::ArchetypeType* type);
SwiftMangledName visitOpaqueTypeArchetypeType(const swift::OpaqueTypeArchetypeType* type);
SwiftMangledName visitOpenedArchetypeType(const swift::OpenedArchetypeType* type);
SwiftMangledName visitProtocolCompositionType(const swift::ProtocolCompositionType* type);
SwiftMangledName visitParenType(const swift::ParenType* type);
SwiftMangledName visitLValueType(const swift::LValueType* type);
SwiftMangledName visitDynamicSelfType(const swift::DynamicSelfType* type);
SwiftMangledName visitUnboundGenericType(const swift::UnboundGenericType* type);
SwiftMangledName visitReferenceStorageType(const swift::ReferenceStorageType* type);
SwiftMangledName visitParametrizedProtocolType(const swift::ParameterizedProtocolType* type);
private:
swift::Mangle::ASTMangler mangler;
std::unordered_map<const swift::Decl*, unsigned> preloadedExtensionIndexes;
virtual SwiftMangledName fetch(const swift::Decl* decl) = 0;
virtual SwiftMangledName fetch(const swift::TypeBase* type) = 0;
SwiftMangledName fetch(swift::Type type) { return fetch(type.getPointer()); }
void indexExtensions(llvm::ArrayRef<swift::Decl*> siblings);
unsigned int getExtensionIndex(const swift::ExtensionDecl* decl, const swift::Decl* parent);
static SwiftMangledName initMangled(const swift::TypeBase* type);
SwiftMangledName initMangled(const swift::Decl* decl);
SwiftMangledName visitTypeDiscriminatedValueDecl(const swift::ValueDecl* decl);
};
// This implementation is indented for use in defining trap keys. In this case fetching gives
// a [trap id-ref][1] is used, using the dispatcher to give us a label reference to that entity.
// Because that entity will also generally have a mangled name, it is important that this does not
// lead to any recursive loop (which is checked at runtime within the dispatcher).
//
// [1]: https://github.com/github/codeql-core/blob/main/wiki/extractors/trap.md#ids
class SwiftTrapMangler : public SwiftMangler {
public:
explicit SwiftTrapMangler(SwiftDispatcher& dispatcher) : dispatcher(dispatcher) {}
private:
SwiftMangledName fetch(const swift::Decl* decl) override;
SwiftMangledName fetch(const swift::TypeBase* type) override;
SwiftDispatcher& dispatcher;
};
// In this implementation, fetching gives a hash of the mangled name itself, leading to a direct
// recursion. This is intended for use in trap file names.
class SwiftRecursiveMangler : public SwiftMangler {
SwiftMangledName fetch(const swift::Decl* decl) override;
SwiftMangledName fetch(const swift::TypeBase* type) override;
};
} // namespace codeql

Просмотреть файл

@ -58,7 +58,7 @@ class SwiftVisitor : private SwiftDispatcher {
StmtTranslator stmtTranslator{*this};
TypeTranslator typeTranslator{*this};
PatternTranslator patternTranslator{*this};
SwiftMangler mangler{*this};
SwiftTrapMangler mangler{*this};
};
} // namespace codeql

Просмотреть файл

@ -40,6 +40,7 @@ class UntypedTrapLabel {
}
std::string str() const {
assert(valid() && "outputting an undefined label!");
std::string ret(strSize(), '\0');
ret[0] = '#';
std::to_chars(ret.data() + 1, ret.data() + ret.size(), id_, 16);

Просмотреть файл

@ -1,16 +1,93 @@
| Sources/deduplication/def.swift:1:1:1:9 | var ... = ... | PatternBindingDecl |
| Sources/deduplication/def.swift:1:5:1:5 | x | ConcreteVarDecl |
| Sources/deduplication/def.swift:3:1:3:20 | Generic | StructDecl |
| Sources/deduplication/def.swift:3:8:3:8 | Generic<T>.init() | Initializer |
| Sources/deduplication/def.swift:3:8:3:8 | self | ParamDecl |
| Sources/deduplication/def.swift:3:16:3:16 | T | GenericTypeParamDecl |
| Sources/deduplication/def.swift:5:1:5:41 | var ... = ... | PatternBindingDecl |
| Sources/deduplication/def.swift:5:5:5:5 | instantiated_generic | ConcreteVarDecl |
| Sources/deduplication/def.swift:7:1:7:42 | function(_:) | NamedFunction |
| Sources/deduplication/def.swift:7:15:7:18 | _ | ParamDecl |
| Sources/deduplication/use.swift:1:1:1:13 | var ... = ... | PatternBindingDecl |
| Sources/deduplication/use.swift:1:5:1:5 | use_x | ConcreteVarDecl |
| Sources/deduplication/use.swift:2:1:2:32 | var ... = ... | PatternBindingDecl |
| Sources/deduplication/use.swift:2:5:2:5 | use_instantiated_generic | ConcreteVarDecl |
| Sources/deduplication/use.swift:3:1:3:20 | var ... = ... | PatternBindingDecl |
| Sources/deduplication/use.swift:3:5:3:5 | use_function | ConcreteVarDecl |
| Sources/deduplication/def.swift:1:1:1:15 | var ... = ... | PatternBindingDecl | - |
| Sources/deduplication/def.swift:1:5:1:5 | def_int | ConcreteVarDecl | Int [StructType] |
| Sources/deduplication/def.swift:3:1:5:1 | Generic | StructDecl | Generic<T>.Type [MetatypeType] |
| Sources/deduplication/def.swift:3:8:3:8 | Generic<T>.init() | Initializer | <T> (Generic<T>.Type) -> () -> Generic<T> [GenericFunctionType] |
| Sources/deduplication/def.swift:3:8:3:8 | self | ParamDecl | Generic<T> [BoundGenericStructType] |
| Sources/deduplication/def.swift:3:16:3:16 | T | GenericTypeParamDecl | T.Type [MetatypeType] |
| Sources/deduplication/def.swift:4:5:4:70 | def_generic_method(t:u:v:) | NamedFunction | <T, U, V> (Generic<T>) -> (T, U, V) -> T [GenericFunctionType] |
| Sources/deduplication/def.swift:4:10:4:10 | self | ParamDecl | Generic<T> [BoundGenericStructType] |
| Sources/deduplication/def.swift:4:29:4:29 | U | GenericTypeParamDecl | U.Type [MetatypeType] |
| Sources/deduplication/def.swift:4:32:4:32 | V | GenericTypeParamDecl | V.Type [MetatypeType] |
| Sources/deduplication/def.swift:4:35:4:38 | t | ParamDecl | T [GenericTypeParamType] |
| Sources/deduplication/def.swift:4:41:4:44 | u | ParamDecl | U [GenericTypeParamType] |
| Sources/deduplication/def.swift:4:47:4:50 | v | ParamDecl | V [GenericTypeParamType] |
| Sources/deduplication/def.swift:7:1:7:45 | var ... = ... | PatternBindingDecl | - |
| Sources/deduplication/def.swift:7:5:7:5 | def_instantiated_generic | ConcreteVarDecl | Generic<Int> [BoundGenericStructType] |
| Sources/deduplication/def.swift:9:1:9:46 | def_function(_:) | NamedFunction | (Int) -> Int [FunctionType] |
| Sources/deduplication/def.swift:9:19:9:22 | _ | ParamDecl | Int [StructType] |
| Sources/deduplication/def.swift:11:1:11:77 | def_function_overloaded_on_return(_:_:) | NamedFunction | (Int, Double) -> Int [FunctionType] |
| Sources/deduplication/def.swift:11:40:11:43 | _ | ParamDecl | Int [StructType] |
| Sources/deduplication/def.swift:11:48:11:51 | _ | ParamDecl | Double [StructType] |
| Sources/deduplication/def.swift:12:1:12:82 | def_function_overloaded_on_return(_:_:) | NamedFunction | (Int, Double) -> Double [FunctionType] |
| Sources/deduplication/def.swift:12:40:12:43 | _ | ParamDecl | Int [StructType] |
| Sources/deduplication/def.swift:12:48:12:51 | _ | ParamDecl | Double [StructType] |
| Sources/deduplication/def.swift:14:1:14:57 | def_function_overloaded_on_parameter_type(_:) | NamedFunction | (Int) -> () [FunctionType] |
| Sources/deduplication/def.swift:14:48:14:51 | _ | ParamDecl | Int [StructType] |
| Sources/deduplication/def.swift:15:1:15:60 | def_function_overloaded_on_parameter_type(_:) | NamedFunction | (Double) -> () [FunctionType] |
| Sources/deduplication/def.swift:15:48:15:51 | _ | ParamDecl | Double [StructType] |
| Sources/deduplication/def.swift:17:1:17:62 | def_function_overloaded_on_parameter_label(one:) | NamedFunction | (Int) -> () [FunctionType] |
| Sources/deduplication/def.swift:17:49:17:56 | x | ParamDecl | Int [StructType] |
| Sources/deduplication/def.swift:18:1:18:62 | def_function_overloaded_on_parameter_label(two:) | NamedFunction | (Int) -> () [FunctionType] |
| Sources/deduplication/def.swift:18:49:18:56 | x | ParamDecl | Int [StructType] |
| Sources/deduplication/def.swift:20:1:20:44 | def_throwing_function(_:) | NamedFunction | (Int) throws -> () [FunctionType] |
| Sources/deduplication/def.swift:20:28:20:31 | _ | ParamDecl | Int [StructType] |
| Sources/deduplication/def.swift:21:1:21:60 | def_rethrowing_function(_:) | NamedFunction | (() throws -> ()) throws -> () [FunctionType] |
| Sources/deduplication/def.swift:21:30:21:47 | _ | ParamDecl | () throws -> () [FunctionType] |
| Sources/deduplication/def.swift:22:1:22:40 | def_async_function(_:) | NamedFunction | (Int) async -> () [FunctionType] |
| Sources/deduplication/def.swift:22:25:22:28 | _ | ParamDecl | Int [StructType] |
| Sources/deduplication/def.swift:23:1:23:56 | def_async_throwing_function(_:) | NamedFunction | (Int) async throws -> () [FunctionType] |
| Sources/deduplication/def.swift:23:34:23:37 | _ | ParamDecl | Int [StructType] |
| Sources/deduplication/def.swift:24:1:24:72 | def_async_rethrowing_function(_:) | NamedFunction | (() throws -> ()) async throws -> () [FunctionType] |
| Sources/deduplication/def.swift:24:36:24:53 | _ | ParamDecl | () throws -> () [FunctionType] |
| Sources/deduplication/def.swift:26:1:26:55 | def_generic_function(_:_:_:) | NamedFunction | <A, B, C> (A, B, C) -> () [GenericFunctionType] |
| Sources/deduplication/def.swift:26:27:26:27 | A | GenericTypeParamDecl | A.Type [MetatypeType] |
| Sources/deduplication/def.swift:26:30:26:30 | B | GenericTypeParamDecl | B.Type [MetatypeType] |
| Sources/deduplication/def.swift:26:33:26:33 | C | GenericTypeParamDecl | C.Type [MetatypeType] |
| Sources/deduplication/def.swift:26:36:26:39 | _ | ParamDecl | A [GenericTypeParamType] |
| Sources/deduplication/def.swift:26:42:26:45 | _ | ParamDecl | B [GenericTypeParamType] |
| Sources/deduplication/def.swift:26:48:26:51 | _ | ParamDecl | C [GenericTypeParamType] |
| Sources/deduplication/def.swift:28:1:28:21 | Protocol1 | ProtocolDecl | Protocol1.Protocol [MetatypeType] |
| Sources/deduplication/def.swift:29:1:31:1 | Protocol2 | ProtocolDecl | Protocol2.Protocol [MetatypeType] |
| Sources/deduplication/def.swift:30:5:30:20 | Associated | AssociatedTypeDecl | Self.Associated.Type [MetatypeType] |
| Sources/deduplication/def.swift:32:1:32:14 | Class | ClassDecl | Class.Type [MetatypeType] |
| Sources/deduplication/def.swift:32:7:32:7 | Class.deinit() | Deinitializer | (Class) -> () -> () [FunctionType] |
| Sources/deduplication/def.swift:32:7:32:7 | Class.init() | Initializer | (Class.Type) -> () -> Class [FunctionType] |
| Sources/deduplication/def.swift:32:7:32:7 | self | ParamDecl | Class [ClassType] |
| Sources/deduplication/def.swift:32:7:32:7 | self | ParamDecl | Class [ClassType] |
| Sources/deduplication/def.swift:34:1:34:128 | def_generic_function_with_conformance(_:_:_:) | NamedFunction | <A, B, C where A : Protocol1, A : Protocol2, B : Class, C == A.Associated> (A, B, C) -> () [GenericFunctionType] |
| Sources/deduplication/def.swift:34:44:34:60 | A | GenericTypeParamDecl | A.Type [MetatypeType] |
| Sources/deduplication/def.swift:34:71:34:75 | B | GenericTypeParamDecl | B.Type [MetatypeType] |
| Sources/deduplication/def.swift:34:82:34:82 | C | GenericTypeParamDecl | C.Type [MetatypeType] |
| Sources/deduplication/def.swift:34:85:34:88 | _ | ParamDecl | A [GenericTypeParamType] |
| Sources/deduplication/def.swift:34:91:34:94 | _ | ParamDecl | B [GenericTypeParamType] |
| Sources/deduplication/def.swift:34:97:34:100 | _ | ParamDecl | C [GenericTypeParamType] |
| Sources/deduplication/def.swift:36:1:36:18 | extension of Class | ExtensionDecl | - |
| Sources/deduplication/use.swift:1:1:1:15 | var ... = ... | PatternBindingDecl | - |
| Sources/deduplication/use.swift:1:5:1:5 | use_int | ConcreteVarDecl | Int [StructType] |
| Sources/deduplication/use.swift:2:1:2:32 | var ... = ... | PatternBindingDecl | - |
| Sources/deduplication/use.swift:2:5:2:5 | use_instantiated_generic | ConcreteVarDecl | Generic<Int> [BoundGenericStructType] |
| Sources/deduplication/use.swift:3:1:3:83 | var ... = ... | PatternBindingDecl | - |
| Sources/deduplication/use.swift:3:5:3:5 | answer | ConcreteVarDecl | Int [StructType] |
| Sources/deduplication/use.swift:4:1:4:20 | var ... = ... | PatternBindingDecl | - |
| Sources/deduplication/use.swift:4:5:4:5 | use_function | ConcreteVarDecl | (Int) -> Int [FunctionType] |
| Sources/deduplication/use.swift:5:1:5:66 | use_generic_function_type(_:_:_:) | NamedFunction | <AA, BB, CC> (AA, BB, CC) -> () [GenericFunctionType] |
| Sources/deduplication/use.swift:5:32:5:32 | AA | GenericTypeParamDecl | AA.Type [MetatypeType] |
| Sources/deduplication/use.swift:5:36:5:36 | BB | GenericTypeParamDecl | BB.Type [MetatypeType] |
| Sources/deduplication/use.swift:5:40:5:40 | CC | GenericTypeParamDecl | CC.Type [MetatypeType] |
| Sources/deduplication/use.swift:5:44:5:47 | _ | ParamDecl | AA [GenericTypeParamType] |
| Sources/deduplication/use.swift:5:51:5:54 | _ | ParamDecl | BB [GenericTypeParamType] |
| Sources/deduplication/use.swift:5:58:5:61 | _ | ParamDecl | CC [GenericTypeParamType] |
| Sources/deduplication/use.swift:6:1:6:45 | use_async_function_type(_:) | NamedFunction | (Int) async -> () [FunctionType] |
| Sources/deduplication/use.swift:6:30:6:33 | _ | ParamDecl | Int [StructType] |
| Sources/deduplication/use.swift:7:1:7:49 | use_throwing_function_type(_:) | NamedFunction | (Int) throws -> () [FunctionType] |
| Sources/deduplication/use.swift:7:33:7:36 | _ | ParamDecl | Int [StructType] |
| Sources/deduplication/use.swift:8:1:8:61 | use_async_throwing_function_type(_:) | NamedFunction | (Int) async throws -> () [FunctionType] |
| Sources/deduplication/use.swift:8:39:8:42 | _ | ParamDecl | Int [StructType] |
| Sources/deduplication/use.swift:9:1:9:150 | use_generic_function_with_conformance_type(_:_:_:) | NamedFunction | <AA, BB, CC where AA : Protocol1, AA : Protocol2, BB : Class, CC == AA.Associated> (AA, BB, CC) -> () [GenericFunctionType] |
| Sources/deduplication/use.swift:9:49:9:49 | AA | GenericTypeParamDecl | AA.Type [MetatypeType] |
| Sources/deduplication/use.swift:9:53:9:53 | BB | GenericTypeParamDecl | BB.Type [MetatypeType] |
| Sources/deduplication/use.swift:9:57:9:57 | CC | GenericTypeParamDecl | CC.Type [MetatypeType] |
| Sources/deduplication/use.swift:9:61:9:64 | _ | ParamDecl | AA [GenericTypeParamType] |
| Sources/deduplication/use.swift:9:68:9:71 | _ | ParamDecl | BB [GenericTypeParamType] |
| Sources/deduplication/use.swift:9:75:9:78 | _ | ParamDecl | CC [GenericTypeParamType] |
| Sources/deduplication/use.swift:11:1:11:18 | extension of Class | ExtensionDecl | - |

Просмотреть файл

@ -1,6 +1,15 @@
import swift
import Relevant
from Decl d
where relevant(d)
select d, d.getPrimaryQlClasses()
from Decl d, string type
where
relevant(d) and
(
not exists(d.(ValueDecl).getInterfaceType()) and type = "-"
or
exists(Type t |
t = d.(ValueDecl).getInterfaceType() and
type = t.toString() + " [" + t.getPrimaryQlClasses() + "]"
)
)
select d, d.getPrimaryQlClasses(), type

Просмотреть файл

@ -1,10 +1,13 @@
// swift-tools-version: 5.5
// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "deduplication",
platforms: [
.macOS(.v10_15),
],
products: [
.library(
name: "deduplication",

Просмотреть файл

@ -1,7 +1,36 @@
var x = 42
var def_int = 42
struct Generic<T> {}
struct Generic<T> {
func def_generic_method<U, V>(t: T, u: U, v: V) -> T { return t; }
}
var instantiated_generic = Generic<Int>()
var def_instantiated_generic = Generic<Int>()
func function(_: Int) -> Int { return 42 }
func def_function(_: Int) -> Int { return 42 }
func def_function_overloaded_on_return(_: Int, _: Double) -> Int { return 0 }
func def_function_overloaded_on_return(_: Int, _: Double) -> Double { return 0.0 }
func def_function_overloaded_on_parameter_type(_: Int) {}
func def_function_overloaded_on_parameter_type(_: Double) {}
func def_function_overloaded_on_parameter_label(one x: Int) {}
func def_function_overloaded_on_parameter_label(two x: Int) {}
func def_throwing_function(_: Int) throws {}
func def_rethrowing_function(_: () throws -> ()) rethrows {}
func def_async_function(_: Int) async {}
func def_async_throwing_function(_: Int) async throws {}
func def_async_rethrowing_function(_: () throws -> ()) async rethrows {}
func def_generic_function<A, B, C>(_: A, _: B, _: C) {}
protocol Protocol1 {}
protocol Protocol2 {
associatedtype Associated;
}
class Class {}
func def_generic_function_with_conformance<A : Protocol1 & Protocol2, B : Class, C>(_: A, _: B, _: C) where C == A.Associated {}
extension Class {}

Просмотреть файл

@ -1,3 +1,11 @@
let use_x = x
let use_instantiated_generic = instantiated_generic
let use_function = function
let use_int = def_int
let use_instantiated_generic = def_instantiated_generic
let answer = use_instantiated_generic.def_generic_method(t: 42, u: "hello", v: 0.0)
let use_function = def_function
func use_generic_function_type<AA, BB, CC>(_: AA, _: BB, _: CC) {}
func use_async_function_type(_: Int) async {}
func use_throwing_function_type(_: Int) throws {}
func use_async_throwing_function_type(_: Int) async throws {}
func use_generic_function_with_conformance_type<AA, BB, CC>(_: AA, _: BB, _: CC) where AA: Protocol1, AA: Protocol2, BB: Class, CC == AA.Associated {}
extension Class {}

Просмотреть файл

@ -1,10 +1,20 @@
| (Int) -> Int | FunctionType | function(_:) |
| (Int) -> Int | FunctionType | use_function |
| <T> (Generic<T>.Type) -> () -> Generic<T> | GenericFunctionType | Generic<T>.init() |
| Generic<Int> | BoundGenericStructType | instantiated_generic |
| Generic<Int> | BoundGenericStructType | use_instantiated_generic |
| Generic<T> | BoundGenericStructType | self |
| Generic<T>.Type | MetatypeType | Generic |
| Int | StructType | _, x |
| Int | StructType | use_x |
| T.Type | MetatypeType | T |
| (() throws -> ()) async throws -> () | FunctionType | def_async_rethrowing_function(_:) | |
| (() throws -> ()) throws -> () | FunctionType | def_rethrowing_function(_:) | |
| (Double) -> () | FunctionType | def_function_overloaded_on_parameter_type(_:) | |
| (Int) -> () | FunctionType | def_function_overloaded_on_parameter_label(one:), def_function_overloaded_on_parameter_label(two:), def_function_overloaded_on_parameter_type(_:) | |
| (Int) -> Int | FunctionType | def_function(_:), use_function | |
| (Int) async -> () | FunctionType | def_async_function(_:), use_async_function_type(_:) | |
| (Int) async throws -> () | FunctionType | def_async_throwing_function(_:), use_async_throwing_function_type(_:) | |
| (Int) throws -> () | FunctionType | def_throwing_function(_:), use_throwing_function_type(_:) | |
| (Int, Double) -> Double | FunctionType | def_function_overloaded_on_return(_:_:) | |
| (Int, Double) -> Int | FunctionType | def_function_overloaded_on_return(_:_:) | |
| <A, B, C where A : Protocol1, A : Protocol2, B : Class, C == A.Associated> (A, B, C) -> () | GenericFunctionType | def_generic_function_with_conformance(_:_:_:) | <\u03c4_0_0, \u03c4_0_1, \u03c4_0_2 where \u03c4_0_0 : Protocol1, \u03c4_0_0 : Protocol2, \u03c4_0_1 : Class, \u03c4_0_2 == \u03c4_0_0.Associated> (\u03c4_0_0, \u03c4_0_1, \u03c4_0_2) -> () |
| <A, B, C> (A, B, C) -> () | GenericFunctionType | def_generic_function(_:_:_:) | <\u03c4_0_0, \u03c4_0_1, \u03c4_0_2> (\u03c4_0_0, \u03c4_0_1, \u03c4_0_2) -> () |
| <AA, BB, CC where AA : Protocol1, AA : Protocol2, BB : Class, CC == AA.Associated> (AA, BB, CC) -> () | GenericFunctionType | use_generic_function_with_conformance_type(_:_:_:) | <\u03c4_0_0, \u03c4_0_1, \u03c4_0_2 where \u03c4_0_0 : Protocol1, \u03c4_0_0 : Protocol2, \u03c4_0_1 : Class, \u03c4_0_2 == \u03c4_0_0.Associated> (\u03c4_0_0, \u03c4_0_1, \u03c4_0_2) -> () |
| <AA, BB, CC> (AA, BB, CC) -> () | GenericFunctionType | use_generic_function_type(_:_:_:) | <\u03c4_0_0, \u03c4_0_1, \u03c4_0_2> (\u03c4_0_0, \u03c4_0_1, \u03c4_0_2) -> () |
| <T, U, V> (Generic<T>) -> (T, U, V) -> T | GenericFunctionType | def_generic_method(t:u:v:) | <\u03c4_0_0, \u03c4_1_0, \u03c4_1_1> (Generic<\u03c4_0_0>) -> (\u03c4_0_0, \u03c4_1_0, \u03c4_1_1) -> \u03c4_0_0 |
| <\u03c4_0_0, \u03c4_0_1, \u03c4_0_2 where \u03c4_0_0 : Protocol1, \u03c4_0_0 : Protocol2, \u03c4_0_1 : Class, \u03c4_0_2 == \u03c4_0_0.Associated> (\u03c4_0_0, \u03c4_0_1, \u03c4_0_2) -> () | GenericFunctionType | def_generic_function_with_conformance(_:_:_:), use_generic_function_with_conformance_type(_:_:_:) | |
| <\u03c4_0_0, \u03c4_0_1, \u03c4_0_2> (\u03c4_0_0, \u03c4_0_1, \u03c4_0_2) -> () | GenericFunctionType | def_generic_function(_:_:_:), use_generic_function_type(_:_:_:) | |
| <\u03c4_0_0, \u03c4_1_0, \u03c4_1_1> (Generic<\u03c4_0_0>) -> (\u03c4_0_0, \u03c4_1_0, \u03c4_1_1) -> \u03c4_0_0 | GenericFunctionType | def_generic_method(t:u:v:) | |
| Generic<Int> | BoundGenericStructType | def_instantiated_generic, use_instantiated_generic | |
| Int | StructType | def_int, use_int | |

Просмотреть файл

@ -1,7 +1,15 @@
import swift
import Relevant
from Type t, string decls
from Type t, string decls, string canonical
where
decls = strictconcat(ValueDecl d | relevant(d) and t = d.getInterfaceType() | d.toString(), ", ")
select t, t.getPrimaryQlClasses(), decls
decls =
strictconcat(ValueDecl d |
relevant(d) and
t = [d.getInterfaceType(), d.getInterfaceType().getCanonicalType()] and
d.toString().matches(["use_%", "def_%"])
|
d.toString(), ", "
) and
if t = t.getCanonicalType() then canonical = "" else canonical = t.getCanonicalType().toString()
select t, t.getPrimaryQlClasses(), decls, canonical

Просмотреть файл

@ -1,3 +0,0 @@
doubleIndexes
| method_lookups.swift:44:11:44:13 | [AutoClosureExpr] { ... } | 2 | getParam(0) | 4 | getParam(1) | file://:0:0:0:0 | [ParamDecl] argument |
| method_lookups.swift:44:11:44:13 | [AutoClosureExpr] { ... } | 4 | getParam(1) | 2 | getParam(0) | file://:0:0:0:0 | [ParamDecl] argument |

Просмотреть файл

@ -0,0 +1,12 @@
//codeql-extractor-options: -parse-stdlib
func foo(
_: Builtin.IntLiteral,
_: Builtin.FPIEEE32,
_: Builtin.FPIEEE64,
_: Builtin.BridgeObject,
_: Builtin.NativeObject,
_: Builtin.RawPointer,
_: Builtin.Executor,
_: Builtin.Job,
_: Builtin.RawUnsafeContinuation
) {}

Просмотреть файл

@ -1,3 +1,7 @@
| Base | getName: | Base | getCanonicalType: | Base | getInterfaceType: | Base | hasSuperclass: | no | getNumberOfProtocols: | 1 |
| Base | getName: | Base | getCanonicalType: | Base | getInterfaceType: | Base | hasSuperclass: | no | getNumberOfProtocols: | 1 |
| Base | getName: | Base | getCanonicalType: | Base | getInterfaceType: | Base | hasSuperclass: | yes | getNumberOfProtocols: | 0 |
| Base | getName: | Base | getCanonicalType: | Base | getInterfaceType: | Base | hasSuperclass: | yes | getNumberOfProtocols: | 0 |
| Param | getName: | Param | getCanonicalType: | Param | getInterfaceType: | Param | hasSuperclass: | no | getNumberOfProtocols: | 0 |
| ParamWithProtocols | getName: | ParamWithProtocols | getCanonicalType: | ParamWithProtocols | getInterfaceType: | ParamWithProtocols | hasSuperclass: | no | getNumberOfProtocols: | 2 |
| ParamWithSuperclass | getName: | ParamWithSuperclass | getCanonicalType: | ParamWithSuperclass | getInterfaceType: | ParamWithSuperclass | hasSuperclass: | yes | getNumberOfProtocols: | 0 |

Просмотреть файл

@ -1,4 +1,6 @@
| Base | 0 | primary_archetypes.swift:4:1:4:13 | P |
| Base | 0 | primary_archetypes.swift:5:1:5:14 | P2 |
| ParamWithProtocols | 0 | file://:0:0:0:0 | Equatable |
| ParamWithProtocols | 1 | primary_archetypes.swift:3:1:3:13 | P |
| ParamWithProtocols | 1 | primary_archetypes.swift:4:1:4:13 | P |
| ParamWithSuperclassAndProtocols | 0 | file://:0:0:0:0 | Equatable |
| ParamWithSuperclassAndProtocols | 1 | primary_archetypes.swift:3:1:3:13 | P |
| ParamWithSuperclassAndProtocols | 1 | primary_archetypes.swift:4:1:4:13 | P |

Просмотреть файл

@ -1,2 +1,4 @@
| Base | S |
| Base | S2 |
| ParamWithSuperclass | S |
| ParamWithSuperclassAndProtocols | S |

Просмотреть файл

@ -1,9 +1,25 @@
class S {}
class S2 {}
protocol P {}
protocol P2 {}
func foo<Param,
ParamWithSuperclass: S,
ParamWithProtocols: P & Equatable,
ParamWithSuperclassAndProtocols: S & Equatable & P>(
_: Param, _: ParamWithSuperclass, _: ParamWithProtocols, _: ParamWithSuperclassAndProtocols) {}
class Generic<Base> {}
extension Generic where Base : P {
func f(_: Base) {}
}
extension Generic where Base : P2 {
func f(_: Base) {}
}
extension Generic where Base : S {
func f(_: Base) {}
}
extension Generic where Base : S2 {
func f(_: Base) {}
}

Просмотреть файл

@ -0,0 +1,2 @@
//codeql-extractor-options: -parse-stdlib
func f(x : (Builtin.IntLiteral, Builtin.IntLiteral)) {}