Skip to content

Commit d5b9752

Browse files
committed
Add option to report missing types for expressions
Signed-off-by: Roberto Raggi <[email protected]>
1 parent 319d04e commit d5b9752

File tree

5 files changed

+189
-101
lines changed

5 files changed

+189
-101
lines changed

packages/cxx-gen-ast/src/gen_ast_h.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ export function gen_ast_h({ ast, output }: { ast: AST; output: string }) {
100100
});
101101
});
102102

103+
emit(`
104+
template <typename T>
105+
[[nodiscard]] auto ast_cast(AST* ast) -> T* {
106+
return ast && ast->kind() == T::Kind ? static_cast<T*>(ast) : nullptr;
107+
}
108+
`);
109+
103110
by_bases.forEach((nodes, base) => {
104111
if (base === "AST") return;
105112
if (!Array.isArray(nodes)) throw new Error("not an array");
@@ -116,15 +123,17 @@ export function gen_ast_h({ ast, output }: { ast: AST; output: string }) {
116123
emit(` default: cxx_runtime_error("unexpected ${variantName}");`);
117124
emit(` } // switch`);
118125
emit(`}`);
126+
119127
emit();
120-
emit(`[[nodiscard]] inline auto is${variantName}(AST* ast) -> bool {`);
121-
emit(` if (!ast) return false;`);
128+
emit(`template <>`);
129+
emit(`[[nodiscard]] inline auto ast_cast<${base}>(AST* ast) -> ${base}* {`);
130+
emit(` if (!ast) return nullptr;`);
122131
emit(` switch (ast->kind()) {`);
123132
nodes.forEach(({ name }) => {
124133
emit(` case ${name}::Kind: `);
125134
});
126-
emit(` return true;`);
127-
emit(` default: return false;`);
135+
emit(` return static_cast<${base}*>(ast);`);
136+
emit(` default: return nullptr;`);
128137
emit(` } // switch`);
129138
emit(`}`);
130139
});
@@ -253,11 +262,6 @@ template <typename T>
253262
254263
${code.join("\n")}
255264
256-
template <typename T>
257-
[[nodiscard]] auto ast_cast(AST* ast) -> T* {
258-
return ast && ast->kind() == T::Kind ? static_cast<T*>(ast) : nullptr;
259-
}
260-
261265
} // namespace cxx
262266
`;
263267

src/frontend/cxx/frontend.cc

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
// SOFTWARE.
2020

2121
#include <cxx/ast.h>
22+
#include <cxx/ast_cursor.h>
2223
#include <cxx/ast_visitor.h>
2324
#include <cxx/cli.h>
2425
#include <cxx/control.h>
@@ -43,7 +44,6 @@
4344
#include <cxx/mlir/cxx_dialect.h>
4445
#endif
4546

46-
#include <cassert>
4747
#include <format>
4848
#include <fstream>
4949
#include <iostream>
@@ -55,8 +55,45 @@
5555
#include "verify_diagnostics_client.h"
5656

5757
namespace {
58+
5859
using namespace cxx;
5960

61+
struct CheckExpressionTypes {
62+
[[nodiscard]] auto operator()(TranslationUnit* unit) {
63+
std::size_t missingTypes = 0;
64+
65+
// iterate over all expressions and check if they have a type
66+
for (auto cursor = ASTCursor{unit->ast(), "unit"}; cursor;
67+
cursor = ++cursor) {
68+
const auto& current = *cursor;
69+
70+
if (!std::holds_alternative<AST*>(current.node)) {
71+
// skip non-AST nodes
72+
continue;
73+
}
74+
75+
auto ast = std::get<AST*>(current.node);
76+
auto expression = ast_cast<ExpressionAST>(ast);
77+
if (!expression) {
78+
// skip non-expression nodes
79+
continue;
80+
}
81+
82+
auto type = expression->type;
83+
if (type) {
84+
// the expression has a type
85+
continue;
86+
}
87+
88+
auto loc = expression->firstSourceLocation();
89+
unit->warning(loc, std::format("missing type for expression"));
90+
++missingTypes;
91+
}
92+
93+
return missingTypes == 0;
94+
}
95+
};
96+
6097
auto readAll(const std::string& fileName, std::istream& in)
6198
-> std::optional<std::string> {
6299
std::string code;
@@ -282,6 +319,11 @@ auto runOnFile(const CLI& cli, const std::string& fileName) -> bool {
282319
.templates = cli.opt_ftemplates,
283320
});
284321

322+
if (cli.opt_freport_missing_types) {
323+
CheckExpressionTypes checkExpressionTypes;
324+
const auto missingTypes = checkExpressionTypes(&unit);
325+
}
326+
285327
if (cli.opt_dump_symbols && unit.globalScope()) {
286328
dump(std::cout, unit.globalScope()->owner());
287329
}

0 commit comments

Comments
 (0)