Skip to content

Commit f2bc73b

Browse files
authored
Merge pull request #9239 from github/redsun82/swift-visitors
Swift: transfer all visitors
2 parents 144937a + fc165c1 commit f2bc73b

File tree

150 files changed

+4313
-270
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+4313
-270
lines changed

swift/codegen/schema.yml

Lines changed: 169 additions & 153 deletions
Large diffs are not rendered by default.

swift/extractor/SwiftDispatcher.h

Lines changed: 71 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,6 @@ class SwiftDispatcher {
3838
emit(ElementIsUnknownTrap{label});
3939
}
4040

41-
private:
42-
// types to be supported by assignNewLabel/fetchLabel need to be listed here
43-
using Store = TrapLabelStore<swift::Decl,
44-
swift::Stmt,
45-
swift::Expr,
46-
swift::Pattern,
47-
swift::TypeRepr,
48-
swift::TypeBase>;
49-
5041
// This method gives a TRAP label for already emitted AST node.
5142
// If the AST node was not emitted yet, then the emission is dispatched to a corresponding
5243
// visitor (see `visit(T *)` methods below).
@@ -72,52 +63,109 @@ class SwiftDispatcher {
7263
return {};
7364
}
7465

66+
// convenience `fetchLabel` overload for `swift::Type` (which is just a wrapper for
67+
// `swift::TypeBase*`)
68+
TrapLabel<TypeTag> fetchLabel(swift::Type t) { return fetchLabel(t.getPointer()); }
69+
70+
TrapLabel<AstNodeTag> fetchLabel(swift::ASTNode node) {
71+
return fetchLabelFromUnion<AstNodeTag>(node);
72+
}
73+
7574
// Due to the lazy emission approach, we must assign a label to a corresponding AST node before
7675
// it actually gets emitted to handle recursive cases such as recursive calls, or recursive type
7776
// declarations
7877
template <typename E>
7978
TrapLabelOf<E> assignNewLabel(E* e) {
8079
assert(waitingForNewLabel == Store::Handle{e} && "assignNewLabel called on wrong entity");
81-
auto label = getLabel<TrapTagOf<E>>();
82-
trap.assignStar(label);
80+
auto label = createLabel<TrapTagOf<E>>();
8381
store.insert(e, label);
8482
waitingForNewLabel = std::monostate{};
8583
return label;
8684
}
8785

