From 86d63f59437f9799281824162f73e0eb5df4be03 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Sat, 15 Feb 2025 11:10:46 +0100 Subject: [PATCH] Add expression kind to missing types warning Signed-off-by: Roberto Raggi --- packages/cxx-gen-ast/src/gen_ast_cc.ts | 25 ++ packages/cxx-gen-ast/src/gen_ast_fwd_h.ts | 2 + packages/cxx-gen-ast/src/gen_ast_kind_h.ts | 2 +- packages/cxx-gen-ast/src/gen_ast_slot_cc.ts | 12 +- packages/cxx-gen-ast/src/gen_token_fwd_h.ts | 12 +- src/frontend/cxx/frontend.cc | 10 +- src/lsp/cxx/lsp/cxx_document.cc | 3 - src/lsp/cxx/lsp/lsp_server.cc | 2 - src/mlir/cxx/mlir/codegen.cc | 2 - src/parser/cxx/ast.cc | 279 +++++++++++++++++++ src/parser/cxx/ast_fwd.h | 2 + src/parser/cxx/ast_kind.h | 2 +- src/parser/cxx/ast_slot.cc | 2 +- src/parser/cxx/cli.cc | 8 +- src/parser/cxx/const_expression_evaluator.cc | 1 - src/parser/cxx/diagnostic.h | 2 +- src/parser/cxx/lexer.cc | 2 +- src/parser/cxx/literals.h | 2 +- src/parser/cxx/name_printer.cc | 94 ++++--- src/parser/cxx/name_printer.h | 41 --- src/parser/cxx/names_fwd.h | 2 + src/parser/cxx/parser.cc | 15 +- src/parser/cxx/parser.h | 12 +- src/parser/cxx/preprocessor.cc | 1 - src/parser/cxx/symbol_instantiation.cc | 2 - src/parser/cxx/symbol_printer.cc | 4 - src/parser/cxx/symbol_printer.h | 34 --- src/parser/cxx/symbols.cc | 2 - src/parser/cxx/symbols_fwd.h | 8 +- src/parser/cxx/token_fwd.h | 4 +- src/parser/cxx/type_printer.cc | 3 - src/parser/cxx/type_printer.h | 33 --- src/parser/cxx/types_fwd.h | 7 + tests/api_tests/test_control.cc | 1 - tests/api_tests/test_substitution.cc | 3 - tests/api_tests/test_type_printer.cc | 1 - 36 files changed, 408 insertions(+), 229 deletions(-) delete mode 100644 src/parser/cxx/name_printer.h delete mode 100644 src/parser/cxx/symbol_printer.h delete mode 100644 src/parser/cxx/type_printer.h diff --git a/packages/cxx-gen-ast/src/gen_ast_cc.ts b/packages/cxx-gen-ast/src/gen_ast_cc.ts index 52a838ac..42dd753e 100644 --- a/packages/cxx-gen-ast/src/gen_ast_cc.ts +++ b/packages/cxx-gen-ast/src/gen_ast_cc.ts @@ -19,6 +19,7 @@ // SOFTWARE. import { cpy_header } from "./cpy_header.js"; +import { groupNodesByBaseType } from "./groupNodesByBaseType.js"; import { AST } from "./parseAST.js"; import * as fs from "fs"; @@ -26,6 +27,13 @@ export function gen_ast_cc({ ast, output }: { ast: AST; output: string }) { const code: string[] = []; const emit = (line = "") => code.push(line); + const by_bases = groupNodesByBaseType(ast); + + const toKebapName = (name: string) => + name.replace(/([A-Z]+)/g, "-$1").toLocaleLowerCase(); + + const astName = (name: string) => toKebapName(name.slice(0, -3)).slice(1); + ast.nodes.forEach(({ name, members }) => { emit(); emit(`auto ${name}::firstSourceLocation() -> SourceLocation {`); @@ -46,6 +54,23 @@ export function gen_ast_cc({ ast, output }: { ast: AST; output: string }) { emit(`}`); }); + emit(); + emit(`namespace {`); + emit(`std::string_view kASTKindNames[] = {`); + by_bases.forEach((nodes, base) => { + emit(); + emit(` // ${base}`); + nodes.forEach(({ name }) => { + emit(` "${astName(name)}",`); + }); + }); + emit(`};`); + emit(`} // namespace`); + + emit(`auto to_string(ASTKind kind) -> std::string_view {`); + emit(` return kASTKindNames[int(kind)];`); + emit(`}`); + const out = `${cpy_header} #include diff --git a/packages/cxx-gen-ast/src/gen_ast_fwd_h.ts b/packages/cxx-gen-ast/src/gen_ast_fwd_h.ts index 546a4ea1..dee05f1f 100644 --- a/packages/cxx-gen-ast/src/gen_ast_fwd_h.ts +++ b/packages/cxx-gen-ast/src/gen_ast_fwd_h.ts @@ -88,6 +88,8 @@ enum class ImplicitCastKind { ${code.join("\n")} +enum class ASTKind; +auto to_string(ASTKind kind) -> std::string_view; auto to_string(ValueCategory valueCategory) -> std::string_view; auto to_string(ImplicitCastKind implicitCastKind) -> std::string_view; diff --git a/packages/cxx-gen-ast/src/gen_ast_kind_h.ts b/packages/cxx-gen-ast/src/gen_ast_kind_h.ts index 2a480f72..f3a27ac8 100644 --- a/packages/cxx-gen-ast/src/gen_ast_kind_h.ts +++ b/packages/cxx-gen-ast/src/gen_ast_kind_h.ts @@ -31,7 +31,7 @@ export function gen_ast_kind_h({ ast, output }: { ast: AST; output: string }) { const enumName = (name: string) => name.slice(0, -3); - emit(`enum struct ASTKind {`); + emit(`enum class ASTKind {`); by_bases.forEach((nodes, base) => { emit(); diff --git a/packages/cxx-gen-ast/src/gen_ast_slot_cc.ts b/packages/cxx-gen-ast/src/gen_ast_slot_cc.ts index e7d4d680..edd1b45c 100644 --- a/packages/cxx-gen-ast/src/gen_ast_slot_cc.ts +++ b/packages/cxx-gen-ast/src/gen_ast_slot_cc.ts @@ -44,14 +44,14 @@ export function gen_ast_slot_cc({ ast, output }: { ast: AST; output: string }) { emit(`};`); emit(`} // namespace`); - emit(`std::string_view to_string(SlotNameIndex index) {`); + emit(`auto to_string(SlotNameIndex index) -> std::string_view {`); emit(` return kMemberSlotNames[int(index)];`); emit(`}`); by_base.forEach((nodes) => { nodes.forEach(({ name, members }) => { const memberSlots = members.filter( - (m) => classifyMemberSlot(m) !== undefined, + (m) => classifyMemberSlot(m) !== undefined ); emit(); @@ -87,7 +87,7 @@ export function gen_ast_slot_cc({ ast, output }: { ast: AST; output: string }) { case MemberSlotClassification.IdentifierAttribute: emit(` case ${slotCount}: // ${m.name}`); emit( - ` value_ = reinterpret_cast(ast->${m.name});`, + ` value_ = reinterpret_cast(ast->${m.name});` ); emit(` slotKind_ = ASTSlotKind::kIdentifierAttribute;`); emit(` slotNameIndex_ = SlotNameIndex{${slotNameIndex}};`); @@ -96,7 +96,7 @@ export function gen_ast_slot_cc({ ast, output }: { ast: AST; output: string }) { case MemberSlotClassification.LiteralAttribute: emit(` case ${slotCount}: // ${m.name}`); emit( - ` value_ = reinterpret_cast(ast->${m.name});`, + ` value_ = reinterpret_cast(ast->${m.name});` ); emit(` slotKind_ = ASTSlotKind::kLiteralAttribute;`); emit(` slotNameIndex_ = SlotNameIndex{${slotNameIndex}};`); @@ -112,7 +112,7 @@ export function gen_ast_slot_cc({ ast, output }: { ast: AST; output: string }) { case MemberSlotClassification.Node: emit(` case ${slotCount}: // ${m.name}`); emit( - ` value_ = reinterpret_cast(ast->${m.name});`, + ` value_ = reinterpret_cast(ast->${m.name});` ); emit(` slotKind_ = ASTSlotKind::kNode;`); emit(` slotNameIndex_ = SlotNameIndex{${slotNameIndex}};`); @@ -121,7 +121,7 @@ export function gen_ast_slot_cc({ ast, output }: { ast: AST; output: string }) { case MemberSlotClassification.NodeList: emit(` case ${slotCount}: // ${m.name}`); emit( - ` value_ = reinterpret_cast(ast->${m.name});`, + ` value_ = reinterpret_cast(ast->${m.name});` ); emit(` slotKind_ = ASTSlotKind::kNodeList;`); emit(` slotNameIndex_ = SlotNameIndex{${slotNameIndex}};`); diff --git a/packages/cxx-gen-ast/src/gen_token_fwd_h.ts b/packages/cxx-gen-ast/src/gen_token_fwd_h.ts index 58f3ff6c..1a9f6829 100644 --- a/packages/cxx-gen-ast/src/gen_token_fwd_h.ts +++ b/packages/cxx-gen-ast/src/gen_token_fwd_h.ts @@ -30,13 +30,13 @@ export function gen_token_fwd_h({ output }: { output: string }) { emit("#define FOR_EACH_BASE_TOKEN(V) \\"); tokens.BASE_TOKENS.forEach((tk) => - emit(` V(${tk}, "${baseTokenId(tk)}") \\`), + emit(` V(${tk}, "${baseTokenId(tk)}") \\`) ); emit(); emit("#define FOR_EACH_OPERATOR(V) \\"); tokens.OPERATORS.forEach(([tk, spelling]) => - emit(` V(${tk}, "${spelling}") \\`), + emit(` V(${tk}, "${spelling}") \\`) ); emit(); @@ -46,13 +46,13 @@ export function gen_token_fwd_h({ output }: { output: string }) { emit(); emit("#define FOR_EACH_BUILTIN_TYPE_TRAIT(V) \\"); tokens.BUILTIN_TYPE_TRAITS.forEach((tk) => - emit(` V(${tk.toUpperCase()}, "${tk}") \\`), + emit(` V(${tk.toUpperCase()}, "${tk}") \\`) ); emit(); emit("#define FOR_EACH_TOKEN_ALIAS(V) \\"); tokens.TOKEN_ALIASES.forEach(([tk, other]) => - emit(` V(${tk.toUpperCase()}, ${other}) \\`), + emit(` V(${tk.toUpperCase()}, ${other}) \\`) ); const out = `${cpy_header} @@ -76,12 +76,12 @@ ${code.join("\n")} // clang-format off #define TOKEN_ENUM(tk, _) T_##tk, #define TOKEN_ALIAS_ENUM(tk, other) T_##tk = T_##other, -enum struct TokenKind : std::uint8_t { +enum class TokenKind : std::uint8_t { FOR_EACH_TOKEN(TOKEN_ENUM) FOR_EACH_TOKEN_ALIAS(TOKEN_ALIAS_ENUM) }; -enum struct BuiltinTypeTraitKind { +enum class BuiltinTypeTraitKind { T_NONE, FOR_EACH_BUILTIN_TYPE_TRAIT(TOKEN_ENUM) }; diff --git a/src/frontend/cxx/frontend.cc b/src/frontend/cxx/frontend.cc index f7e2230a..be1440c5 100644 --- a/src/frontend/cxx/frontend.cc +++ b/src/frontend/cxx/frontend.cc @@ -27,14 +27,11 @@ #include #include #include -#include #include #include #include -#include #include #include -#include #include #include #include @@ -85,8 +82,11 @@ struct CheckExpressionTypes { continue; } - auto loc = expression->firstSourceLocation(); - unit->warning(loc, std::format("missing type for expression")); + const auto loc = expression->firstSourceLocation(); + + unit->warning(loc, std::format("untyped expression of kind '{}'", + to_string(expression->kind()))); + ++missingTypes; } diff --git a/src/lsp/cxx/lsp/cxx_document.cc b/src/lsp/cxx/lsp/cxx_document.cc index dbc1d820..9b8328f4 100644 --- a/src/lsp/cxx/lsp/cxx_document.cc +++ b/src/lsp/cxx/lsp/cxx_document.cc @@ -26,14 +26,11 @@ #include #include #include -#include #include #include #include -#include #include #include -#include #include #include #include diff --git a/src/lsp/cxx/lsp/lsp_server.cc b/src/lsp/cxx/lsp/lsp_server.cc index b41f2e2a..41ddc9f2 100644 --- a/src/lsp/cxx/lsp/lsp_server.cc +++ b/src/lsp/cxx/lsp/lsp_server.cc @@ -24,10 +24,8 @@ #include #include #include -#include #include #include -#include #include #include diff --git a/src/mlir/cxx/mlir/codegen.cc b/src/mlir/cxx/mlir/codegen.cc index 85e7da26..3b4174b9 100644 --- a/src/mlir/cxx/mlir/codegen.cc +++ b/src/mlir/cxx/mlir/codegen.cc @@ -26,11 +26,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include diff --git a/src/parser/cxx/ast.cc b/src/parser/cxx/ast.cc index 322119e1..cdcdb28e 100644 --- a/src/parser/cxx/ast.cc +++ b/src/parser/cxx/ast.cc @@ -3408,6 +3408,285 @@ auto SimpleAttributeTokenAST::lastSourceLocation() -> SourceLocation { return {}; } +namespace { +std::string_view kASTKindNames[] = { + + // UnitAST + "translation-unit", + "module-unit", + + // DeclarationAST + "simple-declaration", + "asm-declaration", + "namespace-alias-definition", + "using-declaration", + "using-enum-declaration", + "using-directive", + "static-assert-declaration", + "alias-declaration", + "opaque-enum-declaration", + "function-definition", + "template-declaration", + "concept-definition", + "deduction-guide", + "explicit-instantiation", + "export-declaration", + "export-compound-declaration", + "linkage-specification", + "namespace-definition", + "empty-declaration", + "attribute-declaration", + "module-import-declaration", + "parameter-declaration", + "access-declaration", + "for-range-declaration", + "structured-binding-declaration", + "asm-operand", + "asm-qualifier", + "asm-clobber", + "asm-goto-label", + + // StatementAST + "labeled-statement", + "case-statement", + "default-statement", + "expression-statement", + "compound-statement", + "if-statement", + "consteval-if-statement", + "switch-statement", + "while-statement", + "do-statement", + "for-range-statement", + "for-statement", + "break-statement", + "continue-statement", + "return-statement", + "coroutine-return-statement", + "goto-statement", + "declaration-statement", + "try-block-statement", + + // ExpressionAST + "generated-literal-expression", + "char-literal-expression", + "bool-literal-expression", + "int-literal-expression", + "float-literal-expression", + "nullptr-literal-expression", + "string-literal-expression", + "user-defined-string-literal-expression", + "this-expression", + "nested-statement-expression", + "nested-expression", + "id-expression", + "lambda-expression", + "fold-expression", + "right-fold-expression", + "left-fold-expression", + "requires-expression", + "va-arg-expression", + "subscript-expression", + "call-expression", + "type-construction", + "braced-type-construction", + "splice-member-expression", + "member-expression", + "post-incr-expression", + "cpp-cast-expression", + "builtin-bit-cast-expression", + "builtin-offsetof-expression", + "typeid-expression", + "typeid-of-type-expression", + "splice-expression", + "global-scope-reflect-expression", + "namespace-reflect-expression", + "type-id-reflect-expression", + "reflect-expression", + "unary-expression", + "await-expression", + "sizeof-expression", + "sizeof-type-expression", + "sizeof-pack-expression", + "alignof-type-expression", + "alignof-expression", + "noexcept-expression", + "new-expression", + "delete-expression", + "cast-expression", + "implicit-cast-expression", + "binary-expression", + "conditional-expression", + "yield-expression", + "throw-expression", + "assignment-expression", + "pack-expansion-expression", + "designated-initializer-clause", + "type-trait-expression", + "condition-expression", + "equal-initializer", + "braced-init-list", + "paren-initializer", + + // AST + "splicer", + "global-module-fragment", + "private-module-fragment", + "module-declaration", + "module-name", + "module-qualifier", + "module-partition", + "import-name", + "init-declarator", + "declarator", + "using-declarator", + "enumerator", + "type-id", + "handler", + "base-specifier", + "requires-clause", + "parameter-declaration-clause", + "trailing-return-type", + "lambda-specifier", + "type-constraint", + "attribute-argument-clause", + "attribute", + "attribute-using-prefix", + "new-placement", + "nested-namespace-specifier", + + // TemplateParameterAST + "template-type-parameter", + "non-type-template-parameter", + "typename-type-parameter", + "constraint-type-parameter", + + // SpecifierAST + "generated-type-specifier", + "typedef-specifier", + "friend-specifier", + "consteval-specifier", + "constinit-specifier", + "constexpr-specifier", + "inline-specifier", + "static-specifier", + "extern-specifier", + "thread-local-specifier", + "thread-specifier", + "mutable-specifier", + "virtual-specifier", + "explicit-specifier", + "auto-type-specifier", + "void-type-specifier", + "size-type-specifier", + "sign-type-specifier", + "va-list-type-specifier", + "integral-type-specifier", + "floating-point-type-specifier", + "complex-type-specifier", + "named-type-specifier", + "atomic-type-specifier", + "underlying-type-specifier", + "elaborated-type-specifier", + "decltype-auto-specifier", + "decltype-specifier", + "placeholder-type-specifier", + "const-qualifier", + "volatile-qualifier", + "restrict-qualifier", + "enum-specifier", + "class-specifier", + "typename-specifier", + "splicer-type-specifier", + + // PtrOperatorAST + "pointer-operator", + "reference-operator", + "ptr-to-member-operator", + + // CoreDeclaratorAST + "bitfield-declarator", + "parameter-pack", + "id-declarator", + "nested-declarator", + + // DeclaratorChunkAST + "function-declarator-chunk", + "array-declarator-chunk", + + // UnqualifiedIdAST + "name-id", + "destructor-id", + "decltype-id", + "operator-function-id", + "literal-operator-id", + "conversion-function-id", + "simple-template-id", + "literal-operator-template-id", + "operator-function-template-id", + + // NestedNameSpecifierAST + "global-nested-name-specifier", + "simple-nested-name-specifier", + "decltype-nested-name-specifier", + "template-nested-name-specifier", + + // FunctionBodyAST + "default-function-body", + "compound-statement-function-body", + "try-statement-function-body", + "delete-function-body", + + // TemplateArgumentAST + "type-template-argument", + "expression-template-argument", + + // ExceptionSpecifierAST + "throw-exception-specifier", + "noexcept-specifier", + + // RequirementAST + "simple-requirement", + "compound-requirement", + "type-requirement", + "nested-requirement", + + // NewInitializerAST + "new-paren-initializer", + "new-braced-initializer", + + // MemInitializerAST + "paren-mem-initializer", + "braced-mem-initializer", + + // LambdaCaptureAST + "this-lambda-capture", + "deref-this-lambda-capture", + "simple-lambda-capture", + "ref-lambda-capture", + "ref-init-lambda-capture", + "init-lambda-capture", + + // ExceptionDeclarationAST + "ellipsis-exception-declaration", + "type-exception-declaration", + + // AttributeSpecifierAST + "cxx-attribute", + "gcc-attribute", + "alignas-attribute", + "alignas-type-attribute", + "asm-attribute", + + // AttributeTokenAST + "scoped-attribute-token", + "simple-attribute-token", +}; +} // namespace +auto to_string(ASTKind kind) -> std::string_view { + return kASTKindNames[int(kind)]; +} + auto to_string(ValueCategory valueCategory) -> std::string_view { switch (valueCategory) { case ValueCategory::kNone: diff --git a/src/parser/cxx/ast_fwd.h b/src/parser/cxx/ast_fwd.h index 075520be..fc0d7875 100644 --- a/src/parser/cxx/ast_fwd.h +++ b/src/parser/cxx/ast_fwd.h @@ -348,6 +348,8 @@ class AsmAttributeAST; class ScopedAttributeTokenAST; class SimpleAttributeTokenAST; +enum class ASTKind; +auto to_string(ASTKind kind) -> std::string_view; auto to_string(ValueCategory valueCategory) -> std::string_view; auto to_string(ImplicitCastKind implicitCastKind) -> std::string_view; diff --git a/src/parser/cxx/ast_kind.h b/src/parser/cxx/ast_kind.h index 2ce61baf..cbaf586b 100644 --- a/src/parser/cxx/ast_kind.h +++ b/src/parser/cxx/ast_kind.h @@ -22,7 +22,7 @@ namespace cxx { -enum struct ASTKind { +enum class ASTKind { // UnitAST TranslationUnit, diff --git a/src/parser/cxx/ast_slot.cc b/src/parser/cxx/ast_slot.cc index 9dbbc4ba..aa75429c 100644 --- a/src/parser/cxx/ast_slot.cc +++ b/src/parser/cxx/ast_slot.cc @@ -278,7 +278,7 @@ std::string_view kMemberSlotNames[] = { "yieldLoc", }; } // namespace -std::string_view to_string(SlotNameIndex index) { +auto to_string(SlotNameIndex index) -> std::string_view { return kMemberSlotNames[int(index)]; } diff --git a/src/parser/cxx/cli.cc b/src/parser/cxx/cli.cc index 2254e66b..15f8c124 100644 --- a/src/parser/cxx/cli.cc +++ b/src/parser/cxx/cli.cc @@ -49,13 +49,13 @@ auto to_string(const CLIMatch& match) -> std::string { namespace { -enum struct CLIOptionDescrKind { +enum class CLIOptionDescrKind { kFlag, kJoined, kSeparated, }; -enum struct CLIOptionVisibility : bool { +enum class CLIOptionVisibility : bool { kDefault, kExperimental, }; @@ -65,7 +65,7 @@ struct CLIOptionDescr { std::string arg; std::string help; CLIOptionDescrKind kind; - bool CLI::*flag = nullptr; + bool CLI::* flag = nullptr; CLIOptionVisibility visibility{CLIOptionVisibility::kDefault}; CLIOptionDescr(std::string option, std::string arg, std::string help, @@ -85,7 +85,7 @@ struct CLIOptionDescr { kind(kind), visibility(visibility) {} - CLIOptionDescr(std::string option, std::string help, bool CLI::*flag, + CLIOptionDescr(std::string option, std::string help, bool CLI::* flag, CLIOptionVisibility visibility = CLIOptionVisibility::kDefault) : option(std::move(option)), help(std::move(help)), diff --git a/src/parser/cxx/const_expression_evaluator.cc b/src/parser/cxx/const_expression_evaluator.cc index 193add8e..7233bc88 100644 --- a/src/parser/cxx/const_expression_evaluator.cc +++ b/src/parser/cxx/const_expression_evaluator.cc @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/src/parser/cxx/diagnostic.h b/src/parser/cxx/diagnostic.h index f4772e94..dd9f3af3 100644 --- a/src/parser/cxx/diagnostic.h +++ b/src/parser/cxx/diagnostic.h @@ -26,7 +26,7 @@ namespace cxx { -enum struct Severity { Message, Warning, Error, Fatal }; +enum class Severity { Message, Warning, Error, Fatal }; class Diagnostic { std::string message_; diff --git a/src/parser/cxx/lexer.cc b/src/parser/cxx/lexer.cc index f18c0dcb..467f9457 100644 --- a/src/parser/cxx/lexer.cc +++ b/src/parser/cxx/lexer.cc @@ -31,7 +31,7 @@ namespace cxx { inline namespace { -enum struct EncodingPrefix { kNone, kWide, kUtf8, kUtf16, kUtf32 }; +enum class EncodingPrefix { kNone, kWide, kUtf8, kUtf16, kUtf32 }; const std::unordered_map> kStringLiteralPrefixes{ diff --git a/src/parser/cxx/literals.h b/src/parser/cxx/literals.h index d240b431..79eb43af 100644 --- a/src/parser/cxx/literals.h +++ b/src/parser/cxx/literals.h @@ -43,7 +43,7 @@ class Literal { class IntegerLiteral final : public Literal { public: - enum struct Radix { + enum class Radix { kDecimal, kHexadecimal, kOctal, diff --git a/src/parser/cxx/name_printer.cc b/src/parser/cxx/name_printer.cc index e325a31f..1851920b 100644 --- a/src/parser/cxx/name_printer.cc +++ b/src/parser/cxx/name_printer.cc @@ -18,70 +18,72 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include #include #include -#include #include #include namespace cxx { -struct { - auto operator()(const Type* type) const -> std::string { - return to_string(type); - } +namespace { - auto operator()(const ConstValue& value) const -> std::string { return {}; } +struct NamePrinter { + struct { + auto operator()(const Type* type) const -> std::string { + return to_string(type); + } - auto operator()(ExpressionAST* value) const -> std::string { return {}; } + auto operator()(const ConstValue& value) const -> std::string { return {}; } -} template_argument_to_string; + auto operator()(ExpressionAST* value) const -> std::string { return {}; } -auto NamePrinter::operator()(const Identifier* name) const -> std::string { - return name->value(); -} + } template_argument_to_string; -auto NamePrinter::operator()(const OperatorId* name) const -> std::string { - switch (name->op()) { - case TokenKind::T_LPAREN: - return "operator ()"; - case TokenKind::T_LBRACKET: - return "operator []"; - case TokenKind::T_NEW_ARRAY: - return "operator new[]"; - case TokenKind::T_DELETE_ARRAY: - return "operator delete[]"; - default: - return std::format("operator {}", Token::spell(name->op())); - } // switch -} + auto operator()(const Identifier* name) const -> std::string { + return name->value(); + } -auto NamePrinter::operator()(const DestructorId* name) const -> std::string { - return "~" + visit(*this, name->name()); -} + auto operator()(const OperatorId* name) const -> std::string { + switch (name->op()) { + case TokenKind::T_LPAREN: + return "operator ()"; + case TokenKind::T_LBRACKET: + return "operator []"; + case TokenKind::T_NEW_ARRAY: + return "operator new[]"; + case TokenKind::T_DELETE_ARRAY: + return "operator delete[]"; + default: + return std::format("operator {}", Token::spell(name->op())); + } // switch + } -auto NamePrinter::operator()(const LiteralOperatorId* name) const - -> std::string { - return std::format("operator \"\"{}", name->name()); -} + auto operator()(const DestructorId* name) const -> std::string { + return "~" + visit(*this, name->name()); + } -auto NamePrinter::operator()(const ConversionFunctionId* name) const - -> std::string { - return std::format("operator {}", to_string(name->type())); -} + auto operator()(const LiteralOperatorId* name) const -> std::string { + return std::format("operator \"\"{}", name->name()); + } -auto NamePrinter::operator()(const TemplateId* name) const -> std::string { - std::string s = visit(*this, name->name()); - s += " <"; - for (auto&& arg : name->arguments()) { - if (&arg != &name->arguments().front()) s += ", "; - s += std::visit(template_argument_to_string, arg); + auto operator()(const ConversionFunctionId* name) const -> std::string { + return std::format("operator {}", to_string(name->type())); } - s += '>'; - return s; -} + + auto operator()(const TemplateId* name) const -> std::string { + std::string s = visit(*this, name->name()); + s += " <"; + for (auto&& arg : name->arguments()) { + if (&arg != &name->arguments().front()) s += ", "; + s += std::visit(template_argument_to_string, arg); + } + s += '>'; + return s; + } +}; + +} // namespace auto to_string(const Name* name) -> std::string { if (!name) return {}; diff --git a/src/parser/cxx/name_printer.h b/src/parser/cxx/name_printer.h deleted file mode 100644 index e8ef7d3f..00000000 --- a/src/parser/cxx/name_printer.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2025 Roberto Raggi -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -#include - -namespace cxx { - -class NamePrinter { - public: - auto operator()(const Identifier* name) const -> std::string; - auto operator()(const OperatorId* name) const -> std::string; - auto operator()(const DestructorId* name) const -> std::string; - auto operator()(const LiteralOperatorId* name) const -> std::string; - auto operator()(const ConversionFunctionId* name) const -> std::string; - auto operator()(const TemplateId* name) const -> std::string; -}; - -auto to_string(const Name* name) -> std::string; - -} // namespace cxx \ No newline at end of file diff --git a/src/parser/cxx/names_fwd.h b/src/parser/cxx/names_fwd.h index 2b5dd1ab..bed5a10b 100644 --- a/src/parser/cxx/names_fwd.h +++ b/src/parser/cxx/names_fwd.h @@ -56,4 +56,6 @@ enum class IdentifierInfoKind { class IdentifierInfo; class TypeTraitIdentifierInfo; +auto to_string(const Name* name) -> std::string; + } // namespace cxx \ No newline at end of file diff --git a/src/parser/cxx/parser.cc b/src/parser/cxx/parser.cc index d4b0a65a..6464565a 100644 --- a/src/parser/cxx/parser.cc +++ b/src/parser/cxx/parser.cc @@ -27,13 +27,11 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -139,7 +137,7 @@ class RecordingDiagnosticsClient : public DiagnosticsClient { }; class FunctionPrototype { - enum struct Kind { Direct, Ptr, Function, Array }; + enum class Kind { Direct, Ptr, Function, Array }; FunctionDeclaratorChunkAST* prototype_ = nullptr; Kind kind_ = Kind::Direct; @@ -2550,17 +2548,6 @@ auto Parser::parse_call_expression(ExpressionAST*& yyast, argumentTypes.push_back(argumentType); } -#if false - if (auto ovlType = type_cast(ast->baseExpression->type)) { - parse_warn(lparenLoc, "overload set call"); - } - - if (auto functionType = type_cast(ast->baseExpression->type)) { - parse_warn(lparenLoc, - std::format("call function {}", to_string(functionType))); - } -#endif - return true; } diff --git a/src/parser/cxx/parser.h b/src/parser/cxx/parser.h index ad798d1a..4ca2c5b0 100644 --- a/src/parser/cxx/parser.h +++ b/src/parser/cxx/parser.h @@ -79,7 +79,7 @@ class Parser final { struct LoopParser; struct GetDeclaratorType; - enum struct BindingContext { + enum class BindingContext { kNamespace, kClass, kTemplate, @@ -88,12 +88,12 @@ class Parser final { kCondition, }; - enum struct NestedNameSpecifierContext { + enum class NestedNameSpecifierContext { kNonDeclarative, kDeclarative, }; - enum struct Prec { + enum class Prec { kLogicalOr, kLogicalAnd, kInclusiveOr, @@ -175,7 +175,7 @@ class Parser final { [[nodiscard]] auto parse_reflect_expression(ExpressionAST*& yyast, const ExprContext& ctx) -> bool; - enum struct IdExpressionContext { + enum class IdExpressionContext { kExpression, kTemplateParameter, kRequiresClause, @@ -487,7 +487,7 @@ class Parser final { void parse_optional_declarator_or_abstract_declarator(DeclaratorAST*& yyast, Decl& decl); - enum struct DeclaratorKind { + enum class DeclaratorKind { kDeclarator, kAbstractDeclarator, kNewDeclarator, @@ -585,7 +585,7 @@ class Parser final { [[nodiscard]] auto parse_linkage_specification(DeclarationAST*& yyast) -> bool; - enum struct AllowedAttributes { + enum class AllowedAttributes { kCxxAttribute = 1 << 0, kGnuAttribute = 1 << 1, kAsmSpecifier = 1 << 2, diff --git a/src/parser/cxx/preprocessor.cc b/src/parser/cxx/preprocessor.cc index effad206..82471713 100644 --- a/src/parser/cxx/preprocessor.cc +++ b/src/parser/cxx/preprocessor.cc @@ -46,7 +46,6 @@ #include #include -#include "cxx/preprocessor_fwd.h" #include "pp_keywords-priv.h" namespace { diff --git a/src/parser/cxx/symbol_instantiation.cc b/src/parser/cxx/symbol_instantiation.cc index d56c7998..6639ecdf 100644 --- a/src/parser/cxx/symbol_instantiation.cc +++ b/src/parser/cxx/symbol_instantiation.cc @@ -24,11 +24,9 @@ #include #include #include -#include #include #include #include -#include #include #include diff --git a/src/parser/cxx/symbol_printer.cc b/src/parser/cxx/symbol_printer.cc index 992f1455..c14675a0 100644 --- a/src/parser/cxx/symbol_printer.cc +++ b/src/parser/cxx/symbol_printer.cc @@ -18,14 +18,10 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include - // cxx -#include #include #include #include -#include #include #include diff --git a/src/parser/cxx/symbol_printer.h b/src/parser/cxx/symbol_printer.h deleted file mode 100644 index ccbbfaf1..00000000 --- a/src/parser/cxx/symbol_printer.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2025 Roberto Raggi -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include - -#include -#include - -namespace cxx { - -void dump(std::ostream& out, Symbol* symbol, int depth = 0); - -auto operator<<(std::ostream& out, Symbol* symbol) -> std::ostream&; - -} // namespace cxx \ No newline at end of file diff --git a/src/parser/cxx/symbols.cc b/src/parser/cxx/symbols.cc index 0042df39..9127d140 100644 --- a/src/parser/cxx/symbols.cc +++ b/src/parser/cxx/symbols.cc @@ -24,9 +24,7 @@ #include #include #include -#include #include -#include #include #include diff --git a/src/parser/cxx/symbols_fwd.h b/src/parser/cxx/symbols_fwd.h index 7129fbf6..f644eed2 100644 --- a/src/parser/cxx/symbols_fwd.h +++ b/src/parser/cxx/symbols_fwd.h @@ -22,6 +22,8 @@ #include +#include + namespace cxx { #define CXX_FOR_EACH_SYMBOL(V) \ @@ -66,10 +68,14 @@ CXX_FOR_EACH_SYMBOL(PROCESS_SYMBOL) enum class SymbolKind { CXX_FOR_EACH_SYMBOL(PROCESS_SYMBOL) }; #undef PROCESS_SYMBOL -enum struct AccessSpecifier { +enum class AccessSpecifier { kPublic, kProtected, kPrivate, }; +void dump(std::ostream& out, Symbol* symbol, int depth = 0); + +auto operator<<(std::ostream& out, Symbol* symbol) -> std::ostream&; + } // namespace cxx diff --git a/src/parser/cxx/token_fwd.h b/src/parser/cxx/token_fwd.h index 5dc1b1a0..ee406779 100644 --- a/src/parser/cxx/token_fwd.h +++ b/src/parser/cxx/token_fwd.h @@ -291,12 +291,12 @@ class Token; // clang-format off #define TOKEN_ENUM(tk, _) T_##tk, #define TOKEN_ALIAS_ENUM(tk, other) T_##tk = T_##other, -enum struct TokenKind : std::uint8_t { +enum class TokenKind : std::uint8_t { FOR_EACH_TOKEN(TOKEN_ENUM) FOR_EACH_TOKEN_ALIAS(TOKEN_ALIAS_ENUM) }; -enum struct BuiltinTypeTraitKind { +enum class BuiltinTypeTraitKind { T_NONE, FOR_EACH_BUILTIN_TYPE_TRAIT(TOKEN_ENUM) }; diff --git a/src/parser/cxx/type_printer.cc b/src/parser/cxx/type_printer.cc index 2e82c278..0f95de22 100644 --- a/src/parser/cxx/type_printer.cc +++ b/src/parser/cxx/type_printer.cc @@ -18,11 +18,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include - // cxx #include -#include #include #include #include diff --git a/src/parser/cxx/type_printer.h b/src/parser/cxx/type_printer.h deleted file mode 100644 index 8bb17b4e..00000000 --- a/src/parser/cxx/type_printer.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2025 Roberto Raggi -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#pragma once - -#include -#include - -#include - -namespace cxx { - -auto to_string(const Type* type, const std::string& id = "") -> std::string; -auto to_string(const Type* type, const Name* name) -> std::string; - -} // namespace cxx \ No newline at end of file diff --git a/src/parser/cxx/types_fwd.h b/src/parser/cxx/types_fwd.h index 24ea8196..80743d9a 100644 --- a/src/parser/cxx/types_fwd.h +++ b/src/parser/cxx/types_fwd.h @@ -22,8 +22,12 @@ #include +#include + namespace cxx { +class Name; + #define CXX_FOR_EACH_TYPE_KIND(V) \ V(Void) \ V(Nullptr) \ @@ -92,4 +96,7 @@ enum class RefQualifier { kRvalue, }; +auto to_string(const Type* type, const std::string& id = "") -> std::string; +auto to_string(const Type* type, const Name* name) -> std::string; + } // namespace cxx diff --git a/tests/api_tests/test_control.cc b/tests/api_tests/test_control.cc index 0b468a29..f5f81afe 100644 --- a/tests/api_tests/test_control.cc +++ b/tests/api_tests/test_control.cc @@ -20,7 +20,6 @@ #include #include -#include #include #include diff --git a/tests/api_tests/test_substitution.cc b/tests/api_tests/test_substitution.cc index de992a54..29403397 100644 --- a/tests/api_tests/test_substitution.cc +++ b/tests/api_tests/test_substitution.cc @@ -20,14 +20,11 @@ #include #include -#include #include #include #include -#include #include #include -#include #include #include diff --git a/tests/api_tests/test_type_printer.cc b/tests/api_tests/test_type_printer.cc index 77c6e081..b78b894d 100644 --- a/tests/api_tests/test_type_printer.cc +++ b/tests/api_tests/test_type_printer.cc @@ -19,7 +19,6 @@ // SOFTWARE. #include -#include #include #include