Skip to content

Commit 76ea63f

Browse files
committed
Swift: deduplicate VarDecl
Deduplication of `ConcreteVarDecl` is triggered only if its `DeclContext` is not local. This avoids a mangled name conflict. Also added more thourough tests for `ConcreteVarDecl` and `ParamDecl`.
1 parent e43755b commit 76ea63f

26 files changed

+191
-20
lines changed

swift/extractor/visitors/DeclVisitor.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,13 @@ codeql::PrecedenceGroupDecl DeclVisitor::translatePrecedenceGroupDecl(
8383
return entry;
8484
}
8585

86-
codeql::ParamDecl DeclVisitor::translateParamDecl(const swift::ParamDecl& decl) {
87-
// TODO: deduplicate
88-
ParamDecl entry{dispatcher_.assignNewLabel(decl)};
89-
fillVarDecl(decl, entry);
90-
entry.is_inout = decl.isInOut();
86+
std::optional<codeql::ParamDecl> DeclVisitor::translateParamDecl(const swift::ParamDecl& decl) {
87+
auto entry = createNamedEntry(decl);
88+
if (!entry) {
89+
return std::nullopt;
90+
}
91+
fillVarDecl(decl, *entry);
92+
entry->is_inout = decl.isInOut();
9193
return entry;
9294
}
9395

@@ -111,11 +113,18 @@ codeql::PatternBindingDecl DeclVisitor::translatePatternBindingDecl(
111113
return entry;
112114
}
113115

114-
codeql::ConcreteVarDecl DeclVisitor::translateVarDecl(const swift::VarDecl& decl) {
115-
// TODO: deduplicate all non-local variables
116-
ConcreteVarDecl entry{dispatcher_.assignNewLabel(decl)};
117-
entry.introducer_int = static_cast<uint8_t>(decl.getIntroducer());
118-
fillVarDecl(decl, entry);
116+
std::optional<codeql::ConcreteVarDecl> DeclVisitor::translateVarDecl(const swift::VarDecl& decl) {
117+
std::optional<codeql::ConcreteVarDecl> entry;
118+
if (decl.getDeclContext()->isLocalContext()) {
119+
entry.emplace(dispatcher_.assignNewLabel(decl));
120+
} else {
121+
entry = createNamedEntry(decl);
122+
if (!entry) {
123+
return std::nullopt;
124+
}
125+
}
126+
entry->introducer_int = static_cast<uint8_t>(decl.getIntroducer());
127+
fillVarDecl(decl, *entry);
119128
return entry;
120129
}
121130

swift/extractor/visitors/DeclVisitor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ class DeclVisitor : public AstVisitorBase<DeclVisitor> {
3030
codeql::PostfixOperatorDecl translatePostfixOperatorDecl(const swift::PostfixOperatorDecl& decl);
3131
codeql::InfixOperatorDecl translateInfixOperatorDecl(const swift::InfixOperatorDecl& decl);
3232
codeql::PrecedenceGroupDecl translatePrecedenceGroupDecl(const swift::PrecedenceGroupDecl& decl);
33-
codeql::ParamDecl translateParamDecl(const swift::ParamDecl& decl);
33+
std::optional<codeql::ParamDecl> translateParamDecl(const swift::ParamDecl& decl);
3434
codeql::TopLevelCodeDecl translateTopLevelCodeDecl(const swift::TopLevelCodeDecl& decl);
3535
codeql::PatternBindingDecl translatePatternBindingDecl(const swift::PatternBindingDecl& decl);
36-
codeql::ConcreteVarDecl translateVarDecl(const swift::VarDecl& decl);
36+
std::optional<codeql::ConcreteVarDecl> translateVarDecl(const swift::VarDecl& decl);
3737
std::variant<codeql::StructDecl, codeql::StructDeclsTrap> translateStructDecl(
3838
const swift::StructDecl& decl);
3939
std::variant<codeql::ClassDecl, codeql::ClassDeclsTrap> translateClassDecl(
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
| var_decls.swift:4:7:4:7 | i | getInterfaceType: | Int | getName: | i | getType: | Int | getIntroducerInt: | 1 |
2+
| var_decls.swift:7:5:7:5 | numbers | getInterfaceType: | [Int] | getName: | numbers | getType: | [Int] | getIntroducerInt: | 1 |
3+
| var_decls.swift:10:12:10:12 | numbers | getInterfaceType: | [Int] | getName: | numbers | getType: | [Int] | getIntroducerInt: | 0 |
4+
| var_decls.swift:15:7:15:7 | wrappedValue | getInterfaceType: | T | getName: | wrappedValue | getType: | T | getIntroducerInt: | 1 |
5+
| var_decls.swift:20:7:20:7 | wrappedValue | getInterfaceType: | Int | getName: | wrappedValue | getType: | Int | getIntroducerInt: | 1 |
6+
| var_decls.swift:24:15:24:15 | _wrapped | getInterfaceType: | X<Y> | getName: | _wrapped | getType: | X<Y> | getIntroducerInt: | 1 |
7+
| var_decls.swift:24:15:24:15 | wrapped | getInterfaceType: | Int | getName: | wrapped | getType: | Int | getIntroducerInt: | 1 |
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// generated by codegen/codegen.py
2+
import codeql.swift.elements
3+
import TestUtils
4+
5+
from ConcreteVarDecl x, Type getInterfaceType, string getName, Type getType, int getIntroducerInt
6+
where
7+
toBeTested(x) and
8+
not x.isUnknown() and
9+
getInterfaceType = x.getInterfaceType() and
10+
getName = x.getName() and
11+
getType = x.getType() and
12+
getIntroducerInt = x.getIntroducerInt()
13+
select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "getType:", getType,
14+
"getIntroducerInt:", getIntroducerInt
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
| var_decls.swift:10:12:10:12 | numbers | 0 | var_decls.swift:10:12:10:12 | get |
2+
| var_decls.swift:15:7:15:7 | wrappedValue | 0 | var_decls.swift:15:7:15:7 | get |
3+
| var_decls.swift:15:7:15:7 | wrappedValue | 1 | var_decls.swift:15:7:15:7 | set |
4+
| var_decls.swift:15:7:15:7 | wrappedValue | 2 | var_decls.swift:15:7:15:7 | (unnamed function decl) |
5+
| var_decls.swift:20:7:20:7 | wrappedValue | 0 | var_decls.swift:20:7:20:7 | get |
6+
| var_decls.swift:20:7:20:7 | wrappedValue | 1 | var_decls.swift:20:7:20:7 | set |
7+
| var_decls.swift:20:7:20:7 | wrappedValue | 2 | var_decls.swift:20:7:20:7 | (unnamed function decl) |
8+
| var_decls.swift:24:15:24:15 | _wrapped | 0 | var_decls.swift:24:15:24:15 | get |
9+
| var_decls.swift:24:15:24:15 | _wrapped | 1 | var_decls.swift:24:15:24:15 | set |
10+
| var_decls.swift:24:15:24:15 | _wrapped | 2 | var_decls.swift:24:15:24:15 | (unnamed function decl) |
11+
| var_decls.swift:24:15:24:15 | wrapped | 0 | var_decls.swift:24:15:24:15 | get |
12+
| var_decls.swift:24:15:24:15 | wrapped | 1 | var_decls.swift:24:15:24:15 | set |
13+
| var_decls.swift:24:15:24:15 | wrapped | 2 | var_decls.swift:24:15:24:15 | (unnamed function decl) |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// generated by codegen/codegen.py
2+
import codeql.swift.elements
3+
import TestUtils
4+
5+
from ConcreteVarDecl x, int index
6+
where toBeTested(x) and not x.isUnknown()
7+
select x, index, x.getAccessorDecl(index)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| var_decls.swift:24:15:24:15 | wrapped | X<Y> |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// generated by codegen/codegen.py
2+
import codeql.swift.elements
3+
import TestUtils
4+
5+
from ConcreteVarDecl x
6+
where toBeTested(x) and not x.isUnknown()
7+
select x, x.getAttachedPropertyWrapperType()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| var_decls.swift:4:7:4:7 | i | var_decls.swift:4:11:4:11 | 0 |
2+
| var_decls.swift:7:5:7:5 | numbers | var_decls.swift:7:15:7:18 | [...] |
3+
| var_decls.swift:10:12:10:12 | numbers | var_decls.swift:10:22:10:35 | [...] |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// generated by codegen/codegen.py
2+
import codeql.swift.elements
3+
import TestUtils
4+
5+
from ConcreteVarDecl x
6+
where toBeTested(x) and not x.isUnknown()
7+
select x, x.getParentInitializer()

0 commit comments

Comments
 (0)