#pragma once #include #include #include #include #include #include #include #include "swift/extractor/trap/generated/TrapEntries.h" #include "swift/extractor/infra/file/PathHash.h" namespace codeql { class TrapDomain; class SwiftLocationExtractor { template struct HasSpecializedImplementation : std::false_type {}; public: explicit SwiftLocationExtractor(TrapDomain& trap) : trap(trap) {} TrapLabel emitFile(swift::SourceFile* file); TrapLabel emitFile(const std::filesystem::path& file); template void attachLocation(const swift::SourceManager& sourceManager, const Locatable& locatable, TrapLabel locatableLabel) { attachLocation(sourceManager, &locatable, locatableLabel); } // Emits a Location TRAP entry and attaches it to a `Locatable` trap label template ::value>* = nullptr> void attachLocation(const swift::SourceManager& sourceManager, const Locatable* locatable, TrapLabel locatableLabel) { attachLocationImpl(sourceManager, locatable->getStartLoc(), locatable->getEndLoc(), locatableLabel); } template ::value>* = nullptr> void attachLocation(const swift::SourceManager& sourceManager, const Locatable* locatable, TrapLabel locatableLabel) { attachLocationImpl(sourceManager, locatable, locatableLabel); } private: // Emits a Location TRAP entry for a list of swift entities and attaches it to a `Locatable` trap // label template void attachLocationImpl(const swift::SourceManager& sourceManager, const llvm::MutableArrayRef* locatables, TrapLabel locatableLabel) { if (locatables->empty()) { return; } attachLocationImpl(sourceManager, locatables->front().getStartLoc(), locatables->back().getEndLoc(), locatableLabel); } void attachLocationImpl(const swift::SourceManager& sourceManager, swift::SourceLoc start, swift::SourceLoc end, TrapLabel locatableLabel); void attachLocationImpl(const swift::SourceManager& sourceManager, swift::SourceLoc loc, TrapLabel locatableLabel); void attachLocationImpl(const swift::SourceManager& sourceManager, const swift::SourceRange& range, TrapLabel locatableLabel); void attachLocationImpl(const swift::SourceManager& sourceManager, const swift::CapturedValue* capture, TrapLabel locatableLabel); void attachLocationImpl(const swift::SourceManager& sourceManager, const swift::IfConfigClause* clause, TrapLabel locatableLabel); void attachLocationImpl(const swift::SourceManager& sourceManager, const swift::AvailabilitySpec* spec, TrapLabel locatableLabel); void attachLocationImpl(const swift::SourceManager& sourceManager, const swift::Token* token, TrapLabel locatableLabel); void attachLocationImpl(const swift::SourceManager& sourceManager, const swift::DiagnosticInfo* token, TrapLabel locatableLabel); void attachLocationImpl(const swift::SourceManager& sourceManager, const swift::KeyPathExpr::Component* component, TrapLabel locatableLabel); private: TrapLabel fetchFileLabel(const std::filesystem::path& file); TrapDomain& trap; std::unordered_map, codeql::PathHash> store; }; template struct SwiftLocationExtractor::HasSpecializedImplementation< Locatable, decltype(std::declval().attachLocationImpl( std::declval(), std::declval(), std::declval>()))> : std::true_type {}; } // namespace codeql