#pragma once #include #include #include "swift/extractor/trap/TrapLabel.h" #include "swift/extractor/infra/TargetFile.h" namespace codeql { // Abstracts a given trap output file, with its own universe of trap labels class TrapDomain { TargetFile& out_; public: explicit TrapDomain(TargetFile& out) : out_{out} {} template void emit(const Entry& e) { print(e); } template void debug(const Args&... args) { print("/* DEBUG:"); print(args...); print("*/"); } template TrapLabel createLabel() { auto ret = allocateLabel(); assignStar(ret); return ret; } template TrapLabel createLabel(Args&&... args) { auto ret = allocateLabel(); assignKey(ret, std::forward(args)...); return ret; } private: uint64_t id_{0}; template TrapLabel allocateLabel() { return TrapLabel::unsafeCreateFromExplicitId(id_++); } template void print(const Args&... args) { (out_ << ... << args) << '\n'; } template void assignStar(TrapLabel label) { print(label, "=*"); } template void assignKey(TrapLabel label, const std::string& key) { // prefix the key with the id to guarantee the same key is not used wrongly with different tags auto prefixed = std::string(Tag::prefix) + '_' + key; print(label, "=@", trapQuoted(prefixed)); } template void assignKey(TrapLabel label, const Args&... keyParts) { std::ostringstream oss; (oss << ... << keyParts); assignKey(label, oss.str()); } }; } // namespace codeql