Skip to content

Commit e1ed49f

Browse files
authored
Merge pull request github#14011 from github/revert-13991-redsun82/swift-use-concepts
Revert "Swift: use C++20 constraints and concepts to simplify code"
2 parents 6d85d0d + 1daedd9 commit e1ed49f

File tree

7 files changed

+225
-120
lines changed

7 files changed

+225
-120
lines changed

misc/codegen/templates/trap_tags_h.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace codeql {
66
{{#tags}}
77

88
// {{id}}
9-
struct {{name}}Tag {{#has_bases}}: {{#bases}}{{^first}}, {{/first}}virtual {{base}}Tag{{/bases}} {{/has_bases}}{
9+
struct {{name}}Tag {{#has_bases}}: {{#bases}}{{^first}}, {{/first}}{{base}}Tag{{/bases}} {{/has_bases}}{
1010
static constexpr const char* prefix = "{{name}}";
1111
};
1212
{{/tags}}

swift/extractor/infra/SwiftDispatcher.h

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@ class SwiftDispatcher {
3838
const swift::PoundAvailableInfo*,
3939
const swift::AvailabilitySpec*>;
4040

41+
template <typename E>
42+
static constexpr bool IsFetchable = std::is_constructible_v<Handle, const E&>;
43+
44+
template <typename E>
45+
static constexpr bool IsLocatable =
46+
std::is_base_of_v<LocatableTag, TrapTagOf<E>> && !std::is_base_of_v<TypeTag, TrapTagOf<E>>;
47+
48+
template <typename E>
49+
static constexpr bool IsDeclPointer = std::is_convertible_v<E, const swift::Decl*>;
50+
51+
template <typename E>
52+
static constexpr bool IsTypePointer = std::is_convertible_v<E, const swift::TypeBase*>;
53+
4154
public:
4255
// all references and pointers passed as parameters to this constructor are supposed to outlive
4356
// the SwiftDispatcher
@@ -63,7 +76,7 @@ class SwiftDispatcher {
6376
using Label = std::remove_reference_t<decltype(label)>;
6477
if (!label.valid()) {
6578
const char* action;
66-
if constexpr (std::derived_from<UnspecifiedElementTag, typename Label::Tag>) {
79+
if constexpr (std::is_base_of_v<typename Label::Tag, UnspecifiedElementTag>) {
6780
action = "replacing with unspecified element";
6881
label = emitUnspecified(idOf(entry), field, index);
6982
} else {
@@ -119,7 +132,7 @@ class SwiftDispatcher {
119132

120133
template <typename E>
121134
std::optional<TrapLabel<ElementTag>> idOf(const E& entry) {
122-
if constexpr (requires { entry.id; }) {
135+
if constexpr (HasId<E>::value) {
123136
return entry.id;
124137
} else {
125138
return std::nullopt;
@@ -129,14 +142,13 @@ class SwiftDispatcher {
129142
// This method gives a TRAP label for already emitted AST node.
130143
// If the AST node was not emitted yet, then the emission is dispatched to a corresponding
131144
// visitor (see `visit(T *)` methods below).
132-
// clang-format off
133-
template <typename E>
134-
requires std::constructible_from<Handle, E*>
135-
TrapLabelOf<E> fetchLabel(const E* e, swift::Type type = {}) {
136-
// clang-format on
137-
if (!e) {
138-
// this will be treated on emission
139-
return undefined_label;
145+
template <typename E, std::enable_if_t<IsFetchable<E>>* = nullptr>
146+
TrapLabelOf<E> fetchLabel(const E& e, swift::Type type = {}) {
147+
if constexpr (std::is_constructible_v<bool, const E&>) {
148+
if (!e) {
149+
// this will be treated on emission
150+
return undefined_label;
151+
}
140152
}
141153
auto& stored = store[e];
142154
if (!stored.valid()) {
@@ -162,11 +174,8 @@ class SwiftDispatcher {
162174
return ret;
163175
}
164176

165-
// clang-format off
166-
template <typename E>
167-
requires std::constructible_from<Handle, E*>
177+
template <typename E, std::enable_if_t<IsFetchable<E*>>* = nullptr>
168178
TrapLabelOf<E> fetchLabel(const E& e) {
169-
// clang-format on
170179
return fetchLabel(&e);
171180
}
172181

@@ -175,8 +184,7 @@ class SwiftDispatcher {
175184
auto createEntry(const E& e) {
176185
auto found = store.find(&e);
177186
CODEQL_ASSERT(found != store.end(), "createEntry called on non-fetched label");
178-
using Tag = ConcreteTrapTagOf<E>;
179-
auto label = TrapLabel<Tag>::unsafeCreateFromUntyped(found->second);
187+
auto label = TrapLabel<ConcreteTrapTagOf<E>>::unsafeCreateFromUntyped(found->second);
180188
if constexpr (IsLocatable<E>) {
181189
locationExtractor.attachLocation(sourceManager, e, label);
182190
}
@@ -187,8 +195,7 @@ class SwiftDispatcher {
187195
// an example is swift::Argument, that are created on the fly and thus have no stable pointer
188196
template <typename E>
189197
auto createUncachedEntry(const E& e) {
190-
using Tag = TrapTagOf<E>;
191-
auto label = trap.createTypedLabel<Tag>();
198+
auto label = trap.createTypedLabel<TrapTagOf<E>>();
192199
locationExtractor.attachLocation(sourceManager, &e, label);
193200
return TrapClassOf<E>{label};
194201
}
@@ -211,7 +218,7 @@ class SwiftDispatcher {
211218
auto fetchRepeatedLabels(Iterable&& arg) {
212219
using Label = decltype(fetchLabel(*arg.begin()));
213220
TrapLabelVectorWrapper<typename Label::Tag> ret;
214-
if constexpr (requires { arg.size(); }) {
221+
if constexpr (HasSize<Iterable>::value) {
215222
ret.data.reserve(arg.size());
216223
}
217224
for (auto&& e : arg) {
@@ -244,7 +251,7 @@ class SwiftDispatcher {
244251
private:
245252
template <typename E>
246253
UntypedTrapLabel createLabel(const E& e, swift::Type type) {
247-
if constexpr (requires { name(e); }) {
254+
if constexpr (IsDeclPointer<E> || IsTypePointer<E>) {
248255
if (auto mangledName = name(e)) {
249256
if (shouldVisit(e)) {
250257
toBeVisited.emplace_back(e, type);
@@ -259,7 +266,7 @@ class SwiftDispatcher {
259266

260267
template <typename E>
261268
bool shouldVisit(const E& e) {
262-
if constexpr (std::convertible_to<E, const swift::Decl*>) {
269+
if constexpr (IsDeclPointer<E>) {
263270
encounteredModules.insert(e->getModuleContext());
264271
if (bodyEmissionStrategy.shouldEmitDeclBody(*e)) {
265272
extractedDeclaration(e);
@@ -288,6 +295,18 @@ class SwiftDispatcher {
288295
module->isNonSwiftModule();
289296
}
290297

298+
template <typename T, typename = void>
299+
struct HasSize : std::false_type {};
300+
301+
template <typename T>
302+
struct HasSize<T, decltype(std::declval<T>().size(), void())> : std::true_type {};
303+
304+
template <typename T, typename = void>
305+
struct HasId : std::false_type {};
306+
307+
template <typename T>
308+
struct HasId<T, decltype(std::declval<T>().id, void())> : std::true_type {};
309+
291310
template <typename Tag, typename... Ts>
292311
TrapLabel<Tag> fetchLabelFromUnion(const llvm::PointerUnion<Ts...> u) {
293312
TrapLabel<Tag> ret{};
@@ -305,7 +324,7 @@ class SwiftDispatcher {
305324
// on `BraceStmt`/`IfConfigDecl` elements), we cannot encounter a standalone `TypeRepr` there,
306325
// so we skip this case; extracting `TypeRepr`s here would be problematic as we would not be
307326
// able to provide the corresponding type
308-
if constexpr (!std::same_as<T, swift::TypeRepr*>) {
327+
if constexpr (!std::is_same_v<T, swift::TypeRepr*>) {
309328
if (auto e = u.template dyn_cast<T>()) {
310329
output = fetchLabel(e);
311330
return true;
@@ -329,8 +348,10 @@ class SwiftDispatcher {
329348
virtual void visit(const swift::TypeBase* type) = 0;
330349
virtual void visit(const swift::CapturedValue* capture) = 0;
331350

332-
template <typename T>
333-
requires(!std::derived_from<T, swift::TypeRepr>) void visit(const T* e, swift::Type) { visit(e); }
351+
template <typename T, std::enable_if<!std::is_base_of_v<swift::TypeRepr, T>>* = nullptr>
352+
void visit(const T* e, swift::Type) {
353+
visit(e);
354+
}
334355

335356
const swift::SourceManager& sourceManager;
336357
SwiftExtractorState& state;

swift/extractor/infra/SwiftLocationExtractor.cpp

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,19 @@
1212

1313
using namespace codeql;
1414

15-
swift::SourceRange detail::getSourceRange(const swift::Token& token) {
16-
const auto charRange = token.getRange();
17-
return {charRange.getStart(), charRange.getEnd()};
18-
}
19-
2015
void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
21-
const swift::SourceRange& range,
16+
swift::SourceLoc start,
17+
swift::SourceLoc end,
2218
TrapLabel<LocatableTag> locatableLabel) {
23-
if (!range) {
19+
if (!start.isValid() || !end.isValid()) {
2420
// invalid locations seem to come from entities synthesized by the compiler
2521
return;
2622
}
27-
auto file = resolvePath(sourceManager.getDisplayNameForLoc(range.Start));
23+
auto file = resolvePath(sourceManager.getDisplayNameForLoc(start));
2824
DbLocation entry{{}};
2925
entry.file = fetchFileLabel(file);
30-
std::tie(entry.start_line, entry.start_column) =
31-
sourceManager.getLineAndColumnInBuffer(range.Start);
32-
std::tie(entry.end_line, entry.end_column) = sourceManager.getLineAndColumnInBuffer(range.End);
26+
std::tie(entry.start_line, entry.start_column) = sourceManager.getLineAndColumnInBuffer(start);
27+
std::tie(entry.end_line, entry.end_column) = sourceManager.getLineAndColumnInBuffer(end);
3328
SwiftMangledName locName{"loc", entry.file, ':', entry.start_line, ':', entry.start_column,
3429
':', entry.end_line, ':', entry.end_column};
3530
entry.id = trap.createTypedLabel<DbLocationTag>(locName);
@@ -48,6 +43,56 @@ TrapLabel<FileTag> SwiftLocationExtractor::emitFile(const std::filesystem::path&
4843
return fetchFileLabel(resolvePath(file));
4944
}
5045

46+
void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
47+
const swift::SourceRange& range,
48+
TrapLabel<LocatableTag> locatableLabel) {
49+
attachLocationImpl(sourceManager, range.Start, range.End, locatableLabel);
50+
}
51+
52+
void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
53+
const swift::CapturedValue* capture,
54+
TrapLabel<LocatableTag> locatableLabel) {
55+
attachLocationImpl(sourceManager, capture->getLoc(), locatableLabel);
56+
}
57+
58+
void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
59+
const swift::IfConfigClause* clause,
60+
TrapLabel<LocatableTag> locatableLabel) {
61+
attachLocationImpl(sourceManager, clause->Loc, locatableLabel);
62+
}
63+
64+
void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
65+
const swift::AvailabilitySpec* spec,
66+
TrapLabel<LocatableTag> locatableLabel) {
67+
attachLocationImpl(sourceManager, spec->getSourceRange(), locatableLabel);
68+
}
69+
70+
void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
71+
const swift::KeyPathExpr::Component* component,
72+
TrapLabel<LocatableTag> locatableLabel) {
73+
attachLocationImpl(sourceManager, component->getSourceRange().Start,
74+
component->getSourceRange().End, locatableLabel);
75+
}
76+
77+
void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
78+
const swift::Token* token,
79+
TrapLabel<LocatableTag> locatableLabel) {
80+
attachLocationImpl(sourceManager, token->getRange().getStart(), token->getRange().getEnd(),
81+
locatableLabel);
82+
}
83+
84+
void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
85+
swift::SourceLoc loc,
86+
TrapLabel<LocatableTag> locatableLabel) {
87+
attachLocationImpl(sourceManager, loc, loc, locatableLabel);
88+
}
89+
90+
void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
91+
const swift::DiagnosticInfo* diagInfo,
92+
TrapLabel<LocatableTag> locatableLabel) {
93+
attachLocationImpl(sourceManager, diagInfo->Loc, locatableLabel);
94+
}
95+
5196
TrapLabel<FileTag> SwiftLocationExtractor::fetchFileLabel(const std::filesystem::path& file) {
5297
if (store.count(file)) {
5398
return store[file];

0 commit comments

Comments
 (0)