8886
template <typename Tag>
89-
TrapLabel<Tag> getLabel() {
90-
return arena.allocateLabel<Tag>();
87+
TrapLabel<Tag> createLabel() {
88+
auto ret = arena.allocateLabel<Tag>();
89+
trap.assignStar(ret);
90+
return ret;
91+
}
92+
93+
template <typename Tag, typename... Args>
94+
TrapLabel<Tag> createLabel(Args&&... args) {
95+
auto ret = arena.allocateLabel<Tag>();
96+
trap.assignKey(ret, std::forward<Args>(args)...);
97+
return ret;
9198
}
9299

93100
template <typename Locatable>
94101
void attachLocation(Locatable locatable, TrapLabel<LocatableTag> locatableLabel) {
95102
attachLocation(&locatable, locatableLabel);
96103
}
97104

98-
// Emits a Location TRAP entry and attaches it to an AST node
105+
// Emits a Location TRAP entry and attaches it to a `Locatable` trap label
99106
template <typename Locatable>
100107
void attachLocation(Locatable* locatable, TrapLabel<LocatableTag> locatableLabel) {
101-
auto start = locatable->getStartLoc();
102-
auto end = locatable->getEndLoc();
108+
attachLocation(locatable->getStartLoc(), locatable->getEndLoc(), locatableLabel);
109+
}
110+
111+
// Emits a Location TRAP entry for a list of swift entities and attaches it to a `Locatable` trap
112+
// label
113+
template <typename Locatable>
114+
void attachLocation(llvm::MutableArrayRef<Locatable>* locatables,
115+
TrapLabel<LocatableTag> locatableLabel) {
116+
if (locatables->empty()) {
117+
return;
118+
}
119+
attachLocation(locatables->front().getStartLoc(), locatables->back().getEndLoc(),
120+
locatableLabel);
121+
}
122+
123+
private:
124+
// types to be supported by assignNewLabel/fetchLabel need to be listed here
125+
using Store = TrapLabelStore<swift::Decl,
126+
swift::Stmt,
127+
swift::StmtCondition,
128+
swift::CaseLabelItem,
129+
swift::Expr,
130+
swift::Pattern,
131+
swift::TypeRepr,
132+
swift::TypeBase>;
133+
134+
void attachLocation(swift::SourceLoc start,
135+
swift::SourceLoc end,
136+
TrapLabel<LocatableTag> locatableLabel) {
103137
if (!start.isValid() || !end.isValid()) {
104138
// invalid locations seem to come from entities synthesized by the compiler
105139
return;
106140
}
107141
std::string filepath = getFilepath(start);
108-
auto fileLabel = arena.allocateLabel<FileTag>();
109-
trap.assignKey(fileLabel, filepath);
142+
auto fileLabel = createLabel<FileTag>(filepath);
110143
// TODO: do not emit duplicate trap entries for Files
111144
trap.emit(FilesTrap{fileLabel, filepath});
112145
auto [startLine, startColumn] = sourceManager.getLineAndColumnInBuffer(start);
113146
auto [endLine, endColumn] = sourceManager.getLineAndColumnInBuffer(end);
114-
auto locLabel = arena.allocateLabel<LocationTag>();
115-
trap.assignKey(locLabel, '{', fileLabel, "}:", startLine, ':', startColumn, ':', endLine, ':',
116-
endColumn);
147+
auto locLabel = createLabel<LocationTag>('{', fileLabel, "}:", startLine, ':', startColumn, ':',
148+
endLine, ':', endColumn);
117149
trap.emit(LocationsTrap{locLabel, fileLabel, startLine, startColumn, endLine, endColumn});
118150
trap.emit(LocatablesTrap{locatableLabel, locLabel});
119151
}
120152

153+
template <typename Tag, typename... Ts>
154+
TrapLabel<Tag> fetchLabelFromUnion(const llvm::PointerUnion<Ts...> u) {
155+
TrapLabel<Tag> ret{};
156+
assert((... || fetchLabelFromUnionCase<Tag, Ts>(u, ret)) && "llvm::PointerUnion not set");
157+
return ret;
158+
}
159+
160+
template <typename Tag, typename T, typename... Ts>
161+
bool fetchLabelFromUnionCase(const llvm::PointerUnion<Ts...> u, TrapLabel<Tag>& output) {
162+
if (auto e = u.template dyn_cast<T>()) {
163+
output = fetchLabel(e);
164+
return true;
165+
}
166+
return false;
167+
}
168+
121169
std::string getFilepath(swift::SourceLoc loc) {
122170
// TODO: this needs more testing
123171
// TODO: check canonicaliztion of names on a case insensitive filesystems
@@ -135,6 +183,8 @@ class SwiftDispatcher {
135183
// which are to be introduced in follow-up PRs
136184
virtual void visit(swift::Decl* decl) = 0;
137185
virtual void visit(swift::Stmt* stmt) = 0;
186+
virtual void visit(swift::StmtCondition* cond) = 0;
187+
virtual void visit(swift::CaseLabelItem* item) = 0;
138188
virtual void visit(swift::Expr* expr) = 0;
139189
virtual void visit(swift::Pattern* pattern) = 0;
140190
virtual void visit(swift::TypeRepr* type) = 0;

swift/extractor/SwiftTagTraits.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ using SILBoxTypeReprTag = SilBoxTypeReprTag;
3535
static_assert(std::is_base_of_v<TYPE##Tag, TAG>, "override is not a subtag");
3636

3737
MAP_TAG(Stmt);
38+
MAP_TAG(StmtCondition);
39+
MAP_TAG(CaseLabelItem);
3840
#define ABSTRACT_STMT(CLASS, PARENT) MAP_SUBTAG(CLASS##Stmt, PARENT)
3941
#define STMT(CLASS, PARENT) ABSTRACT_STMT(CLASS, PARENT)
4042
#include "swift/AST/StmtNodes.def"

swift/extractor/SwiftVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class SwiftVisitor : private SwiftDispatcher {
2222
private:
2323
void visit(swift::Decl* decl) override { declVisitor.visit(decl); }
2424
void visit(swift::Stmt* stmt) override { stmtVisitor.visit(stmt); }
25+
void visit(swift::StmtCondition* cond) override { stmtVisitor.visitStmtCondition(cond); }
26+
void visit(swift::CaseLabelItem* item) override { stmtVisitor.visitCaseLabelItem(item); }
2527
void visit(swift::Expr* expr) override { exprVisitor.visit(expr); }
2628
void visit(swift::Pattern* pattern) override { patternVisitor.visit(pattern); }
2729
void visit(swift::TypeRepr* type) override { typeReprVisitor.visit(type); }

swift/extractor/trap/TrapLabel.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,18 @@ class UntypedTrapLabel {
1313
template <typename Tag>
1414
friend class TrapLabel;
1515

16+
static constexpr uint64_t undefined = 0xffffffffffffffff;
17+
1618
protected:
17-
UntypedTrapLabel() : id_{0xffffffffffffffff} {}
19+
UntypedTrapLabel() : id_{undefined} {}
1820
UntypedTrapLabel(uint64_t id) : id_{id} {}
1921

2022
public:
2123
friend std::ostream& operator<<(std::ostream& out, UntypedTrapLabel l) {
24+
// TODO: this is a temporary fix to catch us from outputting undefined labels to trap
25+
// this should be moved to a validity check, probably aided by code generation and carried out
26+
// by `SwiftDispatcher`
27+
assert(l.id_ != undefined && "outputting an undefined label!");
2228
out << '#' << std::hex << l.id_ << std::dec;
2329
return out;
2430
}

0 commit comments

Comments
 (0)