diff --git a/src/parser/cxx/parser.cc b/src/parser/cxx/parser.cc index 9f6941c8..b1fa34d9 100644 --- a/src/parser/cxx/parser.cc +++ b/src/parser/cxx/parser.cc @@ -2009,6 +2009,31 @@ auto Parser::parse_this_expression(ExpressionAST*& yyast) -> bool { auto ast = make_node(pool_); yyast = ast; ast->thisLoc = thisLoc; + ast->valueCategory = ValueCategory::kPrValue; + + for (auto current = scope_; current; current = current->parent()) { + if (auto classSymbol = symbol_cast(current->owner())) { + // maybe a this expression in a field initializer + ast->type = control_->getPointerType(classSymbol->type()); + break; + } + + if (auto functionSymbol = symbol_cast(current->owner())) { + if (auto classSymbol = + symbol_cast(functionSymbol->enclosingSymbol())) { + auto functionType = type_cast(functionSymbol->type()); + const auto cv = functionType->cvQualifiers(); + if (cv != CvQualifiers::kNone) { + auto elementType = control_->getQualType(classSymbol->type(), cv); + ast->type = control_->getPointerType(elementType); + } else { + ast->type = control_->getPointerType(classSymbol->type()); + } + } + + break; + } + } return true; } diff --git a/tests/unit_tests/sema/class_01.cc b/tests/unit_tests/sema/class_01.cc new file mode 100644 index 00000000..c18aa4b7 --- /dev/null +++ b/tests/unit_tests/sema/class_01.cc @@ -0,0 +1,28 @@ +// RUN: %cxx -verify -fcheck %s + +struct X { + void f() { static_assert(__is_same(decltype(this), X*)); } + + void f() const { static_assert(__is_same(decltype(this), const X*)); } + + void f() volatile { static_assert(__is_same(decltype(this), volatile X*)); } + + void f() const volatile { + static_assert(__is_same(decltype(this), const volatile X*)); + } + + void g(); + void g() const; + void g() volatile; + void g() const volatile; +}; + +void X::g() { static_assert(__is_same(decltype(this), X*)); } + +void X::g() const { static_assert(__is_same(decltype(this), const X*)); } + +void X::g() volatile { static_assert(__is_same(decltype(this), volatile X*)); } + +void X::g() const volatile { + static_assert(__is_same(decltype(this), const volatile X*)); +}