14432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain//=== unittests/Sema/ExternalSemaSourceTest.cpp - ExternalSemaSource tests ===// 24432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// 34432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// The LLVM Compiler Infrastructure 44432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// 54432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// This file is distributed under the University of Illinois Open Source 64432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// License. See LICENSE.TXT for details. 74432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// 84432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain//===----------------------------------------------------------------------===// 94432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 104432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain#include "clang/AST/ASTConsumer.h" 114432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain#include "clang/AST/ASTContext.h" 124432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain#include "clang/Frontend/CompilerInstance.h" 134432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain#include "clang/Lex/Preprocessor.h" 144432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain#include "clang/Parse/ParseAST.h" 154432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain#include "clang/Sema/ExternalSemaSource.h" 164432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain#include "clang/Sema/Sema.h" 174432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain#include "clang/Sema/SemaDiagnostic.h" 184432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain#include "clang/Sema/TypoCorrection.h" 194432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain#include "clang/Tooling/Tooling.h" 204432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain#include "gtest/gtest.h" 214432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 224432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrainusing namespace clang; 234432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrainusing namespace clang::tooling; 244432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 254432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrainnamespace { 264432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 275d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain// \brief Counts the number of times MaybeDiagnoseMissingCompleteType 285d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain// is called. Returns the result it was provided on creation. 295d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrainclass CompleteTypeDiagnoser : public clang::ExternalSemaSource { 305d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrainpublic: 315d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain CompleteTypeDiagnoser(bool MockResult) : CallCount(0), Result(MockResult) {} 325d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain 335d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation L, QualType T) { 345d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain ++CallCount; 355d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain return Result; 365d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain } 375d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain 385d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain int CallCount; 395d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain bool Result; 405d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain}; 415d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain 424432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// \brief Counts the number of err_using_directive_member_suggest diagnostics 434432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// correcting from one namespace to another while still passing all diagnostics 444432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// along a chain of consumers. 454432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrainclass NamespaceDiagnosticWatcher : public clang::DiagnosticConsumer { 464432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain DiagnosticConsumer *Chained; 474432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain std::string FromNS; 484432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain std::string ToNS; 494432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 504432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrainpublic: 514432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceDiagnosticWatcher(StringRef From, StringRef To) 52ef8225444452a1486bd721f3285301fe84643b00Stephen Hines : Chained(nullptr), FromNS(From), ToNS("'"), SeenCount(0) { 534432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ToNS.append(To); 544432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ToNS.append("'"); 554432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 564432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 574432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 584432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain const Diagnostic &Info) { 594432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain if (Chained) 604432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Chained->HandleDiagnostic(DiagLevel, Info); 614432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain if (Info.getID() - 1 == diag::err_using_directive_member_suggest) { 624432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain const IdentifierInfo *Ident = Info.getArgIdentifier(0); 634432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain const std::string &CorrectedQuotedStr = Info.getArgStdStr(1); 644432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain if (Ident->getName() == FromNS && CorrectedQuotedStr == ToNS) 654432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ++SeenCount; 664432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 674432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 684432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 694432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain virtual void clear() { 704432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain DiagnosticConsumer::clear(); 714432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain if (Chained) 724432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Chained->clear(); 734432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 744432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 754432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain virtual bool IncludeInDiagnosticCounts() const { 764432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain if (Chained) 774432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain return Chained->IncludeInDiagnosticCounts(); 784432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain return false; 794432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 804432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 814432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceDiagnosticWatcher *Chain(DiagnosticConsumer *ToChain) { 824432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Chained = ToChain; 834432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain return this; 844432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 854432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 864432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain int SeenCount; 874432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain}; 884432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 894432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// \brief Always corrects a typo matching CorrectFrom with a new namespace 904432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// with the name CorrectTo. 914432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrainclass NamespaceTypoProvider : public clang::ExternalSemaSource { 924432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain std::string CorrectFrom; 934432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain std::string CorrectTo; 944432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Sema *CurrentSema; 954432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 964432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrainpublic: 974432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceTypoProvider(StringRef From, StringRef To) 98ef8225444452a1486bd721f3285301fe84643b00Stephen Hines : CorrectFrom(From), CorrectTo(To), CurrentSema(nullptr), CallCount(0) {} 994432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 1004432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain virtual void InitializeSema(Sema &S) { CurrentSema = &S; } 1014432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 102ef8225444452a1486bd721f3285301fe84643b00Stephen Hines virtual void ForgetSema() { CurrentSema = nullptr; } 1034432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 1044432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, 1054432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain int LookupKind, Scope *S, CXXScopeSpec *SS, 1064432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain CorrectionCandidateCallback &CCC, 1074432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain DeclContext *MemberContext, 1084432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain bool EnteringContext, 1094432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain const ObjCObjectPointerType *OPT) { 1104432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ++CallCount; 1114432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain if (CurrentSema && Typo.getName().getAsString() == CorrectFrom) { 112ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DeclContext *DestContext = nullptr; 1134432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASTContext &Context = CurrentSema->getASTContext(); 114ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (SS) 1154432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain DestContext = CurrentSema->computeDeclContext(*SS, EnteringContext); 116ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (!DestContext) 1174432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain DestContext = Context.getTranslationUnitDecl(); 1184432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain IdentifierInfo *ToIdent = 1194432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain CurrentSema->getPreprocessor().getIdentifierInfo(CorrectTo); 1204432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceDecl *NewNamespace = 1214432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceDecl::Create(Context, DestContext, false, Typo.getBeginLoc(), 122ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Typo.getLoc(), ToIdent, nullptr); 1234432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain DestContext->addDecl(NewNamespace); 1244432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain TypoCorrection Correction(ToIdent); 1254432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Correction.addCorrectionDecl(NewNamespace); 1264432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain return Correction; 1274432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 1284432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain return TypoCorrection(); 1294432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 1304432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 1314432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain int CallCount; 1324432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain}; 1334432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 1344432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// \brief Chains together a vector of NamespaceDiagnosticWatchers and 1354432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// adds a vector of ExternalSemaSources to the CompilerInstance before 1364432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// performing semantic analysis. 1374432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrainclass ExternalSemaSourceInstaller : public clang::ASTFrontendAction { 1384432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain std::vector<NamespaceDiagnosticWatcher *> Watchers; 1394432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain std::vector<clang::ExternalSemaSource *> Sources; 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<DiagnosticConsumer> OwnedClient; 1414432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 1424432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrainprotected: 1434432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain virtual clang::ASTConsumer * 1444432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain CreateASTConsumer(clang::CompilerInstance &Compiler, 1454432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain llvm::StringRef /* dummy */) { 1464432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain return new clang::ASTConsumer(); 1474432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 1484432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 1494432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain virtual void ExecuteAction() { 1504432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain CompilerInstance &CI = getCompilerInstance(); 1514432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_FALSE(CI.hasSema()); 152ef8225444452a1486bd721f3285301fe84643b00Stephen Hines CI.createSema(getTranslationUnitKind(), nullptr); 1534432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_TRUE(CI.hasDiagnostics()); 1544432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain DiagnosticsEngine &Diagnostics = CI.getDiagnostics(); 1554432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain DiagnosticConsumer *Client = Diagnostics.getClient(); 1564432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain if (Diagnostics.ownsClient()) 1574432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain OwnedClient.reset(Diagnostics.takeClient()); 1584432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain for (size_t I = 0, E = Watchers.size(); I < E; ++I) 1594432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Client = Watchers[I]->Chain(Client); 1604432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Diagnostics.setClient(Client, false); 1614432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain for (size_t I = 0, E = Sources.size(); I < E; ++I) { 1624432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Sources[I]->InitializeSema(CI.getSema()); 1634432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain CI.getSema().addExternalSource(Sources[I]); 1644432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 1654432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats, 1664432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain CI.getFrontendOpts().SkipFunctionBodies); 1674432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 1684432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 1694432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrainpublic: 1704432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain void PushSource(clang::ExternalSemaSource *Source) { 1714432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Sources.push_back(Source); 1724432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 1734432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 1744432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain void PushWatcher(NamespaceDiagnosticWatcher *Watcher) { 1754432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Watchers.push_back(Watcher); 1764432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain } 1774432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain}; 1784432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 1794432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// Make sure that the NamespaceDiagnosticWatcher is not miscounting. 1804432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn UhrainTEST(ExternalSemaSource, SanityCheck) { 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<ExternalSemaSourceInstaller> Installer( 1824432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain new ExternalSemaSourceInstaller); 1834432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceDiagnosticWatcher Watcher("AAB", "BBB"); 1844432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Installer->PushWatcher(&Watcher); 1854432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain std::vector<std::string> Args(1, "-std=c++11"); 1864432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs( 187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Installer.release(), "namespace AAA { } using namespace AAB;", Args)); 1884432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_EQ(0, Watcher.SeenCount); 1894432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain} 1904432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 1914432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// Check that when we add a NamespaceTypeProvider, we use that suggestion 1924432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// instead of the usual suggestion we would use above. 1934432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn UhrainTEST(ExternalSemaSource, ExternalTypoCorrectionPrioritized) { 194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<ExternalSemaSourceInstaller> Installer( 1954432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain new ExternalSemaSourceInstaller); 1964432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceTypoProvider Provider("AAB", "BBB"); 1974432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceDiagnosticWatcher Watcher("AAB", "BBB"); 1984432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Installer->PushSource(&Provider); 1994432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Installer->PushWatcher(&Watcher); 2004432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain std::vector<std::string> Args(1, "-std=c++11"); 2014432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs( 202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Installer.release(), "namespace AAA { } using namespace AAB;", Args)); 2034432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_LE(0, Provider.CallCount); 2044432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_EQ(1, Watcher.SeenCount); 2054432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain} 2064432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 2074432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// Check that we use the first successful TypoCorrection returned from an 2084432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain// ExternalSemaSource. 2094432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn UhrainTEST(ExternalSemaSource, ExternalTypoCorrectionOrdering) { 210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<ExternalSemaSourceInstaller> Installer( 2114432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain new ExternalSemaSourceInstaller); 2124432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceTypoProvider First("XXX", "BBB"); 2134432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceTypoProvider Second("AAB", "CCC"); 2144432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceTypoProvider Third("AAB", "DDD"); 2154432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain NamespaceDiagnosticWatcher Watcher("AAB", "CCC"); 2164432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Installer->PushSource(&First); 2174432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Installer->PushSource(&Second); 2184432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Installer->PushSource(&Third); 2194432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain Installer->PushWatcher(&Watcher); 2204432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain std::vector<std::string> Args(1, "-std=c++11"); 2214432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs( 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Installer.release(), "namespace AAA { } using namespace AAB;", Args)); 2234432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_LE(1, First.CallCount); 2244432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_LE(1, Second.CallCount); 2254432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_EQ(0, Third.CallCount); 2264432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain ASSERT_EQ(1, Watcher.SeenCount); 2274432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain} 2284432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain 2295d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain// We should only try MaybeDiagnoseMissingCompleteType if we can't otherwise 2305d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain// solve the problem. 2315d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn UhrainTEST(ExternalSemaSource, TryOtherTacticsBeforeDiagnosing) { 232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<ExternalSemaSourceInstaller> Installer( 2335d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain new ExternalSemaSourceInstaller); 2345d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain CompleteTypeDiagnoser Diagnoser(false); 2355d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain Installer->PushSource(&Diagnoser); 2365d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain std::vector<std::string> Args(1, "-std=c++11"); 2375d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain // This code hits the class template specialization/class member of a class 2385d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain // template specialization checks in Sema::RequireCompleteTypeImpl. 2395d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs( 240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Installer.release(), 2415d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain "template <typename T> struct S { class C { }; }; S<char>::C SCInst;", 2425d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain Args)); 2435d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain ASSERT_EQ(0, Diagnoser.CallCount); 2445d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain} 2455d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain 2465d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain// The first ExternalSemaSource where MaybeDiagnoseMissingCompleteType returns 2475d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain// true should be the last one called. 2485d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn UhrainTEST(ExternalSemaSource, FirstDiagnoserTaken) { 249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<ExternalSemaSourceInstaller> Installer( 2505d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain new ExternalSemaSourceInstaller); 2515d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain CompleteTypeDiagnoser First(false); 2525d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain CompleteTypeDiagnoser Second(true); 2535d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain CompleteTypeDiagnoser Third(true); 2545d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain Installer->PushSource(&First); 2555d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain Installer->PushSource(&Second); 2565d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain Installer->PushSource(&Third); 2575d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain std::vector<std::string> Args(1, "-std=c++11"); 2585d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain ASSERT_FALSE(clang::tooling::runToolOnCodeWithArgs( 259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Installer.release(), "class Incomplete; Incomplete IncompleteInstance;", 2605d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain Args)); 2615d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain ASSERT_EQ(1, First.CallCount); 2625d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain ASSERT_EQ(1, Second.CallCount); 2635d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain ASSERT_EQ(0, Third.CallCount); 2645d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain} 2655d937b3fe7832f8ffa0a258d1b037c64708e97c1Kaelyn Uhrain 2664432bf007abb40cdbe2679dd94ec5b11c5795355Kaelyn Uhrain} // anonymous namespace 267