r188212 - Add hooks to ExternalSemaSource for after-the-fact diagnosis of

Kaelyn Uhrain rikka at google.com
Mon Aug 12 15:11:14 PDT 2013


Author: rikka
Date: Mon Aug 12 17:11:14 2013
New Revision: 188212

URL: http://llvm.org/viewvc/llvm-project?rev=188212&view=rev
Log:
Add hooks to ExternalSemaSource for after-the-fact diagnosis of
incomplete types, courtesy of Luke Zarko.

Modified:
    cfe/trunk/include/clang/Sema/ExternalSemaSource.h
    cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
    cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/unittests/Sema/ExternalSemaSourceTest.cpp

Modified: cfe/trunk/include/clang/Sema/ExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ExternalSemaSource.h?rev=188212&r1=188211&r2=188212&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/ExternalSemaSource.h Mon Aug 12 17:11:14 2013
@@ -14,6 +14,7 @@
 #define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H
 
 #include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/Type.h"
 #include "clang/Sema/TypoCorrection.h"
 #include "clang/Sema/Weak.h"
 #include "llvm/ADT/MapVector.h"
@@ -204,6 +205,20 @@ public:
     return TypoCorrection();
   }
 
+  /// \brief Produces a diagnostic note if the external source contains a
+  /// complete definition for \p T.
+  ///
+  /// \param Loc the location at which a complete type was required but not
+  /// provided
+  ///
+  /// \param T the \c QualType that should have been complete at \p Loc
+  ///
+  /// \return true if a diagnostic was produced, false otherwise.
+  virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
+                                                QualType T) {
+    return false;
+  }
+
   // isa/cast/dyn_cast support
   static bool classof(const ExternalASTSource *Source) {
     return Source->SemaSource;

Modified: cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h?rev=188212&r1=188211&r2=188212&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h (original)
+++ cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h Mon Aug 12 17:11:14 2013
@@ -340,6 +340,18 @@ public:
                                      bool EnteringContext,
                                      const ObjCObjectPointerType *OPT);
 
+  /// \brief Produces a diagnostic note if one of the attached sources
+  /// contains a complete definition for \p T. Queries the sources in list
+  /// order until the first one claims that a diagnostic was produced.
+  ///
+  /// \param Loc the location at which a complete type was required but not
+  /// provided
+  ///
+  /// \param T the \c QualType that should have been complete at \p Loc
+  ///
+  /// \return true if a diagnostic was produced, false otherwise.
+  virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc, QualType T);
+
   // isa/cast/dyn_cast support
   static bool classof(const MultiplexExternalSemaSource*) { return true; }
   //static bool classof(const ExternalSemaSource*) { return true; }

Modified: cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp?rev=188212&r1=188211&r2=188212&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp (original)
+++ cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp Mon Aug 12 17:11:14 2013
@@ -289,3 +289,12 @@ TypoCorrection MultiplexExternalSemaSour
   }
   return TypoCorrection();
 }
+
+bool MultiplexExternalSemaSource::MaybeDiagnoseMissingCompleteType(
+    SourceLocation Loc, QualType T) {
+  for (size_t I = 0, E = Sources.size(); I < E; ++I) {
+    if (Sources[I]->MaybeDiagnoseMissingCompleteType(Loc, T))
+      return true;
+  }
+  return false;
+}

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=188212&r1=188211&r2=188212&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Mon Aug 12 17:11:14 2013
@@ -5052,6 +5052,11 @@ bool Sema::RequireCompleteTypeImpl(Sourc
   if (IFace && !IFace->getDecl()->isInvalidDecl())
     Diag(IFace->getDecl()->getLocation(), diag::note_forward_class);
 
+  // If we have external information that we can use to suggest a fix,
+  // produce a note.
+  if (ExternalSource)
+    ExternalSource->MaybeDiagnoseMissingCompleteType(Loc, T);
+
   return true;
 }
 

Modified: cfe/trunk/unittests/Sema/ExternalSemaSourceTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Sema/ExternalSemaSourceTest.cpp?rev=188212&r1=188211&r2=188212&view=diff
==============================================================================
--- cfe/trunk/unittests/Sema/ExternalSemaSourceTest.cpp (original)
+++ cfe/trunk/unittests/Sema/ExternalSemaSourceTest.cpp Mon Aug 12 17:11:14 2013
@@ -24,6 +24,21 @@ using namespace clang::tooling;
 
 namespace {
 
+// \brief Counts the number of times MaybeDiagnoseMissingCompleteType
+// is called. Returns the result it was provided on creation.
+class CompleteTypeDiagnoser : public clang::ExternalSemaSource {
+public:
+  CompleteTypeDiagnoser(bool MockResult) : CallCount(0), Result(MockResult) {}
+
+  virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation L, QualType T) {
+    ++CallCount;
+    return Result;
+  }
+
+  int CallCount;
+  bool Result;
+};
+
 // \brief Counts the number of err_using_directive_member_suggest diagnostics
 // correcting from one namespace to another while still passing all diagnostics
 // along a chain of consumers.
@@ -211,4 +226,41 @@ TEST(ExternalSemaSource, ExternalTypoCor
   ASSERT_EQ(1, Watcher.SeenCount);
 }
 
+// We should only try MaybeDiagnoseMissingCompleteType if we can't otherwise
+// solve the problem.
+TEST(ExternalSemaSource, TryOtherTacticsBeforeDiagnosing) {
+  llvm::OwningPtr<ExternalSemaSourceInstaller> Installer(
+      new ExternalSemaSourceInstaller);
+  CompleteTypeDiagnoser Diagnoser(false);
+  Installer->PushSource(&Diagnoser);
+  std::vector<std::string> Args(1, "-std=c++11");
+  // This code hits the class template specialization/class member of a class
+  // template specialization checks in Sema::RequireCompleteTypeImpl.
+  ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs(
+      Installer.take(),
+      "template <typename T> struct S { class C { }; }; S<char>::C SCInst;",
+      Args));
+  ASSERT_EQ(0, Diagnoser.CallCount);
+}
+
+// The first ExternalSemaSource where MaybeDiagnoseMissingCompleteType returns
+// true should be the last one called.
+TEST(ExternalSemaSource, FirstDiagnoserTaken) {
+  llvm::OwningPtr<ExternalSemaSourceInstaller> Installer(
+      new ExternalSemaSourceInstaller);
+  CompleteTypeDiagnoser First(false);
+  CompleteTypeDiagnoser Second(true);
+  CompleteTypeDiagnoser Third(true);
+  Installer->PushSource(&First);
+  Installer->PushSource(&Second);
+  Installer->PushSource(&Third);
+  std::vector<std::string> Args(1, "-std=c++11");
+  ASSERT_FALSE(clang::tooling::runToolOnCodeWithArgs(
+      Installer.take(), "class Incomplete; Incomplete IncompleteInstance;",
+      Args));
+  ASSERT_EQ(1, First.CallCount);
+  ASSERT_EQ(1, Second.CallCount);
+  ASSERT_EQ(0, Third.CallCount);
+}
+
 } // anonymous namespace





More information about the cfe-commits mailing list