[cfe-commits] r92376 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaInit.cpp test/FixIt/typo.c

Douglas Gregor dgregor at apple.com
Thu Dec 31 16:03:05 PST 2009


Author: dgregor
Date: Thu Dec 31 18:03:05 2009
New Revision: 92376

URL: http://llvm.org/viewvc/llvm-project?rev=92376&view=rev
Log:
Typo correction for C99 designated field initializers, e.g.,

test/FixIt/typo.c:19:4: error: field designator 'bunds' does not refer to any
      field in type 'struct Window'; did you mean 'bounds'?
  .bunds.
   ^~~~~
   bounds


Added:
    cfe/trunk/test/FixIt/typo.c   (with props)
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaInit.cpp

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

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Dec 31 18:03:05 2009
@@ -2566,6 +2566,9 @@
 def err_mem_init_not_member_or_class_suggest : Error<
   "initializer %0 does not name a non-static data member or base "
   "class; did you mean the %select{base class|member}1 %2?">;
+def err_field_designator_unknown_suggest : Error<
+  "field designator %0 does not refer to any field in type %1; did you mean "
+  "%2?">;
 
 }
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Dec 31 18:03:05 2009
@@ -16,6 +16,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "SemaInit.h"
+#include "Lookup.h"
 #include "Sema.h"
 #include "clang/Parse/Designator.h"
 #include "clang/AST/ASTContext.h"
@@ -1286,22 +1287,33 @@
       // may find nothing, or may find a member of an anonymous
       // struct/union.
       DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName);
+      FieldDecl *ReplacementField = 0;
       if (Lookup.first == Lookup.second) {
-        // Name lookup didn't find anything.
-        SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown)
-          << FieldName << CurrentObjectType;
-        ++Index;
-        return true;
-      } else if (!KnownField && isa<FieldDecl>(*Lookup.first) &&
-                 cast<RecordDecl>((*Lookup.first)->getDeclContext())
-                   ->isAnonymousStructOrUnion()) {
-        // Handle an field designator that refers to a member of an
-        // anonymous struct or union.
-        ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx,
-                                       cast<FieldDecl>(*Lookup.first),
-                                       Field, FieldIndex);
-        D = DIE->getDesignator(DesigIdx);
-      } else {
+        // Name lookup didn't find anything. Determine whether this
+        // was a typo for another field name.
+        LookupResult R(SemaRef, FieldName, D->getFieldLoc(), 
+                       Sema::LookupMemberName);
+        if (SemaRef.CorrectTypo(R, /*Scope=*/0, /*SS=*/0, RT->getDecl()) &&
+            (ReplacementField = R.getAsSingle<FieldDecl>()) &&
+            ReplacementField->getDeclContext()->getLookupContext()
+                                                      ->Equals(RT->getDecl())) {
+          SemaRef.Diag(D->getFieldLoc(), 
+                       diag::err_field_designator_unknown_suggest)
+            << FieldName << CurrentObjectType << R.getLookupName()
+            << CodeModificationHint::CreateReplacement(D->getFieldLoc(),
+                                               R.getLookupName().getAsString());
+        } else {
+          SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown)
+            << FieldName << CurrentObjectType;
+          ++Index;
+          return true;
+        }
+      } else if (!KnownField) {
+        // Determine whether we found a field at all.
+        ReplacementField = dyn_cast<FieldDecl>(*Lookup.first);
+      }
+
+      if (!ReplacementField) {
         // Name lookup found something, but it wasn't a field.
         SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_nonfield)
           << FieldName;
@@ -1310,6 +1322,32 @@
         ++Index;
         return true;
       }
+
+      if (!KnownField && 
+          cast<RecordDecl>((ReplacementField)->getDeclContext())
+                                                 ->isAnonymousStructOrUnion()) {
+        // Handle an field designator that refers to a member of an
+        // anonymous struct or union.
+        ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx,
+                                       ReplacementField,
+                                       Field, FieldIndex);
+        D = DIE->getDesignator(DesigIdx);
+      } else if (!KnownField) {
+        // The replacement field comes from typo correction; find it
+        // in the list of fields.
+        FieldIndex = 0;
+        Field = RT->getDecl()->field_begin();
+        for (; Field != FieldEnd; ++Field) {
+          if (Field->isUnnamedBitfield())
+            continue;
+
+          if (ReplacementField == *Field || 
+              Field->getIdentifier() == ReplacementField->getIdentifier())
+            break;
+
+          ++FieldIndex;
+        }
+      }
     } else if (!KnownField &&
                cast<RecordDecl>((*Field)->getDeclContext())
                  ->isAnonymousStructOrUnion()) {

Added: cfe/trunk/test/FixIt/typo.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/typo.c?rev=92376&view=auto

==============================================================================
--- cfe/trunk/test/FixIt/typo.c (added)
+++ cfe/trunk/test/FixIt/typo.c Thu Dec 31 18:03:05 2009
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fixit -o - | %clang_cc1 -fsyntax-only -pedantic -Werror -x c -
+struct Point {
+  float x, y;
+};
+
+struct Rectangle {
+  struct Point top_left, bottom_right;
+};
+
+enum Color { Red, Green, Blue };
+
+struct Window {
+  struct Rectangle bounds;
+  enum Color color;
+};
+
+struct Window window = {
+  .bunds. // expected-error{{field designator 'bunds' does not refer to any field in type 'struct Window'; did you mean 'bounds'?}}
+  topleft.x = 3.14, // expected-error{{field designator 'topleft' does not refer to any field in type 'struct Rectangle'; did you mean 'top_left'?}}
+  2.71818, 5.0, 6.0, Red
+};

Propchange: cfe/trunk/test/FixIt/typo.c

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/FixIt/typo.c

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/FixIt/typo.c

------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list