Skip to content

Commit a05706d

Browse files
authored
Merge pull request github#11177 from github/redsun82/swift-decls
Swift: extract `PoundDiagnosticDecl` and `MissingMemberDecl`
2 parents 50c2683 + 9d4a208 commit a05706d

File tree

17 files changed

+134
-31
lines changed

17 files changed

+134
-31
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include <swift/AST/DiagnosticConsumer.h>
4+
5+
namespace codeql {
6+
7+
inline int translateDiagnosticsKind(swift::DiagnosticKind kind) {
8+
using Kind = swift::DiagnosticKind;
9+
switch (kind) {
10+
case Kind::Error:
11+
return 1;
12+
case Kind::Warning:
13+
return 2;
14+
case Kind::Note:
15+
return 3;
16+
case Kind::Remark:
17+
return 4;
18+
default:
19+
return 0;
20+
}
21+
}
22+
23+
} // namespace codeql

swift/extractor/invocation/SwiftDiagnosticsConsumer.cpp

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "swift/extractor/invocation/SwiftDiagnosticsConsumer.h"
22
#include "swift/extractor/trap/generated/TrapEntries.h"
33
#include "swift/extractor/trap/TrapDomain.h"
4+
#include "swift/extractor/infra/SwiftDiagnosticKind.h"
45

56
#include <swift/AST/DiagnosticEngine.h>
67
#include <swift/Basic/SourceManager.h>
@@ -10,26 +11,12 @@
1011

1112
using namespace codeql;
1213

