]> granicus.if.org Git - clang/commitdiff
Convert SemaInit.cpp to pass a callback object to CorrectTypo.
authorKaelyn Uhrain <rikka@google.com>
Thu, 12 Jan 2012 19:27:05 +0000 (19:27 +0000)
committerKaelyn Uhrain <rikka@google.com>
Thu, 12 Jan 2012 19:27:05 +0000 (19:27 +0000)
And once again improve the typo correction results in certain
situations just by moving the existing checks on the correction.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148037 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaInit.cpp
test/SemaCXX/typo-correction.cpp

index bcb624be899ce74a2e35a792d8c381887ec1b4f9..a4282e294626fb776a0e26f3b5a359bdbec213a7 100644 (file)
@@ -1529,6 +1529,26 @@ static DesignatedInitExpr *CloneDesignatedInitExpr(Sema &SemaRef,
                                     DIE->usesGNUSyntax(), DIE->getInit());
 }
 
+namespace {
+
+// Callback to only accept typo corrections that are for field members of
+// the given struct or union.
+class FieldInitializerValidatorCCC : public CorrectionCandidateCallback {
+ public:
+  explicit FieldInitializerValidatorCCC(RecordDecl *RD)
+      : Record(RD) {}
+
+  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+    FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>();
+    return FD && FD->getDeclContext()->getRedeclContext()->Equals(Record);
+  }
+
+ private:
+  RecordDecl *Record;
+};
+
+}
+
 /// @brief Check the well-formedness of a C99 designated initializer.
 ///
 /// Determines whether the designated initializer @p DIE, which
@@ -1687,19 +1707,17 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
       if (Lookup.first == Lookup.second) {
         // Name lookup didn't find anything. Determine whether this
         // was a typo for another field name.
-        LookupResult R(SemaRef, FieldName, D->getFieldLoc(),
-                       Sema::LookupMemberName);
+        FieldInitializerValidatorCCC Validator(RT->getDecl());
         TypoCorrection Corrected = SemaRef.CorrectTypo(
             DeclarationNameInfo(FieldName, D->getFieldLoc()),
-            Sema::LookupMemberName, /*Scope=*/NULL, /*SS=*/NULL,
-            RT->getDecl(), false, Sema::CTC_NoKeywords);
-        if ((ReplacementField = Corrected.getCorrectionDeclAs<FieldDecl>()) &&
-            ReplacementField->getDeclContext()->getRedeclContext()
-                                                      ->Equals(RT->getDecl())) {
+            Sema::LookupMemberName, /*Scope=*/0, /*SS=*/0, &Validator,
+            RT->getDecl());
+        if (Corrected) {
           std::string CorrectedStr(
               Corrected.getAsString(SemaRef.getLangOptions()));
           std::string CorrectedQuotedStr(
               Corrected.getQuoted(SemaRef.getLangOptions()));
+          ReplacementField = Corrected.getCorrectionDeclAs<FieldDecl>();
           SemaRef.Diag(D->getFieldLoc(),
                        diag::err_field_designator_unknown_suggest)
             << FieldName << CurrentObjectType << CorrectedQuotedStr
index c3e8480b293978b20a564cac07a011c7859e78d9..9187c1bf1293fe520a67192e0ed0d24cfd942b6f 100644 (file)
@@ -47,3 +47,15 @@ class some_name {}; // expected-note {{'some_name' declared here}}
 somename Foo; // expected-error {{unknown type name 'somename'; did you mean 'some_name'?}}
 namespace SomeName {} // expected-note {{namespace 'SomeName' defined here}}
 using namespace somename; // expected-error {{no namespace named 'somename'; did you mean 'SomeName'?}}
+
+
+// Without the callback object, CorrectTypo would choose "field1" as the
+// correction for "fielda" as it is closer than "FieldA", but that correction
+// would be later discarded by the caller and no suggestion would be given.
+struct st {
+  struct {
+    int field1;
+  };
+  double FieldA; // expected-note{{'FieldA' declared here}}
+};
+st var = { .fielda = 0.0 }; // expected-error{{field designator 'fielda' does not refer to any field in type 'st'; did you mean 'FieldA'?}}