hokein created this revision. hokein added a reviewer: sammccall. Herald added a project: clang.
Previously, we dropped the AST node for nonexistent member exprs. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D76764 Files: clang/lib/Parse/ParseExpr.cpp clang/test/AST/ast-dump-recovery.cpp clang/test/SemaCXX/constructor-initializer.cpp Index: clang/test/SemaCXX/constructor-initializer.cpp =================================================================== --- clang/test/SemaCXX/constructor-initializer.cpp +++ clang/test/SemaCXX/constructor-initializer.cpp @@ -250,7 +250,7 @@ B(const String& s, int e=0) // expected-error {{unknown type name}} : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}} B(const B& e) - : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} \ + : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error 2{{does not name}} \ // expected-error {{no member named 'm_String' in 'test3::B'}} } }; Index: clang/test/AST/ast-dump-recovery.cpp =================================================================== --- clang/test/AST/ast-dump-recovery.cpp +++ clang/test/AST/ast-dump-recovery.cpp @@ -83,3 +83,18 @@ // CHECK-NEXT: `-DeclRefExpr {{.*}} 'a' // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors int ternary = a ? nullptr : a; + +// CHECK: FunctionDecl +// CHECK-NEXT:|-ParmVarDecl {{.*}} x +// CHECK-NEXT:`-CompoundStmt +// CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors +// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'foo' +// CHECK-NEXT: `-CallExpr {{.*}} contains-errors +// CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors +// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'foo' +// CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' +struct Foo {} foo; +void test(int x) { + foo.abc; + foo->func(x); +} \ No newline at end of file Index: clang/lib/Parse/ParseExpr.cpp =================================================================== --- clang/lib/Parse/ParseExpr.cpp +++ clang/lib/Parse/ParseExpr.cpp @@ -2100,8 +2100,14 @@ OpKind, SS, TemplateKWLoc, Name, CurParsedObjCImpl ? CurParsedObjCImpl->Dcl : nullptr); - if (!LHS.isInvalid() && Tok.is(tok::less)) - checkPotentialAngleBracket(LHS); + if (!LHS.isInvalid()) { + if (Tok.is(tok::less)) + checkPotentialAngleBracket(LHS); + } else if (OrigLHS && Name.isValid()) { + // Preserve the member expr if the LHS is an invalid members. + LHS = Actions.CreateRecoveryExpr(OrigLHS->getBeginLoc(), + Name.getEndLoc(), {OrigLHS}); + } break; } case tok::plusplus: // postfix-expression: postfix-expression '++'
Index: clang/test/SemaCXX/constructor-initializer.cpp =================================================================== --- clang/test/SemaCXX/constructor-initializer.cpp +++ clang/test/SemaCXX/constructor-initializer.cpp @@ -250,7 +250,7 @@ B(const String& s, int e=0) // expected-error {{unknown type name}} : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}} B(const B& e) - : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} \ + : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error 2{{does not name}} \ // expected-error {{no member named 'm_String' in 'test3::B'}} } }; Index: clang/test/AST/ast-dump-recovery.cpp =================================================================== --- clang/test/AST/ast-dump-recovery.cpp +++ clang/test/AST/ast-dump-recovery.cpp @@ -83,3 +83,18 @@ // CHECK-NEXT: `-DeclRefExpr {{.*}} 'a' // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors int ternary = a ? nullptr : a; + +// CHECK: FunctionDecl +// CHECK-NEXT:|-ParmVarDecl {{.*}} x +// CHECK-NEXT:`-CompoundStmt +// CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors +// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'foo' +// CHECK-NEXT: `-CallExpr {{.*}} contains-errors +// CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors +// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'foo' +// CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' +struct Foo {} foo; +void test(int x) { + foo.abc; + foo->func(x); +} \ No newline at end of file Index: clang/lib/Parse/ParseExpr.cpp =================================================================== --- clang/lib/Parse/ParseExpr.cpp +++ clang/lib/Parse/ParseExpr.cpp @@ -2100,8 +2100,14 @@ OpKind, SS, TemplateKWLoc, Name, CurParsedObjCImpl ? CurParsedObjCImpl->Dcl : nullptr); - if (!LHS.isInvalid() && Tok.is(tok::less)) - checkPotentialAngleBracket(LHS); + if (!LHS.isInvalid()) { + if (Tok.is(tok::less)) + checkPotentialAngleBracket(LHS); + } else if (OrigLHS && Name.isValid()) { + // Preserve the member expr if the LHS is an invalid members. + LHS = Actions.CreateRecoveryExpr(OrigLHS->getBeginLoc(), + Name.getEndLoc(), {OrigLHS}); + } break; } case tok::plusplus: // postfix-expression: postfix-expression '++'
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits