mirror of
https://github.com/github/codeql.git
synced 2026-04-27 09:45:15 +02:00
Merge pull request #10175 from github/redsun82/swift-missing-extractions
Swift: fix missing extractions
This commit is contained in:
@@ -1121,6 +1121,8 @@ ModuleDecl:
|
||||
_extends: TypeDecl
|
||||
is_builtin_module: predicate
|
||||
is_system_module: predicate
|
||||
imported_modules: ModuleDecl*
|
||||
exported_modules: ModuleDecl*
|
||||
|
||||
ConstructorRefCallExpr:
|
||||
_extends: SelfApplyExpr
|
||||
|
||||
71
swift/extractor/SwiftBuiltinSymbols.h
Normal file
71
swift/extractor/SwiftBuiltinSymbols.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace codeql {
|
||||
constexpr std::array swiftBuiltins = {
|
||||
"zeroInitializer",
|
||||
"BridgeObject",
|
||||
"Word",
|
||||
"NativeObject",
|
||||
"RawPointer",
|
||||
"Executor",
|
||||
"Job",
|
||||
"RawUnsafeContinuation",
|
||||
"addressof",
|
||||
"initialize",
|
||||
"reinterpretCast",
|
||||
"Int1",
|
||||
"Int8",
|
||||
"Int16",
|
||||
"Int32",
|
||||
"Int64",
|
||||
"IntLiteral",
|
||||
"FPIEEE16",
|
||||
"FPIEEE32",
|
||||
"FPIEEE64",
|
||||
"FPIEEE80",
|
||||
"Vec2xInt8",
|
||||
"Vec4xInt8",
|
||||
"Vec8xInt8",
|
||||
"Vec16xInt8",
|
||||
"Vec32xInt8",
|
||||
"Vec64xInt8",
|
||||
"Vec2xInt16",
|
||||
"Vec4xInt16",
|
||||
"Vec8xInt16",
|
||||
"Vec16xInt16",
|
||||
"Vec32xInt16",
|
||||
"Vec64xInt16",
|
||||
"Vec2xInt32",
|
||||
"Vec4xInt32",
|
||||
"Vec8xInt32",
|
||||
"Vec16xInt32",
|
||||
"Vec32xInt32",
|
||||
"Vec64xInt32",
|
||||
"Vec2xInt64",
|
||||
"Vec4xInt64",
|
||||
"Vec8xInt64",
|
||||
"Vec16xInt64",
|
||||
"Vec32xInt64",
|
||||
"Vec64xInt64",
|
||||
"Vec2xFPIEEE16",
|
||||
"Vec4xFPIEEE16",
|
||||
"Vec8xFPIEEE16",
|
||||
"Vec16xFPIEEE16",
|
||||
"Vec32xFPIEEE16",
|
||||
"Vec64xFPIEEE16",
|
||||
"Vec2xFPIEEE32",
|
||||
"Vec4xFPIEEE32",
|
||||
"Vec8xFPIEEE32",
|
||||
"Vec16xFPIEEE32",
|
||||
"Vec32xFPIEEE32",
|
||||
"Vec64xFPIEEE32",
|
||||
"Vec2xFPIEEE64",
|
||||
"Vec4xFPIEEE64",
|
||||
"Vec8xFPIEEE64",
|
||||
"Vec16xFPIEEE64",
|
||||
"Vec32xFPIEEE64",
|
||||
"Vec64xFPIEEE64",
|
||||
};
|
||||
}
|
||||
@@ -6,15 +6,12 @@
|
||||
#include <queue>
|
||||
|
||||
#include <swift/AST/SourceFile.h>
|
||||
#include <swift/Basic/FileTypes.h>
|
||||
#include <llvm/ADT/SmallString.h>
|
||||
#include <llvm/Support/FileSystem.h>
|
||||
#include <llvm/Support/Path.h>
|
||||
#include <swift/AST/Builtins.h>
|
||||
|
||||
#include "swift/extractor/trap/generated/TrapClasses.h"
|
||||
#include "swift/extractor/trap/TrapDomain.h"
|
||||
#include "swift/extractor/visitors/SwiftVisitor.h"
|
||||
#include "swift/extractor/TargetTrapFile.h"
|
||||
#include "swift/extractor/SwiftBuiltinSymbols.h"
|
||||
|
||||
using namespace codeql;
|
||||
using namespace std::string_literals;
|
||||
@@ -65,7 +62,40 @@ static std::string getFilename(swift::ModuleDecl& module, swift::SourceFile* pri
|
||||
filename += module.getName().str();
|
||||
return filename;
|
||||
}
|
||||
return module.getModuleFilename().str();
|
||||
if (module.isBuiltinModule()) {
|
||||
// The Builtin module has an empty filename, let's fix that
|
||||
return "/__Builtin__";
|
||||
}
|
||||
auto filename = module.getModuleFilename().str();
|
||||
// there is a special case of a module without an actual filename reporting `<imports>`: in this
|
||||
// case we want to avoid the `<>` characters, in case a dirty DB is imported on Windows
|
||||
if (filename == "<imports>") {
|
||||
return "/__imports__";
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
/* The builtin module is special, as it does not publish any top-level declaration
|
||||
* It creates (and caches) declarations on demand when a lookup is carried out
|
||||
* (see BuiltinUnit in swift/AST/FileUnit.h for the cache details, and getBuiltinValueDecl in
|
||||
* swift/AST/Builtins.h for the creation details)
|
||||
* As we want to create the Builtin trap file once and for all so that it works for other
|
||||
* extraction runs, rather than collecting what we need we pre-populate the builtin trap with
|
||||
* what we expect. This list might need thus to be expanded.
|
||||
* Notice, that while swift/AST/Builtins.def has a list of builtin symbols, it does not contain
|
||||
* all information required to instantiate builtin variants.
|
||||
* Other possible approaches:
|
||||
* * create one trap per builtin declaration when encountered
|
||||
* * expand the list to all possible builtins (of which there are a lot)
|
||||
*/
|
||||
static void getBuiltinDecls(swift::ModuleDecl& builtinModule,
|
||||
llvm::SmallVector<swift::Decl*>& decls) {
|
||||
llvm::SmallVector<swift::ValueDecl*> values;
|
||||
for (auto symbol : swiftBuiltins) {
|
||||
builtinModule.lookupValue(builtinModule.getASTContext().getIdentifier(symbol),
|
||||
swift::NLKind::QualifiedLookup, values);
|
||||
}
|
||||
decls.insert(decls.end(), values.begin(), values.end());
|
||||
}
|
||||
|
||||
static llvm::SmallVector<swift::Decl*> getTopLevelDecls(swift::ModuleDecl& module,
|
||||
@@ -74,16 +104,19 @@ static llvm::SmallVector<swift::Decl*> getTopLevelDecls(swift::ModuleDecl& modul
|
||||
ret.push_back(&module);
|
||||
if (primaryFile) {
|
||||
primaryFile->getTopLevelDecls(ret);
|
||||
} else if (module.isBuiltinModule()) {
|
||||
getBuiltinDecls(module, ret);
|
||||
} else {
|
||||
module.getTopLevelDecls(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void extractDeclarations(const SwiftExtractorConfiguration& config,
|
||||
swift::CompilerInstance& compiler,
|
||||
swift::ModuleDecl& module,
|
||||
swift::SourceFile* primaryFile = nullptr) {
|
||||
static std::unordered_set<swift::ModuleDecl*> extractDeclarations(
|
||||
const SwiftExtractorConfiguration& config,
|
||||
swift::CompilerInstance& compiler,
|
||||
swift::ModuleDecl& module,
|
||||
swift::SourceFile* primaryFile = nullptr) {
|
||||
auto filename = getFilename(module, primaryFile);
|
||||
|
||||
// The extractor can be called several times from different processes with
|
||||
@@ -92,7 +125,7 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config,
|
||||
auto trapTarget = createTargetTrapFile(config, filename);
|
||||
if (!trapTarget) {
|
||||
// another process arrived first, nothing to do for us
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
TrapDomain trap{*trapTarget};
|
||||
|
||||
@@ -116,6 +149,7 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config,
|
||||
for (auto& comment : comments) {
|
||||
visitor.extract(comment);
|
||||
}
|
||||
return std::move(visitor).getEncounteredModules();
|
||||
}
|
||||
|
||||
static std::unordered_set<std::string> collectInputFilenames(swift::CompilerInstance& compiler) {
|
||||
@@ -132,40 +166,27 @@ static std::unordered_set<std::string> collectInputFilenames(swift::CompilerInst
|
||||
return sourceFiles;
|
||||
}
|
||||
|
||||
static std::unordered_set<swift::ModuleDecl*> collectModules(swift::CompilerInstance& compiler) {
|
||||
// getASTContext().getLoadedModules() does not provide all the modules available within the
|
||||
// program.
|
||||
// We need to iterate over all the imported modules (recursively) to see the whole "universe."
|
||||
std::unordered_set<swift::ModuleDecl*> allModules;
|
||||
std::queue<swift::ModuleDecl*> worklist;
|
||||
for (auto& [_, module] : compiler.getASTContext().getLoadedModules()) {
|
||||
worklist.push(module);
|
||||
allModules.insert(module);
|
||||
static std::vector<swift::ModuleDecl*> collectLoadedModules(swift::CompilerInstance& compiler) {
|
||||
std::vector<swift::ModuleDecl*> ret;
|
||||
for (const auto& [id, module] : compiler.getASTContext().getLoadedModules()) {
|
||||
std::ignore = id;
|
||||
ret.push_back(module);
|
||||
}
|
||||
|
||||
while (!worklist.empty()) {
|
||||
auto module = worklist.front();
|
||||
worklist.pop();
|
||||
llvm::SmallVector<swift::ImportedModule> importedModules;
|
||||
// TODO: we may need more than just Exported ones
|
||||
module->getImportedModules(importedModules, swift::ModuleDecl::ImportFilterKind::Exported);
|
||||
for (auto& imported : importedModules) {
|
||||
if (allModules.count(imported.importedModule) == 0) {
|
||||
worklist.push(imported.importedModule);
|
||||
allModules.insert(imported.importedModule);
|
||||
}
|
||||
}
|
||||
}
|
||||
return allModules;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config,
|
||||
swift::CompilerInstance& compiler) {
|
||||
auto inputFiles = collectInputFilenames(compiler);
|
||||
auto modules = collectModules(compiler);
|
||||
std::vector<swift::ModuleDecl*> todo = collectLoadedModules(compiler);
|
||||
std::unordered_set<swift::ModuleDecl*> seen{todo.begin(), todo.end()};
|
||||
|
||||
for (auto& module : modules) {
|
||||
while (!todo.empty()) {
|
||||
auto module = todo.back();
|
||||
todo.pop_back();
|
||||
llvm::errs() << "processing module " << module->getName() << '\n';
|
||||
bool isFromSourceFile = false;
|
||||
std::unordered_set<swift::ModuleDecl*> encounteredModules;
|
||||
for (auto file : module->getFiles()) {
|
||||
auto sourceFile = llvm::dyn_cast<swift::SourceFile>(file);
|
||||
if (!sourceFile) {
|
||||
@@ -176,10 +197,16 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config,
|
||||
continue;
|
||||
}
|
||||
archiveFile(config, *sourceFile);
|
||||
extractDeclarations(config, compiler, *module, sourceFile);
|
||||
encounteredModules = extractDeclarations(config, compiler, *module, sourceFile);
|
||||
}
|
||||
if (!isFromSourceFile) {
|
||||
extractDeclarations(config, compiler, *module);
|
||||
encounteredModules = extractDeclarations(config, compiler, *module);
|
||||
}
|
||||
for (auto encountered : encounteredModules) {
|
||||
if (seen.count(encountered) == 0) {
|
||||
todo.push_back(encountered);
|
||||
seen.insert(encountered);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,10 @@ class SwiftDispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
const std::unordered_set<swift::ModuleDecl*> getEncounteredModules() && {
|
||||
return std::move(encounteredModules);
|
||||
}
|
||||
|
||||
template <typename Entry>
|
||||
void emit(const Entry& entry) {
|
||||
trap.emit(entry);
|
||||
@@ -228,8 +232,16 @@ class SwiftDispatcher {
|
||||
// - extracting a primary source file: in this mode, we extract several files belonging to the
|
||||
// same module one by one. In this mode, we restrict emission only to the same file ignoring
|
||||
// all the other files.
|
||||
// This is also used to register the modules we encounter.
|
||||
// TODO calls to this function should be taken away from `DeclVisitor` and moved around with a
|
||||
// clearer separation between naming entities (some decls, all types), deciding whether to emit
|
||||
// them and finally visiting emitting the contents of the entity (which should remain in the
|
||||
// visitors). Then this double responsibility (carrying out the test and registering encountered
|
||||
// modules) should also be cleared out
|
||||
bool shouldEmitDeclBody(const swift::Decl& decl) {
|
||||
if (decl.getModuleContext() != ¤tModule) {
|
||||
auto module = decl.getModuleContext();
|
||||
if (module != ¤tModule) {
|
||||
encounteredModules.insert(module);
|
||||
return false;
|
||||
}
|
||||
// ModuleDecl is a special case: if it passed the previous test, it is the current module
|
||||
@@ -333,6 +345,7 @@ class SwiftDispatcher {
|
||||
Store::Handle waitingForNewLabel{std::monostate{}};
|
||||
swift::ModuleDecl& currentModule;
|
||||
swift::SourceFile* currentPrimarySourceFile;
|
||||
std::unordered_set<swift::ModuleDecl*> encounteredModules;
|
||||
};
|
||||
|
||||
} // namespace codeql
|
||||
|
||||
@@ -22,31 +22,31 @@ std::string constructName(const swift::DeclName& declName) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::variant<codeql::ConcreteFuncDecl, codeql::ConcreteFuncDeclsTrap>
|
||||
DeclVisitor::translateFuncDecl(const swift::FuncDecl& decl) {
|
||||
auto ret = createNamedEntryOr<ConcreteFuncDeclsTrap>(decl);
|
||||
if (auto entry = get_if<ConcreteFuncDecl>(&ret)) {
|
||||
std::optional<codeql::ConcreteFuncDecl> DeclVisitor::translateFuncDecl(
|
||||
const swift::FuncDecl& decl) {
|
||||
if (auto entry = createNamedEntry(decl)) {
|
||||
fillAbstractFunctionDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
return ret;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::variant<codeql::ConstructorDecl, codeql::ConstructorDeclsTrap>
|
||||
DeclVisitor::translateConstructorDecl(const swift::ConstructorDecl& decl) {
|
||||
auto ret = createNamedEntryOr<ConstructorDeclsTrap>(decl);
|
||||
if (auto entry = get_if<ConstructorDecl>(&ret)) {
|
||||
std::optional<codeql::ConstructorDecl> DeclVisitor::translateConstructorDecl(
|
||||
const swift::ConstructorDecl& decl) {
|
||||
if (auto entry = createNamedEntry(decl)) {
|
||||
fillAbstractFunctionDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
return ret;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::variant<codeql::DestructorDecl, codeql::DestructorDeclsTrap>
|
||||
DeclVisitor::translateDestructorDecl(const swift::DestructorDecl& decl) {
|
||||
auto ret = createNamedEntryOr<DestructorDeclsTrap>(decl);
|
||||
if (auto entry = get_if<DestructorDecl>(&ret)) {
|
||||
std::optional<codeql::DestructorDecl> DeclVisitor::translateDestructorDecl(
|
||||
const swift::DestructorDecl& decl) {
|
||||
if (auto entry = createNamedEntry(decl)) {
|
||||
fillAbstractFunctionDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
return ret;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
codeql::PrefixOperatorDecl DeclVisitor::translatePrefixOperatorDecl(
|
||||
@@ -124,40 +124,37 @@ std::optional<codeql::ConcreteVarDecl> DeclVisitor::translateVarDecl(const swift
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::StructDecl, codeql::StructDeclsTrap> DeclVisitor::translateStructDecl(
|
||||
const swift::StructDecl& decl) {
|
||||
auto ret = createNamedEntryOr<StructDeclsTrap>(decl);
|
||||
if (auto entry = get_if<StructDecl>(&ret)) {
|
||||
std::optional<codeql::StructDecl> DeclVisitor::translateStructDecl(const swift::StructDecl& decl) {
|
||||
if (auto entry = createNamedEntry(decl)) {
|
||||
fillNominalTypeDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
return ret;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::variant<codeql::ClassDecl, codeql::ClassDeclsTrap> DeclVisitor::translateClassDecl(
|
||||
const swift::ClassDecl& decl) {
|
||||
auto ret = createNamedEntryOr<ClassDeclsTrap>(decl);
|
||||
if (auto entry = get_if<ClassDecl>(&ret)) {
|
||||
std::optional<codeql::ClassDecl> DeclVisitor::translateClassDecl(const swift::ClassDecl& decl) {
|
||||
if (auto entry = createNamedEntry(decl)) {
|
||||
fillNominalTypeDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
return ret;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::variant<codeql::EnumDecl, codeql::EnumDeclsTrap> DeclVisitor::translateEnumDecl(
|
||||
const swift::EnumDecl& decl) {
|
||||
auto ret = createNamedEntryOr<EnumDeclsTrap>(decl);
|
||||
if (auto entry = get_if<EnumDecl>(&ret)) {
|
||||
std::optional<codeql::EnumDecl> DeclVisitor::translateEnumDecl(const swift::EnumDecl& decl) {
|
||||
if (auto entry = createNamedEntry(decl)) {
|
||||
fillNominalTypeDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
return ret;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::variant<codeql::ProtocolDecl, codeql::ProtocolDeclsTrap> DeclVisitor::translateProtocolDecl(
|
||||
std::optional<codeql::ProtocolDecl> DeclVisitor::translateProtocolDecl(
|
||||
const swift::ProtocolDecl& decl) {
|
||||
auto ret = createNamedEntryOr<ProtocolDeclsTrap>(decl);
|
||||
if (auto entry = get_if<ProtocolDecl>(&ret)) {
|
||||
if (auto entry = createNamedEntry(decl)) {
|
||||
fillNominalTypeDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
return ret;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
codeql::EnumCaseDecl DeclVisitor::translateEnumCaseDecl(const swift::EnumCaseDecl& decl) {
|
||||
@@ -166,17 +163,18 @@ codeql::EnumCaseDecl DeclVisitor::translateEnumCaseDecl(const swift::EnumCaseDec
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::EnumElementDecl, codeql::EnumElementDeclsTrap>
|
||||
DeclVisitor::translateEnumElementDecl(const swift::EnumElementDecl& decl) {
|
||||
auto ret = createNamedEntryOr<EnumElementDeclsTrap>(decl);
|
||||
std::visit([&](auto& entry) { entry.name = decl.getNameStr().str(); }, ret);
|
||||
if (auto entry = get_if<EnumElementDecl>(&ret)) {
|
||||
if (decl.hasParameterList()) {
|
||||
entry->params = dispatcher_.fetchRepeatedLabels(*decl.getParameterList());
|
||||
}
|
||||
fillValueDecl(decl, *entry);
|
||||
std::optional<codeql::EnumElementDecl> DeclVisitor::translateEnumElementDecl(
|
||||
const swift::EnumElementDecl& decl) {
|
||||
auto entry = createNamedEntry(decl);
|
||||
if (!entry) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return ret;
|
||||
entry->name = decl.getNameStr().str();
|
||||
if (decl.hasParameterList()) {
|
||||
entry->params = dispatcher_.fetchRepeatedLabels(*decl.getParameterList());
|
||||
}
|
||||
fillValueDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
codeql::GenericTypeParamDecl DeclVisitor::translateGenericTypeParamDecl(
|
||||
@@ -187,45 +185,46 @@ codeql::GenericTypeParamDecl DeclVisitor::translateGenericTypeParamDecl(
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::variant<codeql::AssociatedTypeDecl, codeql::AssociatedTypeDeclsTrap>
|
||||
DeclVisitor::translateAssociatedTypeDecl(const swift::AssociatedTypeDecl& decl) {
|
||||
auto ret = createNamedEntryOr<AssociatedTypeDeclsTrap>(decl);
|
||||
if (auto entry = get_if<AssociatedTypeDecl>(&ret)) {
|
||||
std::optional<codeql::AssociatedTypeDecl> DeclVisitor::translateAssociatedTypeDecl(
|
||||
const swift::AssociatedTypeDecl& decl) {
|
||||
if (auto entry = createNamedEntry(decl)) {
|
||||
fillTypeDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
return ret;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::variant<codeql::TypeAliasDecl, codeql::TypeAliasDeclsTrap> DeclVisitor::translateTypeAliasDecl(
|
||||
std::optional<codeql::TypeAliasDecl> DeclVisitor::translateTypeAliasDecl(
|
||||
const swift::TypeAliasDecl& decl) {
|
||||
auto ret = createNamedEntryOr<TypeAliasDeclsTrap>(decl);
|
||||
if (auto entry = get_if<TypeAliasDecl>(&ret)) {
|
||||
if (auto entry = createNamedEntry(decl)) {
|
||||
fillTypeDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
return ret;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::variant<codeql::AccessorDecl, codeql::AccessorDeclsTrap> DeclVisitor::translateAccessorDecl(
|
||||
std::optional<codeql::AccessorDecl> DeclVisitor::translateAccessorDecl(
|
||||
const swift::AccessorDecl& decl) {
|
||||
auto ret = createNamedEntryOr<AccessorDeclsTrap>(decl);
|
||||
if (auto entry = get_if<AccessorDecl>(&ret)) {
|
||||
switch (decl.getAccessorKind()) {
|
||||
case swift::AccessorKind::Get:
|
||||
entry->is_getter = true;
|
||||
break;
|
||||
case swift::AccessorKind::Set:
|
||||
entry->is_setter = true;
|
||||
break;
|
||||
case swift::AccessorKind::WillSet:
|
||||
entry->is_will_set = true;
|
||||
break;
|
||||
case swift::AccessorKind::DidSet:
|
||||
entry->is_did_set = true;
|
||||
break;
|
||||
}
|
||||
fillAbstractFunctionDecl(decl, *entry);
|
||||
auto entry = createNamedEntry(decl);
|
||||
if (!entry) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return ret;
|
||||
switch (decl.getAccessorKind()) {
|
||||
case swift::AccessorKind::Get:
|
||||
entry->is_getter = true;
|
||||
break;
|
||||
case swift::AccessorKind::Set:
|
||||
entry->is_setter = true;
|
||||
break;
|
||||
case swift::AccessorKind::WillSet:
|
||||
entry->is_will_set = true;
|
||||
break;
|
||||
case swift::AccessorKind::DidSet:
|
||||
entry->is_did_set = true;
|
||||
break;
|
||||
}
|
||||
fillAbstractFunctionDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::optional<codeql::SubscriptDecl> DeclVisitor::translateSubscriptDecl(
|
||||
@@ -265,6 +264,17 @@ std::optional<codeql::ModuleDecl> DeclVisitor::translateModuleDecl(const swift::
|
||||
}
|
||||
entry->is_builtin_module = decl.isBuiltinModule();
|
||||
entry->is_system_module = decl.isSystemModule();
|
||||
using K = swift::ModuleDecl::ImportFilterKind;
|
||||
llvm::SmallVector<swift::ImportedModule> imports;
|
||||
decl.getImportedModules(imports, K::Default);
|
||||
for (const auto& import : imports) {
|
||||
entry->imported_modules.push_back(dispatcher_.fetchLabel(import.importedModule));
|
||||
}
|
||||
imports.clear();
|
||||
decl.getImportedModules(imports, K::Exported);
|
||||
for (const auto& import : imports) {
|
||||
entry->exported_modules.push_back(dispatcher_.fetchLabel(import.importedModule));
|
||||
}
|
||||
fillTypeDecl(decl, *entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
@@ -20,12 +20,10 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
|
||||
dispatcher_.emit(translateIfConfigClause(*clause));
|
||||
}
|
||||
|
||||
std::variant<codeql::ConcreteFuncDecl, codeql::ConcreteFuncDeclsTrap> translateFuncDecl(
|
||||
const swift::FuncDecl& decl);
|
||||
std::variant<codeql::ConstructorDecl, codeql::ConstructorDeclsTrap> translateConstructorDecl(
|
||||
std::optional<codeql::ConcreteFuncDecl> translateFuncDecl(const swift::FuncDecl& decl);
|
||||
std::optional<codeql::ConstructorDecl> translateConstructorDecl(
|
||||
const swift::ConstructorDecl& decl);
|
||||
std::variant<codeql::DestructorDecl, codeql::DestructorDeclsTrap> translateDestructorDecl(
|
||||
const swift::DestructorDecl& decl);
|
||||
std::optional<codeql::DestructorDecl> translateDestructorDecl(const swift::DestructorDecl& decl);
|
||||
codeql::PrefixOperatorDecl translatePrefixOperatorDecl(const swift::PrefixOperatorDecl& decl);
|
||||
codeql::PostfixOperatorDecl translatePostfixOperatorDecl(const swift::PostfixOperatorDecl& decl);
|
||||
codeql::InfixOperatorDecl translateInfixOperatorDecl(const swift::InfixOperatorDecl& decl);
|
||||
@@ -34,25 +32,19 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
|
||||
codeql::TopLevelCodeDecl translateTopLevelCodeDecl(const swift::TopLevelCodeDecl& decl);
|
||||
codeql::PatternBindingDecl translatePatternBindingDecl(const swift::PatternBindingDecl& decl);
|
||||
std::optional<codeql::ConcreteVarDecl> translateVarDecl(const swift::VarDecl& decl);
|
||||
std::variant<codeql::StructDecl, codeql::StructDeclsTrap> translateStructDecl(
|
||||
const swift::StructDecl& decl);
|
||||
std::variant<codeql::ClassDecl, codeql::ClassDeclsTrap> translateClassDecl(
|
||||
const swift::ClassDecl& decl);
|
||||
std::variant<codeql::EnumDecl, codeql::EnumDeclsTrap> translateEnumDecl(
|
||||
const swift::EnumDecl& decl);
|
||||
std::variant<codeql::ProtocolDecl, codeql::ProtocolDeclsTrap> translateProtocolDecl(
|
||||
const swift::ProtocolDecl& decl);
|
||||
std::optional<codeql::StructDecl> translateStructDecl(const swift::StructDecl& decl);
|
||||
std::optional<codeql::ClassDecl> translateClassDecl(const swift::ClassDecl& decl);
|
||||
std::optional<codeql::EnumDecl> translateEnumDecl(const swift::EnumDecl& decl);
|
||||
std::optional<codeql::ProtocolDecl> translateProtocolDecl(const swift::ProtocolDecl& decl);
|
||||
codeql::EnumCaseDecl translateEnumCaseDecl(const swift::EnumCaseDecl& decl);
|
||||
std::variant<codeql::EnumElementDecl, codeql::EnumElementDeclsTrap> translateEnumElementDecl(
|
||||
std::optional<codeql::EnumElementDecl> translateEnumElementDecl(
|
||||
const swift::EnumElementDecl& decl);
|
||||
codeql::GenericTypeParamDecl translateGenericTypeParamDecl(
|
||||
const swift::GenericTypeParamDecl& decl);
|
||||
std::variant<codeql::AssociatedTypeDecl, codeql::AssociatedTypeDeclsTrap>
|
||||
translateAssociatedTypeDecl(const swift::AssociatedTypeDecl& decl);
|
||||
std::variant<codeql::TypeAliasDecl, codeql::TypeAliasDeclsTrap> translateTypeAliasDecl(
|
||||
const swift::TypeAliasDecl& decl);
|
||||
std::variant<codeql::AccessorDecl, codeql::AccessorDeclsTrap> translateAccessorDecl(
|
||||
const swift::AccessorDecl& decl);
|
||||
std::optional<codeql::AssociatedTypeDecl> translateAssociatedTypeDecl(
|
||||
const swift::AssociatedTypeDecl& decl);
|
||||
std::optional<codeql::TypeAliasDecl> translateTypeAliasDecl(const swift::TypeAliasDecl& decl);
|
||||
std::optional<codeql::AccessorDecl> translateAccessorDecl(const swift::AccessorDecl& decl);
|
||||
std::optional<codeql::SubscriptDecl> translateSubscriptDecl(const swift::SubscriptDecl& decl);
|
||||
codeql::ExtensionDecl translateExtensionDecl(const swift::ExtensionDecl& decl);
|
||||
codeql::ImportDecl translateImportDecl(const swift::ImportDecl& decl);
|
||||
@@ -86,17 +78,6 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
|
||||
return entry;
|
||||
}
|
||||
|
||||
template <typename T, typename D, typename... Args>
|
||||
std::variant<TrapClassOf<D>, T> createNamedEntryOr(const D& decl) {
|
||||
auto id = dispatcher_.assignNewLabel(decl, mangledName(decl));
|
||||
if (dispatcher_.shouldEmitDeclBody(decl)) {
|
||||
TrapClassOf<D> entry{id};
|
||||
fillDecl(decl, entry);
|
||||
return entry;
|
||||
}
|
||||
return T{id};
|
||||
}
|
||||
|
||||
template <typename D>
|
||||
TrapClassOf<D> createEntry(const D& decl) {
|
||||
TrapClassOf<D> entry{dispatcher_.template assignNewLabel(decl)};
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace codeql {
|
||||
|
||||
class SwiftVisitor : private SwiftDispatcher {
|
||||
public:
|
||||
using SwiftDispatcher::getEncounteredModules;
|
||||
using SwiftDispatcher::SwiftDispatcher;
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
| file://:0:0:0:0 | A |
|
||||
| file://:0:0:0:0 | B |
|
||||
| file://:0:0:0:0 | PackageDescription |
|
||||
| file://:0:0:0:0 | __ObjC |
|
||||
| file://:0:0:0:0 | main |
|
||||
| file://:0:0:0:0 | partial_modules |
|
||||
|
||||
@@ -1398,6 +1398,10 @@ module Raw {
|
||||
predicate isBuiltinModule() { module_decl_is_builtin_module(this) }
|
||||
|
||||
predicate isSystemModule() { module_decl_is_system_module(this) }
|
||||
|
||||
ModuleDecl getImportedModule(int index) { module_decl_imported_modules(this, index, result) }
|
||||
|
||||
ModuleDecl getExportedModule(int index) { module_decl_exported_modules(this, index, result) }
|
||||
}
|
||||
|
||||
class NumberLiteralExpr extends @number_literal_expr, BuiltinLiteralExpr { }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// generated by codegen/codegen.py
|
||||
private import codeql.swift.generated.Synth
|
||||
private import codeql.swift.generated.Raw
|
||||
import codeql.swift.elements.decl.ModuleDecl
|
||||
import codeql.swift.elements.decl.TypeDecl
|
||||
|
||||
class ModuleDeclBase extends Synth::TModuleDecl, TypeDecl {
|
||||
@@ -13,4 +14,34 @@ class ModuleDeclBase extends Synth::TModuleDecl, TypeDecl {
|
||||
predicate isSystemModule() {
|
||||
Synth::convertModuleDeclToRaw(this).(Raw::ModuleDecl).isSystemModule()
|
||||
}
|
||||
|
||||
ModuleDecl getImmediateImportedModule(int index) {
|
||||
result =
|
||||
Synth::convertModuleDeclFromRaw(Synth::convertModuleDeclToRaw(this)
|
||||
.(Raw::ModuleDecl)
|
||||
.getImportedModule(index))
|
||||
}
|
||||
|
||||
final ModuleDecl getImportedModule(int index) {
|
||||
result = getImmediateImportedModule(index).resolve()
|
||||
}
|
||||
|
||||
final ModuleDecl getAnImportedModule() { result = getImportedModule(_) }
|
||||
|
||||
final int getNumberOfImportedModules() { result = count(getAnImportedModule()) }
|
||||
|
||||
ModuleDecl getImmediateExportedModule(int index) {
|
||||
result =
|
||||
Synth::convertModuleDeclFromRaw(Synth::convertModuleDeclToRaw(this)
|
||||
.(Raw::ModuleDecl)
|
||||
.getExportedModule(index))
|
||||
}
|
||||
|
||||
final ModuleDecl getExportedModule(int index) {
|
||||
result = getImmediateExportedModule(index).resolve()
|
||||
}
|
||||
|
||||
final ModuleDecl getAnExportedModule() { result = getExportedModule(_) }
|
||||
|
||||
final int getNumberOfExportedModules() { result = count(getAnExportedModule()) }
|
||||
}
|
||||
|
||||
@@ -2116,6 +2116,20 @@ module_decl_is_system_module( //dir=decl
|
||||
int id: @module_decl ref
|
||||
);
|
||||
|
||||
#keyset[id, index]
|
||||
module_decl_imported_modules( //dir=decl
|
||||
int id: @module_decl ref,
|
||||
int index: int ref,
|
||||
int imported_module: @module_decl ref
|
||||
);
|
||||
|
||||
#keyset[id, index]
|
||||
module_decl_exported_modules( //dir=decl
|
||||
int id: @module_decl ref,
|
||||
int index: int ref,
|
||||
int exported_module: @module_decl ref
|
||||
);
|
||||
|
||||
constructor_ref_call_exprs( //dir=expr
|
||||
unique int id: @constructor_ref_call_expr
|
||||
);
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
| file://:0:0:0:0 | Foo | getModule: | file://:0:0:0:0 | Foo | getInterfaceType: | module<Foo> | getName: | Foo | isBuiltinModule: | no | isSystemModule: | no |
|
||||
| file://:0:0:0:0 | __ObjC | getModule: | file://:0:0:0:0 | __ObjC | getInterfaceType: | module<__ObjC> | getName: | __ObjC | isBuiltinModule: | no | isSystemModule: | no |
|
||||
| file://:0:0:0:0 | default_module_name | getModule: | file://:0:0:0:0 | default_module_name | getInterfaceType: | module<default_module_name> | getName: | default_module_name | isBuiltinModule: | no | isSystemModule: | no |
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
| file://:0:0:0:0 | Foo | 0 | file://:0:0:0:0 | Swift |
|
||||
| file://:0:0:0:0 | Foo | 1 | file://:0:0:0:0 | _Concurrency |
|
||||
| file://:0:0:0:0 | Foo | 2 | file://:0:0:0:0 | SwiftOnoneSupport |
|
||||
| file://:0:0:0:0 | __ObjC | 0 | file://:0:0:0:0 | Swift |
|
||||
| file://:0:0:0:0 | default_module_name | 0 | file://:0:0:0:0 | Swift |
|
||||
| file://:0:0:0:0 | default_module_name | 1 | file://:0:0:0:0 | _Concurrency |
|
||||
| file://:0:0:0:0 | default_module_name | 2 | file://:0:0:0:0 | SwiftOnoneSupport |
|
||||
@@ -0,0 +1 @@
|
||||
| file://:0:0:0:0 | Foo | 0 | file://:0:0:0:0 | Swift |
|
||||
@@ -0,0 +1,7 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements
|
||||
import TestUtils
|
||||
|
||||
from ModuleDecl x, int index
|
||||
where toBeTested(x) and not x.isUnknown()
|
||||
select x, index, x.getExportedModule(index)
|
||||
@@ -0,0 +1,7 @@
|
||||
| file://:0:0:0:0 | Foo | 0 | file://:0:0:0:0 | Swift |
|
||||
| file://:0:0:0:0 | Foo | 1 | file://:0:0:0:0 | _Concurrency |
|
||||
| file://:0:0:0:0 | Foo | 2 | file://:0:0:0:0 | SwiftOnoneSupport |
|
||||
| file://:0:0:0:0 | __ObjC | 0 | file://:0:0:0:0 | Swift |
|
||||
| file://:0:0:0:0 | default_module_name | 0 | file://:0:0:0:0 | Swift |
|
||||
| file://:0:0:0:0 | default_module_name | 1 | file://:0:0:0:0 | _Concurrency |
|
||||
| file://:0:0:0:0 | default_module_name | 2 | file://:0:0:0:0 | SwiftOnoneSupport |
|
||||
@@ -0,0 +1,7 @@
|
||||
// generated by codegen/codegen.py
|
||||
import codeql.swift.elements
|
||||
import TestUtils
|
||||
|
||||
from ModuleDecl x, int index
|
||||
where toBeTested(x) and not x.isUnknown()
|
||||
select x, index, x.getImportedModule(index)
|
||||
@@ -1 +1,2 @@
|
||||
//codeql-extractor-options: -module-name Foo
|
||||
@_exported import Swift
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
| Builtin.BridgeObject | getName: | Builtin.BridgeObject | getCanonicalType: | Builtin.BridgeObject |
|
||||
| Builtin.DefaultActorStorage | getName: | Builtin.DefaultActorStorage | getCanonicalType: | Builtin.DefaultActorStorage |
|
||||
| Builtin.Executor | getName: | Builtin.Executor | getCanonicalType: | Builtin.Executor |
|
||||
| Builtin.FPIEEE32 | getName: | Builtin.FPIEEE32 | getCanonicalType: | Builtin.FPIEEE32 |
|
||||
| Builtin.FPIEEE64 | getName: | Builtin.FPIEEE64 | getCanonicalType: | Builtin.FPIEEE64 |
|
||||
@@ -8,4 +7,3 @@
|
||||
| Builtin.NativeObject | getName: | Builtin.NativeObject | getCanonicalType: | Builtin.NativeObject |
|
||||
| Builtin.RawPointer | getName: | Builtin.RawPointer | getCanonicalType: | Builtin.RawPointer |
|
||||
| Builtin.RawUnsafeContinuation | getName: | Builtin.RawUnsafeContinuation | getCanonicalType: | Builtin.RawUnsafeContinuation |
|
||||
| Builtin.UnsafeValueBuffer | getName: | Builtin.UnsafeValueBuffer | getCanonicalType: | Builtin.UnsafeValueBuffer |
|
||||
|
||||
@@ -4,11 +4,9 @@ func foo(
|
||||
_: Builtin.FPIEEE32,
|
||||
_: Builtin.FPIEEE64,
|
||||
_: Builtin.BridgeObject,
|
||||
_: Builtin.DefaultActorStorage,
|
||||
_: Builtin.Executor,
|
||||
_: Builtin.Job,
|
||||
_: Builtin.NativeObject,
|
||||
_: Builtin.RawPointer,
|
||||
_: Builtin.RawUnsafeContinuation,
|
||||
_: Builtin.UnsafeValueBuffer
|
||||
_: Builtin.Executor,
|
||||
_: Builtin.Job,
|
||||
_: Builtin.RawUnsafeContinuation
|
||||
) {}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
| module<Foo> | getName: | module<Foo> | getCanonicalType: | module<Foo> | getModule: | file://:0:0:0:0 | Foo |
|
||||
| module<__ObjC> | getName: | module<__ObjC> | getCanonicalType: | module<__ObjC> | getModule: | file://:0:0:0:0 | __ObjC |
|
||||
| module<default_module_name> | getName: | module<default_module_name> | getCanonicalType: | module<default_module_name> | getModule: | file://:0:0:0:0 | default_module_name |
|
||||
|
||||
Reference in New Issue
Block a user