Skip to content

Commit 1d20255

Browse files
committed
Initial clean up of the compiler frontend driver
1 parent 448edf5 commit 1d20255

File tree

10 files changed

+604
-214
lines changed

10 files changed

+604
-214
lines changed

src/frontend/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919

2020

2121
add_executable(cxx
22+
cxx/cxx.cc
23+
cxx/dump_tokens.cc
2224
cxx/frontend.cc
2325
cxx/verify_diagnostics_client.cc
26+
cxx/check_expression_types.cc
2427
)
2528

2629
target_link_libraries(cxx PRIVATE cxx-lsp)
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright (c) 2025 Roberto Raggi <[email protected]>
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
#include "check_expression_types.h"
22+
23+
#include <cxx/ast.h>
24+
#include <cxx/ast_visitor.h>
25+
26+
#include <format>
27+
28+
namespace cxx {
29+
30+
namespace {
31+
32+
class CheckExpressionTypes final : private ASTVisitor {
33+
public:
34+
[[nodiscard]] auto operator()(TranslationUnit* unit) {
35+
std::size_t missingTypes = 0;
36+
std::swap(unit_, unit);
37+
std::swap(missingTypes_, missingTypes);
38+
39+
accept(unit_->ast());
40+
41+
std::swap(unit_, unit);
42+
std::swap(missingTypes_, missingTypes);
43+
44+
return missingTypes == 0;
45+
}
46+
47+
private:
48+
using ASTVisitor::visit;
49+
50+
auto preVisit(AST* ast) -> bool override {
51+
if (ast_cast<TemplateDeclarationAST>(ast)) {
52+
// skip template declarations, as they are not instantiated yet
53+
return false;
54+
}
55+
56+
if (auto expression = ast_cast<ExpressionAST>(ast)) {
57+
if (!expression->type) {
58+
const auto loc = expression->firstSourceLocation();
59+
60+
unit_->warning(loc, std::format("untyped expression of kind '{}'",
61+
to_string(expression->kind())));
62+
63+
++missingTypes_;
64+
return false;
65+
}
66+
}
67+
68+
return true; // visit children
69+
}
70+
71+
private:
72+
TranslationUnit* unit_ = nullptr;
73+
std::size_t missingTypes_ = 0;
74+
};
75+
76+
} // namespace
77+
78+
auto checkExpressionTypes(TranslationUnit& unit) -> bool {
79+
CheckExpressionTypes checkExpressionTypes;
80+
return checkExpressionTypes(&unit);
81+
}
82+
83+
} // namespace cxx
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) 2025 Roberto Raggi <[email protected]>
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
#pragma once
22+
23+
#include <cxx/translation_unit.h>
24+
25+
namespace cxx {
26+
27+
[[nodiscard]] auto checkExpressionTypes(TranslationUnit& unit) -> bool;
28+
29+
}

src/frontend/cxx/cxx.cc

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) 2025 Roberto Raggi <[email protected]>
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
#include <cxx/lsp/lsp_server.h>
22+
23+
#include <iostream>
24+
25+
#include "frontend.h"
26+
27+
auto main(int argc, char* argv[]) -> int {
28+
cxx::CLI cli;
29+
cli.parse(argc, argv);
30+
31+
if (cli.opt_help) {
32+
cli.showHelp();
33+
return EXIT_SUCCESS;
34+
}
35+
36+
const auto& inputFiles = cli.positionals();
37+
38+
if (cli.opt_lsp_test) {
39+
cli.opt_lsp = true;
40+
}
41+
42+
if (!cli.opt_lsp && inputFiles.empty()) {
43+
std::cerr << "cxx: no input files" << std::endl
44+
<< "Usage: cxx [options] file..." << std::endl;
45+
return EXIT_FAILURE;
46+
}
47+
48+
if (cli.opt_lsp) {
49+
auto server = cxx::lsp::Server{cli};
50+
51+
return server.start();
52+
}
53+
54+
auto existStatus = EXIT_SUCCESS;
55+
56+
for (const auto& fileName : inputFiles) {
57+
cxx::Frontend runOnFile(cli, fileName);
58+
59+
if (!runOnFile()) {
60+
existStatus = EXIT_FAILURE;
61+
}
62+
}
63+
64+
return existStatus;
65+
}

src/frontend/cxx/dump_tokens.cc

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright (c) 2025 Roberto Raggi <[email protected]>
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
#include "dump_tokens.h"
22+
23+
#include <cxx/lexer.h>
24+
25+
#include <format>
26+
#include <iostream>
27+
28+
namespace cxx {
29+
30+
DumpTokens::DumpTokens(const CLI& cli) : cli(cli) {}
31+
32+
void DumpTokens::operator()(TranslationUnit& unit, std::ostream& output) {
33+
auto lang = LanguageKind::kCXX;
34+
35+
if (auto x = cli.getSingle("x")) {
36+
if (x == "c") lang = LanguageKind::kC;
37+
} else if (unit.fileName().ends_with(".c")) {
38+
lang = LanguageKind::kC;
39+
}
40+
41+
std::string flags;
42+
43+
for (SourceLocation loc(1);; loc = loc.next()) {
44+
const auto& tk = unit.tokenAt(loc);
45+
46+
flags.clear();
47+
48+
if (tk.startOfLine()) {
49+
flags += " [start-of-line]";
50+
}
51+
52+
if (tk.leadingSpace()) {
53+
flags += " [leading-space]";
54+
}
55+
56+
auto kind = tk.kind();
57+
if (kind == TokenKind::T_IDENTIFIER) {
58+
kind = Lexer::classifyKeyword(tk.spell(), lang);
59+
}
60+
61+
output << std::format("{} '{}'{}", Token::name(kind), tk.spell(), flags);
62+
63+
auto pos = unit.tokenStartPosition(loc);
64+
65+
output << std::format(" at {}:{}:{}\n", pos.fileName, pos.line, pos.column);
66+
67+
if (tk.is(TokenKind::T_EOF_SYMBOL)) break;
68+
}
69+
}
70+
71+
} // namespace cxx

src/frontend/cxx/dump_tokens.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) 2025 Roberto Raggi <[email protected]>
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to deal
5+
// in the Software without restriction, including without limitation the rights
6+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
// copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
#pragma once
22+
23+
#include <cxx/cli.h>
24+
#include <cxx/translation_unit.h>
25+
26+
namespace cxx {
27+
28+
class DumpTokens {
29+
public:
30+
DumpTokens(const CLI& cli);
31+
32+
void operator()(TranslationUnit& unit, std::ostream& output);
33+
34+
private:
35+
const CLI& cli;
36+
};
37+
38+
} // namespace cxx

0 commit comments

Comments
 (0)