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