Skip to content

Commit ecc1622

Browse files
committed
Implement initial type computation for member accesses
Signed-off-by: Roberto Raggi <[email protected]>
1 parent bf78f28 commit ecc1622

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

src/parser/cxx/parser.cc

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,14 +2494,52 @@ auto Parser::parse_member_expression(ExpressionAST*& yyast) -> bool {
24942494
/*inRequiresClause*/ false))
24952495
parse_error("expected an unqualified id");
24962496

2497-
(void)check_psuedo_destructor_access(ast);
2497+
check_member_expression(ast);
24982498

24992499
yyast = ast;
25002500

25012501
return true;
25022502
}
25032503

2504-
auto Parser::check_psuedo_destructor_access(MemberExpressionAST* ast) -> bool {
2504+
void Parser::check_member_expression(MemberExpressionAST* ast) {
2505+
if (check_pseudo_destructor_access(ast)) return;
2506+
if (check_member_access(ast)) return;
2507+
}
2508+
2509+
auto Parser::check_member_access(MemberExpressionAST* ast) -> bool {
2510+
const Type* objectType = ast->baseExpression->type;
2511+
auto cv = strip_cv(objectType);
2512+
2513+
if (ast->accessOp == TokenKind::T_MINUS_GREATER) {
2514+
auto pointerType = type_cast<PointerType>(objectType);
2515+
if (!pointerType) return false;
2516+
2517+
objectType = pointerType->elementType();
2518+
cv = strip_cv(objectType);
2519+
}
2520+
2521+
auto classType = type_cast<ClassType>(objectType);
2522+
if (!classType) return false;
2523+
2524+
auto memberName = convertName(ast->unqualifiedId);
2525+
2526+
auto classSymbol = classType->symbol();
2527+
2528+
auto symbol =
2529+
Lookup{scope_}.qualifiedLookup(classSymbol->scope(), memberName);
2530+
2531+
ast->symbol = symbol;
2532+
2533+
if (symbol) {
2534+
ast->type = symbol->type();
2535+
}
2536+
2537+
// TODO: value category
2538+
2539+
return true;
2540+
}
2541+
2542+
auto Parser::check_pseudo_destructor_access(MemberExpressionAST* ast) -> bool {
25052543
auto objectType = ast->baseExpression->type;
25062544
auto cv = strip_cv(objectType);
25072545

@@ -2538,6 +2576,7 @@ auto Parser::check_psuedo_destructor_access(MemberExpressionAST* ast) -> bool {
25382576
}
25392577

25402578
ast->symbol = symbol;
2579+
ast->type = control_->getFunctionType(control_->getVoidType(), {});
25412580

25422581
return true;
25432582
}

src/parser/cxx/parser.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,11 @@ class Parser final {
240240
-> bool;
241241

242242
[[nodiscard]] auto parse_member_expression(ExpressionAST*& yyast) -> bool;
243-
[[nodiscard]] auto check_psuedo_destructor_access(MemberExpressionAST* ast)
243+
244+
void check_member_expression(MemberExpressionAST* ast);
245+
246+
[[nodiscard]] auto check_member_access(MemberExpressionAST* ast) -> bool;
247+
[[nodiscard]] auto check_pseudo_destructor_access(MemberExpressionAST* ast)
244248
-> bool;
245249

246250
[[nodiscard]] auto parse_subscript_expression(ExpressionAST*& yyast,
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %cxx -verify -fcheck -freport-missing-types %s
2+
3+
struct X {
4+
enum E { kValue = 0 };
5+
6+
static int s_value;
7+
};
8+
9+
auto main() -> int {
10+
X x;
11+
static_assert(__is_reference(decltype(x.kValue)) == false);
12+
static_assert(__is_same(decltype(x.kValue), X::E));
13+
14+
X& xr = x;
15+
static_assert(__is_reference(decltype(xr.kValue)) == false);
16+
static_assert(__is_same(decltype(xr.kValue), X::E));
17+
18+
const X& cxr = x;
19+
static_assert(__is_reference(decltype(cxr.kValue)) == false);
20+
static_assert(__is_same(decltype(cxr.kValue), X::E));
21+
22+
X* px = &x;
23+
24+
static_assert(__is_reference(decltype(px->kValue)) == false);
25+
static_assert(__is_same(decltype(px->kValue), X::E));
26+
27+
static_assert(__is_reference(decltype(px->s_value)) == false);
28+
static_assert(__is_same(decltype(px->s_value), int));
29+
30+
return 0;
31+
}

0 commit comments

Comments
 (0)