[cfe-commits] r90814 - in /cfe/trunk: TODO.txt include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaExpr.cpp

John McCall rjmccall at apple.com
Mon Dec 7 14:47:00 PST 2009


Author: rjmccall
Date: Mon Dec  7 16:46:59 2009
New Revision: 90814

URL: http://llvm.org/viewvc/llvm-project?rev=90814&view=rev
Log:
Recover from dot accesses to record pointers and arrow accesses to records.
Patch by Nicola Gigante!


Modified:
    cfe/trunk/TODO.txt
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/TODO.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/TODO.txt?rev=90814&r1=90813&r2=90814&view=diff

==============================================================================
--- cfe/trunk/TODO.txt (original)
+++ cfe/trunk/TODO.txt Mon Dec  7 16:46:59 2009
@@ -65,7 +65,6 @@
   - If no member of a given name is found in a class/struct, search through the names of entities that do exist in the class and suggest the closest candidate. e.g., if I write "DS.setTypeSpecType", it would suggest "DS.SetTypeSpecType" (edit distance = 1).
   - If a class member is defined out-of-line but isn't in the class declaration (and there are no close matches!), provide the option to add an in-class declaration.
   - Fix-it hints for the inclusion of headers when needed for particular features (e.g., <typeinfo> for typeid)
-  - Change "foo.bar" to "foo->bar" when "foo" is a pointer.
 
 //===---------------------------------------------------------------------===//
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=90814&r1=90813&r2=90814&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Dec  7 16:46:59 2009
@@ -1520,6 +1520,8 @@
   "%0 does not have a member named %1">;
 def err_typecheck_member_reference_arrow : Error<
   "member reference type %0 is not a pointer">;
+def err_typecheck_member_reference_suggestion : Error<
+  "member reference type %0 is %select{a|not a}1 pointer; maybe you meant to use '%select{->|.}1'?">;
 def err_typecheck_member_reference_type : Error<
   "cannot refer to type member %0 with '%select{.|->}1'">;
 def err_typecheck_member_reference_unknown : Error<

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=90814&r1=90813&r2=90814&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Dec  7 16:46:59 2009
@@ -1550,7 +1550,7 @@
                                  const TemplateArgumentListInfo *TemplateArgs);
 
   OwningExprResult LookupMemberExpr(LookupResult &R, Expr *&Base,
-                                    bool IsArrow, SourceLocation OpLoc,
+                                    bool &IsArrow, SourceLocation OpLoc,
                                     const CXXScopeSpec &SS,
                                     NamedDecl *FirstQualifierInScope,
                                     DeclPtrTy ObjCImpDecl);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=90814&r1=90813&r2=90814&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Dec  7 16:46:59 2009
@@ -2473,7 +2473,7 @@
 /// fixed for ObjC++.
 Sema::OwningExprResult
 Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
-                       bool IsArrow, SourceLocation OpLoc,
+                       bool &IsArrow, SourceLocation OpLoc,
                        const CXXScopeSpec &SS,
                        NamedDecl *FirstQualifierInScope,
                        DeclPtrTy ObjCImpDecl) {
@@ -2614,13 +2614,42 @@
       BaseType = PT->getPointeeType();
     else if (BaseType->isObjCObjectPointerType())
       ;
-    else {
+    else if (BaseType->isRecordType()) {
+      // Recover from arrow accesses to records, e.g.:
+      //   struct MyRecord foo;
+      //   foo->bar
+      // This is actually well-formed in C++ if MyRecord has an
+      // overloaded operator->, but that should have been dealt with
+      // by now.
+      Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+        << BaseType << int(IsArrow) << BaseExpr->getSourceRange()
+        << CodeModificationHint::CreateReplacement(OpLoc, ".");
+      IsArrow = false;
+    } else {
       Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
         << BaseType << BaseExpr->getSourceRange();
       return ExprError();
     }
+  } else {
+    // Recover from dot accesses to pointers, e.g.:
+    //   type *foo;
+    //   foo.bar
+    // This is actually well-formed in two cases:
+    //   - 'type' is an Objective C type
+    //   - 'bar' is a pseudo-destructor name which happens to refer to
+    //     the appropriate pointer type
+    if (MemberName.getNameKind() != DeclarationName::CXXDestructorName) {
+      const PointerType *PT = BaseType->getAs<PointerType>();
+      if (PT && PT->getPointeeType()->isRecordType()) {
+        Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+          << BaseType << int(IsArrow) << BaseExpr->getSourceRange()
+          << CodeModificationHint::CreateReplacement(OpLoc, "->");
+        BaseType = PT->getPointeeType();
+        IsArrow = true;
+      }
+    }
   }
-
+  
   // Handle field access to simple records.  This also handles access
   // to fields of the ObjC 'id' struct.
   if (const RecordType *RTy = BaseType->getAs<RecordType>()) {





More information about the cfe-commits mailing list