13-
static int diagnosticsKind(const swift::DiagnosticInfo& diagInfo) {
14-
switch (diagInfo.Kind) {
15-
case swift::DiagnosticKind::Error:
16-
return 1;
17-
case swift::DiagnosticKind::Warning:
18-
return 2;
19-
case swift::DiagnosticKind::Note:
20-
return 3;
21-
case swift::DiagnosticKind::Remark:
22-
return 4;
23-
}
24-
return 0;
25-
}
26-
2714
void SwiftDiagnosticsConsumer::handleDiagnostic(swift::SourceManager& sourceManager,
2815
const swift::DiagnosticInfo& diagInfo) {
2916
auto message = getDiagMessage(sourceManager, diagInfo);
3017
DiagnosticsTrap diag{};
3118
diag.id = trap.createLabel<DiagnosticsTag>();
32-
diag.kind = diagnosticsKind(diagInfo);
19+
diag.kind = translateDiagnosticsKind(diagInfo.Kind);
3320
diag.text = message;
3421
trap.emit(diag);
3522
locationExtractor.attachLocation(sourceManager, diagInfo.Loc, diagInfo.Loc, diag.id);

swift/extractor/translators/DeclTranslator.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <swift/AST/GenericParamList.h>
44
#include <swift/AST/ParameterList.h>
5+
#include "swift/extractor/infra/SwiftDiagnosticKind.h"
56

67
namespace codeql {
78
namespace {
@@ -401,4 +402,18 @@ std::optional<codeql::OpaqueTypeDecl> DeclTranslator::translateOpaqueTypeDecl(
401402
return std::nullopt;
402403
}
403404

405+
codeql::PoundDiagnosticDecl DeclTranslator::translatePoundDiagnosticDecl(
406+
const swift::PoundDiagnosticDecl& decl) {
407+
auto entry = createEntry(decl);
408+
entry.kind = translateDiagnosticsKind(decl.getKind());
409+
entry.message = dispatcher.fetchLabel(decl.getMessage());
410+
return entry;
411+
}
412+
413+
codeql::MissingMemberDecl DeclTranslator::translateMissingMemberDecl(
414+
const swift::MissingMemberDecl& decl) {
415+
auto entry = createEntry(decl);
416+
entry.name = decl.getName().getBaseName().userFacingName().str();
417+
return entry;
418+
}
404419
} // namespace codeql

swift/extractor/translators/DeclTranslator.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class DeclTranslator : public AstTranslatorBase<DeclTranslator> {
4646
std::optional<codeql::ModuleDecl> translateModuleDecl(const swift::ModuleDecl& decl);
4747
codeql::IfConfigDecl translateIfConfigDecl(const swift::IfConfigDecl& decl);
4848
std::optional<codeql::OpaqueTypeDecl> translateOpaqueTypeDecl(const swift::OpaqueTypeDecl& decl);
49+
codeql::PoundDiagnosticDecl translatePoundDiagnosticDecl(const swift::PoundDiagnosticDecl& decl);
50+
codeql::MissingMemberDecl translateMissingMemberDecl(const swift::MissingMemberDecl& decl);
4951

5052
private:
5153
std::string mangledName(const swift::ValueDecl& decl);
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
21
private import codeql.swift.generated.decl.MissingMemberDecl
32

4-
class MissingMemberDecl extends Generated::MissingMemberDecl { }
3+
class MissingMemberDecl extends Generated::MissingMemberDecl {
4+
override string toString() { result = this.getName() + " (missing)" }
5+
}

swift/ql/lib/codeql/swift/elements/decl/PoundDiagnosticDecl.qll

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ private import codeql.swift.generated.decl.PoundDiagnosticDecl
22

33
class PoundDiagnosticDecl extends Generated::PoundDiagnosticDecl {
44
override string toString() {
5-
result = "#..." // TODO: Once we extract whether this is an error or a warning we can improve this.
5+
this.isError() and result = "#error(...)"
6+
or
7+
this.isWarning() and result = "#warning(...)"
68
}
9+
10+
predicate isError() { this.getKind() = 1 }
11+
12+
predicate isWarning() { this.getKind() = 2 }
713
}

swift/ql/lib/codeql/swift/generated/ParentChild.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,14 +373,17 @@ private module Impl {
373373
private Element getImmediateChildOfPoundDiagnosticDecl(
374374
PoundDiagnosticDecl e, int index, string partialPredicateCall
375375
) {
376-
exists(int b, int bDecl, int n |
376+
exists(int b, int bDecl, int n, int nMessage |
377377
b = 0 and
378378
bDecl = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfDecl(e, i, _)) | i) and
379379
n = bDecl and
380+
nMessage = n + 1 and
380381
(
381382
none()
382383
or
383384
result = getImmediateChildOfDecl(e, index - b, partialPredicateCall)
385+
or
386+
index = n and result = e.getImmediateMessage() and partialPredicateCall = "Message()"
384387
)
385388
)
386389
}

swift/ql/lib/codeql/swift/generated/Raw.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ module Raw {
115115

116116
class MissingMemberDecl extends @missing_member_decl, Decl {
117117
override string toString() { result = "MissingMemberDecl" }
118+
119+
string getName() { missing_member_decls(this, result) }
118120
}
119121

120122
class OperatorDecl extends @operator_decl, Decl {
@@ -131,6 +133,10 @@ module Raw {
131133

132134
class PoundDiagnosticDecl extends @pound_diagnostic_decl, Decl {
133135
override string toString() { result = "PoundDiagnosticDecl" }
136+
137+
int getKind() { pound_diagnostic_decls(this, result, _) }
138+
139+
StringLiteralExpr getMessage() { pound_diagnostic_decls(this, _, result) }
134140
}
135141

136142
class PrecedenceGroupDecl extends @precedence_group_decl, Decl {

swift/ql/lib/codeql/swift/generated/decl/MissingMemberDecl.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,17 @@ private import codeql.swift.generated.Raw
44
import codeql.swift.elements.decl.Decl
55

66
module Generated {
7+
/**
8+
* A placeholder for missing declarations that can arise on object deserialization.
9+
*/
710
class MissingMemberDecl extends Synth::TMissingMemberDecl, Decl {
811
override string getAPrimaryQlClass() { result = "MissingMemberDecl" }
12+
13+
/**
14+
* Gets the name of this missing member declaration.
15+
*/
16+
string getName() {
17+
result = Synth::convertMissingMemberDeclToRaw(this).(Raw::MissingMemberDecl).getName()
18+
}
919
}
1020
}

swift/ql/lib/codeql/swift/generated/decl/PoundDiagnosticDecl.qll

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,38 @@
22
private import codeql.swift.generated.Synth
33
private import codeql.swift.generated.Raw
44
import codeql.swift.elements.decl.Decl
5+
import codeql.swift.elements.expr.StringLiteralExpr
56

67
module Generated {
8+
/**
9+
* A diagnostic directive, which is either `#error` or `#warning`.
10+
*/
711
class PoundDiagnosticDecl extends Synth::TPoundDiagnosticDecl, Decl {
812
override string getAPrimaryQlClass() { result = "PoundDiagnosticDecl" }
13+
14+
/**
15+
* Gets the This is 1 for `#error` and 2 for `#warning`.
16+
*/
17+
int getKind() {
18+
result = Synth::convertPoundDiagnosticDeclToRaw(this).(Raw::PoundDiagnosticDecl).getKind()
19+
}
20+
21+
/**
22+
* Gets the message of this pound diagnostic declaration.
23+
*
24+
* This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the
25+
* behavior of both the `Immediate` and non-`Immediate` versions.
26+
*/
27+
StringLiteralExpr getImmediateMessage() {
28+
result =
29+
Synth::convertStringLiteralExprFromRaw(Synth::convertPoundDiagnosticDeclToRaw(this)
30+
.(Raw::PoundDiagnosticDecl)
31+
.getMessage())
32+
}
33+
34+
/**
35+
* Gets the message of this pound diagnostic declaration.
36+
*/
37+
final StringLiteralExpr getMessage() { result = getImmediateMessage().resolve() }
938
}
1039
}

0 commit comments

Comments
 (0)