Skip to content

Commit 3d0935a

Browse files
authored
Merge pull request github#12860 from github/redsun82/swift-logging-assertions-and-prints
Swift: replace assertions and direct prints with proper logging
2 parents 65deb9d + 1d492f8 commit 3d0935a

28 files changed

+251
-146
lines changed

misc/codegen/templates/cpp_classes_h.mustache

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,34 +42,12 @@ struct {{name}}{{#has_bases}} : {{#bases}}{{^first}}, {{/first}}{{ref.name}}{{/b
4242
{{/final}}
4343
template <typename F>
4444
void forEachLabel(F f) {
45-
{{#final}}
46-
f("id", -1, id);
47-
{{/final}}
48-
{{#bases}}
49-
{{ref.name}}::forEachLabel(f);
50-
{{/bases}}
51-
{{#fields}}
52-
{{#is_label}}
53-
{{#is_repeated}}
54-
for (auto i = 0u; i < {{field_name}}.size(); ++i) {
55-
{{#is_optional}}
56-
if ({{field_name}}[i]) f("{{field_name}}", i, *{{field_name}}[i]);
57-
{{/is_optional}}
58-
{{^is_optional}}
59-
f("{{field_name}}", i, {{field_name}}[i]);
60-
{{/is_optional}}
61-
}
62-
{{/is_repeated}}
63-
{{^is_repeated}}
64-
{{#is_optional}}
65-
if ({{field_name}}) f("{{field_name}}", -1, *{{field_name}});
66-
{{/is_optional}}
67-
{{^is_optional}}
68-
f("{{field_name}}", -1, {{field_name}});
69-
{{/is_optional}}
70-
{{/is_repeated}}
71-
{{/is_label}}
72-
{{/fields}}
45+
{{>cpp_for_each_label_body}}
46+
}
47+
48+
template <typename F>
49+
void forEachLabel(F f) const {
50+
{{>cpp_for_each_label_body}}
7351
}
7452

7553
protected:
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{{#final}}
2+
f("id", -1, id);
3+
{{/final}}
4+
{{#bases}}
5+
{{ref.name}}::forEachLabel(f);
6+
{{/bases}}
7+
{{#fields}}
8+
{{#is_label}}
9+
{{#is_repeated}}
10+
for (auto i = 0u; i < {{field_name}}.size(); ++i) {
11+
{{#is_optional}}
12+
if ({{field_name}}[i]) f("{{field_name}}", i, *{{field_name}}[i]);
13+
{{/is_optional}}
14+
{{^is_optional}}
15+
f("{{field_name}}", i, {{field_name}}[i]);
16+
{{/is_optional}}
17+
}
18+
{{/is_repeated}}
19+
{{^is_repeated}}
20+
{{#is_optional}}
21+
if ({{field_name}}) f("{{field_name}}", -1, *{{field_name}});
22+
{{/is_optional}}
23+
{{^is_optional}}
24+
f("{{field_name}}", -1, {{field_name}});
25+
{{/is_optional}}
26+
{{/is_repeated}}
27+
{{/is_label}}
28+
{{/fields}}

misc/codegen/templates/trap_traps_h.mustache

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ struct {{name}}Trap {
2323

2424
template <typename F>
2525
void forEachLabel(F f) {
26-
{{#fields}}
27-
{{#is_label}}
28-
f("{{field_name}}", -1, {{field_name}});
29-
{{/is_label}}
30-
{{/fields}}
26+
{{>cpp_for_each_label_body}}
27+
}
28+
29+
template <typename F>
30+
void forEachLabel(F f) const {
31+
{{>cpp_for_each_label_body}}
3132
}
3233
};
3334

swift/extractor/SwiftExtractor.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <unordered_set>
66
#include <queue>
77

8+
#include <picosha2.h>
89
#include <swift/AST/SourceFile.h>
910
#include <swift/AST/Builtins.h>
1011

@@ -14,19 +15,23 @@
1415
#include "swift/extractor/infra/SwiftLocationExtractor.h"
1516
#include "swift/extractor/infra/SwiftBodyEmissionStrategy.h"
1617
#include "swift/extractor/mangler/SwiftMangler.h"
17-
#include <picosha2.h>
18+
#include "swift/extractor/infra/log/SwiftAssert.h"
1819

1920
using namespace codeql;
2021
using namespace std::string_literals;
2122
namespace fs = std::filesystem;
2223

24+
Logger& main_logger::logger() {
25+
static Logger ret{"main"};
26+
return ret;
27+
}
28+
29+
using namespace main_logger;
30+
2331
static void ensureDirectory(const char* label, const fs::path& dir) {
2432
std::error_code ec;
2533
fs::create_directories(dir, ec);
26-
if (ec) {
27-
std::cerr << "Cannot create " << label << " directory: " << ec.message() << "\n";
28-
std::abort();
29-
}
34+
CODEQL_ASSERT(!ec, "Cannot create {} directory ({})", label, ec);
3035
}
3136

3237
static void archiveFile(const SwiftExtractorConfiguration& config, swift::SourceFile& file) {
@@ -37,10 +42,10 @@ static void archiveFile(const SwiftExtractorConfiguration& config, swift::Source
3742

3843
std::error_code ec;
3944
fs::copy(source, destination, fs::copy_options::overwrite_existing, ec);
40-
4145
if (ec) {
42-
std::cerr << "Cannot archive source file " << source << " -> " << destination << ": "
43-
<< ec.message() << "\n";
46+
LOG_INFO(
47+
"Cannot archive source file {} -> {}, probably a harmless race with another process ({})",
48+
source, destination, ec);
4449
}
4550
}
4651

@@ -73,7 +78,7 @@ static fs::path getFilename(swift::ModuleDecl& module,
7378
if (lazyDeclaration) {
7479
// this code will be thrown away in the near future
7580
auto decl = llvm::dyn_cast<swift::ValueDecl>(lazyDeclaration);
76-
assert(decl);
81+
CODEQL_ASSERT(decl, "not a ValueDecl");
7782
auto mangled = mangledDeclName(*decl);
7883
// mangled name can be too long to use as a file name, so we can't use it directly
7984
mangled = picosha2::hash256_hex_string(mangled);
@@ -276,11 +281,9 @@ void codeql::extractExtractLazyDeclarations(SwiftExtractorState& state,
276281
// Just in case
277282
const int upperBound = 100;
278283
int iteration = 0;
279-
while (!state.pendingDeclarations.empty() && iteration++ < upperBound) {
284+
while (!state.pendingDeclarations.empty()) {
285+
CODEQL_ASSERT(iteration++ < upperBound,
286+
"Swift extractor reached upper bound while extracting lazy declarations");
280287
extractLazy(state, compiler);
281288
}
282-
if (iteration >= upperBound) {
283-
std::cerr << "Swift extractor reached upper bound while extracting lazy declarations\n";
284-
abort();
285-
}
286289
}

swift/extractor/SwiftExtractor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,9 @@
88
namespace codeql {
99
void extractSwiftFiles(SwiftExtractorState& state, swift::CompilerInstance& compiler);
1010
void extractExtractLazyDeclarations(SwiftExtractorState& state, swift::CompilerInstance& compiler);
11+
12+
class Logger;
13+
namespace main_logger {
14+
Logger& logger();
15+
}
1116
} // namespace codeql

swift/extractor/infra/SwiftDispatcher.h

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "swift/extractor/infra/SwiftBodyEmissionStrategy.h"
1414
#include "swift/extractor/infra/SwiftMangledName.h"
1515
#include "swift/extractor/config/SwiftExtractorState.h"
16-
#include "swift/extractor/infra/log/SwiftLogging.h"
16+
#include "swift/extractor/infra/log/SwiftAssert.h"
1717

1818
namespace codeql {
1919

@@ -74,21 +74,20 @@ class SwiftDispatcher {
7474
entry.forEachLabel([&valid, &entry, this](const char* field, int index, auto& label) {
7575
using Label = std::remove_reference_t<decltype(label)>;
7676
if (!label.valid()) {
77-
std::cerr << entry.NAME << " has undefined " << field;
78-
if (index >= 0) {
79-
std::cerr << '[' << index << ']';
80-
}
77+
const char* action;
8178
if constexpr (std::is_base_of_v<typename Label::Tag, UnspecifiedElementTag>) {
82-
std::cerr << ", replacing with unspecified element\n";
79+
action = "replacing with unspecified element";
8380
label = emitUnspecified(idOf(entry), field, index);
8481
} else {
85-
std::cerr << ", skipping emission\n";
82+
action = "skipping emission";
8683
valid = false;
8784
}
85+
LOG_ERROR("{} has undefined field {}{}, {}", entry.NAME, field,
86+
index >= 0 ? ('[' + std::to_string(index) + ']') : "", action);
8887
}
8988
});
9089
if (valid) {
91-
trap.emit(entry);
90+
trap.emit(entry, /* check */ false);
9291
}
9392
}
9493

@@ -153,7 +152,7 @@ class SwiftDispatcher {
153152
auto& stored = store[e];
154153
if (!stored.valid()) {
155154
auto inserted = fetching.insert(e);
156-
assert(inserted.second && "detected infinite fetchLabel recursion");
155+
CODEQL_ASSERT(inserted.second, "detected infinite fetchLabel recursion");
157156
stored = createLabel(e, type);
158157
fetching.erase(e);
159158
}
@@ -165,7 +164,13 @@ class SwiftDispatcher {
165164
TrapLabel<TypeTag> fetchLabel(swift::Type t) { return fetchLabel(t.getPointer()); }
166165

167166
TrapLabel<AstNodeTag> fetchLabel(swift::ASTNode node) {
168-
return fetchLabelFromUnion<AstNodeTag>(node);
167+
auto ret = fetchLabelFromUnion<AstNodeTag>(node);
168+
if (!ret.valid()) {
169+
// TODO to be more useful, we need a generic way of attaching original source location info
170+
// to logs, this will come in upcoming work
171+
LOG_ERROR("Unable to fetch label for ASTNode");
172+
}
173+
return ret;
169174
}
170175

171176
template <typename E, std::enable_if_t<IsFetchable<E*>>* = nullptr>
@@ -177,7 +182,7 @@ class SwiftDispatcher {
177182
template <typename E>
178183
auto createEntry(const E& e) {
179184
auto found = store.find(&e);
180-
assert(found != store.end() && "createEntry called on non-fetched label");
185+
CODEQL_ASSERT(found != store.end(), "createEntry called on non-fetched label");
181186
auto label = TrapLabel<ConcreteTrapTagOf<E>>::unsafeCreateFromUntyped(found->second);
182187
if constexpr (IsLocatable<E>) {
183188
locationExtractor.attachLocation(sourceManager, e, label);
@@ -307,7 +312,6 @@ class SwiftDispatcher {
307312
// with logical op short-circuiting, this will stop trying on the first successful fetch
308313
bool unionCaseFound = (... || fetchLabelFromUnionCase<Tag, Ts>(u, ret));
309314
if (!unionCaseFound) {
310-
// TODO emit error/warning here
311315
return undefined_label;
312316
}
313317
return ret;
@@ -357,7 +361,10 @@ class SwiftDispatcher {
357361
SwiftLocationExtractor& locationExtractor;
358362
SwiftBodyEmissionStrategy& bodyEmissionStrategy;
359363
std::unordered_set<swift::ModuleDecl*> encounteredModules;
360-
Logger logger{"dispatcher"};
364+
Logger& logger() {
365+
static Logger ret{"dispatcher"};
366+
return ret;
367+
}
361368
};
362369

363370
} // namespace codeql

swift/extractor/infra/file/BUILD.bazel

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ load("//swift:rules.bzl", "swift_cc_library")
22

33
swift_cc_library(
44
name = "file",
5-
srcs = glob(["*.cpp"]),
6-
hdrs = glob(["*.h"]) + [":path_hash_workaround"],
5+
srcs = glob(["*.cpp", "FsLogger.h"]),
6+
hdrs = glob(["*.h"], exclude=["FsLogger.h"]) + [":path_hash_workaround"],
77
visibility = ["//swift:__subpackages__"],
8+
deps = ["//swift/extractor/infra/log"],
89
)
910

1011
genrule(

swift/extractor/infra/file/FsLogger.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include "swift/extractor/infra/log/SwiftLogging.h"
2+
3+
namespace codeql {
4+
namespace fs_logger {
5+
inline Logger& logger() {
6+
static Logger ret{"fs"};
7+
return ret;
8+
}
9+
} // namespace fs_logger
10+
} // namespace codeql

swift/extractor/infra/file/Path.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
#include "swift/extractor/infra/file/Path.h"
2+
23
#include <iostream>
34
#include <unistd.h>
45

6+
#include "swift/extractor/infra/file/FsLogger.h"
7+
8+
using namespace std::string_view_literals;
9+
510
namespace codeql {
611

12+
using namespace fs_logger;
13+
714
static bool shouldCanonicalize() {
8-
auto preserve = getenv("CODEQL_PRESERVE_SYMLINKS");
9-
if (preserve && std::string(preserve) == "true") {
10-
return false;
11-
}
12-
preserve = getenv("SEMMLE_PRESERVE_SYMLINKS");
13-
if (preserve && std::string(preserve) == "true") {
14-
return false;
15+
for (auto var : {"CODEQL_PRESERVE_SYMLINKS", "SEMMLE_PRESERVE_SYMLINKS"}) {
16+
if (auto preserve = getenv(var); preserve && preserve == "true"sv) {
17+
return false;
18+
}
1519
}
1620
return true;
1721
}
@@ -26,8 +30,13 @@ std::filesystem::path resolvePath(const std::filesystem::path& path) {
2630
ret = std::filesystem::absolute(path, ec);
2731
}
2832
if (ec) {
29-
std::cerr << "Cannot get " << (canonicalize ? "canonical" : "absolute") << " path: " << path
30-
<< ": " << ec.message() << "\n";
33+
if (ec.value() == ENOENT) {
34+
// this is pretty normal, nothing to spam about
35+
LOG_DEBUG("resolving non-existing {}", path);
36+
} else {
37+
LOG_WARNING("cannot get {} path for {} ({})", canonicalize ? "canonical" : "absolute", path,
38+
ec);
39+
}
3140
return path;
3241
}
3342
return ret;

0 commit comments

Comments
 (0)