Skip to content

Commit

Permalink
Merge pull request #14280 from github/revert-14011-revert-13991-redsu…
Browse files Browse the repository at this point in the history
…n82/swift-use-concepts

Revert "Revert "Swift: use C++20 constraints and concepts to simplify code""
  • Loading branch information
redsun82 authored Sep 21, 2023
2 parents 0530981 + 60b7d79 commit e9e58d9
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 225 deletions.
2 changes: 1 addition & 1 deletion misc/codegen/templates/trap_tags_h.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace codeql {
{{#tags}}

// {{id}}
struct {{name}}Tag {{#has_bases}}: {{#bases}}{{^first}}, {{/first}}{{base}}Tag{{/bases}} {{/has_bases}}{
struct {{name}}Tag {{#has_bases}}: {{#bases}}{{^first}}, {{/first}}virtual {{base}}Tag{{/bases}} {{/has_bases}}{
static constexpr const char* prefix = "{{name}}";
};
{{/tags}}
Expand Down
69 changes: 24 additions & 45 deletions swift/extractor/infra/SwiftDispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,6 @@ class SwiftDispatcher {
const swift::PoundAvailableInfo*,
const swift::AvailabilitySpec*>;

template <typename E>
static constexpr bool IsFetchable = std::is_constructible_v<Handle, const E&>;

template <typename E>
static constexpr bool IsLocatable =
std::is_base_of_v<LocatableTag, TrapTagOf<E>> && !std::is_base_of_v<TypeTag, TrapTagOf<E>>;

template <typename E>
static constexpr bool IsDeclPointer = std::is_convertible_v<E, const swift::Decl*>;

template <typename E>
static constexpr bool IsTypePointer = std::is_convertible_v<E, const swift::TypeBase*>;

public:
// all references and pointers passed as parameters to this constructor are supposed to outlive
// the SwiftDispatcher
Expand All @@ -76,7 +63,7 @@ class SwiftDispatcher {
using Label = std::remove_reference_t<decltype(label)>;
if (!label.valid()) {
const char* action;
if constexpr (std::is_base_of_v<typename Label::Tag, UnspecifiedElementTag>) {
if constexpr (std::derived_from<UnspecifiedElementTag, typename Label::Tag>) {
action = "replacing with unspecified element";
label = emitUnspecified(idOf(entry), field, index);
} else {
Expand Down Expand Up @@ -132,7 +119,7 @@ class SwiftDispatcher {

template <typename E>
std::optional<TrapLabel<ElementTag>> idOf(const E& entry) {
if constexpr (HasId<E>::value) {
if constexpr (requires { entry.id; }) {
return entry.id;
} else {
return std::nullopt;
Expand All @@ -142,13 +129,14 @@ class SwiftDispatcher {
// This method gives a TRAP label for already emitted AST node.
// If the AST node was not emitted yet, then the emission is dispatched to a corresponding
// visitor (see `visit(T *)` methods below).
template <typename E, std::enable_if_t<IsFetchable<E>>* = nullptr>
TrapLabelOf<E> fetchLabel(const E& e, swift::Type type = {}) {
if constexpr (std::is_constructible_v<bool, const E&>) {
if (!e) {
// this will be treated on emission
return undefined_label;
}
// clang-format off
template <typename E>
requires std::constructible_from<Handle, E*>
TrapLabelOf<E> fetchLabel(const E* e, swift::Type type = {}) {
// clang-format on
if (!e) {
// this will be treated on emission
return undefined_label;
}
auto& stored = store[e];
if (!stored.valid()) {
Expand All @@ -174,8 +162,11 @@ class SwiftDispatcher {
return ret;
}

template <typename E, std::enable_if_t<IsFetchable<E*>>* = nullptr>
// clang-format off
template <typename E>
requires std::constructible_from<Handle, E*>
TrapLabelOf<E> fetchLabel(const E& e) {
// clang-format on
return fetchLabel(&e);
}

Expand All @@ -184,7 +175,8 @@ class SwiftDispatcher {
auto createEntry(const E& e) {
auto found = store.find(&e);
CODEQL_ASSERT(found != store.end(), "createEntry called on non-fetched label");
auto label = TrapLabel<ConcreteTrapTagOf<E>>::unsafeCreateFromUntyped(found->second);
using Tag = ConcreteTrapTagOf<E>;
auto label = TrapLabel<Tag>::unsafeCreateFromUntyped(found->second);
if constexpr (IsLocatable<E>) {
locationExtractor.attachLocation(sourceManager, e, label);
}
Expand All @@ -195,7 +187,8 @@ class SwiftDispatcher {
// an example is swift::Argument, that are created on the fly and thus have no stable pointer
template <typename E>
auto createUncachedEntry(const E& e) {
auto label = trap.createTypedLabel<TrapTagOf<E>>();
using Tag = TrapTagOf<E>;
auto label = trap.createTypedLabel<Tag>();
locationExtractor.attachLocation(sourceManager, &e, label);
return TrapClassOf<E>{label};
}
Expand All @@ -218,7 +211,7 @@ class SwiftDispatcher {
auto fetchRepeatedLabels(Iterable&& arg) {
using Label = decltype(fetchLabel(*arg.begin()));
TrapLabelVectorWrapper<typename Label::Tag> ret;
if constexpr (HasSize<Iterable>::value) {
if constexpr (requires { arg.size(); }) {
ret.data.reserve(arg.size());
}
for (auto&& e : arg) {
Expand Down Expand Up @@ -251,7 +244,7 @@ class SwiftDispatcher {
private:
template <typename E>
UntypedTrapLabel createLabel(const E& e, swift::Type type) {
if constexpr (IsDeclPointer<E> || IsTypePointer<E>) {
if constexpr (requires { name(e); }) {
if (auto mangledName = name(e)) {
if (shouldVisit(e)) {
toBeVisited.emplace_back(e, type);
Expand All @@ -266,7 +259,7 @@ class SwiftDispatcher {

template <typename E>
bool shouldVisit(const E& e) {
if constexpr (IsDeclPointer<E>) {
if constexpr (std::convertible_to<E, const swift::Decl*>) {
encounteredModules.insert(e->getModuleContext());
if (bodyEmissionStrategy.shouldEmitDeclBody(*e)) {
extractedDeclaration(e);
Expand Down Expand Up @@ -295,18 +288,6 @@ class SwiftDispatcher {
module->isNonSwiftModule();
}

template <typename T, typename = void>
struct HasSize : std::false_type {};

template <typename T>
struct HasSize<T, decltype(std::declval<T>().size(), void())> : std::true_type {};

template <typename T, typename = void>
struct HasId : std::false_type {};

template <typename T>
struct HasId<T, decltype(std::declval<T>().id, void())> : std::true_type {};

template <typename Tag, typename... Ts>
TrapLabel<Tag> fetchLabelFromUnion(const llvm::PointerUnion<Ts...> u) {
TrapLabel<Tag> ret{};
Expand All @@ -324,7 +305,7 @@ class SwiftDispatcher {
// on `BraceStmt`/`IfConfigDecl` elements), we cannot encounter a standalone `TypeRepr` there,
// so we skip this case; extracting `TypeRepr`s here would be problematic as we would not be
// able to provide the corresponding type
if constexpr (!std::is_same_v<T, swift::TypeRepr*>) {
if constexpr (!std::same_as<T, swift::TypeRepr*>) {
if (auto e = u.template dyn_cast<T>()) {
output = fetchLabel(e);
return true;
Expand All @@ -348,10 +329,8 @@ class SwiftDispatcher {
virtual void visit(const swift::TypeBase* type) = 0;
virtual void visit(const swift::CapturedValue* capture) = 0;

template <typename T, std::enable_if<!std::is_base_of_v<swift::TypeRepr, T>>* = nullptr>
void visit(const T* e, swift::Type) {
visit(e);
}
template <typename T>
requires(!std::derived_from<T, swift::TypeRepr>) void visit(const T* e, swift::Type) { visit(e); }

const swift::SourceManager& sourceManager;
SwiftExtractorState& state;
Expand Down
67 changes: 11 additions & 56 deletions swift/extractor/infra/SwiftLocationExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,24 @@

using namespace codeql;

swift::SourceRange detail::getSourceRange(const swift::Token& token) {
const auto charRange = token.getRange();
return {charRange.getStart(), charRange.getEnd()};
}

void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
swift::SourceLoc start,
swift::SourceLoc end,
const swift::SourceRange& range,
TrapLabel<LocatableTag> locatableLabel) {
if (!start.isValid() || !end.isValid()) {
if (!range) {
// invalid locations seem to come from entities synthesized by the compiler
return;
}
auto file = resolvePath(sourceManager.getDisplayNameForLoc(start));
auto file = resolvePath(sourceManager.getDisplayNameForLoc(range.Start));
DbLocation entry{{}};
entry.file = fetchFileLabel(file);
std::tie(entry.start_line, entry.start_column) = sourceManager.getLineAndColumnInBuffer(start);
std::tie(entry.end_line, entry.end_column) = sourceManager.getLineAndColumnInBuffer(end);
std::tie(entry.start_line, entry.start_column) =
sourceManager.getLineAndColumnInBuffer(range.Start);
std::tie(entry.end_line, entry.end_column) = sourceManager.getLineAndColumnInBuffer(range.End);
SwiftMangledName locName{"loc", entry.file, ':', entry.start_line, ':', entry.start_column,
':', entry.end_line, ':', entry.end_column};
entry.id = trap.createTypedLabel<DbLocationTag>(locName);
Expand All @@ -43,56 +48,6 @@ TrapLabel<FileTag> SwiftLocationExtractor::emitFile(const std::filesystem::path&
return fetchFileLabel(resolvePath(file));
}

void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
const swift::SourceRange& range,
TrapLabel<LocatableTag> locatableLabel) {
attachLocationImpl(sourceManager, range.Start, range.End, locatableLabel);
}

void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
const swift::CapturedValue* capture,
TrapLabel<LocatableTag> locatableLabel) {
attachLocationImpl(sourceManager, capture->getLoc(), locatableLabel);
}

void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
const swift::IfConfigClause* clause,
TrapLabel<LocatableTag> locatableLabel) {
attachLocationImpl(sourceManager, clause->Loc, locatableLabel);
}

void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
const swift::AvailabilitySpec* spec,
TrapLabel<LocatableTag> locatableLabel) {
attachLocationImpl(sourceManager, spec->getSourceRange(), locatableLabel);
}

void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
const swift::KeyPathExpr::Component* component,
TrapLabel<LocatableTag> locatableLabel) {
attachLocationImpl(sourceManager, component->getSourceRange().Start,
component->getSourceRange().End, locatableLabel);
}

void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
const swift::Token* token,
TrapLabel<LocatableTag> locatableLabel) {
attachLocationImpl(sourceManager, token->getRange().getStart(), token->getRange().getEnd(),
locatableLabel);
}

void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
swift::SourceLoc loc,
TrapLabel<LocatableTag> locatableLabel) {
attachLocationImpl(sourceManager, loc, loc, locatableLabel);
}

void SwiftLocationExtractor::attachLocationImpl(const swift::SourceManager& sourceManager,
const swift::DiagnosticInfo* diagInfo,
TrapLabel<LocatableTag> locatableLabel) {
attachLocationImpl(sourceManager, diagInfo->Loc, locatableLabel);
}

TrapLabel<FileTag> SwiftLocationExtractor::fetchFileLabel(const std::filesystem::path& file) {
if (store.count(file)) {
return store[file];
Expand Down
Loading

0 comments on commit e9e58d9

Please sign in to comment.