mirror of
https://github.com/github/codeql.git
synced 2025-12-21 19:26:31 +01:00
`FailStmt` are `return nil` in fallible initializers. `PoundAssertStmt` are an experimental feature for compile time assertions.
190 lines
6.8 KiB
C++
190 lines
6.8 KiB
C++
#include "swift/extractor/translators/StmtTranslator.h"
|
|
|
|
namespace codeql {
|
|
|
|
void StmtTranslator::translateAndEmit(const swift::StmtCondition& cond) {
|
|
auto entry = dispatcher.createEntry(cond);
|
|
entry.elements = dispatcher.fetchRepeatedLabels(cond);
|
|
dispatcher.emit(entry);
|
|
}
|
|
|
|
void StmtTranslator::translateAndEmit(const swift::StmtConditionElement& element) {
|
|
auto entry = dispatcher.createEntry(element);
|
|
if (auto boolean = element.getBooleanOrNull()) {
|
|
entry.boolean = dispatcher.fetchLabel(boolean);
|
|
} else if (auto pattern = element.getPatternOrNull()) {
|
|
entry.pattern = dispatcher.fetchLabel(pattern);
|
|
entry.initializer = dispatcher.fetchLabel(element.getInitializer());
|
|
}
|
|
dispatcher.emit(entry);
|
|
}
|
|
|
|
void StmtTranslator::translateAndEmit(const swift::CaseLabelItem& labelItem) {
|
|
auto entry = dispatcher.createEntry(labelItem);
|
|
entry.pattern = dispatcher.fetchLabel(labelItem.getPattern());
|
|
entry.guard = dispatcher.fetchOptionalLabel(labelItem.getGuardExpr());
|
|
dispatcher.emit(entry);
|
|
}
|
|
|
|
codeql::BraceStmt StmtTranslator::translateBraceStmt(const swift::BraceStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
entry.elements = dispatcher.fetchRepeatedLabels(stmt.getElements());
|
|
return entry;
|
|
}
|
|
|
|
codeql::ReturnStmt StmtTranslator::translateReturnStmt(const swift::ReturnStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
if (stmt.hasResult()) {
|
|
entry.result = dispatcher.fetchLabel(stmt.getResult());
|
|
}
|
|
return entry;
|
|
}
|
|
|
|
codeql::ForEachStmt StmtTranslator::translateForEachStmt(const swift::ForEachStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
fillLabeledStmt(stmt, entry);
|
|
entry.body = dispatcher.fetchLabel(stmt.getBody());
|
|
entry.sequence = dispatcher.fetchLabel(stmt.getParsedSequence());
|
|
entry.pattern = dispatcher.fetchLabel(stmt.getPattern());
|
|
entry.where = dispatcher.fetchOptionalLabel(stmt.getWhere());
|
|
return entry;
|
|
}
|
|
|
|
codeql::IfStmt StmtTranslator::translateIfStmt(const swift::IfStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
fillLabeledConditionalStmt(stmt, entry);
|
|
entry.then = dispatcher.fetchLabel(stmt.getThenStmt());
|
|
entry.else_ = dispatcher.fetchOptionalLabel(stmt.getElseStmt());
|
|
return entry;
|
|
}
|
|
|
|
codeql::BreakStmt StmtTranslator::translateBreakStmt(const swift::BreakStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
entry.target = dispatcher.fetchOptionalLabel(stmt.getTarget());
|
|
if (auto targetName = stmt.getTargetName(); !targetName.empty()) {
|
|
entry.target_name = targetName.str().str();
|
|
}
|
|
return entry;
|
|
}
|
|
|
|
codeql::ContinueStmt StmtTranslator::translateContinueStmt(const swift::ContinueStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
entry.target = dispatcher.fetchOptionalLabel(stmt.getTarget());
|
|
if (auto targetName = stmt.getTargetName(); !targetName.empty()) {
|
|
entry.target_name = targetName.str().str();
|
|
}
|
|
return entry;
|
|
}
|
|
|
|
codeql::WhileStmt StmtTranslator::translateWhileStmt(const swift::WhileStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
fillLabeledConditionalStmt(stmt, entry);
|
|
entry.body = dispatcher.fetchLabel(stmt.getBody());
|
|
return entry;
|
|
}
|
|
|
|
codeql::RepeatWhileStmt StmtTranslator::translateRepeatWhileStmt(
|
|
const swift::RepeatWhileStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
fillLabeledStmt(stmt, entry);
|
|
entry.body = dispatcher.fetchLabel(stmt.getBody());
|
|
entry.condition = dispatcher.fetchLabel(stmt.getCond());
|
|
return entry;
|
|
}
|
|
|
|
codeql::DoCatchStmt StmtTranslator::translateDoCatchStmt(const swift::DoCatchStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
fillLabeledStmt(stmt, entry);
|
|
entry.body = dispatcher.fetchLabel(stmt.getBody());
|
|
entry.catches = dispatcher.fetchRepeatedLabels(stmt.getCatches());
|
|
return entry;
|
|
}
|
|
|
|
codeql::CaseStmt StmtTranslator::translateCaseStmt(const swift::CaseStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
entry.body = dispatcher.fetchLabel(stmt.getBody());
|
|
entry.labels = dispatcher.fetchRepeatedLabels(stmt.getCaseLabelItems());
|
|
if (stmt.hasCaseBodyVariables()) {
|
|
for (auto var : stmt.getCaseBodyVariables()) {
|
|
entry.variables.push_back(dispatcher.fetchLabel(var));
|
|
}
|
|
}
|
|
return entry;
|
|
}
|
|
|
|
codeql::GuardStmt StmtTranslator::translateGuardStmt(const swift::GuardStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
fillLabeledConditionalStmt(stmt, entry);
|
|
entry.body = dispatcher.fetchLabel(stmt.getBody());
|
|
return entry;
|
|
}
|
|
|
|
codeql::ThrowStmt StmtTranslator::translateThrowStmt(const swift::ThrowStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
entry.sub_expr = dispatcher.fetchLabel(stmt.getSubExpr());
|
|
return entry;
|
|
}
|
|
|
|
codeql::DeferStmt StmtTranslator::translateDeferStmt(const swift::DeferStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
entry.body = dispatcher.fetchLabel(stmt.getBodyAsWritten());
|
|
return entry;
|
|
}
|
|
|
|
codeql::DoStmt StmtTranslator::translateDoStmt(const swift::DoStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
fillLabeledStmt(stmt, entry);
|
|
entry.body = dispatcher.fetchLabel(stmt.getBody());
|
|
return entry;
|
|
}
|
|
|
|
codeql::SwitchStmt StmtTranslator::translateSwitchStmt(const swift::SwitchStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
fillLabeledStmt(stmt, entry);
|
|
entry.expr = dispatcher.fetchLabel(stmt.getSubjectExpr());
|
|
entry.cases = dispatcher.fetchRepeatedLabels(stmt.getCases());
|
|
return entry;
|
|
}
|
|
|
|
codeql::FallthroughStmt StmtTranslator::translateFallthroughStmt(
|
|
const swift::FallthroughStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
entry.fallthrough_source = dispatcher.fetchLabel(stmt.getFallthroughSource());
|
|
entry.fallthrough_dest = dispatcher.fetchLabel(stmt.getFallthroughDest());
|
|
return entry;
|
|
}
|
|
|
|
codeql::YieldStmt StmtTranslator::translateYieldStmt(const swift::YieldStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
entry.results = dispatcher.fetchRepeatedLabels(stmt.getYields());
|
|
return entry;
|
|
}
|
|
|
|
void StmtTranslator::fillLabeledStmt(const swift::LabeledStmt& stmt, codeql::LabeledStmt& entry) {
|
|
if (auto info = stmt.getLabelInfo()) {
|
|
entry.label = info.Name.str().str();
|
|
}
|
|
}
|
|
|
|
void StmtTranslator::fillLabeledConditionalStmt(const swift::LabeledConditionalStmt& stmt,
|
|
codeql::LabeledConditionalStmt& entry) {
|
|
// getCondPointer not provided for const stmt by swift...
|
|
entry.condition =
|
|
dispatcher.fetchLabel(const_cast<swift::LabeledConditionalStmt&>(stmt).getCondPointer());
|
|
fillLabeledStmt(stmt, entry);
|
|
}
|
|
|
|
codeql::FailStmt StmtTranslator::translateFailStmt(const swift::FailStmt& stmt) {
|
|
return dispatcher.createEntry(stmt);
|
|
}
|
|
|
|
codeql::PoundAssertStmt StmtTranslator::translatePoundAssertStmt(
|
|
const swift::PoundAssertStmt& stmt) {
|
|
auto entry = dispatcher.createEntry(stmt);
|
|
entry.condition = dispatcher.fetchLabel(stmt.getCondition());
|
|
entry.message = stmt.getMessage();
|
|
return entry;
|
|
}
|
|
|
|
} // namespace codeql
|