Index: include/clang/Sema/CodeCompleteConsumer.h =================================================================== --- include/clang/Sema/CodeCompleteConsumer.h +++ include/clang/Sema/CodeCompleteConsumer.h @@ -956,6 +956,11 @@ return CodeCompleteOpts.LoadExternal; } + /// \breif Whether to disable typo correction when Sema does code completion. + bool disableTypoCorrection() const { + return CodeCompleteOpts.DisableTypoCorrection; + } + /// \brief Determine whether the output of this consumer is binary. bool isOutputBinary() const { return OutputIsBinary; } Index: include/clang/Sema/CodeCompleteOptions.h =================================================================== --- include/clang/Sema/CodeCompleteOptions.h +++ include/clang/Sema/CodeCompleteOptions.h @@ -39,10 +39,13 @@ /// full results. If false, declarations from the preamble may be omitted. unsigned LoadExternal : 1; + /// Whether to disable typo correction when Sema does code completion. + unsigned DisableTypoCorrection : 1; + CodeCompleteOptions() : IncludeMacros(0), IncludeCodePatterns(0), IncludeGlobals(1), IncludeNamespaceLevelDecls(1), IncludeBriefComments(0), - LoadExternal(1) {} + LoadExternal(1), DisableTypoCorrection(0) {} }; } // namespace clang Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -25,6 +25,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Sema/CodeCompleteConsumer.h" #include "clang/Sema/CXXFieldCollector.h" #include "clang/Sema/DelayedDiagnostic.h" #include "clang/Sema/ExternalSemaSource.h" @@ -139,7 +140,9 @@ TUKind(TUKind), NumSFINAEErrors(0), AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false), NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1), CurrentInstantiationScope(nullptr), - DisableTypoCorrection(false), TyposCorrected(0), AnalysisWarnings(*this), + DisableTypoCorrection( + CodeCompleter ? CodeCompleter->disableTypoCorrection() : false), + TyposCorrected(0), AnalysisWarnings(*this), ThreadSafetyDeclCache(nullptr), VarDataSharingAttributesStack(nullptr), CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr) { TUScope = nullptr; Index: unittests/Sema/CodeCompleteTest.cpp =================================================================== --- unittests/Sema/CodeCompleteTest.cpp +++ unittests/Sema/CodeCompleteTest.cpp @@ -28,8 +28,9 @@ class VisitedContextFinder: public CodeCompleteConsumer { public: - VisitedContextFinder(VisitedContextResults &Results) - : CodeCompleteConsumer(/*CodeCompleteOpts=*/{}, + VisitedContextFinder(VisitedContextResults &Results, + const CodeCompleteOptions &CCOpts) + : CodeCompleteConsumer(CCOpts, /*CodeCompleteConsumer*/ false), VCResults(Results), CCTUInfo(std::make_shared()) {} @@ -63,18 +64,21 @@ class CodeCompleteAction : public SyntaxOnlyAction { public: - CodeCompleteAction(ParsedSourceLocation P, VisitedContextResults &Results) - : CompletePosition(std::move(P)), VCResults(Results) {} + CodeCompleteAction(ParsedSourceLocation P, const CodeCompleteOptions &CCOpts, + VisitedContextResults &Results) + : CompletePosition(std::move(P)), CCOpts(std::move(CCOpts)), + VCResults(Results) {} bool BeginInvocation(CompilerInstance &CI) override { CI.getFrontendOpts().CodeCompletionAt = CompletePosition; - CI.setCodeCompletionConsumer(new VisitedContextFinder(VCResults)); + CI.setCodeCompletionConsumer(new VisitedContextFinder(VCResults, CCOpts)); return true; } private: // 1-based code complete position ; ParsedSourceLocation CompletePosition; + CodeCompleteOptions CCOpts; VisitedContextResults& VCResults; }; @@ -88,7 +92,8 @@ static_cast(Offset - StartOfLine + 1)}; } -VisitedContextResults runCodeCompleteOnCode(StringRef Code) { +VisitedContextResults +runCodeCompleteOnCode(StringRef Code, const CodeCompleteOptions &CCOpts = {}) { VisitedContextResults Results; auto TokenOffset = Code.find('^'); assert(TokenOffset != StringRef::npos && @@ -99,7 +104,7 @@ "expected exactly one completion token ^ inside the code"); auto Action = llvm::make_unique( - offsetToPosition(WithoutToken, TokenOffset), Results); + offsetToPosition(WithoutToken, TokenOffset), CCOpts, Results); clang::tooling::runToolOnCodeWithArgs(Action.release(), Code, {"-std=c++11"}, TestCCName); return Results; @@ -131,4 +136,14 @@ EXPECT_TRUE(VisitedNS.empty()); } +TEST(SemaCodeCompleteTest, DisableTypoCorrection) { + CodeCompleteOptions CCOpts; + CCOpts.DisableTypoCorrection = 1; + auto VisitedNS = runCodeCompleteOnCode(R"cpp( + namespace clang {} + clangd::^ + )cpp", CCOpts); + EXPECT_TRUE(VisitedNS.empty()); +} + } // namespace