[clang-tools-extra] ce2f642 - [clangd] Fix shared-lib builds after 2cdbc9cff3b7ef262
Author: Kadir Cetinkaya Date: 2024-04-19T15:52:17+02:00 New Revision: ce2f6423f0168e945b6f29aa40a3054c1abe22a9 URL: https://github.com/llvm/llvm-project/commit/ce2f6423f0168e945b6f29aa40a3054c1abe22a9 DIFF: https://github.com/llvm/llvm-project/commit/ce2f6423f0168e945b6f29aa40a3054c1abe22a9.diff LOG: [clangd] Fix shared-lib builds after 2cdbc9cff3b7ef262 Added: Modified: clang-tools-extra/clangd/unittests/CMakeLists.txt Removed: diff --git a/clang-tools-extra/clangd/unittests/CMakeLists.txt b/clang-tools-extra/clangd/unittests/CMakeLists.txt index e432db8d0912e7..7f1ae5c43d80c6 100644 --- a/clang-tools-extra/clangd/unittests/CMakeLists.txt +++ b/clang-tools-extra/clangd/unittests/CMakeLists.txt @@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support AllTargetsInfos FrontendOpenMP + TargetParser ) if(CLANG_BUILT_STANDALONE) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 550e09d - [clangd][NFC] Delete dead code
Author: Kadir Cetinkaya Date: 2024-04-04T10:01:13+02:00 New Revision: 550e09db1ad6e8f28546fa0c24b5582e57e210c4 URL: https://github.com/llvm/llvm-project/commit/550e09db1ad6e8f28546fa0c24b5582e57e210c4 DIFF: https://github.com/llvm/llvm-project/commit/550e09db1ad6e8f28546fa0c24b5582e57e210c4.diff LOG: [clangd][NFC] Delete dead code Added: Modified: clang-tools-extra/clangd/IncludeCleaner.h Removed: diff --git a/clang-tools-extra/clangd/IncludeCleaner.h b/clang-tools-extra/clangd/IncludeCleaner.h index 387763de340767..624e2116be7da3 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.h +++ b/clang-tools-extra/clangd/IncludeCleaner.h @@ -62,15 +62,6 @@ issueIncludeCleanerDiagnostics(ParsedAST , llvm::StringRef Code, const ThreadsafeFS , HeaderFilter IgnoreHeader = {}); -/// Affects whether standard library includes should be considered for -/// removal. This is off by default for now due to implementation limitations: -/// - macros are not tracked -/// - symbol names without a unique associated header are not tracked -/// - references to std-namespaced C types are not properly tracked: -/// instead of std::size_t -> we see ::size_t -> -/// FIXME: remove this hack once the implementation is good enough. -void setIncludeCleanerAnalyzesStdlib(bool B); - /// Converts the clangd include representation to include-cleaner /// include representation. include_cleaner::Includes convertIncludes(const ParsedAST &); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 4419b2c - [clangd] Make tidy-rename tests conditional
Author: Kadir Cetinkaya Date: 2024-02-23T11:39:14+01:00 New Revision: 4419b2c27fa45a08bc3892ad0c8c5eb95d96d608 URL: https://github.com/llvm/llvm-project/commit/4419b2c27fa45a08bc3892ad0c8c5eb95d96d608 DIFF: https://github.com/llvm/llvm-project/commit/4419b2c27fa45a08bc3892ad0c8c5eb95d96d608.diff LOG: [clangd] Make tidy-rename tests conditional Added: Modified: clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp Removed: diff --git a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp index 555c4c57499819..75a140767035b2 100644 --- a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp @@ -11,6 +11,7 @@ #include "ClangdServer.h" #include "ConfigProvider.h" #include "Diagnostics.h" +#include "Feature.h" #include "FeatureModule.h" #include "LSPBinder.h" #include "LSPClient.h" @@ -198,6 +199,9 @@ TEST_F(LSPTest, RecordsLatencies) { // clang-tidy's renames are converted to clangd's internal rename functionality, // see clangd#1589 and clangd#741 TEST_F(LSPTest, ClangTidyRename) { + // This test requires clang-tidy checks to be linked in. + if (!CLANGD_TIDY_CHECKS) +return; Annotations Header(R"cpp( void [[foo]](); )cpp"); @@ -214,7 +218,9 @@ TEST_F(LSPTest, ClangTidyRename) { Client.didOpen("foo.hpp", Header.code()); Client.didOpen("foo.cpp", Source.code()); - auto RenameDiag = Client.diagnostics("foo.cpp").value().at(0); + auto Diags = Client.diagnostics("foo.cpp"); + ASSERT_TRUE(Diags && !Diags->empty()); + auto RenameDiag = Diags->front(); auto RenameCommand = (*Client ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3533fe7 - Revert "[clang] Preserve found-decl when constructing VarTemplateIds (#82265)"
Author: Kadir Cetinkaya Date: 2024-02-21T11:15:42+01:00 New Revision: 3533fe783df4b417f16077edb70099010d2d7eef URL: https://github.com/llvm/llvm-project/commit/3533fe783df4b417f16077edb70099010d2d7eef DIFF: https://github.com/llvm/llvm-project/commit/3533fe783df4b417f16077edb70099010d2d7eef.diff LOG: Revert "[clang] Preserve found-decl when constructing VarTemplateIds (#82265)" This reverts commit 50373506d570f3db1e1af7c13d46409736452f3a. Broke include-cleaner tests Added: Modified: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaTemplate.cpp clang/test/AST/ast-dump-using.cpp Removed: diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 23e1a623a20d15..89215bf3d1c69a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -8538,7 +8538,7 @@ class Sema final { /// if the arguments are dependent. ExprResult CheckVarTemplateId(const CXXScopeSpec , const DeclarationNameInfo , -VarTemplateDecl *Template, NamedDecl *FoundD, +VarTemplateDecl *Template, SourceLocation TemplateLoc, const TemplateArgumentListInfo *TemplateArgs); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 7d3d665194add1..1a975a8d0a0df5 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4958,10 +4958,11 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc, return Decl; } -ExprResult Sema::CheckVarTemplateId( -const CXXScopeSpec , const DeclarationNameInfo , -VarTemplateDecl *Template, NamedDecl *FoundD, SourceLocation TemplateLoc, -const TemplateArgumentListInfo *TemplateArgs) { +ExprResult +Sema::CheckVarTemplateId(const CXXScopeSpec , + const DeclarationNameInfo , + VarTemplateDecl *Template, SourceLocation TemplateLoc, + const TemplateArgumentListInfo *TemplateArgs) { DeclResult Decl = CheckVarTemplateId(Template, TemplateLoc, NameInfo.getLoc(), *TemplateArgs); @@ -4977,7 +4978,8 @@ ExprResult Sema::CheckVarTemplateId( NameInfo.getLoc()); // Build an ordinary singleton decl ref. - return BuildDeclarationNameExpr(SS, NameInfo, Var, FoundD, TemplateArgs); + return BuildDeclarationNameExpr(SS, NameInfo, Var, + /*FoundD=*/nullptr, TemplateArgs); } void Sema::diagnoseMissingTemplateArguments(TemplateName Name, @@ -5064,9 +5066,9 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec , bool KnownDependent = false; // In C++1y, check variable template ids. if (R.getAsSingle()) { -ExprResult Res = CheckVarTemplateId( -SS, R.getLookupNameInfo(), R.getAsSingle(), -R.getRepresentativeDecl(), TemplateKWLoc, TemplateArgs); +ExprResult Res = CheckVarTemplateId(SS, R.getLookupNameInfo(), +R.getAsSingle(), +TemplateKWLoc, TemplateArgs); if (Res.isInvalid() || Res.isUsable()) return Res; // Result is dependent. Carry on to build an UnresolvedLookupEpxr. diff --git a/clang/test/AST/ast-dump-using.cpp b/clang/test/AST/ast-dump-using.cpp index 8e5c60d3aabf4a..5a4e910ffb8654 100644 --- a/clang/test/AST/ast-dump-using.cpp +++ b/clang/test/AST/ast-dump-using.cpp @@ -2,7 +2,6 @@ namespace a { struct S; -template T x = {}; } namespace b { using a::S; @@ -22,10 +21,4 @@ typedef S e; // check the same UsingType is reused. // CHECK-NEXT: `-UsingType [[TYPE_ADDR]] 'a::S' sugar // CHECK-NEXT: |-UsingShadow [[SHADOW_ADDR]] 'S' // CHECK-NEXT: `-RecordType {{.*}} 'a::S' -using a::x; - -void foo() { - x = 3; - // CHECK: DeclRefExpr {{.*}} 'x' {{.*}} (UsingShadow {{.*}} 'x') -} } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 2103de0 - [clangd] Add header mapping for struct_rusage.h
Author: Kadir Cetinkaya Date: 2023-12-15T14:39:02+01:00 New Revision: 2103de0c4cced5d06165a8a8a84cec89c8ab3be0 URL: https://github.com/llvm/llvm-project/commit/2103de0c4cced5d06165a8a8a84cec89c8ab3be0 DIFF: https://github.com/llvm/llvm-project/commit/2103de0c4cced5d06165a8a8a84cec89c8ab3be0.diff LOG: [clangd] Add header mapping for struct_rusage.h Added: Modified: clang-tools-extra/clangd/index/CanonicalIncludes.cpp Removed: diff --git a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp index 9ba4d7a95415bc..42eeba36a80e43 100644 --- a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp +++ b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp @@ -670,6 +670,7 @@ const std::pair IncludeMappings[] = { {"bits/types.h", ""}, {"bits/types/siginfo_t.h", ""}, {"bits/types/struct_itimerspec.h", ""}, +{"bits/types/struct_rusage.h", ""}, {"bits/uio.h", ""}, {"bits/ustat.h", ""}, {"bits/utmp.h", ""}, ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 076ec9f - Fix build failure on certain bots
Author: Kadir Cetinkaya Date: 2023-11-24T11:39:16+01:00 New Revision: 076ec9f5f5bf03983f43f703e3f9d4600bad9653 URL: https://github.com/llvm/llvm-project/commit/076ec9f5f5bf03983f43f703e3f9d4600bad9653 DIFF: https://github.com/llvm/llvm-project/commit/076ec9f5f5bf03983f43f703e3f9d4600bad9653.diff LOG: Fix build failure on certain bots Added: Modified: clang/lib/Basic/Targets/RISCV.cpp Removed: diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 0ecc35f3a332a9b..d1d9cc1c770e361 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -269,7 +269,7 @@ resolveTargetAttrOverride(const std::vector , std::vector NonISAExtFeature = collectNonISAExtFeature(FeaturesNeedOverride, XLen); - auto ResolvedFeature = std::vector(++I, FeaturesVec.end()); + auto ResolvedFeature = std::vector(++I, FeaturesVec.end()); ResolvedFeature.insert(ResolvedFeature.end(), NonISAExtFeature.begin(), NonISAExtFeature.end()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 7aaa86b - [include-cleaner] Add regression tests for outliving File Manager
Author: Kadir Cetinkaya Date: 2023-11-17T11:32:51+01:00 New Revision: 7aaa86b28ddc3deded6e357b27f2bbebb97a3864 URL: https://github.com/llvm/llvm-project/commit/7aaa86b28ddc3deded6e357b27f2bbebb97a3864 DIFF: https://github.com/llvm/llvm-project/commit/7aaa86b28ddc3deded6e357b27f2bbebb97a3864.diff LOG: [include-cleaner] Add regression tests for outliving File Manager Added: Modified: clang-tools-extra/include-cleaner/unittests/RecordTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp index dfefa66887b0f24..0f2ded5f1834531 100644 --- a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp @@ -558,5 +558,35 @@ TEST_F(PragmaIncludeTest, ExportInUnnamedBuffer) { PI.getExporters(llvm::cantFail(FM->getFileRef("foo.h")), *FM), testing::ElementsAre(llvm::cantFail(FM->getFileRef("exporter.h"; } + +TEST_F(PragmaIncludeTest, OutlivesFMAndSM) { + Inputs.Code = R"cpp( +#include "public.h" + )cpp"; + Inputs.ExtraFiles["public.h"] = R"cpp( +#include "private.h" +#include "private2.h" // IWYU pragma: export + )cpp"; + Inputs.ExtraFiles["private.h"] = R"cpp( +// IWYU pragma: private, include "public.h" + )cpp"; + Inputs.ExtraFiles["private2.h"] = R"cpp( +// IWYU pragma: private + )cpp"; + build(); // Fills up PI, file/source manager used is destroyed afterwards. + Inputs.MakeAction = nullptr; // Don't populate PI anymore. + + // Now this build gives us a new File Manager. + TestAST Processed = build(); + auto = Processed.fileManager(); + auto PrivateFE = FM.getFile("private.h"); + assert(PrivateFE); + EXPECT_EQ(PI.getPublic(PrivateFE.get()), "\"public.h\""); + + auto Private2FE = FM.getFile("private2.h"); + assert(Private2FE); + EXPECT_THAT(PI.getExporters(Private2FE.get(), FM), + testing::ElementsAre(llvm::cantFail(FM.getFileRef("public.h"; +} } // namespace } // namespace clang::include_cleaner ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] ec095b7 - [clangd] Fix builds after 0255b217c3766ce0aa23bd4fb050b447be2a1d26
Author: Kadir Cetinkaya Date: 2023-11-10T13:55:43+01:00 New Revision: ec095b74243bf5db2a70961ecbbde2a30efdccce URL: https://github.com/llvm/llvm-project/commit/ec095b74243bf5db2a70961ecbbde2a30efdccce DIFF: https://github.com/llvm/llvm-project/commit/ec095b74243bf5db2a70961ecbbde2a30efdccce.diff LOG: [clangd] Fix builds after 0255b217c3766ce0aa23bd4fb050b447be2a1d26 Added: Modified: clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp Removed: diff --git a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp index 357af8c9b679a99..e36b3249bc7b929 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp @@ -7,15 +7,28 @@ //===--===// #include "ParsedAST.h" +#include "Protocol.h" +#include "Selection.h" +#include "SourceCode.h" #include "XRefs.h" #include "refactor/Tweak.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Tooling/Core/Replacement.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" +#include "llvm/Support/MemoryBuffer.h" +#include #include +#include +#include +#include namespace clang::clangd { namespace { @@ -87,9 +100,9 @@ Expected ScopifyEnum::apply(const Selection ) { SM->getBufferData(SM->getMainFileID(; if (auto Err = addClassKeywordToDeclarations()) -return Err; +return std::move(Err); if (auto Err = scopifyEnumValues()) -return Err; +return std::move(Err); return E; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e214bda - Revert "[Sema] Add check for bitfield assignments to integral types (#69049)"
Author: Kadir Cetinkaya Date: 2023-10-23T18:23:21+02:00 New Revision: e214bdac51c46b554e1fb99de6b6b6c735b75bf1 URL: https://github.com/llvm/llvm-project/commit/e214bdac51c46b554e1fb99de6b6b6c735b75bf1 DIFF: https://github.com/llvm/llvm-project/commit/e214bdac51c46b554e1fb99de6b6b6c735b75bf1.diff LOG: Revert "[Sema] Add check for bitfield assignments to integral types (#69049)" This reverts commit 708808e8532e7c3647356aec0664fcf94b1093d1 which is causing crashes on valid code, see https://github.com/llvm/llvm-project/pull/69049#issuecomment-1775538177. Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/DiagnosticGroups.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaChecking.cpp Removed: clang/test/SemaCXX/bitfield-width.c diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f71b458597e1833..403a74fc602fd81 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -211,9 +211,6 @@ New Compiler Flags the preprocessed text to the output. This can greatly reduce the size of the preprocessed output, which can be helpful when trying to reduce a test case. -* ``-Wbitfield-conversion`` was added to detect assignments of integral - types to a bitfield that may change the value. - Deprecated Compiler Flags - diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 4cb792132d6e09d..e990bf6b7938ac6 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -53,7 +53,6 @@ def SingleBitBitFieldConstantConversion : def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion", [SingleBitBitFieldConstantConversion]>; def BitFieldEnumConversion : DiagGroup<"bitfield-enum-conversion">; -def BitFieldConversion : DiagGroup<"bitfield-conversion">; def BitFieldWidth : DiagGroup<"bitfield-width">; def CompoundTokenSplitByMacro : DiagGroup<"compound-token-split-by-macro">; def CompoundTokenSplitBySpace : DiagGroup<"compound-token-split-by-space">; @@ -936,7 +935,6 @@ def Conversion : DiagGroup<"conversion", ConstantConversion, EnumConversion, BitFieldEnumConversion, -BitFieldConversion, FloatConversion, Shorten64To32, IntConversion, diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 3bcbb003d6dee19..88315f25d1dcd79 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6191,9 +6191,6 @@ def warn_signed_bitfield_enum_conversion : Warning< "signed bit-field %0 needs an extra bit to represent the largest positive " "enumerators of %1">, InGroup, DefaultIgnore; -def warn_bitfield_too_small_for_integral_type : Warning< - "conversion from %2 (%3 bits) to bit-field %0 (%1 bits) may change value">, - InGroup, DefaultIgnore; def note_change_bitfield_sign : Note< "consider making the bitfield type %select{unsigned|signed}0">; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index f3c55d059e66380..7972919d1420116 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -14332,18 +14332,6 @@ static bool AnalyzeBitFieldAssignment(Sema , FieldDecl *Bitfield, Expr *Init, S.Diag(WidthExpr->getExprLoc(), diag::note_widen_bitfield) << BitsNeeded << ED << WidthExpr->getSourceRange(); } -} else if (OriginalInit->getType()->isIntegralType(S.Context)) { - IntRange LikelySourceRange = - GetExprRange(S.Context, Init, S.isConstantEvaluatedContext(), - /*Approximate=*/true); - - if (LikelySourceRange.Width > FieldWidth) { -Expr *WidthExpr = Bitfield->getBitWidth(); -S.Diag(InitLoc, diag::warn_bitfield_too_small_for_integral_type) -<< Bitfield << FieldWidth << OriginalInit->getType() -<< LikelySourceRange.Width; -S.Diag(WidthExpr->getExprLoc(), diag::note_declared_at); - } } return false; @@ -15241,6 +15229,7 @@ static void CheckImplicitConversion(Sema , Expr *E, QualType T, if (LikelySourceRange.Width > TargetRange.Width) { // If the source is a constant, use a default-on diagnostic. +// TODO: this should happen for bitfield stores, too. Expr::EvalResult Result; if (E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects, S.isConstantEvaluatedContext())) { diff --git a/clang/test/SemaCXX/bitfield-width.c
[clang-tools-extra] 26f9e49 - [clangd] Delete deprecated enumerateTweaks endpoint
Author: Kadir Cetinkaya Date: 2023-09-11T09:09:12+02:00 New Revision: 26f9e49d9c92255f7e6e0420eb1d549a023bbcb5 URL: https://github.com/llvm/llvm-project/commit/26f9e49d9c92255f7e6e0420eb1d549a023bbcb5 DIFF: https://github.com/llvm/llvm-project/commit/26f9e49d9c92255f7e6e0420eb1d549a023bbcb5.diff LOG: [clangd] Delete deprecated enumerateTweaks endpoint Added: Modified: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h Removed: diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index dce6bfc04ce6dd5..13d788162817fb4 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -704,38 +704,6 @@ void ClangdServer::codeAction(const CodeActionInputs , Transient); } -void ClangdServer::enumerateTweaks( -PathRef File, Range Sel, llvm::unique_function Filter, -Callback> CB) { - auto Action = [Sel, CB = std::move(CB), Filter = std::move(Filter), - FeatureModules(this->FeatureModules)]( -Expected InpAST) mutable { -if (!InpAST) - return CB(InpAST.takeError()); -auto Selections = tweakSelection(Sel, *InpAST, /*FS=*/nullptr); -if (!Selections) - return CB(Selections.takeError()); -std::vector Res; -// Don't allow a tweak to fire more than once across ambiguous selections. -llvm::DenseSet PreparedTweaks; -auto DeduplicatingFilter = [&](const Tweak ) { - return Filter(T) && !PreparedTweaks.count(T.id()); -}; -for (const auto : *Selections) { - for (auto : prepareTweaks(*Sel, DeduplicatingFilter, FeatureModules)) { -Res.push_back({T->id(), T->title(), T->kind()}); -PreparedTweaks.insert(T->id()); -TweakAvailable.record(1, T->id()); - } -} - -CB(std::move(Res)); - }; - - WorkScheduler->runWithAST("EnumerateTweaks", File, std::move(Action), -Transient); -} - void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, Callback CB) { // Tracks number of times a tweak has been attempted. diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 2bc8f02ff38a4bd..a416602251428b0 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -386,13 +386,6 @@ class ClangdServer { void codeAction(const CodeActionInputs , Callback CB); - /// Enumerate the code tweaks available to the user at a specified point. - /// Tweaks where Filter returns false will not be checked or included. - /// Deprecated, use codeAction instead. - void enumerateTweaks(PathRef File, Range Sel, - llvm::unique_function Filter, - Callback> CB); - /// Apply the code tweak with a specified \p ID. void applyTweak(PathRef File, Range Sel, StringRef ID, Callback CB); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 73b2c86 - [include-cleaner] Weaken signal for boosting preferred headers
Author: Kadir Cetinkaya Date: 2023-09-06T14:46:33+02:00 New Revision: 73b2c86d95dc510d6972aaa4b44688aebebd89f1 URL: https://github.com/llvm/llvm-project/commit/73b2c86d95dc510d6972aaa4b44688aebebd89f1 DIFF: https://github.com/llvm/llvm-project/commit/73b2c86d95dc510d6972aaa4b44688aebebd89f1.diff LOG: [include-cleaner] Weaken signal for boosting preferred headers Putting preferred header signal above completeness implied we would uprank forward declarations above complete ones in certain cases. This can be desired in cases where: - Complete definition is private. But this case is already governed by publicness signal. - The library indeed intends to provide a forward declaring interface, like iosfwd vs ostream. In all other cases, upranking is undesired as it means we've picked up prefered headerness signal by mistake from an unrelated declaration to the library. This change regresses the behavior for libraries that intentionally provide a forward declaring interface. But that wasn't something we intended to support explicitly, it was working incidentally when the forward declaring header had a similar name to the symbol. Moreover, include-cleaner deliberately discourages forward-declarations, so not working in this case is also more aligned with rest of the components. Differential Revision: https://reviews.llvm.org/D159441 Added: Modified: clang-tools-extra/include-cleaner/lib/TypesInternal.h clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/TypesInternal.h b/clang-tools-extra/include-cleaner/lib/TypesInternal.h index ca9b961cbccdad..0bd2766c900abc 100644 --- a/clang-tools-extra/include-cleaner/lib/TypesInternal.h +++ b/clang-tools-extra/include-cleaner/lib/TypesInternal.h @@ -66,13 +66,13 @@ enum class Hints : uint8_t { /// Symbol is directly originating from this header, rather than being /// exported or included transitively. OriginHeader = 1 << 0, - /// Provides a generally-usable definition for the symbol. (a function decl, - /// or class definition and not a forward declaration of a template). - CompleteSymbol = 1 << 1, /// Header providing the symbol is explicitly marked as preferred, with an /// IWYU private pragma that points at this provider or header and symbol has /// ~the same name. - PreferredHeader = 1 << 2, + PreferredHeader = 1 << 1, + /// Provides a generally-usable definition for the symbol. (a function decl, + /// or class definition and not a forward declaration of a template). + CompleteSymbol = 1 << 2, /// Symbol is provided by a public file. Only absent in the cases where file /// is explicitly marked as such, non self-contained or IWYU private /// pragmas. diff --git a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp index b8f30c25e5c11b..89910e72beb463 100644 --- a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp @@ -344,7 +344,7 @@ TEST_F(HeadersForSymbolTest, RankByName) { } TEST_F(HeadersForSymbolTest, Ranking) { - // Sorting is done over (canonical, public, complete, origin)-tuple. + // Sorting is done over (public, complete, canonical, origin)-tuple. Inputs.Code = R"cpp( #include "private.h" #include "public.h" @@ -363,11 +363,11 @@ TEST_F(HeadersForSymbolTest, Ranking) { )cpp"); Inputs.ExtraFiles["public_complete.h"] = guard("struct foo {};"); buildAST(); - EXPECT_THAT(headersForFoo(), ElementsAre(Header("\"canonical.h\""), - physicalHeader("public_complete.h"), - physicalHeader("public.h"), - physicalHeader("exporter.h"), - physicalHeader("private.h"))); + EXPECT_THAT(headersForFoo(), + ElementsAre(physicalHeader("public_complete.h"), + Header("\"canonical.h\""), physicalHeader("public.h"), + physicalHeader("exporter.h"), + physicalHeader("private.h"))); } TEST_F(HeadersForSymbolTest, PreferPublicOverComplete) { @@ -391,14 +391,11 @@ TEST_F(HeadersForSymbolTest, PreferNameMatch) { #include "public_complete.h" #include "test/foo.fwd.h" )cpp"; - Inputs.ExtraFiles["public_complete.h"] = guard(R"cpp( -struct foo {}; - )cpp"); + Inputs.ExtraFiles["public_complete.h"] = guard("struct foo {};"); Inputs.ExtraFiles["test/foo.fwd.h"] = guard("struct foo;"); buildAST(); - EXPECT_THAT(headersForFoo(), - ElementsAre(physicalHeader("test/foo.fwd.h"), - physicalHeader("public_complete.h"))); + EXPECT_THAT(headersForFoo(),
[clang-tools-extra] 9a26d2c - [clangd][unittests] Limit paralelism for clangd unittests
Author: Kadir Cetinkaya Date: 2023-09-06T10:53:18+02:00 New Revision: 9a26d2c6d35f574d7a4b06a5a22f8a1c063cb664 URL: https://github.com/llvm/llvm-project/commit/9a26d2c6d35f574d7a4b06a5a22f8a1c063cb664 DIFF: https://github.com/llvm/llvm-project/commit/9a26d2c6d35f574d7a4b06a5a22f8a1c063cb664.diff LOG: [clangd][unittests] Limit paralelism for clangd unittests We started seeing a lot of timeouts that align with the change in lit to execute gtests in shards. The logic there assumes tests are single-threaded, which is the case for most of the LLVM, hence they pick #shards ~ #cores (by slightly overshooting). There are enough unittests in clangd that rely on multi-threading, they can create arbitrarily many threads but we limit amount of meaningful work to ~4 thread per process. This change ensures that we're accounting for that paralelism when executing clangd tests and not overloading test executors. In theory the change overestimates the requirements, not all tests are multi-threaded, but it doesn't seem to be resulting in any regressions on my local runs. Fixes https://github.com/llvm/llvm-project/issues/64964. Fixes https://github.com/clangd/clangd/issues/1712. Added: Modified: clang-tools-extra/clangd/unittests/lit.cfg.py Removed: diff --git a/clang-tools-extra/clangd/unittests/lit.cfg.py b/clang-tools-extra/clangd/unittests/lit.cfg.py index 48ee5f5d5ab920..33aa9e61f4ce9d 100644 --- a/clang-tools-extra/clangd/unittests/lit.cfg.py +++ b/clang-tools-extra/clangd/unittests/lit.cfg.py @@ -1,4 +1,5 @@ import lit.formats +import lit.util config.name = "Clangd Unit Tests" config.test_format = lit.formats.GoogleTest(".", "Tests") @@ -9,6 +10,13 @@ # FIXME: it seems every project has a copy of this logic. Move it somewhere. import platform +# Clangd unittests uses ~4 threads per test. So make sure we don't over commit. +core_count = lit.util.usable_core_count() +# FIXME: Split unittests into groups that use threads, and groups that do not, +# and only limit multi-threaded tests. +lit_config.parallelism_groups["clangd"] = max(1, core_count // 4) +config.parallelism_group = "clangd" + if platform.system() == "Darwin": shlibpath_var = "DYLD_LIBRARY_PATH" elif platform.system() == "Windows": ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 16b8b3e - [clangd][tests] Bump timeouts in TUSchedulerTests to 60 secs
Author: Kadir Cetinkaya Date: 2023-09-01T12:19:10+02:00 New Revision: 16b8b3e59f7e5d64d4bb4e252a6fea5235feb630 URL: https://github.com/llvm/llvm-project/commit/16b8b3e59f7e5d64d4bb4e252a6fea5235feb630 DIFF: https://github.com/llvm/llvm-project/commit/16b8b3e59f7e5d64d4bb4e252a6fea5235feb630.diff LOG: [clangd][tests] Bump timeouts in TUSchedulerTests to 60 secs There are some slow/congested bots, that can't go idle in 10 secs, see https://github.com/llvm/llvm-project/issues/64964 Differential Revision: https://reviews.llvm.org/D159338 Added: Modified: clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp Removed: diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp index a3c1916b9b1d41..4f028f2cbe5a14 100644 --- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp +++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp @@ -251,7 +251,7 @@ TEST_F(TUSchedulerTests, WantDiagnostics) { [&](std::vector) { ++CallbackCount; }); Ready.notify(); -ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); +ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60))); } EXPECT_EQ(2, CallbackCount); } @@ -274,7 +274,7 @@ TEST_F(TUSchedulerTests, Debounce) { Notification N; updateWithDiags(S, Path, "auto (timed out)", WantDiagnostics::Auto, [&](std::vector) { N.notify(); }); - EXPECT_TRUE(N.wait(timeoutSeconds(5))); + EXPECT_TRUE(N.wait(timeoutSeconds(60))); // Once we start shutting down the TUScheduler, this one becomes a dead write. updateWithDiags(S, Path, "auto (discarded)", WantDiagnostics::Auto, @@ -340,7 +340,7 @@ TEST_F(TUSchedulerTests, Cancellation) { Read("R3")(); Proceed.notify(); -ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); +ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60))); } EXPECT_THAT(DiagsSeen, ElementsAre("U2", "U3")) << "U1 and all dependent reads were cancelled. " @@ -361,7 +361,7 @@ TEST_F(TUSchedulerTests, InvalidationNoCrash) { // We expect invalidation logic to not crash by trying to invalidate a running // request. S.update(Path, getInputs(Path, ""), WantDiagnostics::Auto); - ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); + ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60))); S.runWithAST( "invalidatable-but-running", Path, [&](llvm::Expected AST) { @@ -373,7 +373,7 @@ TEST_F(TUSchedulerTests, InvalidationNoCrash) { StartedRunning.wait(); S.update(Path, getInputs(Path, ""), WantDiagnostics::Auto); ScheduledChange.notify(); - ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); + ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60))); } TEST_F(TUSchedulerTests, Invalidation) { @@ -429,7 +429,7 @@ TEST_F(TUSchedulerTests, Invalidation) { }, TUScheduler::InvalidateOnUpdate); Start.notify(); - ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); + ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60))); EXPECT_EQ(2, Builds.load()) << "Middle build should be skipped"; EXPECT_EQ(4, Actions.load()) << "All actions should run (some with error)"; @@ -462,7 +462,7 @@ TEST_F(TUSchedulerTests, InvalidationUnchanged) { ADD_FAILURE() << "Shouldn't build, identical to previous"; }); Start.notify(); - ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); + ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60))); EXPECT_EQ(1, Actions.load()) << "All actions should run"; } @@ -569,7 +569,7 @@ TEST_F(TUSchedulerTests, ManyUpdates) { } } } -ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); +ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60))); } // TUScheduler destructor waits for all operations to finish. std::lock_guard Lock(Mut); @@ -611,7 +611,7 @@ TEST_F(TUSchedulerTests, EvictedAST) { // one that the cache will evict. updateWithCallback(S, Foo, SourceContents, WantDiagnostics::Yes, []() { ++BuiltASTCounter; }); - ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); + ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60))); ASSERT_EQ(BuiltASTCounter.load(), 1); EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "hit"), SizeIs(0)); EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "miss"), SizeIs(1)); @@ -622,7 +622,7 @@ TEST_F(TUSchedulerTests, EvictedAST) { []() { ++BuiltASTCounter; }); updateWithCallback(S, Baz, SourceContents, WantDiagnostics::Yes, []() { ++BuiltASTCounter; }); - ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); + ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(60))); ASSERT_EQ(BuiltASTCounter.load(), 3); EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "hit"), SizeIs(0)); EXPECT_THAT(Tracer.takeMetric("ast_access_diag", "miss"), SizeIs(2)); @@ -633,7 +633,7 @@ TEST_F(TUSchedulerTests, EvictedAST) { //
[clang-tools-extra] 69feef0 - [clangd][tests] Assert for idleness of scheduler
Author: Kadir Cetinkaya Date: 2023-09-01T12:19:09+02:00 New Revision: 69feef0e827793fd1c9df5dddc736441ff46f8af URL: https://github.com/llvm/llvm-project/commit/69feef0e827793fd1c9df5dddc736441ff46f8af DIFF: https://github.com/llvm/llvm-project/commit/69feef0e827793fd1c9df5dddc736441ff46f8af.diff LOG: [clangd][tests] Assert for idleness of scheduler We could fail going idle in 5 seconds and get spurious errors afterwards. See https://github.com/llvm/llvm-project/issues/64964. Differential Revision: https://reviews.llvm.org/D159337 Added: Modified: clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp Removed: diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp index 5d5b618a854806..a3c1916b9b1d41 100644 --- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp +++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp @@ -1307,7 +1307,7 @@ TEST_F(TUSchedulerTests, PublishWithStalePreamble) { ASSERT_THAT(BlockForDiags(PI), testing::Pair("1", "3")); UnblockPreamble.notify(); - S.blockUntilIdle(timeoutSeconds(5)); + ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(5))); // Make sure that we have eventual consistency. EXPECT_THAT(Collector.diagVersions().back(), Pair(PI.Version, PI.Version)); @@ -1316,7 +1316,7 @@ TEST_F(TUSchedulerTests, PublishWithStalePreamble) { PI.Version = "4"; PI.Contents = "#define FOO\n" + PI.Version; S.update(File, PI, WantDiagnostics::No); - S.blockUntilIdle(timeoutSeconds(5)); + ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(5))); EXPECT_THAT(Collector.diagVersions().back(), Pair("3", "3")); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7590b76 - Revert "[clang-format] Annotate constructor/destructor names"
Author: Kadir Cetinkaya Date: 2023-08-28T10:31:07+02:00 New Revision: 7590b7657004b33b1a12b05f8e9174db3e192f8c URL: https://github.com/llvm/llvm-project/commit/7590b7657004b33b1a12b05f8e9174db3e192f8c DIFF: https://github.com/llvm/llvm-project/commit/7590b7657004b33b1a12b05f8e9174db3e192f8c.diff LOG: Revert "[clang-format] Annotate constructor/destructor names" This reverts commit 0e63f1aacc0040e9a16fa2fab15a140b1686e2ab. clang-format started to crash with contents like: a.h: ``` ``` $ clang-format a.h ``` PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace. Stack dump: 0. Program arguments: ../llvm/build/bin/clang-format a.h #0 0x560b689fe177 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /usr/local/google/home/kadircet/repos/llvm/llvm/lib/Support/Unix/Signals.inc:723:13 #1 0x560b689fbfbe llvm::sys::RunSignalHandlers() /usr/local/google/home/kadircet/repos/llvm/llvm/lib/Support/Signals.cpp:106:18 #2 0x560b689feaca SignalHandler(int) /usr/local/google/home/kadircet/repos/llvm/llvm/lib/Support/Unix/Signals.inc:413:1 #3 0x7f030405a540 (/lib/x86_64-linux-gnu/libc.so.6+0x3c540) #4 0x560b68a9a980 is /usr/local/google/home/kadircet/repos/llvm/clang/include/clang/Lex/Token.h:98:44 #5 0x560b68a9a980 is /usr/local/google/home/kadircet/repos/llvm/clang/lib/Format/FormatToken.h:562:51 #6 0x560b68a9a980 startsSequenceInternal /usr/local/google/home/kadircet/repos/llvm/clang/lib/Format/FormatToken.h:831:9 #7 0x560b68a9a980 startsSequence /usr/local/google/home/kadircet/repos/llvm/clang/lib/Format/FormatToken.h:600:12 #8 0x560b68a9a980 getFunctionName /usr/local/google/home/kadircet/repos/llvm/clang/lib/Format/TokenAnnotator.cpp:3131:17 #9 0x560b68a9a980 clang::format::TokenAnnotator::annotate(clang::format::AnnotatedLine&) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Format/TokenAnnotator.cpp:3191:17 Segmentation fault ``` Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 97df0b447b4baa..b6b4172818d171 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3097,76 +3097,6 @@ static unsigned maxNestingDepth(const AnnotatedLine ) { return Result; } -// Returns the name of a function with no return type, e.g. a constructor or -// destructor. -static FormatToken *getFunctionName(const AnnotatedLine ) { - for (FormatToken *Tok = Line.getFirstNonComment(), *Name = nullptr; Tok; - Tok = Tok->getNextNonComment()) { -// Skip C++11 attributes both before and after the function name. -if (Tok->is(tok::l_square) && Tok->is(TT_AttributeSquare)) { - Tok = Tok->MatchingParen; - if (!Tok) -break; - continue; -} - -// Make sure the name is followed by a pair of parentheses. -if (Name) - return Tok->is(tok::l_paren) && Tok->MatchingParen ? Name : nullptr; - -// Skip keywords that may precede the constructor/destructor name. -if (Tok->isOneOf(tok::kw_friend, tok::kw_inline, tok::kw_virtual, - tok::kw_constexpr, tok::kw_consteval, tok::kw_explicit)) { - continue; -} - -// A qualified name may start from the global namespace. -if (Tok->is(tok::coloncolon)) { - Tok = Tok->Next; - if (!Tok) -break; -} - -// Skip to the unqualified part of the name. -while (Tok->startsSequence(tok::identifier, tok::coloncolon)) { - assert(Tok->Next); - Tok = Tok->Next->Next; - if (!Tok) -break; -} - -// Skip the `~` if a destructor name. -if (Tok->is(tok::tilde)) { - Tok = Tok->Next; - if (!Tok) -break; -} - -// Make sure the name is not already annotated, e.g. as NamespaceMacro. -if (Tok->isNot(tok::identifier) || Tok->isNot(TT_Unknown)) - break; - -Name = Tok; - } - - return nullptr; -} - -// Checks if Tok is a constructor/destructor name qualified by its class name. -static bool isCtorOrDtorName(const FormatToken *Tok) { - assert(Tok && Tok->is(tok::identifier)); - const auto *Prev = Tok->Previous; - - if (Prev && Prev->is(tok::tilde)) -Prev = Prev->Previous; - - if (!Prev || !Prev->endsSequence(tok::coloncolon, tok::identifier)) -return false; - - assert(Prev->Previous); - return Prev->Previous->TokenText == Tok->TokenText; -} - void TokenAnnotator::annotate(AnnotatedLine ) { for (auto : Line.Children) annotate(*Child); @@ -3187,14 +3117,6 @@ void TokenAnnotator::annotate(AnnotatedLine ) { ExpressionParser ExprParser(Style, Keywords, Line); ExprParser.parse(); - if (Style.isCpp()) { -auto *Tok = getFunctionName(Line); -if (Tok &&
[clang-tools-extra] ab090e9 - [include-cleaner] Make handling of enum constants similar to members
Author: Kadir Cetinkaya Date: 2023-08-28T09:31:58+02:00 New Revision: ab090e9e49ff85d031a263abf327e9e436ce3873 URL: https://github.com/llvm/llvm-project/commit/ab090e9e49ff85d031a263abf327e9e436ce3873 DIFF: https://github.com/llvm/llvm-project/commit/ab090e9e49ff85d031a263abf327e9e436ce3873.diff LOG: [include-cleaner] Make handling of enum constants similar to members We were treating enum constants more like regular decls, which results in ignoring type aliases/exports. This patch brings the handling to be closer to member-like decls, with one caveat. When we encounter reference to an enum constant we still report an explicit reference to the particular enum constant, as otherwise we might not see any references to the enum itself. Also drops implicit references from qualified names to containers, as we already have explicit references from the qualifier to relevant container. Differential Revision: https://reviews.llvm.org/D158515 Added: Modified: clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index febdf19e695cd9..e3ba2d3b604072 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -126,13 +126,22 @@ class ASTWalker : public RecursiveASTVisitor { } bool VisitDeclRefExpr(DeclRefExpr *DRE) { -// Static class members are handled here, as they don't produce MemberExprs. -if (DRE->getFoundDecl()->isCXXClassMember()) { - if (auto *Qual = DRE->getQualifier()) -report(DRE->getLocation(), Qual->getAsRecordDecl(), RefType::Implicit); -} else { - report(DRE->getLocation(), DRE->getFoundDecl()); +auto *FD = DRE->getFoundDecl(); +// For refs to non-meber-like decls, use the found decl. +// For member-like decls, we should have a reference from the qualifier to +// the container decl instead, which is preferred as it'll handle +// aliases/exports properly. +if (!FD->isCXXClassMember() && !llvm::isa(FD)) { + report(DRE->getLocation(), FD); + return true; } +// If the ref is without a qualifier, and is a member, ignore it. As it is +// available in current context due to some other construct (e.g. base +// specifiers, using decls) that has to spell the name explicitly. +// If it's an enum constant, it must be due to prior decl. Report references +// to it instead. +if (llvm::isa(FD) && !DRE->hasQualifier()) + report(DRE->getLocation(), FD); return true; } diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index 3a86f36e3964f6..67248d4eedb915 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -50,7 +50,7 @@ std::vector testWalk(llvm::StringRef TargetCode, Inputs.ExtraFiles["target.h"] = Target.code().str(); Inputs.ExtraArgs.push_back("-include"); Inputs.ExtraArgs.push_back("target.h"); - Inputs.ExtraArgs.push_back("-std=c++17"); + Inputs.ExtraArgs.push_back("-std=c++20"); TestAST AST(Inputs); const auto = AST.sourceManager(); @@ -114,7 +114,7 @@ TEST(WalkAST, DeclRef) { testWalk("int $explicit^x;", "int y = ^x;"); testWalk("int $explicit^foo();", "int y = ^foo();"); testWalk("namespace ns { int $explicit^x; }", "int y = ns::^x;"); - testWalk("struct $implicit^S { static int x; };", "int y = S::^x;"); + testWalk("struct S { static int x; };", "int y = S::^x;"); // Canonical declaration only. testWalk("extern int $explicit^x; int x;", "int y = ^x;"); // Return type of `foo` isn't used. @@ -309,6 +309,14 @@ TEST(WalkAST, Alias) { namespace ns { using ::$explicit^Foo; } template<> struct ns::Foo {};)cpp", "ns::^Foo x;"); + testWalk(R"cpp( +namespace ns { enum class foo { bar }; } +using ns::foo;)cpp", + "auto x = foo::^bar;"); + testWalk(R"cpp( +namespace ns { enum foo { bar }; } +using ns::foo::$explicit^bar;)cpp", + "auto x = ^bar;"); } TEST(WalkAST, Using) { @@ -338,6 +346,8 @@ TEST(WalkAST, Using) { } using ns::$explicit^Y;)cpp", "^Y x;"); + testWalk("namespace ns { enum E {A}; } using enum ns::$explicit^E;", + "auto x = ^A;"); } TEST(WalkAST, Namespaces) { @@ -399,10 +409,10 @@ TEST(WalkAST, NestedTypes) { } TEST(WalkAST, MemberExprs) { - testWalk("struct $implicit^S { static int f; };", "void foo() { S::^f; }"); - testWalk("struct B { static int f; }; struct $implicit^S : B {};", + testWalk("struct S { static int f; };", "void foo() { S::^f; }"); + testWalk("struct B { static int f; }; struct S : B {};",
[clang-tools-extra] 8c21544 - [clangd] Bump timeouts for LSPServerTests
Author: Kadir Cetinkaya Date: 2023-08-22T16:20:15+02:00 New Revision: 8c21544286a0cf5eba7df67e23e3b7265364e752 URL: https://github.com/llvm/llvm-project/commit/8c21544286a0cf5eba7df67e23e3b7265364e752 DIFF: https://github.com/llvm/llvm-project/commit/8c21544286a0cf5eba7df67e23e3b7265364e752.diff LOG: [clangd] Bump timeouts for LSPServerTests We seem to be hitting limits in some windows build bots, see https://github.com/clangd/clangd/issues/1712#issuecomment-1686478931. So bumping the timeouts to 60 seconds and completely dropping them for sync requests. As mentioned in the comment above, this should improve things, considering even the tests that don't touch any complicated scheduler is failing. Differential Revision: https://reviews.llvm.org/D158426 Added: Modified: clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp clang-tools-extra/clangd/unittests/LSPClient.cpp clang-tools-extra/clangd/unittests/LSPClient.h Removed: diff --git a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp index 4c6a238bbb261f..15d4be8dd9ba91 100644 --- a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp @@ -8,19 +8,38 @@ #include "Annotations.h" #include "ClangdLSPServer.h" +#include "ClangdServer.h" +#include "ConfigProvider.h" +#include "Diagnostics.h" +#include "FeatureModule.h" +#include "LSPBinder.h" #include "LSPClient.h" -#include "Protocol.h" #include "TestFS.h" +#include "support/Function.h" #include "support/Logger.h" #include "support/TestTracer.h" +#include "support/Threading.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/FunctionExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/JSON.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Testing/Support/Error.h" #include "llvm/Testing/Support/SupportHelpers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include +#include +#include +#include +#include +#include #include +#include +#include namespace clang { namespace clangd { @@ -358,7 +377,7 @@ TEST_F(LSPTest, FeatureModulesThreadingTest) { Client.notify("increment", nullptr); Client.notify("increment", nullptr); Client.notify("increment", nullptr); - EXPECT_THAT_EXPECTED(Client.call("sync", nullptr).take(), Succeeded()); + Client.sync(); EXPECT_EQ(3, FeatureModules.get()->getSync()); // Throw some work on the queue to make sure shutdown blocks on it. Client.notify("increment", nullptr); diff --git a/clang-tools-extra/clangd/unittests/LSPClient.cpp b/clang-tools-extra/clangd/unittests/LSPClient.cpp index 9361c0e29c91e7..4d8ba137e8c55d 100644 --- a/clang-tools-extra/clangd/unittests/LSPClient.cpp +++ b/clang-tools-extra/clangd/unittests/LSPClient.cpp @@ -12,21 +12,36 @@ #include "Transport.h" #include "support/Logger.h" #include "support/Threading.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/JSON.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include "gtest/gtest.h" #include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include namespace clang { namespace clangd { llvm::Expected clang::clangd::LSPClient::CallResult::take() { std::unique_lock Lock(Mu); - if (!clangd::wait(Lock, CV, timeoutSeconds(10), + static constexpr size_t TimeoutSecs = 60; + if (!clangd::wait(Lock, CV, timeoutSeconds(TimeoutSecs), [this] { return Value.has_value(); })) { -ADD_FAILURE() << "No result from call after 10 seconds!"; +ADD_FAILURE() << "No result from call after " << TimeoutSecs << " seconds!"; return llvm::json::Value(nullptr); } auto Res = std::move(*Value); diff --git a/clang-tools-extra/clangd/unittests/LSPClient.h b/clang-tools-extra/clangd/unittests/LSPClient.h index be8bd42b84df13..3d459076321aca 100644 --- a/clang-tools-extra/clangd/unittests/LSPClient.h +++ b/clang-tools-extra/clangd/unittests/LSPClient.h @@ -9,12 +9,14 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_LSPCLIENT_H +#include "llvm/ADT/StringRef.h" +#include #include #include -#include -#include +#include #include #include +#include namespace clang { namespace clangd { @@ -32,7 +34,7 @@ class LSPClient { class CallResult { public: ~CallResult(); -// Blocks up to 10 seconds for the result to be ready. +// Blocks up to 60 seconds for the result to be ready. // Records a test failure if there was no reply. llvm::Expected
[clang] 851c248 - [clang] Prevent possible use-after-free
Author: Kadir Cetinkaya Date: 2023-08-18T16:27:57+02:00 New Revision: 851c248dfcdbf52ee88e4643e59453fcc13501d5 URL: https://github.com/llvm/llvm-project/commit/851c248dfcdbf52ee88e4643e59453fcc13501d5 DIFF: https://github.com/llvm/llvm-project/commit/851c248dfcdbf52ee88e4643e59453fcc13501d5.diff LOG: [clang] Prevent possible use-after-free This prevents further parsing of tokens (that'll be freed) inside method body by propagating EOF emitted by reaching code completion token up the parsing stack. Differential Revision: https://reviews.llvm.org/D158269 Added: clang/test/Parser/objc-delayed-method-use-after-free.m Modified: clang/lib/Parse/ParseObjc.cpp Removed: diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index d0af98b9106c3e..38448a0825617a 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -3764,6 +3764,8 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod , bool parseMethod) { while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof)) ConsumeAnyToken(); } - // Clean up the remaining EOF token. - ConsumeAnyToken(); + // Clean up the remaining EOF token, only if it's inserted by us. Otherwise + // this might be code-completion token, which must be propagated to callers. + if (Tok.is(tok::eof) && Tok.getEofData() == MCDecl) +ConsumeAnyToken(); } diff --git a/clang/test/Parser/objc-delayed-method-use-after-free.m b/clang/test/Parser/objc-delayed-method-use-after-free.m new file mode 100644 index 00..83927b2c705175 --- /dev/null +++ b/clang/test/Parser/objc-delayed-method-use-after-free.m @@ -0,0 +1,13 @@ +// Make sure we don't trigger use-after-free when we encounter a code completion +// token inside a objc method. +@interface Foo +@end + +@implementation Foo +- (void)foo { + +// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -code-completion-at=%s:%(line-1):1 %s | FileCheck %s +// CHECK: COMPLETION: self : [#Foo *#]self + [self foo]; +} +@end ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 90ecadd - [include-cleaner] Filter references to identity macros
Author: Kadir Cetinkaya Date: 2023-08-18T14:40:03+02:00 New Revision: 90ecadde62f30275c35fdf7928e3477a41691d21 URL: https://github.com/llvm/llvm-project/commit/90ecadde62f30275c35fdf7928e3477a41691d21 DIFF: https://github.com/llvm/llvm-project/commit/90ecadde62f30275c35fdf7928e3477a41691d21.diff LOG: [include-cleaner] Filter references to identity macros Despite being true positives, these results just confuse users. So filter them out. Differential Revision: https://reviews.llvm.org/D157905 Added: Modified: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/IncludeCleaner.cpp clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h clang-tools-extra/include-cleaner/lib/Analysis.cpp clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp Removed: diff --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp index f47609b19badfc..2658c4b38702ca 100644 --- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp @@ -87,7 +87,7 @@ void IncludeCleanerCheck::registerPPCallbacks(const SourceManager , Preprocessor *PP, Preprocessor *ModuleExpanderPP) { PP->addPPCallbacks(RecordedPreprocessor.record(*PP)); - HS = >getHeaderSearchInfo(); + this->PP = PP; RecordedPI.record(*PP); } @@ -121,7 +121,7 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult ) { // FIXME: Find a way to have less code duplication between include-cleaner // analysis implementation and the below code. walkUsed(MainFileDecls, RecordedPreprocessor.MacroReferences, , - *SM, + *PP, [&](const include_cleaner::SymbolReference , llvm::ArrayRef Providers) { // Process each symbol once to reduce noise in the findings. @@ -200,8 +200,8 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult ) { tooling::HeaderIncludes HeaderIncludes(getCurrentMainFile(), Code, FileStyle->IncludeStyle); for (const auto : Missing) { -std::string Spelling = -include_cleaner::spellHeader({Inc.Missing, *HS, MainFile}); +std::string Spelling = include_cleaner::spellHeader( +{Inc.Missing, PP->getHeaderSearchInfo(), MainFile}); bool Angled = llvm::StringRef{Spelling}.starts_with("<"); // We might suggest insertion of an existing include in edge cases, e.g., // include is present in a PP-disabled region, or spelling of the header diff --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h index 9641c7fd9dfcf6..b46e409bd6f6a0 100644 --- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h +++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h @@ -18,6 +18,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/Preprocessor.h" #include "llvm/Support/Regex.h" #include @@ -42,7 +43,7 @@ class IncludeCleanerCheck : public ClangTidyCheck { private: include_cleaner::RecordedPP RecordedPreprocessor; include_cleaner::PragmaIncludes RecordedPI; - HeaderSearch *HS; + const Preprocessor *PP = nullptr; std::vector IgnoreHeaders; // Whether emit only one finding per usage of a symbol. const bool DeduplicateFindings; diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index aaa160bb048ef5..0ec85fc24df151 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -1245,12 +1245,11 @@ std::string getSymbolName(include_cleaner::Symbol Sym) { } void maybeAddUsedSymbols(ParsedAST , HoverInfo , const Inclusion ) { - const SourceManager = AST.getSourceManager(); auto Converted = convertIncludes(AST); llvm::DenseSet UsedSymbols; include_cleaner::walkUsed( AST.getLocalTopLevelDecls(), collectMacroReferences(AST), - AST.getPragmaIncludes().get(), SM, + AST.getPragmaIncludes().get(), AST.getPreprocessor(), [&](const include_cleaner::SymbolReference , llvm::ArrayRef Providers) { if (Ref.RT != include_cleaner::RefType::Explicit || diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index 07c6937ac10d5b..1fcb5c7228fb63 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -394,7 +394,7 @@
[clang] 373fcd5 - [clang] Use RecoveryExprs for broken defaultargs, instead of OpaqueValueExprs
Author: Kadir Cetinkaya Date: 2023-08-16T10:22:16+02:00 New Revision: 373fcd5d73a3ed5bedff771bcf6a3aba981155cc URL: https://github.com/llvm/llvm-project/commit/373fcd5d73a3ed5bedff771bcf6a3aba981155cc DIFF: https://github.com/llvm/llvm-project/commit/373fcd5d73a3ed5bedff771bcf6a3aba981155cc.diff LOG: [clang] Use RecoveryExprs for broken defaultargs, instead of OpaqueValueExprs This makes sure we can preserve invalid-ness for consumers of this node, it prevents crashes. It also aligns better with rest of the places that store invalid expressions. Differential Revision: https://reviews.llvm.org/D157868 Added: clang/test/AST/ast-dump-default-arg-recovery.cpp Modified: clang-tools-extra/clangd/unittests/HoverTests.cpp clang/include/clang/Sema/Sema.h clang/lib/Parse/ParseCXXInlineMethods.cpp clang/lib/Parse/ParseDecl.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/test/Index/complete-optional-params.cpp Removed: diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp index 2ad7f0ee55d726..9cab9a086958d6 100644 --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -2543,6 +2543,19 @@ TEST(Hover, All) { HI.Type = "Test &&"; HI.Definition = "Test & = {}"; }}, + { + R"cpp(// Shouldn't crash when evaluating the initializer. +struct Bar {}; // error-ok +struct Foo { void foo(Bar x = y); } +void Foo::foo(Bar [[^x]]) {})cpp", + [](HoverInfo ) { +HI.Name = "x"; +HI.Kind = index::SymbolKind::Parameter; +HI.NamespaceScope = ""; +HI.LocalScope = "Foo::foo::"; +HI.Type = "Bar"; +HI.Definition = "Bar x = ()"; + }}, { R"cpp(// auto on alias typedef int int_type; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 8a63f10a6e1561..05a0e43b5b73d9 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3022,7 +3022,8 @@ class Sema final { Expr *defarg); void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc, SourceLocation ArgLoc); - void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc); + void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc, + Expr* DefaultArg); ExprResult ConvertParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc); void SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 4951eb9aa2802a..573c90a36eeab3 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -395,9 +395,10 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration ) { DefArgResult = ParseBraceInitializer(); } else DefArgResult = ParseAssignmentExpression(); - DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult); + DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult, Param); if (DefArgResult.isInvalid()) { -Actions.ActOnParamDefaultArgumentError(Param, EqualLoc); +Actions.ActOnParamDefaultArgumentError(Param, EqualLoc, + /*DefaultArg=*/nullptr); } else { if (Tok.isNot(tok::eof) || Tok.getEofData() != Param) { // The last two tokens are the terminator and the saved value of diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index b5a3ee1eaf076d..cd7c5dcf275c04 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -7548,7 +7548,8 @@ void Parser::ParseParameterDeclarationClause( } else { if (Tok.is(tok::l_paren) && NextToken().is(tok::l_brace)) { Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0; - Actions.ActOnParamDefaultArgumentError(Param, EqualLoc); + Actions.ActOnParamDefaultArgumentError(Param, EqualLoc, + /*DefaultArg=*/nullptr); // Skip the statement expression and continue parsing SkipUntil(tok::comma, StopBeforeMatch); continue; @@ -7557,7 +7558,8 @@ void Parser::ParseParameterDeclarationClause( } DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult); if (DefArgResult.isInvalid()) { -Actions.ActOnParamDefaultArgumentError(Param, EqualLoc); +
[clang-tools-extra] 09a622b - [clangd] Fix typo in comment
Author: Eymen Ãœnay Date: 2023-08-14T20:07:58+02:00 New Revision: 09a622baa2d80ccc38eb42b6b58b39519704399f URL: https://github.com/llvm/llvm-project/commit/09a622baa2d80ccc38eb42b6b58b39519704399f DIFF: https://github.com/llvm/llvm-project/commit/09a622baa2d80ccc38eb42b6b58b39519704399f.diff LOG: [clangd] Fix typo in comment Reviewed By: kadircet Differential Revision: https://reviews.llvm.org/D157207 Added: Modified: clang-tools-extra/clangd/Protocol.h Removed: diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h index 23a48e0a8e5f61..e88c804692568f 100644 --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -592,7 +592,7 @@ bool fromJSON(const llvm::json::Value &, ConfigurationSettings &, /// Clangd extension: parameters configurable at `initialize` time. /// LSP defines this type as `any`. struct InitializationOptions { - // What we can change throught the didChangeConfiguration request, we can + // What we can change through the didChangeConfiguration request, we can // also set through the initialize request (initializationOptions field). ConfigurationSettings ConfigSettings; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7d259b3 - Revert "[Sema] Fix handling of functions that hide classes"
Author: Kadir Cetinkaya Date: 2023-08-10T14:06:00+02:00 New Revision: 7d259b36d2e8148d13087844e6494ad3a5c63edf URL: https://github.com/llvm/llvm-project/commit/7d259b36d2e8148d13087844e6494ad3a5c63edf DIFF: https://github.com/llvm/llvm-project/commit/7d259b36d2e8148d13087844e6494ad3a5c63edf.diff LOG: Revert "[Sema] Fix handling of functions that hide classes" This reverts commit d031ff38779bd688c514136dbdcce3169ee82b6e. See https://reviews.llvm.org/D154503#4576393 for a reproducer and details. Added: Modified: clang/lib/Sema/SemaLookup.cpp Removed: clang/test/SemaCXX/using-hiding.cpp diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 05a6618cd0d1e6..a6c948da2b12fb 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -514,42 +514,21 @@ void LookupResult::resolveKind() { const NamedDecl *HasNonFunction = nullptr; llvm::SmallVector EquivalentNonFunctions; - llvm::BitVector RemovedDecls(N); - for (unsigned I = 0; I < N; I++) { + unsigned UniqueTagIndex = 0; + + unsigned I = 0; + while (I < N) { const NamedDecl *D = Decls[I]->getUnderlyingDecl(); D = cast(D->getCanonicalDecl()); // Ignore an invalid declaration unless it's the only one left. // Also ignore HLSLBufferDecl which not have name conflict with other Decls. -if ((D->isInvalidDecl() || isa(D)) && -N - RemovedDecls.count() > 1) { - RemovedDecls.set(I); +if ((D->isInvalidDecl() || isa(D)) && !(I == 0 && N == 1)) { + Decls[I] = Decls[--N]; continue; } -// C++ [basic.scope.hiding]p2: -// A class name or enumeration name can be hidden by the name of -// an object, function, or enumerator declared in the same -// scope. If a class or enumeration name and an object, function, -// or enumerator are declared in the same scope (in any order) -// with the same name, the class or enumeration name is hidden -// wherever the object, function, or enumerator name is visible. -if (HideTags && isa(D)) { - bool Hidden = false; - for (auto *OtherDecl : Decls) { -if (canHideTag(OtherDecl) && -getContextForScopeMatching(OtherDecl)->Equals( -getContextForScopeMatching(Decls[I]))) { - RemovedDecls.set(I); - Hidden = true; - break; -} - } - if (Hidden) -continue; -} - std::optional ExistingI; // Redeclarations of types via typedef can occur both within a scope @@ -582,7 +561,7 @@ void LookupResult::resolveKind() { if (isPreferredLookupResult(getSema(), getLookupKind(), Decls[I], Decls[*ExistingI])) Decls[*ExistingI] = Decls[I]; - RemovedDecls.set(I); + Decls[I] = Decls[--N]; continue; } @@ -593,6 +572,7 @@ void LookupResult::resolveKind() { } else if (isa(D)) { if (HasTag) Ambiguous = true; + UniqueTagIndex = I; HasTag = true; } else if (isa(D)) { HasFunction = true; @@ -608,7 +588,7 @@ void LookupResult::resolveKind() { if (getSema().isEquivalentInternalLinkageDeclaration(HasNonFunction, D)) { EquivalentNonFunctions.push_back(D); - RemovedDecls.set(I); + Decls[I] = Decls[--N]; continue; } if (D->isPlaceholderVar(getSema().getLangOpts()) && @@ -620,6 +600,28 @@ void LookupResult::resolveKind() { } HasNonFunction = D; } +I++; + } + + // C++ [basic.scope.hiding]p2: + // A class name or enumeration name can be hidden by the name of + // an object, function, or enumerator declared in the same + // scope. If a class or enumeration name and an object, function, + // or enumerator are declared in the same scope (in any order) + // with the same name, the class or enumeration name is hidden + // wherever the object, function, or enumerator name is visible. + // But it's still an error if there are distinct tag types found, + // even if they're not visible. (ref?) + if (N > 1 && HideTags && HasTag && !Ambiguous && + (HasFunction || HasNonFunction || HasUnresolved)) { +const NamedDecl *OtherDecl = Decls[UniqueTagIndex ? 0 : N - 1]; +if (isa(Decls[UniqueTagIndex]->getUnderlyingDecl()) && +getContextForScopeMatching(Decls[UniqueTagIndex])->Equals( +getContextForScopeMatching(OtherDecl)) && +canHideTag(OtherDecl)) + Decls[UniqueTagIndex] = Decls[--N]; +else + Ambiguous = true; } // FIXME: This diagnostic should really be delayed until we're done with @@ -628,15 +630,9 @@ void LookupResult::resolveKind() { getSema().diagnoseEquivalentInternalLinkageDeclarations( getNameLoc(), HasNonFunction, EquivalentNonFunctions); - //
[clang-tools-extra] 0a315be - [include-cleaner] Dont boost private headers beyond public ones
Author: Kadir Cetinkaya Date: 2023-08-09T09:36:48+02:00 New Revision: 0a315be2a46f35bb990dd6c8418a189daec15350 URL: https://github.com/llvm/llvm-project/commit/0a315be2a46f35bb990dd6c8418a189daec15350 DIFF: https://github.com/llvm/llvm-project/commit/0a315be2a46f35bb990dd6c8418a189daec15350.diff LOG: [include-cleaner] Dont boost private headers beyond public ones Private headers should be the last resort, even if they match the name of a symbol. It's pretty common in umrella headers to have internal file names that match the symbol (e.g. Eigen::Matrix, declared in private header Matrix.h, and exposed in umbrella header Eigen/Core). Differential Revision: https://reviews.llvm.org/D157400 Added: Modified: clang-tools-extra/include-cleaner/lib/TypesInternal.h clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/TypesInternal.h b/clang-tools-extra/include-cleaner/lib/TypesInternal.h index e9f8689e8647e0..ca9b961cbccdad 100644 --- a/clang-tools-extra/include-cleaner/lib/TypesInternal.h +++ b/clang-tools-extra/include-cleaner/lib/TypesInternal.h @@ -69,15 +69,15 @@ enum class Hints : uint8_t { /// Provides a generally-usable definition for the symbol. (a function decl, /// or class definition and not a forward declaration of a template). CompleteSymbol = 1 << 1, - /// Symbol is provided by a public file. Only absent in the cases where file - /// is explicitly marked as such, non self-contained or IWYU private - /// pragmas. - PublicHeader = 1 << 2, /// Header providing the symbol is explicitly marked as preferred, with an /// IWYU private pragma that points at this provider or header and symbol has /// ~the same name. - PreferredHeader = 1 << 3, - LLVM_MARK_AS_BITMASK_ENUM(PreferredHeader), + PreferredHeader = 1 << 2, + /// Symbol is provided by a public file. Only absent in the cases where file + /// is explicitly marked as such, non self-contained or IWYU private + /// pragmas. + PublicHeader = 1 << 3, + LLVM_MARK_AS_BITMASK_ENUM(PublicHeader), }; LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); /// A wrapper to augment values with hints. diff --git a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp index 3ad632a18c563a..d5f79f54c81db3 100644 --- a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp @@ -441,9 +441,9 @@ TEST(Hints, Ordering) { }; EXPECT_LT(Hinted(Hints::None), Hinted(Hints::CompleteSymbol)); EXPECT_LT(Hinted(Hints::CompleteSymbol), Hinted(Hints::PublicHeader)); - EXPECT_LT(Hinted(Hints::PublicHeader), Hinted(Hints::PreferredHeader)); - EXPECT_LT(Hinted(Hints::CompleteSymbol | Hints::PublicHeader), -Hinted(Hints::PreferredHeader)); + EXPECT_LT(Hinted(Hints::PreferredHeader), Hinted(Hints::PublicHeader)); + EXPECT_LT(Hinted(Hints::CompleteSymbol | Hints::PreferredHeader), +Hinted(Hints::PublicHeader)); } // Test ast traversal & redecl selection end-to-end for templates, as explicit diff --git a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp index 9f9ac11a93eb85..cbe1f67d9bf7e5 100644 --- a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp @@ -465,6 +465,22 @@ TEST_F(HeadersForSymbolTest, PreferPublicOverNameMatchOnPrivate) { physicalHeader("foo.h"))); } +TEST_F(HeadersForSymbolTest, PublicOverPrivateWithoutUmbrella) { + Inputs.Code = R"cpp( +#include "bar.h" +#include "foo.h" + )cpp"; + Inputs.ExtraFiles["bar.h"] = + guard(R"cpp(#include "foo.h" // IWYU pragma: export)cpp"); + Inputs.ExtraFiles["foo.h"] = guard(R"cpp( +// IWYU pragma: private +struct foo {}; + )cpp"); + buildAST(); + EXPECT_THAT(headersForFoo(), + ElementsAre(physicalHeader("bar.h"), physicalHeader("foo.h"))); +} + TEST_F(HeadersForSymbolTest, AmbiguousStdSymbols) { struct { llvm::StringRef Code; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 724b40a - [clang-tidy][Docs] Update docs per post-commit review
Author: Kadir Cetinkaya Date: 2023-08-08T16:16:51+02:00 New Revision: 724b40a1379f7c116473a02a3cec4d341c475b46 URL: https://github.com/llvm/llvm-project/commit/724b40a1379f7c116473a02a3cec4d341c475b46 DIFF: https://github.com/llvm/llvm-project/commit/724b40a1379f7c116473a02a3cec4d341c475b46.diff LOG: [clang-tidy][Docs] Update docs per post-commit review Added: Modified: clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst Removed: diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 815237656a4035..dbd2fbf6de6d42 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -180,6 +180,10 @@ Changes in existing checks ` check to provide fixes for ``inline`` namespaces in the same format as :program:`clang-format`. +- Improved :doc:`misc-include-cleaner + ` check by adding option + `DeduplicateFindings` to output one finding per symbol occurence. + - Improved :doc:`modernize-loop-convert ` to support for-loops with iterators initialized by free functions like ``begin``, ``end``, or ``size``. @@ -192,9 +196,6 @@ Changes in existing checks ` check to emit proper warnings when a type forward declaration precedes its definition. -- Misc-include-cleaner check has option `DeduplicateFindings` to output one - finding per occurence of a symbol. - Removed checks ^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst index d56bb4526ff015..e40335b2543b29 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst @@ -37,4 +37,4 @@ Options .. option:: DeduplicateFindings A boolean that controls whether the check should deduplicate findings for the - same symbol. Defaults to true. + same symbol. Defaults to `true`. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 89d0a76 - [clang-tidy][include-cleaner] Add option to control deduplication of findings per symbol
Author: Kadir Cetinkaya Date: 2023-08-08T16:01:33+02:00 New Revision: 89d0a76be68b866779ac41e56bc7f7b4fc452f47 URL: https://github.com/llvm/llvm-project/commit/89d0a76be68b866779ac41e56bc7f7b4fc452f47 DIFF: https://github.com/llvm/llvm-project/commit/89d0a76be68b866779ac41e56bc7f7b4fc452f47.diff LOG: [clang-tidy][include-cleaner] Add option to control deduplication of findings per symbol We received some user feedback around this being disruptful rather than useful in certain workflows so add an option to control the output behaviour. Differential Revision: https://reviews.llvm.org/D157390 Added: Modified: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/misc/include-cleaner.rst clang-tools-extra/unittests/clang-tidy/IncludeCleanerTest.cpp Removed: diff --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp index c5cb18978b6497..f47609b19badfc 100644 --- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp @@ -55,7 +55,9 @@ IncludeCleanerCheck::IncludeCleanerCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IgnoreHeaders(utils::options::parseStringList( - Options.getLocalOrGlobal("IgnoreHeaders", ""))) { + Options.getLocalOrGlobal("IgnoreHeaders", ""))), + DeduplicateFindings( + Options.getLocalOrGlobal("DeduplicateFindings", true)) { for (const auto : IgnoreHeaders) { if (!llvm::Regex{Header}.isValid()) configurationDiag("Invalid ignore headers regex '%0'") << Header; @@ -69,6 +71,7 @@ IncludeCleanerCheck::IncludeCleanerCheck(StringRef Name, void IncludeCleanerCheck::storeOptions(ClangTidyOptions::OptionMap ) { Options.store(Opts, "IgnoreHeaders", utils::options::serializeStringList(IgnoreHeaders)); + Options.store(Opts, "DeduplicateFindings", DeduplicateFindings); } bool IncludeCleanerCheck::isLanguageVersionSupported( @@ -114,12 +117,26 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult ) { // FIXME: Filter out implicit template specializations. MainFileDecls.push_back(D); } + llvm::DenseSet SeenSymbols; // FIXME: Find a way to have less code duplication between include-cleaner // analysis implementation and the below code. walkUsed(MainFileDecls, RecordedPreprocessor.MacroReferences, , *SM, [&](const include_cleaner::SymbolReference , llvm::ArrayRef Providers) { + // Process each symbol once to reduce noise in the findings. + // Tidy checks are used in two diff erent workflows: + // - Ones that show all the findings for a given file. For such + // workflows there is not much point in showing all the occurences, + // as one is enough to indicate the issue. + // - Ones that show only the findings on changed pieces. For such + // workflows it's useful to show findings on every reference of a + // symbol as otherwise tools might give incosistent results + // depending on the parts of the file being edited. But it should + // still help surface findings for "new violations" (i.e. + // dependency did not exist in the code at all before). + if (DeduplicateFindings && !SeenSymbols.insert(Ref.Target).second) + return; bool Satisfied = false; for (const include_cleaner::Header : Providers) { if (H.kind() == include_cleaner::Header::Physical && diff --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h index d5f75f2b1c7fa2..9641c7fd9dfcf6 100644 --- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h +++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h @@ -44,6 +44,8 @@ class IncludeCleanerCheck : public ClangTidyCheck { include_cleaner::PragmaIncludes RecordedPI; HeaderSearch *HS; std::vector IgnoreHeaders; + // Whether emit only one finding per usage of a symbol. + const bool DeduplicateFindings; llvm::SmallVector IgnoreHeadersRegex; bool shouldIgnore(const include_cleaner::Header ); }; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 2af86407069a68..815237656a4035 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -192,6 +192,9 @@ Changes in existing checks ` check to emit proper warnings when a type forward declaration precedes its definition. +-
[clang-tools-extra] 31873d3 - [include-cleaner] Handle files with unnamed buffers
Author: Kadir Cetinkaya Date: 2023-08-04T11:13:03+02:00 New Revision: 31873d3fca38e32a17c2b0aa8975e09aca0f8f89 URL: https://github.com/llvm/llvm-project/commit/31873d3fca38e32a17c2b0aa8975e09aca0f8f89 DIFF: https://github.com/llvm/llvm-project/commit/31873d3fca38e32a17c2b0aa8975e09aca0f8f89.diff LOG: [include-cleaner] Handle files with unnamed buffers Some tools can register virtual buffers without identifiers into the filemanager. Make sure we can handle pragmas in such cases. Differential Revision: https://reviews.llvm.org/D157078 Added: Modified: clang-tools-extra/include-cleaner/lib/Record.cpp clang-tools-extra/include-cleaner/unittests/RecordTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/Record.cpp b/clang-tools-extra/include-cleaner/lib/Record.cpp index e6fe859b2fb360..62eaa16dbf3373 100644 --- a/clang-tools-extra/include-cleaner/lib/Record.cpp +++ b/clang-tools-extra/include-cleaner/lib/Record.cpp @@ -279,20 +279,6 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler { auto [CommentFID, CommentOffset] = SM.getDecomposedLoc(Range.getBegin()); int CommentLine = SM.getLineNumber(CommentFID, CommentOffset); -auto Filename = SM.getBufferName(Range.getBegin()); -// Record export pragma. -if (Pragma->startswith("export")) { - ExportStack.push_back({CommentLine, CommentFID, save(Filename), false}); -} else if (Pragma->startswith("begin_exports")) { - ExportStack.push_back({CommentLine, CommentFID, save(Filename), true}); -} else if (Pragma->startswith("end_exports")) { - // FIXME: be robust on unmatching cases. We should only pop the stack if - // the begin_exports and end_exports is in the same file. - if (!ExportStack.empty()) { -assert(ExportStack.back().Block); -ExportStack.pop_back(); - } -} if (InMainFile) { if (Pragma->startswith("keep")) { @@ -307,8 +293,10 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler { auto FE = SM.getFileEntryRefForID(CommentFID); if (!FE) { - // FIXME: Support IWYU pragmas in virtual files. Our mappings rely on - // "persistent" UniqueIDs and that is not the case for virtual files. + // This can only happen when the buffer was registered virtually into + // SourceManager and FileManager has no idea about it. In such a scenario, + // that file cannot be discovered by HeaderSearch, therefore no "explicit" + // includes for that file. return false; } auto CommentUID = FE->getUniqueID(); @@ -327,6 +315,20 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler { Out->ShouldKeep.insert(CommentUID); return false; } +auto Filename = FE->getName(); +// Record export pragma. +if (Pragma->startswith("export")) { + ExportStack.push_back({CommentLine, CommentFID, save(Filename), false}); +} else if (Pragma->startswith("begin_exports")) { + ExportStack.push_back({CommentLine, CommentFID, save(Filename), true}); +} else if (Pragma->startswith("end_exports")) { + // FIXME: be robust on unmatching cases. We should only pop the stack if + // the begin_exports and end_exports is in the same file. + if (!ExportStack.empty()) { +assert(ExportStack.back().Block); +ExportStack.pop_back(); + } +} return false; } diff --git a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp index 79a5b559a67efb..69bec04ed60194 100644 --- a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp @@ -7,18 +7,32 @@ //===--===// #include "clang-include-cleaner/Record.h" +#include "clang-include-cleaner/Types.h" +#include "clang/AST/Decl.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/FrontendActions.h" +#include "clang/Frontend/FrontendOptions.h" +#include "clang/Serialization/PCHContainerOperations.h" #include "clang/Testing/TestAST.h" #include "clang/Tooling/Inclusions/StandardLibrary.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Testing/Annotations/Annotations.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include +#include +#include +#include namespace clang::include_cleaner { namespace { @@ -509,5
[clang-tools-extra] 734da23 - [clangd] Dont assert on specific uris for diagnostics docs
Author: Kadir Cetinkaya Date: 2023-08-04T11:09:19+02:00 New Revision: 734da23e21eb687ff4a613d520cbef5348e26a65 URL: https://github.com/llvm/llvm-project/commit/734da23e21eb687ff4a613d520cbef5348e26a65 DIFF: https://github.com/llvm/llvm-project/commit/734da23e21eb687ff4a613d520cbef5348e26a65.diff LOG: [clangd] Dont assert on specific uris for diagnostics docs To enable customization of links in downstream projects without breaking tests (and also ease of pointing at different links in the future). Just check for existence instead. Differential Revision: https://reviews.llvm.org/D157071 Added: Modified: clang-tools-extra/clangd/test/include-cleaner-batch-fix.test clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp Removed: diff --git a/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test b/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test index bf9e5abca83312..72d69ec0d49415 100644 --- a/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test +++ b/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test @@ -34,7 +34,7 @@ # CHECK-NEXT: { # CHECK-NEXT: "code": "missing-includes", # CHECK-NEXT: "codeDescription": { -# CHECK-NEXT: "href": "https://clangd.llvm.org/guides/include-cleaner; +# CHECK-NEXT: "href": "{{.*}}" # CHECK-NEXT: }, # CHECK-NEXT: "message": "No header providing \"Foo\" is directly included (fixes available)", # CHECK-NEXT: "range": { @@ -53,7 +53,7 @@ # CHECK-NEXT: { # CHECK-NEXT: "code": "missing-includes", # CHECK-NEXT: "codeDescription": { -# CHECK-NEXT: "href": "https://clangd.llvm.org/guides/include-cleaner; +# CHECK-NEXT: "href": "{{.*}}" # CHECK-NEXT: }, # CHECK-NEXT: "message": "No header providing \"Bar\" is directly included (fixes available)", # CHECK-NEXT: "range": { @@ -72,7 +72,7 @@ # CHECK-NEXT: { # CHECK-NEXT: "code": "unused-includes", # CHECK-NEXT: "codeDescription": { -# CHECK-NEXT: "href": "https://clangd.llvm.org/guides/include-cleaner; +# CHECK-NEXT: "href": "{{.*}}" # CHECK-NEXT: }, # CHECK-NEXT: "message": "Included header all1.h is not used directly (fixes available)", # CHECK-NEXT: "range": { @@ -94,7 +94,7 @@ # CHECK-NEXT: { # CHECK-NEXT: "code": "unused-includes", # CHECK-NEXT: "codeDescription": { -# CHECK-NEXT: "href": "https://clangd.llvm.org/guides/include-cleaner; +# CHECK-NEXT: "href": "{{.*}}" # CHECK-NEXT: }, # CHECK-NEXT: "message": "Included header all2.h is not used directly (fixes available)", # CHECK-NEXT: "range": { diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp index 51ffa45dbc8f6f..f9b71a32304f21 100644 --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -34,6 +34,7 @@ #include "llvm/Support/JSON.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Testing/Support/SupportHelpers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include @@ -1961,8 +1962,8 @@ TEST(DiagnosticsTest, IncludeCleaner) { withTag(DiagnosticTag::Unnecessary), diagSource(Diag::Clangd), withFix(Fix(Test.range("fix"), "", "remove #include directive"); auto = AST.getDiagnostics().front(); - EXPECT_EQ(getDiagnosticDocURI(Diag.Source, Diag.ID, Diag.Name), -std::string("https://clangd.llvm.org/guides/include-cleaner;)); + EXPECT_THAT(getDiagnosticDocURI(Diag.Source, Diag.ID, Diag.Name), + llvm::ValueIs(Not(IsEmpty(; Cfg.Diagnostics.SuppressAll = true; WithContextValue SuppressAllWithCfg(Config::Key, std::move(Cfg)); EXPECT_THAT(TU.build().getDiagnostics(), IsEmpty()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 4397433 - [include-cleaner] Unify always_keep with rest of the keep logic
Author: Kadir Cetinkaya Date: 2023-08-02T12:47:53+02:00 New Revision: 43974333dd094e7ffef2bb75a799a47cf1b5ddbc URL: https://github.com/llvm/llvm-project/commit/43974333dd094e7ffef2bb75a799a47cf1b5ddbc DIFF: https://github.com/llvm/llvm-project/commit/43974333dd094e7ffef2bb75a799a47cf1b5ddbc.diff LOG: [include-cleaner] Unify always_keep with rest of the keep logic Depends on D156122 Differential Revision: https://reviews.llvm.org/D156123 Added: Modified: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp clang-tools-extra/clangd/IncludeCleaner.cpp clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h clang-tools-extra/include-cleaner/lib/Analysis.cpp clang-tools-extra/include-cleaner/lib/Record.cpp clang-tools-extra/include-cleaner/unittests/RecordTest.cpp Removed: diff --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp index 079889045b3f2b..c5cb18978b6497 100644 --- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp @@ -143,7 +143,7 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult ) { RecordedPreprocessor.Includes.all()) { if (Used.contains() || !I.Resolved) continue; -if (RecordedPI.shouldKeep(I.Line) || RecordedPI.shouldKeep(*I.Resolved)) +if (RecordedPI.shouldKeep(*I.Resolved)) continue; // Check if main file is the public interface for a private header. If so // we shouldn't diagnose it as unused. diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index 32563ca9cb35a9..07c6937ac10d5b 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -75,7 +75,7 @@ bool mayConsiderUnused(const Inclusion , ParsedAST , auto FE = AST.getSourceManager().getFileManager().getFileRef( AST.getIncludeStructure().getRealPath(HID)); assert(FE); - if (PI && (PI->shouldKeep(Inc.HashLine + 1) || PI->shouldKeep(*FE))) + if (PI && PI->shouldKeep(*FE)) return false; // FIXME(kirillbobyrev): We currently do not support the umbrella headers. // System headers are likely to be standard library headers. diff --git a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp index afaba8aa68d1a7..1d6b99af081429 100644 --- a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp +++ b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp @@ -15,7 +15,6 @@ #include "TestTU.h" #include "clang-include-cleaner/Analysis.h" #include "clang-include-cleaner/Types.h" -#include "support/Context.h" #include "clang/AST/DeclBase.h" #include "clang/Basic/SourceManager.h" #include "clang/Tooling/Syntax/Tokens.h" @@ -26,13 +25,11 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" #include "llvm/Support/ScopedPrinter.h" -#include "llvm/Testing/Support/SupportHelpers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include #include #include -#include #include namespace clang { diff --git a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h index 93a047cdac3817..08bc1dbdfad42a 100644 --- a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h +++ b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h @@ -59,7 +59,6 @@ class PragmaIncludes { /// Returns true if the given #include of the main-file should never be /// removed. - bool shouldKeep(unsigned HashLineNumber) const; bool shouldKeep(const FileEntry *FE) const; /// Returns the public mapping include for the given physical header file. @@ -81,10 +80,6 @@ class PragmaIncludes { private: class RecordPragma; - /// 1-based Line numbers for the #include directives of the main file that - /// should always keep (e.g. has the `IWYU pragma: keep` or `IWYU pragma: - /// export` right after). - llvm::DenseSet ShouldKeep; /// The public header mapping by the IWYU private pragma. For private pragmas // without public mapping an empty StringRef is stored. @@ -112,8 +107,10 @@ class PragmaIncludes { /// Contains all non self-contained files detected during the parsing. llvm::DenseSet NonSelfContainedFiles; - // Files with an always_keep pragma. - llvm::DenseSet AlwaysKeep; + // Files whose inclusions shouldn't be dropped. E.g. because they have an + // always_keep pragma or because user marked particular includes with + // keep/export pragmas in the main file. + llvm::DenseSet ShouldKeep; /// Owns the strings. llvm::BumpPtrAllocator Arena; diff
[clang-tools-extra] 778a5e9 - [include-cleaner] Introduce support for always_keep pragma
Author: Kadir Cetinkaya Date: 2023-08-02T12:47:53+02:00 New Revision: 778a5e9bc6335061d5c6c27795bb8c4f768af7f3 URL: https://github.com/llvm/llvm-project/commit/778a5e9bc6335061d5c6c27795bb8c4f768af7f3 DIFF: https://github.com/llvm/llvm-project/commit/778a5e9bc6335061d5c6c27795bb8c4f768af7f3.diff LOG: [include-cleaner] Introduce support for always_keep pragma Differential Revision: https://reviews.llvm.org/D156122 Added: Modified: clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp clang-tools-extra/clangd/IncludeCleaner.cpp clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h clang-tools-extra/include-cleaner/lib/Analysis.cpp clang-tools-extra/include-cleaner/lib/Record.cpp clang-tools-extra/include-cleaner/unittests/RecordTest.cpp Removed: diff --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp index f6292d765451c2..079889045b3f2b 100644 --- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp @@ -143,7 +143,7 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult ) { RecordedPreprocessor.Includes.all()) { if (Used.contains() || !I.Resolved) continue; -if (RecordedPI.shouldKeep(I.Line)) +if (RecordedPI.shouldKeep(I.Line) || RecordedPI.shouldKeep(*I.Resolved)) continue; // Check if main file is the public interface for a private header. If so // we shouldn't diagnose it as unused. diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index 4a1ba484bfc492..32563ca9cb35a9 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -68,21 +68,20 @@ bool isIgnored(llvm::StringRef HeaderPath, HeaderFilter IgnoreHeaders) { return false; } -bool mayConsiderUnused( -const Inclusion , ParsedAST , -const include_cleaner::PragmaIncludes *PI) { - if (PI && PI->shouldKeep(Inc.HashLine + 1)) - return false; - // FIXME(kirillbobyrev): We currently do not support the umbrella headers. - // System headers are likely to be standard library headers. - // Until we have good support for umbrella headers, don't warn about them. - if (Inc.Written.front() == '<') -return tooling::stdlib::Header::named(Inc.Written).has_value(); +bool mayConsiderUnused(const Inclusion , ParsedAST , + const include_cleaner::PragmaIncludes *PI) { assert(Inc.HeaderID); auto HID = static_cast(*Inc.HeaderID); auto FE = AST.getSourceManager().getFileManager().getFileRef( AST.getIncludeStructure().getRealPath(HID)); assert(FE); + if (PI && (PI->shouldKeep(Inc.HashLine + 1) || PI->shouldKeep(*FE))) +return false; + // FIXME(kirillbobyrev): We currently do not support the umbrella headers. + // System headers are likely to be standard library headers. + // Until we have good support for umbrella headers, don't warn about them. + if (Inc.Written.front() == '<') +return tooling::stdlib::Header::named(Inc.Written).has_value(); if (PI) { // Check if main file is the public interface for a private header. If so we // shouldn't diagnose it as unused. diff --git a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h index ae11f49f837095..93a047cdac3817 100644 --- a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h +++ b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h @@ -59,9 +59,8 @@ class PragmaIncludes { /// Returns true if the given #include of the main-file should never be /// removed. - bool shouldKeep(unsigned HashLineNumber) const { -return ShouldKeep.contains(HashLineNumber); - } + bool shouldKeep(unsigned HashLineNumber) const; + bool shouldKeep(const FileEntry *FE) const; /// Returns the public mapping include for the given physical header file. /// Returns "" if there is none. @@ -113,6 +112,8 @@ class PragmaIncludes { /// Contains all non self-contained files detected during the parsing. llvm::DenseSet NonSelfContainedFiles; + // Files with an always_keep pragma. + llvm::DenseSet AlwaysKeep; /// Owns the strings. llvm::BumpPtrAllocator Arena; diff --git a/clang-tools-extra/include-cleaner/lib/Analysis.cpp b/clang-tools-extra/include-cleaner/lib/Analysis.cpp index 888b7026436b01..7c4df4a58c422e 100644 --- a/clang-tools-extra/include-cleaner/lib/Analysis.cpp +++ b/clang-tools-extra/include-cleaner/lib/Analysis.cpp @@ -91,7 +91,7 @@ analyze(llvm::ArrayRef ASTRoots, HeaderFilter(I.Resolved->getFileEntry().tryGetRealPathName())) continue; if (PI) { - if (PI->shouldKeep(I.Line)) + if
[clang-tools-extra] 3736eaa - [include-cleaner] Handle StdInitializerListExprs
Author: Kadir Cetinkaya Date: 2023-08-01T10:58:56+02:00 New Revision: 3736eaa6a0b8396e30978c768c02e43c821a8257 URL: https://github.com/llvm/llvm-project/commit/3736eaa6a0b8396e30978c768c02e43c821a8257 DIFF: https://github.com/llvm/llvm-project/commit/3736eaa6a0b8396e30978c768c02e43c821a8257.diff LOG: [include-cleaner] Handle StdInitializerListExprs Per C++ standard, programs omitting the definition for initializer_list is ill-formed, https://eel.is/c++draft/dcl.init.list#2. Fixes https://github.com/llvm/llvm-project/issues/64198 Differential Revision: https://reviews.llvm.org/D156712 Added: Modified: clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index 8cfda506fc254f..febdf19e695cd9 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -304,6 +304,16 @@ class ASTWalker : public RecursiveASTVisitor { } return RecursiveASTVisitor::TraverseTemplateArgumentLoc(TL); } + + bool VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { +// Reliance on initializer_lists requires std::initializer_list to be +// visible per standard. So report a reference to it, otherwise include of +// `` might not receive any use. +report(E->getExprLoc(), + const_cast(E->getBestDynamicClassType()), + RefType::Implicit); +return true; + } }; } // namespace diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index 525f645ec91efe..3a86f36e3964f6 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -282,7 +282,6 @@ template<> void $ambiguous^function(int); // full specialization "using ns::^function;"); } - TEST(WalkAST, Alias) { testWalk(R"cpp( namespace ns { int x; } @@ -510,5 +509,14 @@ TEST(WalkAST, Enums) { testWalk("enum class E : int {};", "enum class ^E : int ;"); } +TEST(WalkAST, InitializerList) { + testWalk(R"cpp( + namespace std { +template struct $implicit^initializer_list {}; + })cpp", + R"cpp( + const char* s = ""; + auto sx = ^{s};)cpp"); +} } // namespace } // namespace clang::include_cleaner ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 0a093f6 - [clangd] Prefer definitions for gototype and implementation
Author: Kadir Cetinkaya Date: 2023-07-21T14:38:51+02:00 New Revision: 0a093f62d15468f2b6ac4bfdc7a2dc7ba88364d0 URL: https://github.com/llvm/llvm-project/commit/0a093f62d15468f2b6ac4bfdc7a2dc7ba88364d0 DIFF: https://github.com/llvm/llvm-project/commit/0a093f62d15468f2b6ac4bfdc7a2dc7ba88364d0.diff LOG: [clangd] Prefer definitions for gototype and implementation Differential Revision: https://reviews.llvm.org/D133843 Added: Modified: clang-tools-extra/clangd/ClangdLSPServer.cpp Removed: diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 65ee60382ba991..a87da252b7a7e9 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -1451,7 +1451,7 @@ void ClangdLSPServer::onGoToType(const TextDocumentPositionParams , return Reply(Types.takeError()); std::vector Response; for (const LocatedSymbol : *Types) - Response.push_back(Sym.PreferredDeclaration); + Response.push_back(Sym.Definition.value_or(Sym.PreferredDeclaration)); return Reply(std::move(Response)); }); } @@ -1467,7 +1467,7 @@ void ClangdLSPServer::onGoToImplementation( return Reply(Overrides.takeError()); std::vector Impls; for (const LocatedSymbol : *Overrides) - Impls.push_back(Sym.PreferredDeclaration); + Impls.push_back(Sym.Definition.value_or(Sym.PreferredDeclaration)); return Reply(std::move(Impls)); }); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 27ade4b - Reland "[clangd] Always run preamble indexing on a separate thread"
Author: Kadir Cetinkaya Date: 2023-07-19T16:30:46+02:00 New Revision: 27ade4b554774187d2c0afcf64cd16fa6d5f619d URL: https://github.com/llvm/llvm-project/commit/27ade4b554774187d2c0afcf64cd16fa6d5f619d DIFF: https://github.com/llvm/llvm-project/commit/27ade4b554774187d2c0afcf64cd16fa6d5f619d.diff LOG: Reland "[clangd] Always run preamble indexing on a separate thread" This reverts commit 92c0546941190973e9201a08fa10edf27cb6992d. Prevents tsan issues by resetting ref-counted-pointers eagerly, before passing the copies into a new thread. Added: Modified: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Preamble.cpp Removed: diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index af002e0cb2d689..29390196a6d977 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -68,11 +68,10 @@ struct UpdateIndexCallbacks : public ParsingCallbacks { UpdateIndexCallbacks(FileIndex *FIndex, ClangdServer::Callbacks *ServerCallbacks, const ThreadsafeFS , AsyncTaskRunner *Tasks, - bool CollectInactiveRegions, - const ClangdServer::Options ) + bool CollectInactiveRegions) : FIndex(FIndex), ServerCallbacks(ServerCallbacks), TFS(TFS), Stdlib{std::make_shared()}, Tasks(Tasks), -CollectInactiveRegions(CollectInactiveRegions), Opts(Opts) {} +CollectInactiveRegions(CollectInactiveRegions) {} void onPreambleAST( PathRef Path, llvm::StringRef Version, CapturedASTCtx ASTCtx, @@ -94,7 +93,7 @@ struct UpdateIndexCallbacks : public ParsingCallbacks { ASTCtx.getPreprocessor(), *PI); }; -if (Opts.AsyncPreambleIndexing && Tasks) { +if (Tasks) { Tasks->runAsync("Preamble indexing for:" + Path + Version, std::move(Task)); } else @@ -164,7 +163,6 @@ struct UpdateIndexCallbacks : public ParsingCallbacks { std::shared_ptr Stdlib; AsyncTaskRunner *Tasks; bool CollectInactiveRegions; - const ClangdServer::Options }; class DraftStoreFS : public ThreadsafeFS { @@ -229,7 +227,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase , std::make_unique( DynamicIdx.get(), Callbacks, TFS, IndexTasks ? &*IndexTasks : nullptr, -PublishInactiveRegions, Opts)); +PublishInactiveRegions)); // Adds an index to the stack, at higher priority than existing indexes. auto AddIndex = [&](SymbolIndex *Idx) { if (this->Index != nullptr) { diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 88b6d2f11d9a0b..2bc8f02ff38a4b 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -185,10 +185,6 @@ class ClangdServer { /// regions in the document. bool PublishInactiveRegions = false; -/// Whether to run preamble indexing asynchronously in an independent -/// thread. -bool AsyncPreambleIndexing = false; - explicit operator TUScheduler::Options() const; }; // Sensible default options for use in tests. diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index f4547a5babf081..31b38d067b2727 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -11,6 +11,8 @@ #include "Compiler.h" #include "Config.h" #include "Diagnostics.h" +#include "FS.h" +#include "FeatureModule.h" #include "Headers.h" #include "Protocol.h" #include "SourceCode.h" @@ -20,8 +22,10 @@ #include "support/ThreadsafeFS.h" #include "support/Trace.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/Type.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticLex.h" +#include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" @@ -50,12 +54,17 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" +#include +#include #include +#include +#include #include #include #include @@ -606,7 +615,8 @@ buildPreamble(PathRef FileName, CompilerInvocation CI, }); llvm::IntrusiveRefCntPtr PreambleDiagsEngine = CompilerInstance::createDiagnostics((), - ,
[clang-tools-extra] d06af7a - Revert "[clangd] Remove unused private field 'Opts' in UpdateIndexCallbacks (NFC)"
Author: Kadir Cetinkaya Date: 2023-07-19T10:45:23+02:00 New Revision: d06af7a44eb3d72036c7c5e05e39d43609311dc5 URL: https://github.com/llvm/llvm-project/commit/d06af7a44eb3d72036c7c5e05e39d43609311dc5 DIFF: https://github.com/llvm/llvm-project/commit/d06af7a44eb3d72036c7c5e05e39d43609311dc5.diff LOG: Revert "[clangd] Remove unused private field 'Opts' in UpdateIndexCallbacks (NFC)" This reverts commit c4fa97fca7e92c736fcb09779c84b42c25ffae70. Added: Modified: clang-tools-extra/clangd/ClangdServer.cpp Removed: diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index cbcc90258f34eb..1451adcbf4d4fe 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -67,10 +67,11 @@ struct UpdateIndexCallbacks : public ParsingCallbacks { UpdateIndexCallbacks(FileIndex *FIndex, ClangdServer::Callbacks *ServerCallbacks, const ThreadsafeFS , AsyncTaskRunner *Tasks, - bool CollectInactiveRegions) + bool CollectInactiveRegions, + const ClangdServer::Options ) : FIndex(FIndex), ServerCallbacks(ServerCallbacks), TFS(TFS), Stdlib{std::make_shared()}, Tasks(Tasks), -CollectInactiveRegions(CollectInactiveRegions) {} +CollectInactiveRegions(CollectInactiveRegions), Opts(Opts) {} void onPreambleAST( PathRef Path, llvm::StringRef Version, CapturedASTCtx ASTCtx, @@ -163,6 +164,7 @@ struct UpdateIndexCallbacks : public ParsingCallbacks { std::shared_ptr Stdlib; AsyncTaskRunner *Tasks; bool CollectInactiveRegions; + const ClangdServer::Options }; class DraftStoreFS : public ThreadsafeFS { @@ -227,7 +229,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase , std::make_unique( DynamicIdx.get(), Callbacks, TFS, IndexTasks ? &*IndexTasks : nullptr, -PublishInactiveRegions)); +PublishInactiveRegions, Opts)); // Adds an index to the stack, at higher priority than existing indexes. auto AddIndex = [&](SymbolIndex *Idx) { if (this->Index != nullptr) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 92c0546 - Revert "[clangd] Always run preamble indexing on a separate thread"
Author: Kadir Cetinkaya Date: 2023-07-19T10:38:23+02:00 New Revision: 92c0546941190973e9201a08fa10edf27cb6992d URL: https://github.com/llvm/llvm-project/commit/92c0546941190973e9201a08fa10edf27cb6992d DIFF: https://github.com/llvm/llvm-project/commit/92c0546941190973e9201a08fa10edf27cb6992d.diff LOG: Revert "[clangd] Always run preamble indexing on a separate thread" This reverts commit 036a1b2202cb71aacfa72ef15145a88dc50a02cf. Triggering failures under tsan, https://lab.llvm.org/buildbot/#/builders/131/builds/48349 Added: Modified: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h Removed: diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 763fea68360ac9..cbcc90258f34eb 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -93,7 +93,7 @@ struct UpdateIndexCallbacks : public ParsingCallbacks { ASTCtx.getPreprocessor(), *CanonIncludes); }; -if (Tasks) { +if (Opts.AsyncPreambleIndexing && Tasks) { Tasks->runAsync("Preamble indexing for:" + Path + Version, std::move(Task)); } else diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 2bc8f02ff38a4b..88b6d2f11d9a0b 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -185,6 +185,10 @@ class ClangdServer { /// regions in the document. bool PublishInactiveRegions = false; +/// Whether to run preamble indexing asynchronously in an independent +/// thread. +bool AsyncPreambleIndexing = false; + explicit operator TUScheduler::Options() const; }; // Sensible default options for use in tests. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 036a1b2 - [clangd] Always run preamble indexing on a separate thread
Author: Kadir Cetinkaya Date: 2023-07-19T08:48:14+02:00 New Revision: 036a1b2202cb71aacfa72ef15145a88dc50a02cf URL: https://github.com/llvm/llvm-project/commit/036a1b2202cb71aacfa72ef15145a88dc50a02cf DIFF: https://github.com/llvm/llvm-project/commit/036a1b2202cb71aacfa72ef15145a88dc50a02cf.diff LOG: [clangd] Always run preamble indexing on a separate thread This has been the default in our production setup for weeks now, showing great improvements to latency and no problems around stability or correctness of the results. Differential Revision: https://reviews.llvm.org/D155619 Added: Modified: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h Removed: diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 1451adcbf4d4fe..52731222ed8264 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -94,7 +94,7 @@ struct UpdateIndexCallbacks : public ParsingCallbacks { ASTCtx.getPreprocessor(), *CanonIncludes); }; -if (Opts.AsyncPreambleIndexing && Tasks) { +if (Tasks) { Tasks->runAsync("Preamble indexing for:" + Path + Version, std::move(Task)); } else diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 88b6d2f11d9a0b..2bc8f02ff38a4b 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -185,10 +185,6 @@ class ClangdServer { /// regions in the document. bool PublishInactiveRegions = false; -/// Whether to run preamble indexing asynchronously in an independent -/// thread. -bool AsyncPreambleIndexing = false; - explicit operator TUScheduler::Options() const; }; // Sensible default options for use in tests. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 5933d26 - [include-cleaner] Add a signal to down-rank exporting headers
Author: Kadir Cetinkaya Date: 2023-07-05T15:37:17+02:00 New Revision: 5933d265b72a8e9aade5edd68998a00dc4fbb359 URL: https://github.com/llvm/llvm-project/commit/5933d265b72a8e9aade5edd68998a00dc4fbb359 DIFF: https://github.com/llvm/llvm-project/commit/5933d265b72a8e9aade5edd68998a00dc4fbb359.diff LOG: [include-cleaner] Add a signal to down-rank exporting headers Currently exporter can have same relevance signals as the origin header when name match signals don't trigger. This patch introduces a tie braker signal to boost origin headers in such cases, this is deliberately introduced with lower significance than public-ness to make sure we still prefer a public-exporter instead of a private-origin header. Differential Revision: https://reviews.llvm.org/D154349 Added: Modified: clang-tools-extra/include-cleaner/lib/FindHeaders.cpp clang-tools-extra/include-cleaner/lib/TypesInternal.h clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp index 1eff19cb5b..a1d9d3b5fb2154 100644 --- a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp +++ b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp @@ -96,7 +96,7 @@ hintedHeadersForStdHeaders(llvm::ArrayRef Headers, const SourceManager , const PragmaIncludes *PI) { llvm::SmallVector> Results; for (const auto : Headers) { -Results.emplace_back(H, Hints::PublicHeader); +Results.emplace_back(H, Hints::PublicHeader | Hints::OriginHeader); if (!PI) continue; for (const auto *Export : PI->getExporters(H, SM.getFileManager())) @@ -186,10 +186,12 @@ llvm::SmallVector> findHeaders(const SymbolLocation , if (!FE) return {}; if (!PI) - return {{FE, Hints::PublicHeader}}; + return {{FE, Hints::PublicHeader | Hints::OriginHeader}}; +bool IsOrigin = true; while (FE) { - Hints CurrentHints = isPublicHeader(FE, *PI); - Results.emplace_back(FE, CurrentHints); + Results.emplace_back(FE, + isPublicHeader(FE, *PI) | + (IsOrigin ? Hints::OriginHeader : Hints::None)); // FIXME: compute transitive exporter headers. for (const auto *Export : PI->getExporters(FE, SM.getFileManager())) Results.emplace_back(Export, isPublicHeader(Export, *PI)); @@ -205,6 +207,7 @@ llvm::SmallVector> findHeaders(const SymbolLocation , // Walkup the include stack for non self-contained headers. FID = SM.getDecomposedIncludedLoc(FID).first; FE = SM.getFileEntryForID(FID); + IsOrigin = false; } return Results; } diff --git a/clang-tools-extra/include-cleaner/lib/TypesInternal.h b/clang-tools-extra/include-cleaner/lib/TypesInternal.h index 09a3933577a94f..e9f8689e8647e0 100644 --- a/clang-tools-extra/include-cleaner/lib/TypesInternal.h +++ b/clang-tools-extra/include-cleaner/lib/TypesInternal.h @@ -63,17 +63,20 @@ llvm::raw_ostream <<(llvm::raw_ostream &, const SymbolLocation &); /// Hints are sorted in ascending order of relevance. enum class Hints : uint8_t { None = 0x00, + /// Symbol is directly originating from this header, rather than being + /// exported or included transitively. + OriginHeader = 1 << 0, /// Provides a generally-usable definition for the symbol. (a function decl, /// or class definition and not a forward declaration of a template). - CompleteSymbol = 1 << 0, + CompleteSymbol = 1 << 1, /// Symbol is provided by a public file. Only absent in the cases where file /// is explicitly marked as such, non self-contained or IWYU private /// pragmas. - PublicHeader = 1 << 1, + PublicHeader = 1 << 2, /// Header providing the symbol is explicitly marked as preferred, with an /// IWYU private pragma that points at this provider or header and symbol has /// ~the same name. - PreferredHeader = 1 << 2, + PreferredHeader = 1 << 3, LLVM_MARK_AS_BITMASK_ENUM(PreferredHeader), }; LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); @@ -86,6 +89,11 @@ template struct Hinted : public T { bool operator<(const Hinted ) const { return static_cast(Hint) < static_cast(Other.Hint); } + + friend llvm::raw_ostream <<(llvm::raw_ostream , + const Hinted ) { +return OS << static_cast(H.Hint) << " - " << static_cast(H); + } }; } // namespace clang::include_cleaner diff --git a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp index 5b5f77b5fdea80..b6521d56bcff44 100644 --- a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
[clang] 80c6792 - [clang][Tooling] Add mapping for make_error_code
Author: Kadir Cetinkaya Date: 2023-07-05T09:35:28+02:00 New Revision: 80c6792200380699bf8cc9837ac2c02e64a1b78b URL: https://github.com/llvm/llvm-project/commit/80c6792200380699bf8cc9837ac2c02e64a1b78b DIFF: https://github.com/llvm/llvm-project/commit/80c6792200380699bf8cc9837ac2c02e64a1b78b.diff LOG: [clang][Tooling] Add mapping for make_error_code Differential Revision: https://reviews.llvm.org/D154473 Added: Modified: clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc Removed: diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc index c8da9f266ba1d6..ae620a0b995816 100644 --- a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc +++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc @@ -347,6 +347,11 @@ SYMBOL(atomic_wchar_t, None, ) // which is tricky to disambiguate without type information. // Don't set any header for it, as it comes with the type header. SYMBOL(get, std::, /*no headers*/) +// Similarly make_error_{code,condition} also have diff erent overloads (errc, +// io_errc, future_errc) and each of them are provided by relevant headers +// providing the type. +SYMBOL(make_error_code, std::, /*no headers*/) +SYMBOL(make_error_condition, std::, /*no headers*/) // cppreference symbol index page was missing these symbols. // Remove them when the cppreference offline archive catches up. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] a59b24b - [clangd] Downgrade deprecated warnings to hints
Author: Kadir Cetinkaya Date: 2023-07-04T16:07:08+02:00 New Revision: a59b24be47ed6263c254d168567b9ebba391fac9 URL: https://github.com/llvm/llvm-project/commit/a59b24be47ed6263c254d168567b9ebba391fac9 DIFF: https://github.com/llvm/llvm-project/commit/a59b24be47ed6263c254d168567b9ebba391fac9.diff LOG: [clangd] Downgrade deprecated warnings to hints This tries to improve adoption of noisy warnings in existing codebases. Hints have a lot less visual clutter in most of the editors, and DiagnosticTags already imply a custom decorations per LSP. Differential Revision: https://reviews.llvm.org/D154443 Added: Modified: clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp Removed: diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp index bae528a105c87d..704e61b1e4dd79 100644 --- a/clang-tools-extra/clangd/Diagnostics.cpp +++ b/clang-tools-extra/clangd/Diagnostics.cpp @@ -15,24 +15,35 @@ #include "clang/Basic/AllDiagnostics.h" // IWYU pragma: keep #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticIDs.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/TokenKinds.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Token.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include #include -#include #include +#include +#include +#include +#include #include namespace clang { @@ -460,6 +471,14 @@ void toLSPDiags( llvm::function_ref)> OutFn) { clangd::Diagnostic Main; Main.severity = getSeverity(D.Severity); + // We downgrade severity for certain noisy warnings, like deprecated + // declartions. These already have visible decorations inside the editor and + // most users find the extra clutter in the UI (gutter, minimap, diagnostics + // views) overwhelming. + if (D.Severity == DiagnosticsEngine::Warning) { +if (llvm::is_contained(D.Tags, DiagnosticTag::Deprecated)) + Main.severity = getSeverity(DiagnosticsEngine::Remark); + } // Main diagnostic should always refer to a range inside main file. If a // diagnostic made it so for, it means either itself or one of its notes is diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp index 5f36f28becb0da..51ffa45dbc8f6f 100644 --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -38,6 +38,7 @@ #include "gtest/gtest.h" #include #include +#include #include #include #include @@ -1879,6 +1880,42 @@ TEST(Diagnostics, Tags) { withTag(DiagnosticTag::Deprecated); } +TEST(Diagnostics, DeprecatedDiagsAreHints) { + ClangdDiagnosticOptions Opts; + std::optional Diag; + clangd::Diag D; + D.Range = {pos(1, 2), pos(3, 4)}; + D.InsideMainFile = true; + + // Downgrade warnings with deprecated tags to remark. + D.Tags = {Deprecated}; + D.Severity = DiagnosticsEngine::Warning; + toLSPDiags(D, {}, Opts, + [&](clangd::Diagnostic LSPDiag, ArrayRef) { + Diag = std::move(LSPDiag); + }); + EXPECT_EQ(Diag->severity, getSeverity(DiagnosticsEngine::Remark)); + Diag.reset(); + + // Preserve errors. + D.Severity = DiagnosticsEngine::Error; + toLSPDiags(D, {}, Opts, + [&](clangd::Diagnostic LSPDiag, ArrayRef) { + Diag = std::move(LSPDiag); + }); + EXPECT_EQ(Diag->severity, getSeverity(DiagnosticsEngine::Error)); + Diag.reset(); + + // No-op without tag. + D.Tags = {}; + D.Severity = DiagnosticsEngine::Warning; + toLSPDiags(D, {}, Opts, + [&](clangd::Diagnostic LSPDiag, ArrayRef) { + Diag = std::move(LSPDiag); + }); + EXPECT_EQ(Diag->severity, getSeverity(DiagnosticsEngine::Warning)); +} + TEST(DiagnosticsTest, IncludeCleaner) { Annotations Test(R"cpp( $fix[[ $diag[[#include "unused.h"]] ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 9841daf - [clang][tooling] Fix early termination when there are nested expansions
Author: Kadir Cetinkaya Date: 2023-07-03T16:58:04+02:00 New Revision: 9841daf27076886c6ab8e155eb812bda76f77532 URL: https://github.com/llvm/llvm-project/commit/9841daf27076886c6ab8e155eb812bda76f77532 DIFF: https://github.com/llvm/llvm-project/commit/9841daf27076886c6ab8e155eb812bda76f77532.diff LOG: [clang][tooling] Fix early termination when there are nested expansions This also does some cleanups, I am happy to undo them (or send as separate patches): - Change the early exit to stop only once we hit an expansion inside the main file, to make sure we keep following the nested expansions. - Add more tests to cover all the cases mentioned in the implementation - Drop the adjustments for prev/next tokens. We do the final checks based on the expansion locations anyway, so any intermediate mapping was a no-op. Differential Revision: https://reviews.llvm.org/D154335 Added: Modified: clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp clang/lib/Tooling/Syntax/Tokens.cpp clang/unittests/Tooling/Syntax/TokensTest.cpp Removed: diff --git a/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp index da76ecad145548..1fd2487378d705 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp @@ -71,6 +71,13 @@ class cc { // NestedNameSpecifier, but no namespace. EXPECT_UNAVAILABLE(Header + "class Foo {}; class F^oo foo;"); + // Nested macro case. + EXPECT_AVAILABLE(R"cpp( + #define ID2(X) X + #define ID(Y, X) Y;ID2(X) + namespace ns { struct Foo{}; } + ID(int xyz, ns::F^oo) f;)cpp"); + // Check that we do not trigger in header files. FileName = "test.h"; ExtraArgs.push_back("-xc++-header"); // .h file is treated a C by default. diff --git a/clang/lib/Tooling/Syntax/Tokens.cpp b/clang/lib/Tooling/Syntax/Tokens.cpp index 64e6eee6b62f2f..9c2f470e985fb6 100644 --- a/clang/lib/Tooling/Syntax/Tokens.cpp +++ b/clang/lib/Tooling/Syntax/Tokens.cpp @@ -103,66 +103,13 @@ SourceRange spelledForExpandedSlow(SourceLocation First, SourceLocation Last, // The token `a` is wrapped in 4 arg-expansions, we only want to unwrap 2. // We distinguish them by whether the macro expands into the target file. // Fortunately, the target file ones will always appear first. -auto = -SM.getSLocEntry(SM.getFileID(ExpFirst.getExpansionLocStart())) -.getExpansion(); -if (ExpMacro.getExpansionLocStart().isMacroID()) +auto ExpFileID = SM.getFileID(ExpFirst.getExpansionLocStart()); +if (ExpFileID == TargetFile) break; // Replace each endpoint with its spelling inside the macro arg. // (This is getImmediateSpellingLoc without repeating lookups). First = ExpFirst.getSpellingLoc().getLocWithOffset(DecFirst.second); Last = ExpLast.getSpellingLoc().getLocWithOffset(DecLast.second); - -// Now: how do we adjust the previous/next bounds? Three cases: -// A) If they are also part of the same macro arg, we translate them too. -// This will ensure that we don't select any macros nested within the -// macro arg that cover extra tokens. Critical case: -// #define ID(X) X -// ID(prev target) // selecting 'target' succeeds -// #define LARGE ID(prev target) -// LARGE // selecting 'target' fails. -// B) They are not in the macro at all, then their expansion range is a -//sibling to it, and we can safely substitute that. -// #define PREV prev -// #define ID(X) X -// PREV ID(target) // selecting 'target' succeeds. -// #define LARGE PREV ID(target) -// LARGE // selecting 'target' fails. -// C) They are in a diff erent arg of this macro, or the macro body. -//Now selecting the whole macro arg is fine, but the whole macro is not. -//Model this by setting using the edge of the macro call as the bound. -// #define ID2(X, Y) X Y -// ID2(prev, target) // selecting 'target' succeeds -// #define LARGE ID2(prev, target) -// LARGE // selecting 'target' fails -auto AdjustBound = [&](SourceLocation ) { - if (Bound.isInvalid() || !Bound.isMacroID()) // Non-macro must be case B. -return; - auto DecBound = SM.getDecomposedLoc(Bound); - auto = SM.getSLocEntry(DecBound.first).getExpansion(); - if (ExpBound.isMacroArgExpansion() && - ExpBound.getExpansionLocStart() == ExpFirst.getExpansionLocStart()) { -// Case A: translate to (spelling) loc within the macro arg. -Bound = ExpBound.getSpellingLoc().getLocWithOffset(DecBound.second); -return; - } - while (Bound.isMacroID()) { -SourceRange Exp = SM.getImmediateExpansionRange(Bound).getAsRange(); -if
[clang-tools-extra] bd89f9e - [clangd] Always allow diagnostics from stale preambles
Author: Kadir Cetinkaya Date: 2023-06-28T10:41:45+02:00 New Revision: bd89f9ec293ea5e20e89d4bce49135431239cf3e URL: https://github.com/llvm/llvm-project/commit/bd89f9ec293ea5e20e89d4bce49135431239cf3e DIFF: https://github.com/llvm/llvm-project/commit/bd89f9ec293ea5e20e89d4bce49135431239cf3e.diff LOG: [clangd] Always allow diagnostics from stale preambles We've been running this internally for months now, without any stability or correctness concerns. It has ~40% speed up on incremental diagnostics latencies (as preamble can get invalidated through code completion etc.). Differential Revision: https://reviews.llvm.org/D153882 Added: Modified: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Config.h clang-tools-extra/clangd/ConfigCompile.cpp clang-tools-extra/clangd/ConfigFragment.h clang-tools-extra/clangd/ConfigYAML.cpp clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/ParsedAST.h clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/tool/Check.cpp clang-tools-extra/clangd/unittests/ClangdTests.cpp clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp clang-tools-extra/clangd/unittests/FeatureModulesTests.cpp clang-tools-extra/clangd/unittests/ModulesTests.cpp clang-tools-extra/clangd/unittests/ParsedASTTests.cpp clang-tools-extra/clangd/unittests/PreambleTests.cpp clang-tools-extra/clangd/unittests/SelectionTests.cpp clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp clang-tools-extra/clangd/unittests/TestTU.cpp clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp Removed: diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 396b903a9a762..bf4c1a982834b 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -650,7 +650,6 @@ void ClangdLSPServer::onInitialize(const InitializeParams , CodeAction::INFO_KIND}}} : llvm::json::Value(true); - std::vector Commands; for (llvm::StringRef Command : Handlers.CommandHandlers.keys()) Commands.push_back(Command); @@ -1744,7 +1743,7 @@ bool ClangdLSPServer::shouldRunCompletion( } void ClangdLSPServer::onDiagnosticsReady(PathRef File, llvm::StringRef Version, - std::vector Diagnostics) { + llvm::ArrayRef Diagnostics) { PublishDiagnosticsParams Notification; Notification.version = decodeVersion(Version); Notification.uri = URIForFile::canonicalize(File, /*TUPath=*/File); diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index a483d1110f64c..6cf1db4306324 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H #include "ClangdServer.h" +#include "Diagnostics.h" #include "GlobalCompilationDatabase.h" #include "LSPBinder.h" #include "Protocol.h" @@ -18,6 +19,7 @@ #include "support/MemoryTree.h" #include "support/Path.h" #include "support/Threading.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/JSON.h" #include #include @@ -80,7 +82,7 @@ class ClangdLSPServer : private ClangdServer::Callbacks, private: // Implement ClangdServer::Callbacks. void onDiagnosticsReady(PathRef File, llvm::StringRef Version, - std::vector Diagnostics) override; + llvm::ArrayRef Diagnostics) override; void onFileUpdated(PathRef File, const TUStatus ) override; void onBackgroundIndexProgress(const BackgroundQueue::Stats ) override; void onSemanticsMaybeChanged(PathRef File) override; @@ -197,7 +199,6 @@ class ClangdLSPServer : private ClangdServer::Callbacks, void bindMethods(LSPBinder &, const ClientCapabilities ); std::vector getFixes(StringRef File, const clangd::Diagnostic ); - /// Checks if completion request should be ignored. We need this due to the /// limitation of the LSP. Per LSP, a client sends requests for all "trigger /// character" we specify, but for '>' and ':' we need to check they actually diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 7b4224a20cec3..d8df4c6a69910 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -124,13 +124,10 @@ struct
[clang] 4d0cfa6 - [clang] Don't create import decls without -fmodules
Author: Kadir Cetinkaya Date: 2023-06-16T09:26:45+02:00 New Revision: 4d0cfa6d09e2a84cceb669949d72df58c031a8c5 URL: https://github.com/llvm/llvm-project/commit/4d0cfa6d09e2a84cceb669949d72df58c031a8c5 DIFF: https://github.com/llvm/llvm-project/commit/4d0cfa6d09e2a84cceb669949d72df58c031a8c5.diff LOG: [clang] Don't create import decls without -fmodules When modules are disabled, there's no loaded module for these import decls to point at. This results in crashes when there are modulemap files but no -fmodules flag (this configuration is used for layering check violations). This patch makes sure import declarations are introduced only when modules are enabled, which makes this case similar to textual headers (no import decls are created for #include of textual headers from a modulemap). Differential Revision: https://reviews.llvm.org/D152274 Added: clang/test/Modules/Inputs/modulemaps-nomodules/header.h clang/test/Modules/Inputs/modulemaps-nomodules/module.modulemap clang/test/Modules/modulemaps-nomodules.cpp clang/test/PCH/Inputs/modulemaps-nomodules/header.h clang/test/PCH/Inputs/modulemaps-nomodules/module.modulemap clang/test/PCH/modulemaps-nomodules.cpp Modified: clang/lib/Sema/SemaModule.cpp clang/test/Modules/getSourceDescriptor-crash.cpp Removed: diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index 67c6556e00ddf..5ce5330b09466 100644 --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -636,11 +636,9 @@ void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { TUKind == TU_Module && getSourceManager().isWrittenInMainFile(DirectiveLoc); - bool ShouldAddImport = !IsInModuleIncludes; - - // If this module import was due to an inclusion directive, create an - // implicit import declaration to capture it in the AST. - if (ShouldAddImport) { + // If we are really importing a module (not just checking layering) due to an + // #include in the main file, synthesize an ImportDecl. + if (getLangOpts().Modules && !IsInModuleIncludes) { TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, DirectiveLoc, Mod, diff --git a/clang/test/Modules/Inputs/modulemaps-nomodules/header.h b/clang/test/Modules/Inputs/modulemaps-nomodules/header.h new file mode 100644 index 0..e69de29bb2d1d diff --git a/clang/test/Modules/Inputs/modulemaps-nomodules/module.modulemap b/clang/test/Modules/Inputs/modulemaps-nomodules/module.modulemap new file mode 100644 index 0..dcae7e5a37c3a --- /dev/null +++ b/clang/test/Modules/Inputs/modulemaps-nomodules/module.modulemap @@ -0,0 +1,3 @@ +module M { + private header "header.h" +} diff --git a/clang/test/Modules/getSourceDescriptor-crash.cpp b/clang/test/Modules/getSourceDescriptor-crash.cpp index 84e527aef91b5..53111786472f7 100644 --- a/clang/test/Modules/getSourceDescriptor-crash.cpp +++ b/clang/test/Modules/getSourceDescriptor-crash.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -I %S/Inputs/getSourceDescriptor-crash -S -emit-llvm -debug-info-kind=limited -debugger-tuning=lldb -fimplicit-module-maps %s -o - | FileCheck %s +// RUN: rm -rf %t +// RUN: %clang_cc1 -I %S/Inputs/getSourceDescriptor-crash -S -emit-llvm -debug-info-kind=limited -debugger-tuning=lldb -fmodules -fmodules-cache-path=%t -fimplicit-module-maps %s -o - | FileCheck %s #include "h1.h" #include "h1.h" diff --git a/clang/test/Modules/modulemaps-nomodules.cpp b/clang/test/Modules/modulemaps-nomodules.cpp new file mode 100644 index 0..eec024fa24b47 --- /dev/null +++ b/clang/test/Modules/modulemaps-nomodules.cpp @@ -0,0 +1,8 @@ +// Make sure we treat includes that are part of modulemaps the same as textual +// headers when modules are not enabled (e.g do't generate import decls, but +// still perform layering checks). +// No need to pass -fno-modules explicitly, absence implies negation for cc1. +// RUN: %clang_cc1 -I %S/Inputs/modulemaps-nomodules -fmodule-map-file=%S/Inputs/modulemaps-nomodules/module.modulemap %s -verify -ast-dump | FileCheck %s + +#include "header.h" // expected-error{{use of private header from outside its module: 'header.h'}} +// CHECK-NOT: ImportDecl diff --git a/clang/test/PCH/Inputs/modulemaps-nomodules/header.h b/clang/test/PCH/Inputs/modulemaps-nomodules/header.h new file mode 100644 index 0..e69de29bb2d1d diff --git a/clang/test/PCH/Inputs/modulemaps-nomodules/module.modulemap b/clang/test/PCH/Inputs/modulemaps-nomodules/module.modulemap new file mode 100644 index 0..15b101f4be60e --- /dev/null +++ b/clang/test/PCH/Inputs/modulemaps-nomodules/module.modulemap @@ -0,0 +1,3 @@ +module M { + header "header.h" +} diff --git
[clang-tools-extra] ea20f33 - [clangd] Enforce strict unused includes by default
Author: Kadir Cetinkaya Date: 2023-06-12T11:47:03+02:00 New Revision: ea20f339d91f57694899c29198f2dfb41bf9a03a URL: https://github.com/llvm/llvm-project/commit/ea20f339d91f57694899c29198f2dfb41bf9a03a DIFF: https://github.com/llvm/llvm-project/commit/ea20f339d91f57694899c29198f2dfb41bf9a03a.diff LOG: [clangd] Enforce strict unused includes by default Depends on D152685 Differential Revision: https://reviews.llvm.org/D152686 Added: Modified: clang-tools-extra/clangd/Config.h clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp clang-tools-extra/clangd/unittests/ParsedASTTests.cpp Removed: diff --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h index 4c6fad25384a8..78fcec1582f00 100644 --- a/clang-tools-extra/clangd/Config.h +++ b/clang-tools-extra/clangd/Config.h @@ -108,7 +108,7 @@ struct Config { /// Enable emitting diagnostics using stale preambles. bool AllowStalePreamble = false; -IncludesPolicy UnusedIncludes = IncludesPolicy::None; +IncludesPolicy UnusedIncludes = IncludesPolicy::Strict; IncludesPolicy MissingIncludes = IncludesPolicy::None; /// IncludeCleaner will not diagnose usages of these headers matched by diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp index 45dacba5822b7..f0ba582187fd5 100644 --- a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp +++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp @@ -246,22 +246,19 @@ TEST_F(ConfigCompileTests, PathSpecMatch) { } TEST_F(ConfigCompileTests, DiagnosticsIncludeCleaner) { - // Defaults to None. + // Defaults to Strict. EXPECT_TRUE(compileAndApply()); - EXPECT_EQ(Conf.Diagnostics.UnusedIncludes, -Config::IncludesPolicy::None); + EXPECT_EQ(Conf.Diagnostics.UnusedIncludes, Config::IncludesPolicy::Strict); Frag = {}; Frag.Diagnostics.UnusedIncludes.emplace("None"); EXPECT_TRUE(compileAndApply()); - EXPECT_EQ(Conf.Diagnostics.UnusedIncludes, -Config::IncludesPolicy::None); + EXPECT_EQ(Conf.Diagnostics.UnusedIncludes, Config::IncludesPolicy::None); Frag = {}; Frag.Diagnostics.UnusedIncludes.emplace("Strict"); EXPECT_TRUE(compileAndApply()); - EXPECT_EQ(Conf.Diagnostics.UnusedIncludes, -Config::IncludesPolicy::Strict); + EXPECT_EQ(Conf.Diagnostics.UnusedIncludes, Config::IncludesPolicy::Strict); Frag = {}; EXPECT_TRUE(Conf.Diagnostics.Includes.IgnoreHeader.empty()) diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp index 552f4f4ecf886..62b5c466ee77c 100644 --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -6,6 +6,7 @@ // //===--===// +#include "../clang-tidy/ClangTidyOptions.h" #include "Annotations.h" #include "Config.h" #include "Diagnostics.h" @@ -18,18 +19,28 @@ #include "TestTU.h" #include "TidyProvider.h" #include "index/MemIndex.h" +#include "index/Ref.h" +#include "index/Relation.h" +#include "index/Symbol.h" #include "support/Context.h" #include "support/Path.h" +#include "clang/AST/Decl.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticSema.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/JSON.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/TargetSelect.h" #include "gmock/gmock.h" #include "gtest/gtest.h" -#include +#include #include +#include +#include +#include namespace clang { namespace clangd { @@ -42,6 +53,7 @@ using ::testing::Each; using ::testing::ElementsAre; using ::testing::Field; using ::testing::IsEmpty; +using ::testing::Not; using ::testing::Pair; using ::testing::SizeIs; using ::testing::UnorderedElementsAre; @@ -889,7 +901,8 @@ TEST(DiagnosticsTest, RecursivePreamblePragmaOnce) { int symbol; )cpp"); TU.Filename = "foo.h"; - EXPECT_THAT(*TU.build().getDiagnostics(), IsEmpty()); + EXPECT_THAT(*TU.build().getDiagnostics(), + Not(Contains(diagName("pp_including_mainfile_in_preamble"; EXPECT_THAT(TU.build().getLocalTopLevelDecls(), SizeIs(1)); } @@ -1597,9 +1610,9 @@ TEST(DiagsInHeaders, DiagInTransitiveInclude) { TU.AdditionalFiles = {{"a.h", "#include \"b.h\""}, {"b.h", "no_type_spec; // error-ok"}}; EXPECT_THAT(*TU.build().getDiagnostics(), - UnorderedElementsAre( - Diag(Main.range(), "in included file: a type specifier is " - "required for all declarations"))); +
[clang-tools-extra] 031ffc3 - [clangd] Decouple IncludeCleaner implementation from Config
Author: Kadir Cetinkaya Date: 2023-06-12T11:38:58+02:00 New Revision: 031ffc3e064525731914eff2ea0dfab1ff34cce1 URL: https://github.com/llvm/llvm-project/commit/031ffc3e064525731914eff2ea0dfab1ff34cce1 DIFF: https://github.com/llvm/llvm-project/commit/031ffc3e064525731914eff2ea0dfab1ff34cce1.diff LOG: [clangd] Decouple IncludeCleaner implementation from Config This should help managing tests as we change defaults in configs. Differential Revision: https://reviews.llvm.org/D152685 Added: Modified: clang-tools-extra/clangd/IncludeCleaner.cpp clang-tools-extra/clangd/IncludeCleaner.h clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp Removed: diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index fa30592e75807..95585a61c023d 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -7,7 +7,6 @@ //===--===// #include "IncludeCleaner.h" -#include "Config.h" #include "Diagnostics.h" #include "Headers.h" #include "ParsedAST.h" @@ -48,7 +47,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/StringSet.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" @@ -62,8 +60,7 @@ #include #include -namespace clang { -namespace clangd { +namespace clang::clangd { static bool AnalyzeStdlib = false; void setIncludeCleanerAnalyzesStdlib(bool B) { AnalyzeStdlib = B; } @@ -84,20 +81,19 @@ clangd::Range getDiagnosticRange(llvm::StringRef Code, unsigned HashOffset) { return Result; } -bool isFilteredByConfig(const Config , llvm::StringRef HeaderPath) { +bool isIgnored(llvm::StringRef HeaderPath, HeaderFilter IgnoreHeaders) { // Convert the path to Unix slashes and try to match against the filter. llvm::SmallString<64> NormalizedPath(HeaderPath); llvm::sys::path::native(NormalizedPath, llvm::sys::path::Style::posix); - for (auto : Cfg.Diagnostics.Includes.IgnoreHeader) { + for (auto : IgnoreHeaders) { if (Filter(NormalizedPath)) return true; } return false; } -static bool mayConsiderUnused(const Inclusion , ParsedAST , - const Config , - const include_cleaner::PragmaIncludes *PI) { +bool mayConsiderUnused(const Inclusion , ParsedAST , + const include_cleaner::PragmaIncludes *PI) { // FIXME(kirillbobyrev): We currently do not support the umbrella headers. // System headers are likely to be standard library headers. // Until we have good support for umbrella headers, don't warn about them. @@ -133,11 +129,6 @@ static bool mayConsiderUnused(const Inclusion , ParsedAST , FE->getName()); return false; } - - if (isFilteredByConfig(Cfg, Inc.Resolved)) { -dlog("{0} header is filtered out by the configuration", FE->getName()); -return false; - } return true; } @@ -166,15 +157,8 @@ std::string getSymbolName(const include_cleaner::Symbol ) { std::vector generateMissingIncludeDiagnostics( ParsedAST , llvm::ArrayRef MissingIncludes, -llvm::StringRef Code) { +llvm::StringRef Code, HeaderFilter IgnoreHeaders) { std::vector Result; - const Config = Config::current(); - if (Cfg.Diagnostics.MissingIncludes != Config::IncludesPolicy::Strict || - Cfg.Diagnostics.SuppressAll || - Cfg.Diagnostics.Suppress.contains("missing-includes")) { -return Result; - } - const SourceManager = AST.getSourceManager(); const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID()); @@ -191,7 +175,7 @@ std::vector generateMissingIncludeDiagnostics( for (const auto : MissingIncludes) { llvm::StringRef ResolvedPath = getResolvedPath(SymbolWithMissingInclude.Providers.front()); -if (isFilteredByConfig(Cfg, ResolvedPath)) { +if (isIgnored(ResolvedPath, IgnoreHeaders)) { dlog("IncludeCleaner: not diagnosing missing include {0}, filtered by " "config", ResolvedPath); @@ -252,15 +236,11 @@ std::vector generateMissingIncludeDiagnostics( std::vector generateUnusedIncludeDiagnostics( PathRef FileName, llvm::ArrayRef UnusedIncludes, -llvm::StringRef Code) { +llvm::StringRef Code, HeaderFilter IgnoreHeaders) { std::vector Result; - const Config = Config::current(); - if (Cfg.Diagnostics.UnusedIncludes == Config::IncludesPolicy::None || - Cfg.Diagnostics.SuppressAll || - Cfg.Diagnostics.Suppress.contains("unused-includes")) { -return Result; - } for (const auto *Inc : UnusedIncludes) { +if (isIgnored(Inc->Resolved, IgnoreHeaders)) + continue; Diag = Result.emplace_back();
[clang] 476e7c4 - [clang][test] Use a physical copy of FS
Author: Kadir Cetinkaya Date: 2023-06-06T15:45:55+02:00 New Revision: 476e7c49ecb762df1d68273696b06c36feb0fd96 URL: https://github.com/llvm/llvm-project/commit/476e7c49ecb762df1d68273696b06c36feb0fd96 DIFF: https://github.com/llvm/llvm-project/commit/476e7c49ecb762df1d68273696b06c36feb0fd96.diff LOG: [clang][test] Use a physical copy of FS Make use of a physical copy, rather than real FS in unittests that change working-directory to get rid of the side effect of changing cwd for the whole process. It's triggering crashes depending on the test order. Differential Revision: https://reviews.llvm.org/D152265 Added: Modified: clang/unittests/Serialization/ModuleCacheTest.cpp clang/unittests/Serialization/NoCommentsTest.cpp clang/unittests/Serialization/VarDeclConstantInitTest.cpp Removed: diff --git a/clang/unittests/Serialization/ModuleCacheTest.cpp b/clang/unittests/Serialization/ModuleCacheTest.cpp index 268b037179851..1e152a399c218 100644 --- a/clang/unittests/Serialization/ModuleCacheTest.cpp +++ b/clang/unittests/Serialization/ModuleCacheTest.cpp @@ -14,6 +14,7 @@ #include "clang/Lex/HeaderSearch.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include "gtest/gtest.h" @@ -98,6 +99,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) { CompilerInstance::createDiagnostics(new DiagnosticOptions()); CreateInvocationOptions CIOpts; CIOpts.Diags = Diags; + CIOpts.VFS = llvm::vfs::createPhysicalFileSystem(); // First run should pass with no errors const char *Args[] = {"clang","-fmodules", "-Fframeworks", diff --git a/clang/unittests/Serialization/NoCommentsTest.cpp b/clang/unittests/Serialization/NoCommentsTest.cpp index 48f76bbd9d5f8..2632a6337807a 100644 --- a/clang/unittests/Serialization/NoCommentsTest.cpp +++ b/clang/unittests/Serialization/NoCommentsTest.cpp @@ -87,6 +87,7 @@ void foo() {} CompilerInstance::createDiagnostics(new DiagnosticOptions()); CreateInvocationOptions CIOpts; CIOpts.Diags = Diags; + CIOpts.VFS = llvm::vfs::createPhysicalFileSystem(); std::string CacheBMIPath = llvm::Twine(TestDir + "/Comments.pcm").str(); const char *Args[] = { diff --git a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp index 33fc82b9adc75..86ae929e7f17e 100644 --- a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp +++ b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp @@ -94,6 +94,7 @@ export namespace Fibonacci CompilerInstance::createDiagnostics(new DiagnosticOptions()); CreateInvocationOptions CIOpts; CIOpts.Diags = Diags; + CIOpts.VFS = llvm::vfs::createPhysicalFileSystem(); std::string CacheBMIPath = llvm::Twine(TestDir + "/Cached.pcm").str(); const char *Args[] = { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] fe7afcf - [clangd] Remove inline Specifier for DefineOutline Tweak
Author: Brian Gluzman Date: 2023-05-26T10:43:08+02:00 New Revision: fe7afcf70c93223a16ec7a2a5e07c4ace16c9a04 URL: https://github.com/llvm/llvm-project/commit/fe7afcf70c93223a16ec7a2a5e07c4ace16c9a04 DIFF: https://github.com/llvm/llvm-project/commit/fe7afcf70c93223a16ec7a2a5e07c4ace16c9a04.diff LOG: [clangd] Remove inline Specifier for DefineOutline Tweak `inline` specifiers should be removed from from the function declaration and the newly-created implementation. For example, take the following (working) code: ```cpp // foo.hpp struct A { inline void foo() { std::cout << "hello world\n" << std::flush; } }; // foo.cpp #include "foo.hpp" // main.cpp #include "foo.hpp" int main() { A a; a.foo(); return 0; } // compile: clang++ -std=c++20 main.cpp foo.cpp -o main ``` After applying the tweak: ``` // foo.hpp struct A { inline void foo(); }; // foo.cpp #include "foo.hpp" inline void A::foo() { std::cout << "hello world\n" << std::flush; } // main.cpp #include "foo.hpp" int main() { A a; a.foo(); return 0; } // compile: clang++ -std=c++20 main.cpp foo.cpp -o main ``` We get a link error, as expected: ``` /usr/bin/ld: /tmp/main-4c5d99.o: in function `main': main.cpp:(.text+0x14): undefined reference to `A::foo()' clang: error: linker command failed with exit code 1 (use -v to see invocation) ``` This revision removes these specifiers from both the header and the source file. This was identified in Github issue llvm/llvm-project#61295. Reviewed By: kadircet Differential Revision: https://reviews.llvm.org/D151294 Added: Modified: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp Removed: diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp index f883397aaaf1e..b84ae04072f2c 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -131,6 +131,47 @@ getFunctionSourceAfterReplacements(const FunctionDecl *FD, return QualifiedFunc->substr(FuncBegin, FuncEnd - FuncBegin + 1); } +// Returns replacements to delete tokens with kind `Kind` in the range +// `FromRange`. Removes matching instances of given token preceeding the +// function defition. +llvm::Expected +deleteTokensWithKind(const syntax::TokenBuffer , tok::TokenKind Kind, + SourceRange FromRange) { + tooling::Replacements DelKeywordCleanups; + llvm::Error Errors = llvm::Error::success(); + bool FoundAny = false; + for (const auto : TokBuf.expandedTokens(FromRange)) { +if (Tok.kind() != Kind) + continue; +FoundAny = true; +auto Spelling = TokBuf.spelledForExpanded(llvm::ArrayRef(Tok)); +if (!Spelling) { + Errors = llvm::joinErrors( + std::move(Errors), + error("define outline: couldn't remove `{0}` keyword.", +tok::getKeywordSpelling(Kind))); + break; +} +auto = TokBuf.sourceManager(); +CharSourceRange DelRange = +syntax::Token::range(SM, Spelling->front(), Spelling->back()) +.toCharRange(SM); +if (auto Err = +DelKeywordCleanups.add(tooling::Replacement(SM, DelRange, ""))) + Errors = llvm::joinErrors(std::move(Errors), std::move(Err)); + } + if (!FoundAny) { +Errors = llvm::joinErrors( +std::move(Errors), +error("define outline: couldn't find `{0}` keyword to remove.", + tok::getKeywordSpelling(Kind))); + } + + if (Errors) +return std::move(Errors); + return DelKeywordCleanups; +} + // Creates a modified version of function definition that can be inserted at a // diff erent location, qualifies return value and function name to achieve that. // Contains function signature, except defaulted parameter arguments, body and @@ -251,34 +292,16 @@ getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace, DelAttr(FD->getAttr()); auto DelKeyword = [&](tok::TokenKind Kind, SourceRange FromRange) { -bool FoundAny = false; -for (const auto : TokBuf.expandedTokens(FromRange)) { - if (Tok.kind() != Kind) -continue; - FoundAny = true; - auto Spelling = TokBuf.spelledForExpanded(llvm::ArrayRef(Tok)); - if (!Spelling) { -Errors = llvm::joinErrors( -std::move(Errors), -error("define outline: couldn't remove `{0}` keyword.", - tok::getKeywordSpelling(Kind))); -break; - } - CharSourceRange DelRange = - syntax::Token::range(SM, Spelling->front(), Spelling->back()) - .toCharRange(SM); - if (auto Err = - DeclarationCleanups.add(tooling::Replacement(SM, DelRange, ""))) -Errors = llvm::joinErrors(std::move(Errors), std::move(Err)); -} -
[clang-tools-extra] a2f7352 - [clangd] Dont run raw-lexer for OOB source locations
Author: Kadir Cetinkaya Date: 2023-05-25T09:38:04+02:00 New Revision: a2f7352f3e809cb1b267e769d00ea84e4ef46bf0 URL: https://github.com/llvm/llvm-project/commit/a2f7352f3e809cb1b267e769d00ea84e4ef46bf0 DIFF: https://github.com/llvm/llvm-project/commit/a2f7352f3e809cb1b267e769d00ea84e4ef46bf0.diff LOG: [clangd] Dont run raw-lexer for OOB source locations We can get stale source locations from preamble, make sure we don't access those locations without checking first. Fixes https://github.com/clangd/clangd/issues/1636. Differential Revision: https://reviews.llvm.org/D151321 Added: Modified: clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/unittests/PreambleTests.cpp Removed: diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp index b708f9c3d3b03..4c5def3063f1e 100644 --- a/clang-tools-extra/clangd/Diagnostics.cpp +++ b/clang-tools-extra/clangd/Diagnostics.cpp @@ -96,7 +96,8 @@ bool locationInRange(SourceLocation L, CharSourceRange R, // Clang diags have a location (shown as ^) and 0 or more ranges (). // LSP needs a single range. -Range diagnosticRange(const clang::Diagnostic , const LangOptions ) { +std::optional diagnosticRange(const clang::Diagnostic , + const LangOptions ) { auto = D.getSourceManager(); auto PatchedRange = [](CharSourceRange ) { R.setBegin(translatePreamblePatchLocation(R.getBegin(), M)); @@ -115,13 +116,18 @@ Range diagnosticRange(const clang::Diagnostic , const LangOptions ) { if (locationInRange(Loc, R, M)) return halfOpenToRange(M, PatchedRange(R)); } + // Source locations from stale preambles might become OOB. + // FIXME: These diagnostics might point to wrong locations even when they're + // not OOB. + auto [FID, Offset] = M.getDecomposedLoc(Loc); + if (Offset > M.getBufferData(FID).size()) +return std::nullopt; // If the token at the location is not a comment, we use the token. // If we can't get the token at the location, fall back to using the location auto R = CharSourceRange::getCharRange(Loc); Token Tok; - if (!Lexer::getRawToken(Loc, Tok, M, L, true) && Tok.isNot(tok::comment)) { + if (!Lexer::getRawToken(Loc, Tok, M, L, true) && Tok.isNot(tok::comment)) R = CharSourceRange::getTokenRange(Tok.getLocation(), Tok.getEndLoc()); - } return halfOpenToRange(M, PatchedRange(R)); } @@ -697,7 +703,10 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, SourceLocation PatchLoc = translatePreamblePatchLocation(Info.getLocation(), SM); D.InsideMainFile = isInsideMainFile(PatchLoc, SM); -D.Range = diagnosticRange(Info, *LangOpts); +if (auto DRange = diagnosticRange(Info, *LangOpts)) + D.Range = *DRange; +else + D.Severity = DiagnosticsEngine::Ignored; auto FID = SM.getFileID(Info.getLocation()); if (const auto FE = SM.getFileEntryRefForID(FID)) { D.File = FE->getName().str(); diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp index 23ba0fc3e52fc..4f2cc3e0abe77 100644 --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -829,6 +829,37 @@ x>)"); auto AST = createPatchedAST(Code.code(), NewCode.code()); EXPECT_THAT(*AST->getDiagnostics(), IsEmpty()); } + { +Annotations Code(R"( +#ifndef FOO +#define FOO +void foo(); +#endif)"); +// This code will emit a diagnostic for unterminated #ifndef (as stale +// preamble has the conditional but main file doesn't terminate it). +// We shouldn't emit any diagnotiscs (and shouldn't crash). +Annotations NewCode(""); +auto AST = createPatchedAST(Code.code(), NewCode.code()); +EXPECT_THAT(*AST->getDiagnostics(), IsEmpty()); + } + { +Annotations Code(R"( +#ifndef FOO +#define FOO +void foo(); +#endif)"); +// This code will emit a diagnostic for unterminated #ifndef (as stale +// preamble has the conditional but main file doesn't terminate it). +// We shouldn't emit any diagnotiscs (and shouldn't crash). +// FIXME: Patch/ignore diagnostics in such cases. +Annotations NewCode(R"( +i[[nt]] xyz; +)"); +auto AST = createPatchedAST(Code.code(), NewCode.code()); +EXPECT_THAT( +*AST->getDiagnostics(), +ElementsAre(Diag(NewCode.range(), "pp_unterminated_conditional"))); + } } MATCHER_P2(Mark, Range, Text, "") { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 51df1a9 - [clangd] Fix add-using tweak on declrefs with template arguments
Author: Kadir Cetinkaya Date: 2023-05-24T09:56:53+02:00 New Revision: 51df1a9ac96f0cf588e97d3174d5c16ed9577b96 URL: https://github.com/llvm/llvm-project/commit/51df1a9ac96f0cf588e97d3174d5c16ed9577b96 DIFF: https://github.com/llvm/llvm-project/commit/51df1a9ac96f0cf588e97d3174d5c16ed9577b96.diff LOG: [clangd] Fix add-using tweak on declrefs with template arguments Differential Revision: https://reviews.llvm.org/D151303 Added: Modified: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp Removed: diff --git a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp index 5ca45f94ea9f0..ca96da34e0920 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp @@ -288,11 +288,18 @@ bool AddUsing::prepare(const Selection ) { if (Node == nullptr) return false; + // Closed range for the fully qualified name as spelled in source code. SourceRange SpelledNameRange; if (auto *D = Node->ASTNode.get()) { if (D->getDecl()->getIdentifier()) { QualifierToRemove = D->getQualifierLoc(); + // Use the name range rather than expr, as the latter can contain template + // arguments in the range. SpelledNameRange = D->getSourceRange(); + // Remove the template arguments from the name, as they shouldn't be + // spelled in the using declaration. + if (auto AngleLoc = D->getLAngleLoc(); AngleLoc.isValid()) +SpelledNameRange.setEnd(AngleLoc.getLocWithOffset(-1)); MustInsertAfterLoc = D->getDecl()->getBeginLoc(); } } else if (auto *T = Node->ASTNode.get()) { diff --git a/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp index f3a479a9a240f..da76ecad14554 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp @@ -498,6 +498,30 @@ void foo() { switch(one::two::ee{}) { case ee_one:break; } } )cpp"}, + {R"cpp( +#include "test.hpp" +void foo() { + one::f^unc_temp(); +})cpp", + R"cpp( +#include "test.hpp" +using one::func_temp; + +void foo() { + func_temp(); +})cpp"}, + {R"cpp( +#include "test.hpp" +void foo() { + one::va^r_temp; +})cpp", + R"cpp( +#include "test.hpp" +using one::var_temp; + +void foo() { + var_temp; +})cpp"}, }; llvm::StringMap EditedFiles; for (const auto : Cases) { @@ -515,6 +539,8 @@ class cc { } using uu = two::cc; template struct vec {}; +template void func_temp(); +template T var_temp(); })cpp"; // Typo correction is disabled in msvc-compatibility mode. ExtraArgs.push_back("-fno-ms-compatibility"); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] cce7b81 - [include-cleaner] Treat references to nested types implicit
Author: Kadir Cetinkaya Date: 2023-05-23T16:40:51+02:00 New Revision: cce7b816a1ee70f2d1f3c21d2a99475c17b54bd7 URL: https://github.com/llvm/llvm-project/commit/cce7b816a1ee70f2d1f3c21d2a99475c17b54bd7 DIFF: https://github.com/llvm/llvm-project/commit/cce7b816a1ee70f2d1f3c21d2a99475c17b54bd7.diff LOG: [include-cleaner] Treat references to nested types implicit Differential Revision: https://reviews.llvm.org/D149948 Added: Modified: clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index 4ea7bceeb96ed..c593192c50191 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -218,31 +218,45 @@ class ASTWalker : public RecursiveASTVisitor { } // TypeLoc visitors. + void reportType(SourceLocation RefLoc, NamedDecl *ND) { +// Reporting explicit references to types nested inside classes can cause +// issues, e.g. a type accessed through a derived class shouldn't require +// inclusion of the base. +// Hence we report all such references as implicit. The code must spell the +// outer type-location somewhere, which will trigger an explicit reference +// and per IWYS, it's that spelling's responsibility to bring in necessary +// declarations. +RefType RT = llvm::isa(ND->getDeclContext()) + ? RefType::Implicit + : RefType::Explicit; +return report(RefLoc, ND, RT); + } + bool VisitUsingTypeLoc(UsingTypeLoc TL) { -report(TL.getNameLoc(), TL.getFoundDecl()); +reportType(TL.getNameLoc(), TL.getFoundDecl()); return true; } bool VisitTagTypeLoc(TagTypeLoc TTL) { -report(TTL.getNameLoc(), TTL.getDecl()); +reportType(TTL.getNameLoc(), TTL.getDecl()); return true; } bool VisitTypedefTypeLoc(TypedefTypeLoc TTL) { -report(TTL.getNameLoc(), TTL.getTypedefNameDecl()); +reportType(TTL.getNameLoc(), TTL.getTypedefNameDecl()); return true; } bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) { -report(TL.getTemplateNameLoc(), - getMostRelevantTemplatePattern(TL.getTypePtr())); +reportType(TL.getTemplateNameLoc(), + getMostRelevantTemplatePattern(TL.getTypePtr())); return true; } bool VisitDeducedTemplateSpecializationTypeLoc( DeducedTemplateSpecializationTypeLoc TL) { -report(TL.getTemplateNameLoc(), - getMostRelevantTemplatePattern(TL.getTypePtr())); +reportType(TL.getTemplateNameLoc(), + getMostRelevantTemplatePattern(TL.getTypePtr())); return true; } diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index ffe8bbffc3712..0d504c3303f9e 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -341,6 +341,34 @@ TEST(WalkAST, TemplateNames) { testWalk("template struct $explicit^S { S(T); };", "^S s(42);"); } +TEST(WalkAST, NestedTypes) { + testWalk(R"cpp( + struct Base { typedef int $implicit^a; }; + struct Derived : public Base {};)cpp", + "void fun() { Derived::^a x; }"); + testWalk(R"cpp( + struct Base { using $implicit^a = int; }; + struct Derived : public Base {};)cpp", + "void fun() { Derived::^a x; }"); + testWalk(R"cpp( + struct ns { struct a {}; }; + struct Base : public ns { using ns::$implicit^a; }; + struct Derived : public Base {};)cpp", + "void fun() { Derived::^a x; }"); + testWalk(R"cpp( + struct Base { struct $implicit^a {}; }; + struct Derived : public Base {};)cpp", + "void fun() { Derived::^a x; }"); + testWalk("struct Base { struct $implicit^a {}; };", + "struct Derived : public Base { ^a x; };"); + testWalk(R"cpp( + struct Base { struct $implicit^a {}; }; + struct Derived : public Base {}; + struct SoDerived : public Derived {}; + )cpp", + "void fun() { SoDerived::Derived::^a x; }"); +} + TEST(WalkAST, MemberExprs) { testWalk("struct $implicit^S { static int f; };", "void foo() { S::^f; }"); testWalk("struct B { static int f; }; struct $implicit^S : B {};", ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 35ce741 - [clangd] Store paths as requested in PreambleStatCache
Author: Kadir Cetinkaya Date: 2023-05-23T14:30:58+02:00 New Revision: 35ce741ef3e3dd9db1da3ea0a06c565cb90f665a URL: https://github.com/llvm/llvm-project/commit/35ce741ef3e3dd9db1da3ea0a06c565cb90f665a DIFF: https://github.com/llvm/llvm-project/commit/35ce741ef3e3dd9db1da3ea0a06c565cb90f665a.diff LOG: [clangd] Store paths as requested in PreambleStatCache Underlying FS can store different file names inside the stat response (e.g. symlinks resolved, absolute paths, dots removed). But we store path names as requested inside the preamble, https://github.com/llvm/llvm-project/blob/main/clang/lib/Serialization/ASTWriter.cpp#L1635. This improves cache hit rates from ~30% to 90% in a build system that uses symlinks. Differential Revision: https://reviews.llvm.org/D151185 Added: Modified: clang-tools-extra/clangd/FS.cpp clang-tools-extra/clangd/FS.h clang-tools-extra/clangd/unittests/FSTests.cpp Removed: diff --git a/clang-tools-extra/clangd/FS.cpp b/clang-tools-extra/clangd/FS.cpp index 3622d35d9d52..c67636dbf2d4 100644 --- a/clang-tools-extra/clangd/FS.cpp +++ b/clang-tools-extra/clangd/FS.cpp @@ -11,6 +11,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/VirtualFileSystem.h" #include +#include namespace clang { namespace clangd { @@ -23,9 +24,10 @@ PreambleFileStatusCache::PreambleFileStatusCache(llvm::StringRef MainFilePath){ } void PreambleFileStatusCache::update(const llvm::vfs::FileSystem , - llvm::vfs::Status S) { + llvm::vfs::Status S, + llvm::StringRef File) { // Canonicalize path for later lookup, which is usually by absolute path. - llvm::SmallString<32> PathStore(S.getName()); + llvm::SmallString<32> PathStore(File); if (FS.makeAbsolute(PathStore)) return; llvm::sys::path::remove_dots(PathStore, /*remove_dot_dot=*/true); @@ -72,14 +74,14 @@ PreambleFileStatusCache::getProducingFS( // many times (e.g. code completion) and the repeated status call is // likely to be cached in the underlying file system anyway. if (auto S = File->get()->status()) -StatCache.update(getUnderlyingFS(), std::move(*S)); +StatCache.update(getUnderlyingFS(), std::move(*S), Path.str()); return File; } llvm::ErrorOr status(const llvm::Twine ) override { auto S = getUnderlyingFS().status(Path); if (S) -StatCache.update(getUnderlyingFS(), *S); +StatCache.update(getUnderlyingFS(), *S, Path.str()); return S; } diff --git a/clang-tools-extra/clangd/FS.h b/clang-tools-extra/clangd/FS.h index ea07de24bbae..827b465aed98 100644 --- a/clang-tools-extra/clangd/FS.h +++ b/clang-tools-extra/clangd/FS.h @@ -41,7 +41,8 @@ class PreambleFileStatusCache { /// corresponds to. The stat for the main file will not be cached. PreambleFileStatusCache(llvm::StringRef MainFilePath); - void update(const llvm::vfs::FileSystem , llvm::vfs::Status S); + void update(const llvm::vfs::FileSystem , llvm::vfs::Status S, + llvm::StringRef File); /// \p Path is a path stored in preamble. std::optional lookup(llvm::StringRef Path) const; diff --git a/clang-tools-extra/clangd/unittests/FSTests.cpp b/clang-tools-extra/clangd/unittests/FSTests.cpp index 81129fec98c2..0b2bc688335d 100644 --- a/clang-tools-extra/clangd/unittests/FSTests.cpp +++ b/clang-tools-extra/clangd/unittests/FSTests.cpp @@ -37,18 +37,19 @@ TEST(FSTests, PreambleStatusCache) { std::chrono::system_clock::now(), 0, 0, 1024, llvm::sys::fs::file_type::regular_file, llvm::sys::fs::all_all); - StatCache.update(*FS, S); + StatCache.update(*FS, S, "real"); auto ConsumeFS = StatCache.getConsumingFS(FS); - auto Cached = ConsumeFS->status(testPath("fake")); + EXPECT_FALSE(ConsumeFS->status(testPath("fake"))); + auto Cached = ConsumeFS->status(testPath("real")); EXPECT_TRUE(Cached); - EXPECT_EQ(Cached->getName(), testPath("fake")); + EXPECT_EQ(Cached->getName(), testPath("real")); EXPECT_EQ(Cached->getUniqueID(), S.getUniqueID()); - // fake and temp/../fake should hit the same cache entry. + // real and temp/../real should hit the same cache entry. // However, the Status returned reflects the actual path requested. - auto CachedDotDot = ConsumeFS->status(testPath("temp/../fake")); + auto CachedDotDot = ConsumeFS->status(testPath("temp/../real")); EXPECT_TRUE(CachedDotDot); - EXPECT_EQ(CachedDotDot->getName(), testPath("temp/../fake")); + EXPECT_EQ(CachedDotDot->getName(), testPath("temp/../real")); EXPECT_EQ(CachedDotDot->getUniqueID(), S.getUniqueID()); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org
[clang-tools-extra] ece76dc - [clangd][check] Print directory with compile flags
Author: Kadir Cetinkaya Date: 2023-05-16T19:01:23+02:00 New Revision: ece76dce55f79efc733a0b42718700a5c42c602e URL: https://github.com/llvm/llvm-project/commit/ece76dce55f79efc733a0b42718700a5c42c602e DIFF: https://github.com/llvm/llvm-project/commit/ece76dce55f79efc733a0b42718700a5c42c602e.diff LOG: [clangd][check] Print directory with compile flags Added: Modified: clang-tools-extra/clangd/tool/Check.cpp Removed: diff --git a/clang-tools-extra/clangd/tool/Check.cpp b/clang-tools-extra/clangd/tool/Check.cpp index 4a6f6f8857aa0..d1ece69e3ba08 100644 --- a/clang-tools-extra/clangd/tool/Check.cpp +++ b/clang-tools-extra/clangd/tool/Check.cpp @@ -24,12 +24,17 @@ // //===--===// +#include "../clang-tidy/ClangTidyModule.h" #include "../clang-tidy/ClangTidyModuleRegistry.h" +#include "../clang-tidy/ClangTidyOptions.h" #include "../clang-tidy/GlobList.h" #include "ClangdLSPServer.h" +#include "ClangdServer.h" #include "CodeComplete.h" #include "CompileCommands.h" +#include "Compiler.h" #include "Config.h" +#include "Diagnostics.h" #include "Feature.h" #include "GlobalCompilationDatabase.h" #include "Hover.h" @@ -37,23 +42,39 @@ #include "ParsedAST.h" #include "Preamble.h" #include "Protocol.h" +#include "Selection.h" #include "SemanticHighlighting.h" #include "SourceCode.h" +#include "TidyProvider.h" #include "XRefs.h" #include "index/CanonicalIncludes.h" #include "index/FileIndex.h" #include "refactor/Tweak.h" +#include "support/Context.h" +#include "support/Logger.h" #include "support/ThreadsafeFS.h" #include "support/Trace.h" #include "clang/AST/ASTContext.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/LLVM.h" #include "clang/Format/Format.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/Chrono.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" +#include +#include +#include +#include +#include #include +#include +#include namespace clang { namespace clangd { @@ -153,12 +174,13 @@ class Checker { if (auto TrueCmd = CDB->getCompileCommand(File)) { Cmd = std::move(*TrueCmd); - log("Compile command {0} is: {1}", - Cmd.Heuristic.empty() ? "from CDB" : Cmd.Heuristic, + log("Compile command {0} is: [{1}] {2}", + Cmd.Heuristic.empty() ? "from CDB" : Cmd.Heuristic, Cmd.Directory, printArgv(Cmd.CommandLine)); } else { Cmd = CDB->getFallbackCommand(File); - log("Generic fallback command is: {0}", printArgv(Cmd.CommandLine)); + log("Generic fallback command is: [{0}] {1}", Cmd.Directory, + printArgv(Cmd.CommandLine)); } return true; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 9ffef0f - [clangd] Fix builds after 4ddae8b941398a6579d3
Author: Kadir Cetinkaya Date: 2023-05-16T08:44:53+02:00 New Revision: 9ffef0f24de0fc05b946e662a7b233a32ad058e3 URL: https://github.com/llvm/llvm-project/commit/9ffef0f24de0fc05b946e662a7b233a32ad058e3 DIFF: https://github.com/llvm/llvm-project/commit/9ffef0f24de0fc05b946e662a7b233a32ad058e3.diff LOG: [clangd] Fix builds after 4ddae8b941398a6579d3 Added: Modified: clang-tools-extra/clangd/test/CMakeLists.txt Removed: clang-tools-extra/clangd/test/compile_commands.json diff --git a/clang-tools-extra/clangd/test/CMakeLists.txt b/clang-tools-extra/clangd/test/CMakeLists.txt index 840fe2bdc12b0..d073267066e0b 100644 --- a/clang-tools-extra/clangd/test/CMakeLists.txt +++ b/clang-tools-extra/clangd/test/CMakeLists.txt @@ -28,14 +28,11 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py ) -# Copy an empty compile_commands.json to override the compile_commands.json -# in the top level build directory. Or if a clangd test involves creating a -# temporary source file in the build directory and run clangd to check it, -# it can pick up unrecognizable command options when LLVM is built with -# another compiler or a diff erent version of Clang. -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/compile_commands.json - ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json +# Copy an empty compile_flags.txt to make sure tests don't pick up arbitrary +# commands from parents. +file( + TOUCH + ${CMAKE_CURRENT_BINARY_DIR}/compile_flags.txt ) add_lit_testsuite(check-clangd "Running the Clangd regression tests" diff --git a/clang-tools-extra/clangd/test/compile_commands.json b/clang-tools-extra/clangd/test/compile_commands.json deleted file mode 100644 index fe51488c7066f..0 --- a/clang-tools-extra/clangd/test/compile_commands.json +++ /dev/null @@ -1 +0,0 @@ -[] ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 0d1be98 - [clang][USR] Prevent crashes on incomplete FunctionDecls
Author: Kadir Cetinkaya Date: 2023-05-15T18:05:48+02:00 New Revision: 0d1be98a67e29b70ccfab23d86a2bea13de117d7 URL: https://github.com/llvm/llvm-project/commit/0d1be98a67e29b70ccfab23d86a2bea13de117d7 DIFF: https://github.com/llvm/llvm-project/commit/0d1be98a67e29b70ccfab23d86a2bea13de117d7.diff LOG: [clang][USR] Prevent crashes on incomplete FunctionDecls FunctionDecls can be created with null types (D124351 added such a new code path), to be filled in later. But parsing can stop before completing the Decl (e.g. if code completion point is reached). Unfortunately most of the methods in FunctionDecl and its derived classes assume a complete decl and don't perform null-checks. Since we're not encountring crashes in the wild along other code paths today introducing extra checks into quite a lot of places didn't feel right (due to extra complexity && run time checks). I believe another alternative would be to change Parser & Sema to never create decls with invalid types, but I can't really see an easy way of doing that, as most of the pieces are structured around filling that information as parsing proceeds. Differential Revision: https://reviews.llvm.org/D149733 Added: Modified: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang/lib/Index/USRGeneration.cpp Removed: diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 25d6a7b189ed5..1975488fd035a 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -4002,6 +4002,19 @@ TEST(SignatureHelp, TemplateArguments) { EXPECT_EQ(Second.activeParameter, 1); } +TEST(CompletionTest, DoNotCrash) { + llvm::StringLiteral Cases[] = { + R"cpp( +template struct Foo {}; +auto a = [x(3)](Foo<^>){}; +)cpp", + }; + for (auto Case : Cases) { +SCOPED_TRACE(Case); +auto Completions = completions(Case); + } +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp index 06a3717f9ffaf..b10028a526ed5 100644 --- a/clang/lib/Index/USRGeneration.cpp +++ b/clang/lib/Index/USRGeneration.cpp @@ -226,6 +226,11 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) { if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) return; + if (D->getType().isNull()) { +IgnoreResults = true; +return; + } + const unsigned StartSize = Buf.size(); VisitDeclContext(D->getDeclContext()); if (Buf.size() == StartSize) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 2b240cc - [tidy] Expose getID to tidy checks
Author: Kadir Cetinkaya Date: 2023-05-10T12:50:25+02:00 New Revision: 2b240cc377b5e4f41c05d68c9a513f7d08ab69c8 URL: https://github.com/llvm/llvm-project/commit/2b240cc377b5e4f41c05d68c9a513f7d08ab69c8 DIFF: https://github.com/llvm/llvm-project/commit/2b240cc377b5e4f41c05d68c9a513f7d08ab69c8.diff LOG: [tidy] Expose getID to tidy checks This also fixes a possible use-after-free in the IdentifierNamingCheck. Differential Revision: https://reviews.llvm.org/D150254 Added: Modified: clang-tools-extra/clang-tidy/ClangTidyCheck.h clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h Removed: diff --git a/clang-tools-extra/clang-tidy/ClangTidyCheck.h b/clang-tools-extra/clang-tidy/ClangTidyCheck.h index 9381b6e8becb2..17e9df96c39be 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyCheck.h +++ b/clang-tools-extra/clang-tidy/ClangTidyCheck.h @@ -407,7 +407,6 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { private: void run(const ast_matchers::MatchFinder::MatchResult ) override; - StringRef getID() const override { return CheckName; } std::string CheckName; ClangTidyContext *Context; @@ -422,6 +421,7 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { bool areDiagsSelfContained() const { return Context->areDiagsSelfContained(); } + StringRef getID() const override { return CheckName; } }; /// Read a named option from the ``Context`` and parse it as a bool. diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index 9561b2b00904f..0e16edc10a953 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -14,6 +14,7 @@ #include "clang/Lex/Preprocessor.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" @@ -396,7 +397,7 @@ std::string IdentifierNamingCheck::HungarianNotation::getDeclTypeName( IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name, ClangTidyContext *Context) -: RenamerClangTidyCheck(Name, Context), Context(Context), CheckName(Name), +: RenamerClangTidyCheck(Name, Context), Context(Context), GetConfigPerFile(Options.get("GetConfigPerFile", true)), IgnoreFailedSplit(Options.get("IgnoreFailedSplit", false)) { @@ -1461,6 +1462,7 @@ IdentifierNamingCheck::getStyleForFile(StringRef FileName) const { if (Iter != NamingStylesCache.end()) return Iter->getValue(); + llvm::StringRef CheckName = getID(); ClangTidyOptions Options = Context->getOptionsForFile(FileName); if (Options.Checks && GlobList(*Options.Checks).contains(CheckName)) { auto It = NamingStylesCache.try_emplace( diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h index 3df15ad780180..2e3d4ea8c39c8 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h @@ -11,6 +11,7 @@ #include "../utils/RenamerClangTidyCheck.h" #include +#include namespace clang::tidy { namespace readability { @@ -202,7 +203,6 @@ class IdentifierNamingCheck final : public RenamerClangTidyCheck { mutable llvm::StringMap NamingStylesCache; FileStyle *MainFileStyle; ClangTidyContext *Context; - const StringRef CheckName; const bool GetConfigPerFile; const bool IgnoreFailedSplit; HungarianNotation HungarianNotation; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 62a090f - [clangd] Initialize clang-tidy modules only once
Author: Kadir Cetinkaya Date: 2023-05-10T12:32:33+02:00 New Revision: 62a090f958ce02a8035e3c9424a05dbfe25859e1 URL: https://github.com/llvm/llvm-project/commit/62a090f958ce02a8035e3c9424a05dbfe25859e1 DIFF: https://github.com/llvm/llvm-project/commit/62a090f958ce02a8035e3c9424a05dbfe25859e1.diff LOG: [clangd] Initialize clang-tidy modules only once This is showing up on our profiles with ~100ms contribution @95th% for buildAST latencies. The patch is unlikely to address it all, but should help with some low-hanging fruit. Differential Revision: https://reviews.llvm.org/D150257 Added: clang-tools-extra/clangd/unittests/ReplayPeambleTests.cpp Modified: clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/TidyProvider.cpp clang-tools-extra/clangd/unittests/CMakeLists.txt clang-tools-extra/clangd/unittests/ParsedASTTests.cpp Removed: diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index 1501a5c5f3c3b..e5a391a775389 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -9,6 +9,7 @@ #include "ParsedAST.h" #include "../clang-tidy/ClangTidyCheck.h" #include "../clang-tidy/ClangTidyDiagnosticConsumer.h" +#include "../clang-tidy/ClangTidyModule.h" #include "../clang-tidy/ClangTidyModuleRegistry.h" #include "AST.h" #include "Compiler.h" @@ -25,7 +26,6 @@ #include "TidyProvider.h" #include "clang-include-cleaner/Record.h" #include "index/CanonicalIncludes.h" -#include "index/Index.h" #include "index/Symbol.h" #include "support/Logger.h" #include "support/Trace.h" @@ -50,7 +50,6 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include #include #include #include @@ -476,16 +475,19 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs , // diagnostics. if (PreserveDiags) { trace::Span Tracer("ClangTidyInit"); -tidy::ClangTidyCheckFactories CTFactories; -for (const auto : tidy::ClangTidyModuleRegistry::entries()) - E.instantiate()->addCheckFactories(CTFactories); +static const auto *CTFactories = [] { + auto *CTFactories = new tidy::ClangTidyCheckFactories; + for (const auto : tidy::ClangTidyModuleRegistry::entries()) +E.instantiate()->addCheckFactories(*CTFactories); + return CTFactories; +}(); CTContext.emplace(std::make_unique( tidy::ClangTidyGlobalOptions(), ClangTidyOpts)); CTContext->setDiagnosticsEngine(>getDiagnostics()); CTContext->setASTContext(>getASTContext()); CTContext->setCurrentFile(Filename); CTContext->setSelfContainedDiags(true); -CTChecks = CTFactories.createChecksForLanguage(&*CTContext); +CTChecks = CTFactories->createChecksForLanguage(&*CTContext); Preprocessor *PP = >getPreprocessor(); for (const auto : CTChecks) { Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP); @@ -610,10 +612,8 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs , Macros = Patch->mainFileMacros(); Marks = Patch->marks(); } - auto& PP = Clang->getPreprocessor(); - PP.addPPCallbacks( - std::make_unique( - PP, Macros)); + auto = Clang->getPreprocessor(); + PP.addPPCallbacks(std::make_unique(PP, Macros)); PP.addPPCallbacks( collectPragmaMarksCallback(Clang->getSourceManager(), Marks)); diff --git a/clang-tools-extra/clangd/TidyProvider.cpp b/clang-tools-extra/clangd/TidyProvider.cpp index f3ed6f08a9acb..e3a6d5af20ae2 100644 --- a/clang-tools-extra/clangd/TidyProvider.cpp +++ b/clang-tools-extra/clangd/TidyProvider.cpp @@ -8,6 +8,7 @@ #include "TidyProvider.h" #include "../clang-tidy/ClangTidyModuleRegistry.h" +#include "../clang-tidy/ClangTidyOptions.h" #include "Config.h" #include "support/FileCache.h" #include "support/Logger.h" @@ -283,8 +284,15 @@ TidyProvider combine(std::vector Providers) { tidy::ClangTidyOptions getTidyOptionsForFile(TidyProviderRef Provider, llvm::StringRef Filename) { - tidy::ClangTidyOptions Opts = tidy::ClangTidyOptions::getDefaults(); - Opts.Checks->clear(); + // getDefaults instantiates all check factories, which are registered at link + // time. So cache the results once. + static const auto *DefaultOpts = [] { +auto *Opts = new tidy::ClangTidyOptions; +*Opts = tidy::ClangTidyOptions::getDefaults(); +Opts->Checks->clear(); +return Opts; + }(); + auto Opts = *DefaultOpts; if (Provider) Provider(Opts, Filename); return Opts; diff --git a/clang-tools-extra/clangd/unittests/CMakeLists.txt b/clang-tools-extra/clangd/unittests/CMakeLists.txt index 6d7bb59be3ab1..8d02b91fdd716 100644 --- a/clang-tools-extra/clangd/unittests/CMakeLists.txt +++ b/clang-tools-extra/clangd/unittests/CMakeLists.txt @@ -79,8 +79,9 @@
[clang-tools-extra] b36a2e7 - [tidy][IdentifierNaming] Fix crashes on non-identifiers
Author: Kadir Cetinkaya Date: 2023-05-09T12:50:57+02:00 New Revision: b36a2e7828befcf948f461b72c78a8d2386db2e7 URL: https://github.com/llvm/llvm-project/commit/b36a2e7828befcf948f461b72c78a8d2386db2e7 DIFF: https://github.com/llvm/llvm-project/commit/b36a2e7828befcf948f461b72c78a8d2386db2e7.diff LOG: [tidy][IdentifierNaming] Fix crashes on non-identifiers Differential Revision: https://reviews.llvm.org/D150187 Added: Modified: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-bugfix.cpp Removed: diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp index 5347dadf18ac5..ee400d88a3a74 100644 --- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp @@ -448,14 +448,18 @@ void RenamerClangTidyCheck::addUsage( void RenamerClangTidyCheck::addUsage(const NamedDecl *Decl, SourceRange Range, const SourceManager *SourceMgr) { + // Don't keep track for non-identifier names. + auto *II = Decl->getIdentifier(); + if (!II) +return; if (const auto *Method = dyn_cast(Decl)) { if (const CXXMethodDecl *Overridden = getOverrideMethod(Method)) Decl = Overridden; } Decl = cast(Decl->getCanonicalDecl()); - return addUsage(RenamerClangTidyCheck::NamingCheckId(Decl->getLocation(), - Decl->getName()), - Range, SourceMgr); + return addUsage( + RenamerClangTidyCheck::NamingCheckId(Decl->getLocation(), II->getName()), + Range, SourceMgr); } void RenamerClangTidyCheck::checkNamedDecl(const NamedDecl *Decl, diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-bugfix.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-bugfix.cpp index 9f892ebceccf2..25f2c71a316d7 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-bugfix.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming-bugfix.cpp @@ -3,3 +3,14 @@ // This used to cause a null pointer dereference. auto [left] = right; // CHECK-MESSAGES: :[[@LINE-1]]:15: error: use of undeclared identifier 'right' + +namespace crash_on_nonidentifiers { +struct Foo { + operator bool(); +}; +void foo() { + // Make sure we don't crash on non-identifier names (e.g. conversion + // operators). + if (Foo()) {} +} +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 5e74a3d - [clangd][IncludeCleaner] Use a proper comparator for deduplicating findings
Author: Kadir Cetinkaya Date: 2023-05-01T12:19:33+02:00 New Revision: 5e74a3dc2da879d98204f2360e2e33571b93b91b URL: https://github.com/llvm/llvm-project/commit/5e74a3dc2da879d98204f2360e2e33571b93b91b DIFF: https://github.com/llvm/llvm-project/commit/5e74a3dc2da879d98204f2360e2e33571b93b91b.diff LOG: [clangd][IncludeCleaner] Use a proper comparator for deduplicating findings Previous one didn't have strict weak ordering guarantees. Added: Modified: clang-tools-extra/clangd/IncludeCleaner.cpp clang-tools-extra/clangd/test/include-cleaner-batch-fix.test Removed: diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index d3754de689eb0..3b913d851abe2 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -422,13 +422,17 @@ IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST ) { // times. llvm::stable_sort(MissingIncludes, [](const MissingIncludeDiagInfo , const MissingIncludeDiagInfo ) { -if (LHS.Symbol == RHS.Symbol) { +// First sort by reference location. +if (LHS.SymRefRange != RHS.SymRefRange) { // We can get away just by comparing the offsets as all the ranges are in // main file. return LHS.SymRefRange.beginOffset() < RHS.SymRefRange.beginOffset(); } -// If symbols are diff erent we don't care about the ordering. -return true; +// For the same location, break ties using the symbol. Note that this won't +// be stable across runs. +using MapInfo = llvm::DenseMapInfo; +return MapInfo::getHashValue(LHS.Symbol) < + MapInfo::getHashValue(RHS.Symbol); }); MissingIncludes.erase(llvm::unique(MissingIncludes), MissingIncludes.end()); std::vector UnusedIncludes = diff --git a/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test b/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test index 4b2208ba3e146..b7e9661b79b08 100644 --- a/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test +++ b/clang-tools-extra/clangd/test/include-cleaner-batch-fix.test @@ -33,14 +33,14 @@ # CHECK-NEXT: "diagnostics": [ # CHECK-NEXT: { # CHECK-NEXT: "code": "missing-includes", -# CHECK-NEXT: "message": "No header providing \"Bar\" is directly included (fixes available)", +# CHECK-NEXT: "message": "No header providing \"Foo\" is directly included (fixes available)", # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 14, +# CHECK-NEXT: "character": 4, # CHECK-NEXT: "line": 2 # CHECK-NEXT: }, # CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 11, +# CHECK-NEXT: "character": 1, # CHECK-NEXT: "line": 2 # CHECK-NEXT: } # CHECK-NEXT: }, @@ -49,14 +49,14 @@ # CHECK-NEXT: }, # CHECK-NEXT: { # CHECK-NEXT: "code": "missing-includes", -# CHECK-NEXT: "message": "No header providing \"Foo\" is directly included (fixes available)", +# CHECK-NEXT: "message": "No header providing \"Bar\" is directly included (fixes available)", # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 4, +# CHECK-NEXT: "character": 14, # CHECK-NEXT: "line": 2 # CHECK-NEXT: }, # CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 1, +# CHECK-NEXT: "character": 11, # CHECK-NEXT: "line": 2 # CHECK-NEXT: } # CHECK-NEXT: }, ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 08f0725 - [clangd] Deduplicate missing-include findings
Author: Kadir Cetinkaya Date: 2023-04-26T10:33:55+02:00 New Revision: 08f0725a3a5471d16b8a1e9d1d55b9952300ac41 URL: https://github.com/llvm/llvm-project/commit/08f0725a3a5471d16b8a1e9d1d55b9952300ac41 DIFF: https://github.com/llvm/llvm-project/commit/08f0725a3a5471d16b8a1e9d1d55b9952300ac41.diff LOG: [clangd] Deduplicate missing-include findings Differential Revision: https://reviews.llvm.org/D149165 Added: Modified: clang-tools-extra/clangd/IncludeCleaner.cpp clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp Removed: diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index d15dd70efdb70..b88ad0ff5c5b5 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -40,6 +40,7 @@ #include "clang/Tooling/Syntax/Tokens.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/GenericUniformityImpl.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/SmallString.h" @@ -415,6 +416,20 @@ IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST ) { Ref.Target, TouchingTokens.back().range(SM), Providers}; MissingIncludes.push_back(std::move(DiagInfo)); }); + // Put possibly equal diagnostics together for deduplication. + // The duplicates might be from macro arguments that get expanded multiple + // times. + llvm::stable_sort(MissingIncludes, [](const MissingIncludeDiagInfo , +const MissingIncludeDiagInfo ) { +if (LHS.Symbol == RHS.Symbol) { + // We can get away just by comparing the offsets as all the ranges are in + // main file. + return LHS.SymRefRange.beginOffset() < RHS.SymRefRange.beginOffset(); +} +// If symbols are diff erent we don't care about the ordering. +return true; + }); + MissingIncludes.erase(llvm::unique(MissingIncludes), MissingIncludes.end()); std::vector UnusedIncludes = getUnused(AST, Used, /*ReferencedPublicHeaders*/ {}); return {std::move(UnusedIncludes), std::move(MissingIncludes)}; diff --git a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp index 39901fda31656..32b7c5444e06f 100644 --- a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp +++ b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp @@ -403,15 +403,36 @@ TEST(IncludeCleaner, MacroExpandedThroughIncludes) { ParsedAST AST = TU.build(); auto Findings = computeIncludeCleanerFindings(AST).MissingIncludes; - // FIXME: Deduplicate references resulting from expansion of the same macro in - // multiple places. - EXPECT_THAT(Findings, testing::SizeIs(2)); + EXPECT_THAT(Findings, testing::SizeIs(1)); auto RefRange = Findings.front().SymRefRange; auto = AST.getSourceManager(); EXPECT_EQ(RefRange.file(), SM.getMainFileID()); // FIXME: Point at the spelling location, rather than the include. EXPECT_EQ(halfOpenToRange(SM, RefRange.toCharRange(SM)), MainFile.range()); - EXPECT_EQ(RefRange, Findings[1].SymRefRange); +} + +TEST(IncludeCleaner, MissingIncludesAreUnique) { + Annotations MainFile(R"cpp( +#include "all.h" +FOO([[Foo]]); + )cpp"); + + TestTU TU; + TU.AdditionalFiles["foo.h"] = guard("struct Foo {};"); + TU.AdditionalFiles["all.h"] = guard(R"cpp( +#include "foo.h" +#define FOO(X) X y; X z + )cpp"); + + TU.Code = MainFile.code(); + ParsedAST AST = TU.build(); + + auto Findings = computeIncludeCleanerFindings(AST).MissingIncludes; + EXPECT_THAT(Findings, testing::SizeIs(1)); + auto RefRange = Findings.front().SymRefRange; + auto = AST.getSourceManager(); + EXPECT_EQ(RefRange.file(), SM.getMainFileID()); + EXPECT_EQ(halfOpenToRange(SM, RefRange.toCharRange(SM)), MainFile.range()); } TEST(IncludeCleaner, NoCrash) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] cc5fb7a - [include-cleaner] Unify behaviour for static & instance members
Author: Kadir Cetinkaya Date: 2023-04-18T10:01:31+02:00 New Revision: cc5fb7a79b58d7e6509b74e1935850e3307bbdc7 URL: https://github.com/llvm/llvm-project/commit/cc5fb7a79b58d7e6509b74e1935850e3307bbdc7 DIFF: https://github.com/llvm/llvm-project/commit/cc5fb7a79b58d7e6509b74e1935850e3307bbdc7.diff LOG: [include-cleaner] Unify behaviour for static & instance members Fixes https://github.com/llvm/llvm-project/issues/62185 Differential Revision: https://reviews.llvm.org/D148552 Added: Modified: clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index e977bcbb402f7..4ea7bceeb96ed 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -125,7 +125,13 @@ class ASTWalker : public RecursiveASTVisitor { } bool VisitDeclRefExpr(DeclRefExpr *DRE) { -report(DRE->getLocation(), DRE->getFoundDecl()); +// Static class members are handled here, as they don't produce MemberExprs. +if (DRE->getFoundDecl()->isCXXClassMember()) { + if (auto *Qual = DRE->getQualifier()) +report(DRE->getLocation(), Qual->getAsRecordDecl(), RefType::Implicit); +} else { + report(DRE->getLocation(), DRE->getFoundDecl()); +} return true; } diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index 2060ffe3bb56c..ffe8bbffc3712 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -114,7 +114,7 @@ TEST(WalkAST, DeclRef) { testWalk("int $explicit^x;", "int y = ^x;"); testWalk("int $explicit^foo();", "int y = ^foo();"); testWalk("namespace ns { int $explicit^x; }", "int y = ns::^x;"); - testWalk("struct S { static int $explicit^x; };", "int y = S::^x;"); + testWalk("struct $implicit^S { static int x; };", "int y = S::^x;"); // Canonical declaration only. testWalk("extern int $explicit^x; int x;", "int y = ^x;"); // Return type of `foo` isn't used. @@ -342,6 +342,13 @@ TEST(WalkAST, TemplateNames) { } TEST(WalkAST, MemberExprs) { + testWalk("struct $implicit^S { static int f; };", "void foo() { S::^f; }"); + testWalk("struct B { static int f; }; struct $implicit^S : B {};", + "void foo() { S::^f; }"); + testWalk("struct B { static void f(); }; struct $implicit^S : B {};", + "void foo() { S::^f; }"); + testWalk("struct B { static void f(); }; ", + "struct S : B { void foo() { ^f(); } };"); testWalk("struct $implicit^S { void foo(); };", "void foo() { S{}.^foo(); }"); testWalk( "struct S { void foo(); }; struct $implicit^X : S { using S::foo; };", ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] f099f2f - [clangd] Use all inputs to SystemIncludeExtractor in cache key
Author: Kadir Cetinkaya Date: 2023-04-17T16:57:33+02:00 New Revision: f099f2fefbab0592c828573d816b46a475076f49 URL: https://github.com/llvm/llvm-project/commit/f099f2fefbab0592c828573d816b46a475076f49 DIFF: https://github.com/llvm/llvm-project/commit/f099f2fefbab0592c828573d816b46a475076f49.diff LOG: [clangd] Use all inputs to SystemIncludeExtractor in cache key Instead of passing in a tooling::CompileCommand into system include extraction, pass a limited set, whose elements are used as keys. Also fix the issue around accepting `-isysroot=/foo` which isn't a valid argument (or the directory should be `=/foo` not `/foo`). Fixes https://github.com/clangd/clangd/issues/1404 Fixes https://github.com/clangd/clangd/issues/1403 This should also unblock https://reviews.llvm.org/D138546 Differential Revision: https://reviews.llvm.org/D146941 Added: Modified: clang-tools-extra/clangd/SystemIncludeExtractor.cpp clang-tools-extra/clangd/test/system-include-extractor.test Removed: diff --git a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp index c334697e1e238..4d359b0058280 100644 --- a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp +++ b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp @@ -32,32 +32,44 @@ #include "CompileCommands.h" #include "GlobalCompilationDatabase.h" #include "support/Logger.h" -#include "support/Path.h" +#include "support/Threading.h" #include "support/Trace.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticIDs.h" +#include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Driver/Types.h" #include "clang/Tooling/CompilationDatabase.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Hashing.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" #include "llvm/Support/Regex.h" #include "llvm/Support/ScopedPrinter.h" -#include +#include "llvm/Support/raw_ostream.h" +#include +#include #include -#include +#include #include #include +#include +#include #include -namespace clang { -namespace clangd { +namespace clang::clangd { namespace { struct DriverInfo { @@ -65,12 +77,138 @@ struct DriverInfo { std::string Target; }; +struct DriverArgs { + // Name of the driver program to execute or absolute path to it. + std::string Driver; + // Whether certain includes should be part of query. + bool StandardIncludes = true; + bool StandardCXXIncludes = true; + bool BuiltinIncludes = true; + // Language to use while querying. + std::string Lang; + std::string Sysroot; + std::string ISysroot; + + bool operator==(const DriverArgs ) const { +return std::tie(Driver, StandardIncludes, StandardCXXIncludes, +BuiltinIncludes, Lang, Sysroot, ISysroot) == + std::tie(RHS.Driver, RHS.StandardIncludes, RHS.StandardCXXIncludes, +RHS.BuiltinIncludes, RHS.Lang, RHS.Sysroot, ISysroot); + } + + DriverArgs(const tooling::CompileCommand , llvm::StringRef File) { +llvm::SmallString<128> Driver(Cmd.CommandLine.front()); +// Driver is a not a single executable name but instead a path (either +// relative or absolute). +if (llvm::any_of(Driver, + [](char C) { return llvm::sys::path::is_separator(C); })) { + llvm::sys::fs::make_absolute(Cmd.Directory, Driver); +} +this->Driver = Driver.str().str(); +for (size_t I = 0, E = Cmd.CommandLine.size(); I < E; ++I) { + llvm::StringRef Arg = Cmd.CommandLine[I]; + + // Look for Language related flags. + if (Arg.consume_front("-x")) { +if (Arg.empty() && I + 1 < E) + Lang = Cmd.CommandLine[I + 1]; +else + Lang = Arg.str(); + } + // Look for standard/builtin includes. + else if (Arg == "-nostdinc" || Arg == "--no-standard-includes") +StandardIncludes = false; + else if (Arg == "-nostdinc++") +StandardCXXIncludes = false; + else if (Arg == "-nobuiltininc") +BuiltinIncludes = false; + // Figure out sysroot + else if (Arg.consume_front("--sysroot")) { +if (Arg.consume_front("=")) + Sysroot = Arg.str(); +else if (Arg.empty() && I + 1 < E) + Sysroot = Cmd.CommandLine[I + 1]; + } else if (Arg.consume_front("-isysroot")) { +if (Arg.empty() && I + 1 < E) + ISysroot = Cmd.CommandLine[I + 1]; +
[clang-tools-extra] 3d6d2ae - [include-cleaner] Handle incomplete template specializations
Author: Kadir Cetinkaya Date: 2023-04-13T13:34:12+02:00 New Revision: 3d6d2ae6f490f0698e3d4727ae44db34b30ea33e URL: https://github.com/llvm/llvm-project/commit/3d6d2ae6f490f0698e3d4727ae44db34b30ea33e DIFF: https://github.com/llvm/llvm-project/commit/3d6d2ae6f490f0698e3d4727ae44db34b30ea33e.diff LOG: [include-cleaner] Handle incomplete template specializations Instantiation pattern is null for incomplete template types and using specializaiton decl results in not seeing re-declarations. Differential Revision: https://reviews.llvm.org/D148158 Added: Modified: clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index 25afdaa3a75b0..e977bcbb402f7 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -21,6 +21,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/Support/Casting.h" @@ -81,9 +82,10 @@ class ASTWalker : public RecursiveASTVisitor { if (llvm::isa_and_present(ND)) return ND; // This is the underlying decl used by TemplateSpecializationType, can be -// null when type is dependent if so fallback to primary template. +// null when type is dependent or not resolved to a pattern yet. +// If so, fallback to primary template. CXXRecordDecl *TD = TST->getAsCXXRecordDecl(); -if (!TD) +if (!TD || TD->getTemplateSpecializationKind() == TSK_Undeclared) return ND; // We ignore explicit instantiations. This might imply marking the wrong // declaration as used in specific cases, but seems like the right trade-off diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index ad5bb0aba3076..2060ffe3bb56c 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -144,6 +144,9 @@ TEST(WalkAST, ClassTemplates) { ElementsAre(Decl::CXXRecord)); // Implicit instantiations references most relevant template. + EXPECT_THAT( + testWalk("template struct $explicit^Foo;", "^Foo x();"), + ElementsAre(Decl::Kind::ClassTemplate)); EXPECT_THAT( testWalk("template struct $explicit^Foo {};", "^Foo x;"), ElementsAre(Decl::CXXRecord)); @@ -154,9 +157,15 @@ TEST(WalkAST, ClassTemplates) { ElementsAre(Decl::ClassTemplateSpecialization)); EXPECT_THAT(testWalk(R"cpp( template struct Foo {}; -template struct $explicit^Foo { void x(); };)cpp", +template struct $explicit^Foo {};)cpp", "^Foo x;"), ElementsAre(Decl::ClassTemplatePartialSpecialization)); + // Incomplete instantiations don't have a specific specialization associated. + EXPECT_THAT(testWalk(R"cpp( +template struct $explicit^Foo; +template struct Foo;)cpp", + "^Foo x();"), + ElementsAre(Decl::Kind::ClassTemplate)); EXPECT_THAT(testWalk(R"cpp( template struct $explicit^Foo {}; template struct Foo;)cpp", ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 144562e - [clangd] Treat preamble patch as main file for include-cleaner analysis
Author: Kadir Cetinkaya Date: 2023-04-12T21:03:21+02:00 New Revision: 144562e678d932dc2685f8a83aeb2229bc96d71a URL: https://github.com/llvm/llvm-project/commit/144562e678d932dc2685f8a83aeb2229bc96d71a DIFF: https://github.com/llvm/llvm-project/commit/144562e678d932dc2685f8a83aeb2229bc96d71a.diff LOG: [clangd] Treat preamble patch as main file for include-cleaner analysis Since we redefine all macros in preamble-patch, and it's parsed after consuming the preamble macros, we can get false missing-include diagnostics while a fresh preamble is being rebuilt. This patch makes sure preamble-patch is treated same as main file for include-cleaner purposes. Differential Revision: https://reviews.llvm.org/D148143 Added: Modified: clang-tools-extra/clangd/IncludeCleaner.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/unittests/PreambleTests.cpp Removed: diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index ee645efa6e6e1..e645b1cce6a09 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -11,6 +11,7 @@ #include "Diagnostics.h" #include "Headers.h" #include "ParsedAST.h" +#include "Preamble.h" #include "Protocol.h" #include "SourceCode.h" #include "URI.h" @@ -112,12 +113,12 @@ static bool mayConsiderUnused(const Inclusion , ParsedAST , return false; // Check if main file is the public interface for a private header. If so we // shouldn't diagnose it as unused. -if(auto PHeader = PI->getPublic(*FE); !PHeader.empty()) { +if (auto PHeader = PI->getPublic(*FE); !PHeader.empty()) { PHeader = PHeader.trim("<>\""); // Since most private -> public mappings happen in a verbatim way, we // check textually here. This might go wrong in presence of symlinks or // header mappings. But that's not diff erent than rest of the places. - if(AST.tuPath().endswith(PHeader)) + if (AST.tuPath().endswith(PHeader)) return false; } } @@ -360,6 +361,7 @@ IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST ) { include_cleaner::Includes ConvertedIncludes = convertIncludes(SM, Includes.MainFileIncludes); const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID()); + auto *PreamblePatch = PreamblePatch::getPatchEntry(AST.tuPath(), SM); std::vector Macros = collectMacroReferences(AST); @@ -374,7 +376,7 @@ IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST ) { bool Satisfied = false; for (const auto : Providers) { if (H.kind() == include_cleaner::Header::Physical && - H.physical() == MainFile) { + (H.physical() == MainFile || H.physical() == PreamblePatch)) { Satisfied = true; continue; } diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index 08662697a4a5c..ea060bed03922 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -738,6 +738,14 @@ static std::vector patchDiags(llvm::ArrayRef BaselineDiags, return PatchedDiags; } +static std::string getPatchName(llvm::StringRef FileName) { + // This shouldn't coincide with any real file name. + llvm::SmallString<128> PatchName; + llvm::sys::path::append(PatchName, llvm::sys::path::parent_path(FileName), + PreamblePatch::HeaderName); + return PatchName.str().str(); +} + PreamblePatch PreamblePatch::create(llvm::StringRef FileName, const ParseInputs , const PreambleData , @@ -776,11 +784,7 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName, PreamblePatch PP; PP.Baseline = - // This shouldn't coincide with any real file name. - llvm::SmallString<128> PatchName; - llvm::sys::path::append(PatchName, llvm::sys::path::parent_path(FileName), - PreamblePatch::HeaderName); - PP.PatchFileName = PatchName.str().str(); + PP.PatchFileName = getPatchName(FileName); PP.ModifiedBounds = ModifiedScan->Bounds; llvm::raw_string_ostream Patch(PP.PatchContents); @@ -921,5 +925,13 @@ const MainFileMacros ::mainFileMacros() const { return Baseline->Macros; return PatchedMacros; } + +const FileEntry *PreamblePatch::getPatchEntry(llvm::StringRef MainFilePath, + const SourceManager ) { + auto PatchFilePath = getPatchName(MainFilePath); + if (auto File = SM.getFileManager().getFile(PatchFilePath)) +return *File; + return nullptr; +} } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/Preamble.h b/clang-tools-extra/clangd/Preamble.h index
[clang-tools-extra] caea93c - [icnlude-cleaner] Fix dandling pointers in tests
Author: Kadir Cetinkaya Date: 2023-04-12T20:30:33+02:00 New Revision: caea93cc4478cca28321cba4fa2871d5e6090299 URL: https://github.com/llvm/llvm-project/commit/caea93cc4478cca28321cba4fa2871d5e6090299 DIFF: https://github.com/llvm/llvm-project/commit/caea93cc4478cca28321cba4fa2871d5e6090299.diff LOG: [icnlude-cleaner] Fix dandling pointers in tests Added: Modified: clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index 264bedf2e9ac7..ad5bb0aba3076 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -16,7 +16,6 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Frontend/TextDiagnostic.h" #include "clang/Testing/TestAST.h" -#include "llvm/ADT/GenericUniformityImpl.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" @@ -42,8 +41,8 @@ using testing::ElementsAre; // Referencing: int x = ^foo(); // There must be exactly one referencing location marked. // Returns target decls. -std::vector testWalk(llvm::StringRef TargetCode, - llvm::StringRef ReferencingCode) { +std::vector testWalk(llvm::StringRef TargetCode, + llvm::StringRef ReferencingCode) { llvm::Annotations Target(TargetCode); llvm::Annotations Referencing(ReferencingCode); @@ -63,7 +62,7 @@ std::vector testWalk(llvm::StringRef TargetCode, FileID TargetFile = SM.translateFile( llvm::cantFail(AST.fileManager().getFileRef("target.h"))); - std::vector TargetDecls; + std::vector TargetDecls; // Perform the walk, and capture the offsets of the referenced targets. std::unordered_map> ReferencedOffsets; for (Decl *D : AST.context().getTranslationUnitDecl()->decls()) { @@ -76,7 +75,7 @@ std::vector testWalk(llvm::StringRef TargetCode, if (NDLoc.first != TargetFile) return; ReferencedOffsets[RT].push_back(NDLoc.second); - TargetDecls.push_back(); + TargetDecls.push_back(ND.getKind()); }); } for (auto : ReferencedOffsets) @@ -131,52 +130,45 @@ TEST(WalkAST, TagType) { testWalk("struct $explicit^$implicit^S { static int x; };", "auto y = ^S();"); } -MATCHER_P(HasKind, Kind, "") { - if (arg->getKind() == Kind) -return true; - *result_listener << "Got kind: " << arg->getDeclKindName(); - return false; -} - TEST(WalkAST, ClassTemplates) { // Explicit instantiation and (partial) specialization references primary // template. EXPECT_THAT(testWalk("template struct $explicit^Foo{};", "template struct ^Foo;"), - ElementsAre(HasKind(Decl::CXXRecord))); + ElementsAre(Decl::CXXRecord)); EXPECT_THAT(testWalk("template struct $explicit^Foo{};", "template<> struct ^Foo {};"), - ElementsAre(HasKind(Decl::CXXRecord))); + ElementsAre(Decl::CXXRecord)); EXPECT_THAT(testWalk("template struct $explicit^Foo{};", "template struct ^Foo {};"), - ElementsAre(HasKind(Decl::CXXRecord))); + ElementsAre(Decl::CXXRecord)); // Implicit instantiations references most relevant template. EXPECT_THAT( testWalk("template struct $explicit^Foo {};", "^Foo x;"), - ElementsAre(HasKind(Decl::CXXRecord))); + ElementsAre(Decl::CXXRecord)); EXPECT_THAT(testWalk(R"cpp( template struct Foo {}; template<> struct $explicit^Foo {};)cpp", "^Foo x;"), - ElementsAre(HasKind(Decl::ClassTemplateSpecialization))); + ElementsAre(Decl::ClassTemplateSpecialization)); EXPECT_THAT(testWalk(R"cpp( template struct Foo {}; template struct $explicit^Foo { void x(); };)cpp", "^Foo x;"), - ElementsAre(HasKind(Decl::ClassTemplatePartialSpecialization))); + ElementsAre(Decl::ClassTemplatePartialSpecialization)); EXPECT_THAT(testWalk(R"cpp( template struct $explicit^Foo {}; template struct Foo;)cpp", "^Foo x;"), - ElementsAre(HasKind(Decl::CXXRecord))); + ElementsAre(Decl::CXXRecord)); // FIXME: This is broken due to // https://github.com/llvm/llvm-project/issues/42259. EXPECT_THAT(testWalk(R"cpp( template struct $explicit^Foo { Foo(T); }; template<> struct Foo { Foo(int); };)cpp", "^Foo x(3);"), - ElementsAre(HasKind(Decl::ClassTemplate))); + ElementsAre(Decl::ClassTemplate)); } TEST(WalkAST, VarTemplates) { // Explicit instantiation and (partial) specialization references primary @@ -188,10 +180,10 @@ TEST(WalkAST,
[clang-tools-extra] 34f5774 - [include-cleaner] Improve handling for templates
Author: Kadir Cetinkaya Date: 2023-04-12T17:36:05+02:00 New Revision: 34f5774920f54f81b3e3a361a7c7f21a61e39b39 URL: https://github.com/llvm/llvm-project/commit/34f5774920f54f81b3e3a361a7c7f21a61e39b39 DIFF: https://github.com/llvm/llvm-project/commit/34f5774920f54f81b3e3a361a7c7f21a61e39b39.diff LOG: [include-cleaner] Improve handling for templates Principal here is: - Making sure each template instantiation implies use of the most specialized template. As explicit instantiations/specializations are not redeclarations of the primary template. - Introducing a use from explicit instantions/specializaitons to the primary template, as they're required but not traversed as part of the RAV. Differential Revision: https://reviews.llvm.org/D148112 Added: Modified: clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index f702460ccbb22..25afdaa3a75b0 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -8,8 +8,10 @@ #include "AnalysisInternal.h" #include "clang-include-cleaner/Types.h" +#include "clang/AST/ASTFwd.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/RecursiveASTVisitor.h" @@ -72,17 +74,25 @@ class ASTWalker : public RecursiveASTVisitor { // Picks the most specific specialization for a // (Deduced)TemplateSpecializationType, while prioritizing using-decls. NamedDecl *getMostRelevantTemplatePattern(const T *TST) { -// This is the underlying decl used by TemplateSpecializationType, can be -// null when type is dependent. -auto *RD = TST->getAsTagDecl(); -auto *ND = resolveTemplateName(TST->getTemplateName()); // In case of exported template names always prefer the using-decl. This // implies we'll point at the using-decl even when there's an explicit // specializaiton using the exported name, but that's rare. +auto *ND = resolveTemplateName(TST->getTemplateName()); if (llvm::isa_and_present(ND)) return ND; -// Fallback to primary template for dependent instantiations. -return RD ? RD : ND; +// This is the underlying decl used by TemplateSpecializationType, can be +// null when type is dependent if so fallback to primary template. +CXXRecordDecl *TD = TST->getAsCXXRecordDecl(); +if (!TD) + return ND; +// We ignore explicit instantiations. This might imply marking the wrong +// declaration as used in specific cases, but seems like the right trade-off +// in general (e.g. we don't want to include a custom library that has an +// explicit specialization of a common type). +if (auto *Pat = TD->getTemplateInstantiationPattern()) + return Pat; +// For explicit specializations, use the specialized decl directly. +return TD; } public: @@ -182,6 +192,23 @@ class ASTWalker : public RecursiveASTVisitor { return true; } + // Report a reference from explicit specializations to the specialized + // template. Implicit ones are filtered out by RAV and explicit instantiations + // are already traversed through typelocs. + bool + VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *CTSD) { +if (CTSD->isExplicitSpecialization()) + report(CTSD->getLocation(), + CTSD->getSpecializedTemplate()->getTemplatedDecl()); +return true; + } + bool VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *VTSD) { +if (VTSD->isExplicitSpecialization()) + report(VTSD->getLocation(), + VTSD->getSpecializedTemplate()->getTemplatedDecl()); +return true; + } + // TypeLoc visitors. bool VisitUsingTypeLoc(UsingTypeLoc TL) { report(TL.getNameLoc(), TL.getFoundDecl()); diff --git a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp index dc649b1392294..8593d05a1b12d 100644 --- a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp @@ -16,11 +16,11 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" +#include "clang/Format/Format.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Testing/TestAST.h" #include "clang/Tooling/Inclusions/StandardLibrary.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ScopedPrinter.h"
[clang-tools-extra] 3402b77 - [include-cleaner] Only ignore builtins without a header
Author: Kadir Cetinkaya Date: 2023-04-04T13:28:56+02:00 New Revision: 3402b77db3ee83f0c576988631afa12cfba61285 URL: https://github.com/llvm/llvm-project/commit/3402b77db3ee83f0c576988631afa12cfba61285 DIFF: https://github.com/llvm/llvm-project/commit/3402b77db3ee83f0c576988631afa12cfba61285.diff LOG: [include-cleaner] Only ignore builtins without a header Certain standard library functions (e.g. std::move) are also implemented as builtins. This patch moves filtering logic to the symbol->header mapping phase to rather generate these references without any providers only when we don't have a mapping. That way we can also map them to header names mentioned in the builtin mappings. Differential Revision: https://reviews.llvm.org/D147449 Added: Modified: clang-tools-extra/include-cleaner/lib/FindHeaders.cpp clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp index e273d429cd8c3..1b705e1d52c2d 100644 --- a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp +++ b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp @@ -10,18 +10,21 @@ #include "TypesInternal.h" #include "clang-include-cleaner/Record.h" #include "clang-include-cleaner/Types.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/FileEntry.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Tooling/Inclusions/StandardLibrary.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" -#include +#include #include namespace clang::include_cleaner { @@ -106,37 +109,68 @@ hintedHeadersForStdHeaders(llvm::ArrayRef Headers, return Results; } -// Special-case the ambiguous standard library symbols (e.g. std::move) which -// are not supported by the tooling stdlib lib. -llvm::SmallVector> -headersForSpecialSymbol(const Symbol , const SourceManager , -const PragmaIncludes *PI) { - if (S.kind() != Symbol::Declaration || !S.declaration().isInStdNamespace()) +// Symbol to header mapping for std::move and std::remove, based on number of +// parameters. +std::optional +headerForAmbiguousStdSymbol(const NamedDecl *ND) { + if (!ND->isInStdNamespace()) return {}; - - const auto *FD = S.declaration().getAsFunction(); + const auto *FD = ND->getAsFunction(); if (!FD) -return {}; - - llvm::StringRef FName = symbolName(S); - llvm::SmallVector Headers; +return std::nullopt; + llvm::StringRef FName = symbolName(*ND); if (FName == "move") { if (FD->getNumParams() == 1) // move(T&& t) - Headers.push_back(*tooling::stdlib::Header::named("")); + return tooling::stdlib::Header::named(""); if (FD->getNumParams() == 3) // move(InputIt first, InputIt last, OutputIt dest); - Headers.push_back(*tooling::stdlib::Header::named("")); + return tooling::stdlib::Header::named(""); } else if (FName == "remove") { if (FD->getNumParams() == 1) // remove(const char*); - Headers.push_back(*tooling::stdlib::Header::named("")); + return tooling::stdlib::Header::named(""); if (FD->getNumParams() == 3) // remove(ForwardIt first, ForwardIt last, const T& value); - Headers.push_back(*tooling::stdlib::Header::named("")); + return tooling::stdlib::Header::named(""); } - return applyHints(hintedHeadersForStdHeaders(Headers, SM, PI), -Hints::CompleteSymbol); + return std::nullopt; +} + +// Special-case symbols without proper locations, like the ambiguous standard +// library symbols (e.g. std::move) or builtin declarations. +std::optional>> +headersForSpecialSymbol(const Symbol , const SourceManager , +const PragmaIncludes *PI) { + // Our special casing logic only deals with decls, so bail out early for + // macros. + if (S.kind() != Symbol::Declaration) +return std::nullopt; + const auto *ND = llvm::cast(()); + // We map based on names, so again bail out early if there are no names. + if (!ND) +return std::nullopt; + auto *II = ND->getIdentifier(); + if (!II) +return std::nullopt; + + // Check first for symbols that are part of our stdlib mapping. As we have + // header names for those. + if (auto Header = headerForAmbiguousStdSymbol(ND)) { +return applyHints(hintedHeadersForStdHeaders({*Header}, SM, PI), + Hints::CompleteSymbol); + } + + // Now check for builtin symbols, we
[clang-tools-extra] f323e7f - [include-cleaner] Treat member operator calls as implicit
Author: Kadir Cetinkaya Date: 2023-04-03T16:27:23+02:00 New Revision: f323e7f3ca760be786d2584c926edade34c3fbde URL: https://github.com/llvm/llvm-project/commit/f323e7f3ca760be786d2584c926edade34c3fbde DIFF: https://github.com/llvm/llvm-project/commit/f323e7f3ca760be786d2584c926edade34c3fbde.diff LOG: [include-cleaner] Treat member operator calls as implicit 26ff268b80c589fd9f71c1c214af77cd972642ca treated member operator calls as explicit, while trying to treat them the same way as regular member expressions, which should've been implicit. Added: Modified: clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index 8a1dd77176cd..ab1476ea0997 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -95,14 +95,15 @@ class ASTWalker : public RecursiveASTVisitor { // to them doesn't count as uses (generally the type should provide them, so // ignore them). // Unless we're using an operator defined as a member, in such cases treat - // this as a regular reference. + // these as regular member references. bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) { if (!WalkUpFromCXXOperatorCallExpr(S)) return false; if (auto *CD = S->getCalleeDecl()) { if (llvm::isa(CD)) { // Treat this as a regular member reference. -report(S->getOperatorLoc(), getMemberProvider(S->getArg(0)->getType())); +report(S->getOperatorLoc(), getMemberProvider(S->getArg(0)->getType()), + RefType::Implicit); } else { report(S->getOperatorLoc(), llvm::dyn_cast(CD), RefType::Implicit); diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index fceec670076c..ac2085d82c1d 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -296,12 +296,12 @@ TEST(WalkAST, Operator) { testWalk( "struct string { friend int $implicit^operator+(string, string); }; ", "int k = string() ^+ string();"); - // Unless they're members, we treat them as regular member expr calls. - testWalk("struct $explicit^string {int operator+(string); }; ", + // Treat member operators as regular member expr calls. + testWalk("struct $implicit^string {int operator+(string); }; ", "int k = string() ^+ string();"); // Make sure usage is attributed to the alias. testWalk( - "struct string {int operator+(string); }; using $explicit^foo = string;", + "struct string {int operator+(string); }; using $implicit^foo = string;", "int k = foo() ^+ string();"); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 26ff268 - [include-cleaner] Report references to operator calls as implicit
Author: Kadir Cetinkaya Date: 2023-04-03T15:49:28+02:00 New Revision: 26ff268b80c589fd9f71c1c214af77cd972642ca URL: https://github.com/llvm/llvm-project/commit/26ff268b80c589fd9f71c1c214af77cd972642ca DIFF: https://github.com/llvm/llvm-project/commit/26ff268b80c589fd9f71c1c214af77cd972642ca.diff LOG: [include-cleaner] Report references to operator calls as implicit Missing these references can result in false negatives in the used-ness analysis and break builds. Differential Revision: https://reviews.llvm.org/D147144 Added: Modified: clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index b10c722b6653a..8a1dd77176cdf 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -91,14 +91,23 @@ class ASTWalker : public RecursiveASTVisitor { public: ASTWalker(DeclCallback Callback) : Callback(Callback) {} + // Operators are almost always ADL extension points and by design references + // to them doesn't count as uses (generally the type should provide them, so + // ignore them). + // Unless we're using an operator defined as a member, in such cases treat + // this as a regular reference. bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) { if (!WalkUpFromCXXOperatorCallExpr(S)) return false; - -// Operators are always ADL extension points, by design references to them -// doesn't count as uses (generally the type should provide them). -// Don't traverse the callee. - +if (auto *CD = S->getCalleeDecl()) { + if (llvm::isa(CD)) { +// Treat this as a regular member reference. +report(S->getOperatorLoc(), getMemberProvider(S->getArg(0)->getType())); + } else { +report(S->getOperatorLoc(), llvm::dyn_cast(CD), + RefType::Implicit); + } +} for (auto *Arg : S->arguments()) if (!TraverseStmt(Arg)) return false; diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index fd6c6da9d5509..fceec670076c9 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -291,13 +291,18 @@ TEST(WalkAST, ConstructExprs) { } TEST(WalkAST, Operator) { - // References to operators are not counted as uses. - testWalk("struct string {}; int operator+(string, string);", - "int k = string() ^+ string();"); - testWalk("struct string {int operator+(string); }; ", - "int k = string() ^+ string();"); - testWalk("struct string { friend int operator+(string, string); }; ", + // Operator calls are marked as implicit references as they're ADL-used and + // type should be providing them. + testWalk( + "struct string { friend int $implicit^operator+(string, string); }; ", + "int k = string() ^+ string();"); + // Unless they're members, we treat them as regular member expr calls. + testWalk("struct $explicit^string {int operator+(string); }; ", "int k = string() ^+ string();"); + // Make sure usage is attributed to the alias. + testWalk( + "struct string {int operator+(string); }; using $explicit^foo = string;", + "int k = foo() ^+ string();"); } TEST(WalkAST, VarDecls) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] f3a815a - [clangd] Map references from include'd files to directives
Author: Kadir Cetinkaya Date: 2023-03-30T12:06:22+02:00 New Revision: f3a815aa776f42c4f4b80fc8d19a69ff1b359906 URL: https://github.com/llvm/llvm-project/commit/f3a815aa776f42c4f4b80fc8d19a69ff1b359906 DIFF: https://github.com/llvm/llvm-project/commit/f3a815aa776f42c4f4b80fc8d19a69ff1b359906.diff LOG: [clangd] Map references from include'd files to directives Differential Revision: https://reviews.llvm.org/D147139 Added: Modified: clang-tools-extra/clangd/IncludeCleaner.cpp clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp Removed: diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index fb245593b2f94..ee645efa6e6e1 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -51,9 +51,11 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" #include "llvm/Support/Regex.h" +#include #include #include #include +#include #include namespace clang { @@ -266,7 +268,6 @@ std::vector generateUnusedIncludeDiagnostics( } } // namespace - std::vector collectMacroReferences(ParsedAST ) { const auto = AST.getSourceManager(); @@ -398,6 +399,10 @@ IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST ) { // FIXME: Use presumed locations to map such usages back to patched // locations safely. auto Loc = SM.getFileLoc(Ref.RefLocation); +// File locations can be outside of the main file if macro is expanded +// through an #include. +while (SM.getFileID(Loc) != SM.getMainFileID()) + Loc = SM.getIncludeLoc(SM.getFileID(Loc)); const auto *Token = AST.getTokens().spelledTokenAt(Loc); MissingIncludeDiagInfo DiagInfo{Ref.Target, Token->range(SM), Providers}; diff --git a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp index de45da02bfe87..c0c15cd0db8e5 100644 --- a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp +++ b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp @@ -384,6 +384,35 @@ TEST(IncludeCleaner, UmbrellaUsesPrivate) { EXPECT_THAT(Findings.UnusedIncludes, IsEmpty()); } +TEST(IncludeCleaner, MacroExpandedThroughIncludes) { + Annotations MainFile(R"cpp( + #include "all.h" + #define FOO(X) const Foo *X + void foo() { + #include [["expander.inc"]] + } +)cpp"); + + TestTU TU; + TU.AdditionalFiles["expander.inc"] = guard("FOO(f1);FOO(f2);"); + TU.AdditionalFiles["foo.h"] = guard("struct Foo {};"); + TU.AdditionalFiles["all.h"] = guard("#include \"foo.h\""); + + TU.Code = MainFile.code(); + ParsedAST AST = TU.build(); + + auto Findings = computeIncludeCleanerFindings(AST).MissingIncludes; + // FIXME: Deduplicate references resulting from expansion of the same macro in + // multiple places. + EXPECT_THAT(Findings, testing::SizeIs(2)); + auto RefRange = Findings.front().SymRefRange; + auto = AST.getSourceManager(); + EXPECT_EQ(RefRange.file(), SM.getMainFileID()); + // FIXME: Point at the spelling location, rather than the include. + EXPECT_EQ(halfOpenToRange(SM, RefRange.toCharRange(SM)), MainFile.range()); + EXPECT_EQ(RefRange, Findings[1].SymRefRange); +} + } // namespace } // namespace clangd } // namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] f5b6e9b - [include-cleaner] Fix crash on unresolved headers
Author: Kadir Cetinkaya Date: 2023-03-26T16:37:56+02:00 New Revision: f5b6e9b6d355866c2aa4e440438b870885ec0373 URL: https://github.com/llvm/llvm-project/commit/f5b6e9b6d355866c2aa4e440438b870885ec0373 DIFF: https://github.com/llvm/llvm-project/commit/f5b6e9b6d355866c2aa4e440438b870885ec0373.diff LOG: [include-cleaner] Fix crash on unresolved headers Make sure unresolved headers are not analyzed as part of unused includes. Also introduces a testing fixture for analyze tests Differential Revision: https://reviews.llvm.org/D146916 Added: Modified: clang-tools-extra/include-cleaner/lib/Analysis.cpp clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/Analysis.cpp b/clang-tools-extra/include-cleaner/lib/Analysis.cpp index fb0879b7aab63..58402cce0b717 100644 --- a/clang-tools-extra/include-cleaner/lib/Analysis.cpp +++ b/clang-tools-extra/include-cleaner/lib/Analysis.cpp @@ -10,7 +10,6 @@ #include "AnalysisInternal.h" #include "clang-include-cleaner/Record.h" #include "clang-include-cleaner/Types.h" -#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/Basic/SourceManager.h" @@ -19,9 +18,13 @@ #include "clang/Tooling/Core/Replacement.h" #include "clang/Tooling/Inclusions/StandardLibrary.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/Support/Error.h" +#include namespace clang::include_cleaner { @@ -91,7 +94,7 @@ AnalysisResults analyze(llvm::ArrayRef ASTRoots, AnalysisResults Results; for (const Include : Inc.all()) { -if (Used.contains()) +if (Used.contains() || !I.Resolved) continue; if (PI) { if (PI->shouldKeep(I.Line)) diff --git a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp index a2084d4f37903..fc7d14582f632 100644 --- a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp @@ -8,22 +8,28 @@ #include "clang-include-cleaner/Analysis.h" #include "AnalysisInternal.h" +#include "TypesInternal.h" #include "clang-include-cleaner/Record.h" #include "clang-include-cleaner/Types.h" #include "clang/AST/ASTContext.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Testing/TestAST.h" #include "clang/Tooling/Inclusions/StandardLibrary.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Testing/Annotations/Annotations.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include +#include +#include #include namespace clang::include_cleaner { @@ -178,8 +184,31 @@ TEST_F(WalkUsedTest, MacroRefs) { Pair(Code.point("2"), UnorderedElementsAre(HdrFile; } -TEST(Analyze, Basic) { +class AnalyzeTest : public testing::Test { +protected: TestInputs Inputs; + PragmaIncludes PI; + RecordedPP PP; + AnalyzeTest() { +Inputs.MakeAction = [this] { + struct Hook : public SyntaxOnlyAction { + public: +Hook(RecordedPP , PragmaIncludes ) : PP(PP), PI(PI) {} +bool BeginSourceFileAction(clang::CompilerInstance ) override { + CI.getPreprocessor().addPPCallbacks(PP.record(CI.getPreprocessor())); + PI.record(CI); + return true; +} + +RecordedPP +PragmaIncludes + }; + return std::make_unique(PP, PI); +}; + } +}; + +TEST_F(AnalyzeTest, Basic) { Inputs.Code = R"cpp( #include "a.h" #include "b.h" @@ -194,53 +223,41 @@ int x = a + c; )cpp"); Inputs.ExtraFiles["c.h"] = guard("int c;"); Inputs.ExtraFiles["keep.h"] = guard(""); + TestAST AST(Inputs); + auto Decls = AST.context().getTranslationUnitDecl()->decls(); + auto Results = + analyze(std::vector{Decls.begin(), Decls.end()}, + PP.MacroReferences, PP.Includes, , AST.sourceManager(), + AST.preprocessor().getHeaderSearchInfo()); - RecordedPP PP; - PragmaIncludes PI; - Inputs.MakeAction = [, ] { -struct Hook : public SyntaxOnlyAction { -public: - Hook(RecordedPP , PragmaIncludes ) : PP(PP), PI(PI) {} - bool BeginSourceFileAction(clang::CompilerInstance ) override { -CI.getPreprocessor().addPPCallbacks(PP.record(CI.getPreprocessor())); -PI.record(CI); -return true; - } - - RecordedPP - PragmaIncludes -}; -return std::make_unique(PP,
[clang-tools-extra] 03101e1 - [include-cleaner] Attribute references to explicit specializations
Author: Kadir Cetinkaya Date: 2023-03-24T11:39:21+01:00 New Revision: 03101e141bf745f036be604e2a5a7c085eb02f5e URL: https://github.com/llvm/llvm-project/commit/03101e141bf745f036be604e2a5a7c085eb02f5e DIFF: https://github.com/llvm/llvm-project/commit/03101e141bf745f036be604e2a5a7c085eb02f5e.diff LOG: [include-cleaner] Attribute references to explicit specializations Fixes https://github.com/llvm/llvm-project/issues/61652 Differential Revision: https://reviews.llvm.org/D146732 Added: Modified: clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index 0ca84145721a6..e70a24367d6a9 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -7,16 +7,19 @@ //===--===// #include "AnalysisInternal.h" +#include "clang-include-cleaner/Types.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/Support/Casting.h" namespace clang::include_cleaner { @@ -62,6 +65,24 @@ class ASTWalker : public RecursiveASTVisitor { return resolveTemplateName(TST->getTemplateName()); return Base->getAsRecordDecl(); } + // Templated as TemplateSpecializationType and + // DeducedTemplateSpecializationType doesn't share a common base. + template + // Picks the most specific specialization for a + // (Deduced)TemplateSpecializationType, while prioritizing using-decls. + NamedDecl *getMostRelevantTemplatePattern(const T *TST) { +// This is the underlying decl used by TemplateSpecializationType, can be +// null when type is dependent. +auto *RD = TST->getAsTagDecl(); +auto *ND = resolveTemplateName(TST->getTemplateName()); +// In case of exported template names always prefer the using-decl. This +// implies we'll point at the using-decl even when there's an explicit +// specializaiton using the exported name, but that's rare. +if (llvm::isa_and_present(ND)) + return ND; +// Fallback to primary template for dependent instantiations. +return RD ? RD : ND; + } public: ASTWalker(DeclCallback Callback) : Callback(Callback) {} @@ -161,17 +182,15 @@ class ASTWalker : public RecursiveASTVisitor { } bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) { -// FIXME: Handle explicit specializations. report(TL.getTemplateNameLoc(), - resolveTemplateName(TL.getTypePtr()->getTemplateName())); + getMostRelevantTemplatePattern(TL.getTypePtr())); return true; } bool VisitDeducedTemplateSpecializationTypeLoc( DeducedTemplateSpecializationTypeLoc TL) { -// FIXME: Handle specializations. report(TL.getTemplateNameLoc(), - resolveTemplateName(TL.getTypePtr()->getTemplateName())); + getMostRelevantTemplatePattern(TL.getTypePtr())); return true; } diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index 68b6b217a2e01..8fcc2b5886ae4 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -114,6 +114,25 @@ TEST(WalkAST, TagType) { // One explicit call from the TypeLoc in constructor spelling, another // implicit reference through the constructor call. testWalk("struct $explicit^$implicit^S { static int x; };", "auto y = ^S();"); + testWalk("template struct $explicit^Foo {};", "^Foo x;"); + testWalk(R"cpp( +template struct Foo {}; +template<> struct $explicit^Foo {};)cpp", + "^Foo x;"); + testWalk(R"cpp( +template struct Foo {}; +template struct $explicit^Foo { void x(); };)cpp", + "^Foo x;"); + testWalk(R"cpp( +template struct Foo {}; +template struct $explicit^Foo;)cpp", + "^Foo x;"); + // FIXME: This is broken due to + // https://github.com/llvm/llvm-project/issues/42259. + testWalk(R"cpp( +template struct $explicit^Foo { Foo(T); }; +template<> struct Foo { void get(); Foo(int); };)cpp", + "^Foo x(3);"); } TEST(WalkAST, Alias) { @@ -124,6 +143,25 @@ TEST(WalkAST, Alias) { "int y = ^x;"); testWalk("using $explicit^foo = int;", "^foo x;"); testWalk("struct S {}; using $explicit^foo = S;", "^foo
[clang] 43fcfdb - [IncludeCleaner][clangd] Mark umbrella headers as users of private
Author: Kadir Cetinkaya Date: 2023-03-23T13:08:07+01:00 New Revision: 43fcfdb1d6a63129ffbb7d77174ccb56863d0b30 URL: https://github.com/llvm/llvm-project/commit/43fcfdb1d6a63129ffbb7d77174ccb56863d0b30 DIFF: https://github.com/llvm/llvm-project/commit/43fcfdb1d6a63129ffbb7d77174ccb56863d0b30.diff LOG: [IncludeCleaner][clangd] Mark umbrella headers as users of private Private headers inside umbrella files shouldn't be marked as unused. Differential Revision: https://reviews.llvm.org/D146406 Added: Modified: clang-tools-extra/clangd/IncludeCleaner.cpp clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp clang-tools-extra/include-cleaner/lib/Analysis.cpp clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp clang/include/clang/Testing/TestAST.h clang/lib/Testing/TestAST.cpp Removed: diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp index 98135529f259..ee470bd8b963 100644 --- a/clang-tools-extra/clangd/IncludeCleaner.cpp +++ b/clang-tools-extra/clangd/IncludeCleaner.cpp @@ -93,8 +93,6 @@ bool isFilteredByConfig(const Config , llvm::StringRef HeaderPath) { static bool mayConsiderUnused(const Inclusion , ParsedAST , const Config , const include_cleaner::PragmaIncludes *PI) { - if (PI && PI->shouldKeep(Inc.HashLine + 1)) -return false; // FIXME(kirillbobyrev): We currently do not support the umbrella headers. // System headers are likely to be standard library headers. // Until we have good support for umbrella headers, don't warn about them. @@ -108,6 +106,20 @@ static bool mayConsiderUnused(const Inclusion , ParsedAST , auto FE = AST.getSourceManager().getFileManager().getFileRef( AST.getIncludeStructure().getRealPath(HID)); assert(FE); + if (PI) { +if (PI->shouldKeep(Inc.HashLine + 1)) + return false; +// Check if main file is the public interface for a private header. If so we +// shouldn't diagnose it as unused. +if(auto PHeader = PI->getPublic(*FE); !PHeader.empty()) { + PHeader = PHeader.trim("<>\""); + // Since most private -> public mappings happen in a verbatim way, we + // check textually here. This might go wrong in presence of symlinks or + // header mappings. But that's not diff erent than rest of the places. + if(AST.tuPath().endswith(PHeader)) +return false; +} + } // Headers without include guards have side effects and are not // self-contained, skip them. if (!AST.getPreprocessor().getHeaderSearchInfo().isFileMultipleIncludeGuarded( diff --git a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp index 409e3cee791c..69b4e07439c3 100644 --- a/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp +++ b/clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp @@ -30,6 +30,7 @@ #include "gtest/gtest.h" #include #include +#include #include namespace clang { @@ -328,6 +329,26 @@ TEST(IncludeCleaner, NoDiagsForObjC) { ParsedAST AST = TU.build(); EXPECT_THAT(AST.getDiagnostics(), llvm::ValueIs(IsEmpty())); } + +TEST(IncludeCleaner, UmbrellaUsesPrivate) { + TestTU TU; + TU.Code = R"cpp( +#include "private.h" +)cpp"; + TU.AdditionalFiles["private.h"] = guard(R"cpp( +// IWYU pragma: private, include "public.h" +void foo() {} + )cpp"); + TU.Filename = "public.h"; + Config Cfg; + Cfg.Diagnostics.UnusedIncludes = Config::IncludesPolicy::Strict; + WithContextValue Ctx(Config::Key, std::move(Cfg)); + ParsedAST AST = TU.build(); + EXPECT_THAT(AST.getDiagnostics(), llvm::ValueIs(IsEmpty())); + IncludeCleanerFindings Findings = computeIncludeCleanerFindings(AST); + EXPECT_THAT(Findings.UnusedIncludes, IsEmpty()); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/include-cleaner/lib/Analysis.cpp b/clang-tools-extra/include-cleaner/lib/Analysis.cpp index 6237bdb46bab..fb0879b7aab6 100644 --- a/clang-tools-extra/include-cleaner/lib/Analysis.cpp +++ b/clang-tools-extra/include-cleaner/lib/Analysis.cpp @@ -90,9 +90,25 @@ AnalysisResults analyze(llvm::ArrayRef ASTRoots, }); AnalysisResults Results; - for (const Include : Inc.all()) -if (!Used.contains() && PI && !PI->shouldKeep(I.Line)) - Results.Unused.push_back(); + for (const Include : Inc.all()) { +if (Used.contains()) + continue; +if (PI) { + if (PI->shouldKeep(I.Line)) +continue; + // Check if main file is the public interface for a private header. If so + // we shouldn't diagnose it as unused. + if (auto PHeader = PI->getPublic(I.Resolved); !PHeader.empty()) { +PHeader = PHeader.trim("<>\""); +// Since most private -> public mappings happen in a
[clang-tools-extra] 029ec03 - [clangd][NFC] Format & include cleanup for AddUsingTests.cpp
Author: Kadir Cetinkaya Date: 2023-03-21T07:53:08+01:00 New Revision: 029ec03a096901a83d650ac08375b78f9161ab51 URL: https://github.com/llvm/llvm-project/commit/029ec03a096901a83d650ac08375b78f9161ab51 DIFF: https://github.com/llvm/llvm-project/commit/029ec03a096901a83d650ac08375b78f9161ab51.diff LOG: [clangd][NFC] Format & include cleanup for AddUsingTests.cpp Added: Modified: clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp Removed: diff --git a/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp index d466dd5349d44..f3a479a9a240f 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp @@ -8,11 +8,12 @@ #include "Config.h" #include "TweakTesting.h" +#include "support/Context.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" -#include "gmock/gmock.h" #include "gtest/gtest.h" #include +#include namespace clang { namespace clangd { @@ -96,16 +97,17 @@ TEST_F(AddUsingTest, Apply) { struct { llvm::StringRef TestSource; llvm::StringRef ExpectedSource; - } Cases[]{{ -// Function, no other using, namespace. -R"cpp( + } Cases[]{ + { + // Function, no other using, namespace. + R"cpp( #include "test.hpp" namespace { void fun() { ^one::two::ff(); } })cpp", -R"cpp( + R"cpp( #include "test.hpp" namespace {using one::two::ff; @@ -113,17 +115,17 @@ void fun() { ff(); } })cpp", -}, -// Type, no other using, namespace. -{ -R"cpp( + }, + // Type, no other using, namespace. + { + R"cpp( #include "test.hpp" namespace { void fun() { ::one::t^wo::cc inst; } })cpp", -R"cpp( + R"cpp( #include "test.hpp" namespace {using ::one::two::cc; @@ -131,16 +133,16 @@ void fun() { cc inst; } })cpp", -}, -// Type, no other using, no namespace. -{ -R"cpp( + }, + // Type, no other using, no namespace. + { + R"cpp( #include "test.hpp" void fun() { one::two::e^e inst; })cpp", -R"cpp( + R"cpp( #include "test.hpp" using one::two::ee; @@ -148,9 +150,9 @@ using one::two::ee; void fun() { ee inst; })cpp"}, -// Function, other usings. -{ -R"cpp( + // Function, other usings. + { + R"cpp( #include "test.hpp" using one::two::cc; @@ -161,7 +163,7 @@ void fun() { one::two::f^f(); } })cpp", -R"cpp( + R"cpp( #include "test.hpp" using one::two::cc; @@ -172,10 +174,10 @@ void fun() { ff(); } })cpp", -}, -// Function, other usings inside namespace. -{ -R"cpp( + }, + // Function, other usings inside namespace. + { + R"cpp( #include "test.hpp" using one::two::cc; @@ -188,7 +190,7 @@ void fun() { o^ne::oo(); } })cpp", -R"cpp( + R"cpp( #include "test.hpp" using one::two::cc; @@ -201,9 +203,9 @@ void fun() { oo(); } })cpp"}, -// Using comes after cursor. -{ -R"cpp( + // Using comes after cursor. + { + R"cpp( #include "test.hpp" namespace { @@ -215,7 +217,7 @@ void fun() { using one::two::cc; })cpp", -R"cpp( + R"cpp( #include "test.hpp" namespace {using one::two::ff; @@ -228,14 +230,14 @@ void fun() { using one::two::cc; })cpp"}, -// Pointer type. -{R"cpp( + // Pointer type. + {R"cpp( #include "test.hpp" void fun() { one::two::c^c *p; })cpp", - R"cpp( + R"cpp( #include "test.hpp" using one::two::cc; @@ -243,8 +245,8 @@ using one::two::cc; void fun() { cc *p; })cpp"}, -// Namespace declared via macro. -{R"cpp( + // Namespace declared via macro. + {R"cpp( #include "test.hpp" #define NS_BEGIN(name) namespace name { @@ -254,7 +256,7 @@ void fun() { one::two::f^f(); } })cpp", - R"cpp( + R"cpp( #include "test.hpp" #define NS_BEGIN(name) namespace name { @@ -266,15 +268,15 @@ void fun() { ff(); } })cpp"}, -// Inside macro argument. -{R"cpp( + // Inside macro argument. + {R"cpp( #include "test.hpp" #define CALL(name) name() void fun() { CALL(one::t^wo::ff); })cpp", - R"cpp( + R"cpp( #include "test.hpp" #define CALL(name) name() @@ -283,15 +285,15 @@ using one::two::ff; void fun() { CALL(ff); })cpp"}, -// Parent namespace != lexical parent namespace -{R"cpp( + // Parent namespace !=
[clang-tools-extra] 35c2aac - Revert "Revert "[clangd] Fix AddUsing in the face of typo-correction""
Author: Kadir Cetinkaya Date: 2023-03-21T07:27:21+01:00 New Revision: 35c2aac6e3957c2e82bf92269039fa02bab0e1d9 URL: https://github.com/llvm/llvm-project/commit/35c2aac6e3957c2e82bf92269039fa02bab0e1d9 DIFF: https://github.com/llvm/llvm-project/commit/35c2aac6e3957c2e82bf92269039fa02bab0e1d9.diff LOG: Revert "Revert "[clangd] Fix AddUsing in the face of typo-correction"" This reverts commit fb3f6a95393f33bc8d8550a5ac62c18e488a9b6f. Added: Modified: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp Removed: diff --git a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp index 103e13f44d060..1e51d8fb9a518 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp @@ -8,10 +8,25 @@ #include "AST.h" #include "Config.h" +#include "SourceCode.h" #include "refactor/Tweak.h" #include "support/Logger.h" #include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/Type.h" +#include "clang/AST/TypeLoc.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Tooling/Core/Replacement.h" +#include "clang/Tooling/Syntax/Tokens.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include namespace clang { namespace clangd { @@ -45,8 +60,12 @@ class AddUsing : public Tweak { // All of the following are set by prepare(). // The qualifier to remove. NestedNameSpecifierLoc QualifierToRemove; - // The name following QualifierToRemove. - llvm::StringRef Name; + // Qualified name to use when spelling the using declaration. This might be + // diff erent than SpelledQualifier in presence of error correction. + std::string QualifierToSpell; + // The name and qualifier as spelled in the code. + llvm::StringRef SpelledQualifier; + llvm::StringRef SpelledName; // If valid, the insertion point for "using" statement must come after this. // This is relevant when the type is defined in the main file, to make sure // the type/function is already defined at the point where "using" is added. @@ -56,7 +75,7 @@ REGISTER_TWEAK(AddUsing) std::string AddUsing::title() const { return std::string(llvm::formatv( - "Add using-declaration for {0} and remove qualifier", Name)); + "Add using-declaration for {0} and remove qualifier", SpelledName)); } // Locates all "using" statements relevant to SelectionDeclContext. @@ -269,36 +288,23 @@ bool AddUsing::prepare(const Selection ) { if (Node == nullptr) return false; + SourceRange SpelledNameRange; if (auto *D = Node->ASTNode.get()) { if (auto *II = D->getDecl()->getIdentifier()) { QualifierToRemove = D->getQualifierLoc(); - Name = II->getName(); + SpelledNameRange = D->getSourceRange(); MustInsertAfterLoc = D->getDecl()->getBeginLoc(); } } else if (auto *T = Node->ASTNode.get()) { if (auto E = T->getAs()) { QualifierToRemove = E.getQualifierLoc(); - if (!QualifierToRemove) -return false; - auto NameRange = E.getSourceRange(); + SpelledNameRange = E.getSourceRange(); if (auto T = E.getNamedTypeLoc().getAs()) { // Remove the template arguments from the name. -NameRange.setEnd(T.getLAngleLoc().getLocWithOffset(-1)); +SpelledNameRange.setEnd(T.getLAngleLoc().getLocWithOffset(-1)); } - auto SpelledTokens = TB.spelledForExpanded(TB.expandedTokens(NameRange)); - if (!SpelledTokens) -return false; - auto SpelledRange = syntax::Token::range(SM, SpelledTokens->front(), - SpelledTokens->back()); - Name = SpelledRange.text(SM); - - std::string QualifierToRemoveStr = getNNSLAsString( - QualifierToRemove, Inputs.AST->getASTContext().getPrintingPolicy()); - if (!Name.consume_front(QualifierToRemoveStr)) -return false; // What's spelled doesn't match the qualifier. - if (const auto *ET = E.getTypePtr()) { if (const auto *TDT = dyn_cast(ET->getNamedType().getTypePtr())) { @@ -309,19 +315,14 @@ bool AddUsing::prepare(const Selection ) { } } } - - // FIXME: This only supports removing qualifiers that are made up of just - // namespace names. If qualifier contains a type, we could take the longest - // namespace prefix and remove that. - if (!QualifierToRemove.hasQualifier() || + if (!QualifierToRemove || + // FIXME: This only supports removing qualifiers that are made up of just + // namespace names. If qualifier contains a type, we could take the +
[clang-tools-extra] fb3f6a9 - Revert "[clangd] Fix AddUsing in the face of typo-correction"
Author: Kadir Cetinkaya Date: 2023-03-20T18:57:53+01:00 New Revision: fb3f6a95393f33bc8d8550a5ac62c18e488a9b6f URL: https://github.com/llvm/llvm-project/commit/fb3f6a95393f33bc8d8550a5ac62c18e488a9b6f DIFF: https://github.com/llvm/llvm-project/commit/fb3f6a95393f33bc8d8550a5ac62c18e488a9b6f.diff LOG: Revert "[clangd] Fix AddUsing in the face of typo-correction" This reverts commit 6f23fee4ef98a695062aa128a177478ba7d742d4. Breaks windows buildbots Added: Modified: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp Removed: diff --git a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp index 1e51d8fb9a518..103e13f44d060 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp @@ -8,25 +8,10 @@ #include "AST.h" #include "Config.h" -#include "SourceCode.h" #include "refactor/Tweak.h" #include "support/Logger.h" #include "clang/AST/Decl.h" -#include "clang/AST/Expr.h" -#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/RecursiveASTVisitor.h" -#include "clang/AST/Type.h" -#include "clang/AST/TypeLoc.h" -#include "clang/Basic/LLVM.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Tooling/Core/Replacement.h" -#include "clang/Tooling/Syntax/Tokens.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -#include namespace clang { namespace clangd { @@ -60,12 +45,8 @@ class AddUsing : public Tweak { // All of the following are set by prepare(). // The qualifier to remove. NestedNameSpecifierLoc QualifierToRemove; - // Qualified name to use when spelling the using declaration. This might be - // diff erent than SpelledQualifier in presence of error correction. - std::string QualifierToSpell; - // The name and qualifier as spelled in the code. - llvm::StringRef SpelledQualifier; - llvm::StringRef SpelledName; + // The name following QualifierToRemove. + llvm::StringRef Name; // If valid, the insertion point for "using" statement must come after this. // This is relevant when the type is defined in the main file, to make sure // the type/function is already defined at the point where "using" is added. @@ -75,7 +56,7 @@ REGISTER_TWEAK(AddUsing) std::string AddUsing::title() const { return std::string(llvm::formatv( - "Add using-declaration for {0} and remove qualifier", SpelledName)); + "Add using-declaration for {0} and remove qualifier", Name)); } // Locates all "using" statements relevant to SelectionDeclContext. @@ -288,23 +269,36 @@ bool AddUsing::prepare(const Selection ) { if (Node == nullptr) return false; - SourceRange SpelledNameRange; if (auto *D = Node->ASTNode.get()) { if (auto *II = D->getDecl()->getIdentifier()) { QualifierToRemove = D->getQualifierLoc(); - SpelledNameRange = D->getSourceRange(); + Name = II->getName(); MustInsertAfterLoc = D->getDecl()->getBeginLoc(); } } else if (auto *T = Node->ASTNode.get()) { if (auto E = T->getAs()) { QualifierToRemove = E.getQualifierLoc(); + if (!QualifierToRemove) +return false; - SpelledNameRange = E.getSourceRange(); + auto NameRange = E.getSourceRange(); if (auto T = E.getNamedTypeLoc().getAs()) { // Remove the template arguments from the name. -SpelledNameRange.setEnd(T.getLAngleLoc().getLocWithOffset(-1)); +NameRange.setEnd(T.getLAngleLoc().getLocWithOffset(-1)); } + auto SpelledTokens = TB.spelledForExpanded(TB.expandedTokens(NameRange)); + if (!SpelledTokens) +return false; + auto SpelledRange = syntax::Token::range(SM, SpelledTokens->front(), + SpelledTokens->back()); + Name = SpelledRange.text(SM); + + std::string QualifierToRemoveStr = getNNSLAsString( + QualifierToRemove, Inputs.AST->getASTContext().getPrintingPolicy()); + if (!Name.consume_front(QualifierToRemoveStr)) +return false; // What's spelled doesn't match the qualifier. + if (const auto *ET = E.getTypePtr()) { if (const auto *TDT = dyn_cast(ET->getNamedType().getTypePtr())) { @@ -315,14 +309,19 @@ bool AddUsing::prepare(const Selection ) { } } } - if (!QualifierToRemove || - // FIXME: This only supports removing qualifiers that are made up of just - // namespace names. If qualifier contains a type, we could take the - // longest namespace prefix and remove that. + + // FIXME: This only supports removing qualifiers that are made up of just + // namespace names. If qualifier contains a type, we could take the longest + // namespace
[clang-tools-extra] 6f23fee - [clangd] Fix AddUsing in the face of typo-correction
Author: Kadir Cetinkaya Date: 2023-03-20T14:30:36+01:00 New Revision: 6f23fee4ef98a695062aa128a177478ba7d742d4 URL: https://github.com/llvm/llvm-project/commit/6f23fee4ef98a695062aa128a177478ba7d742d4 DIFF: https://github.com/llvm/llvm-project/commit/6f23fee4ef98a695062aa128a177478ba7d742d4.diff LOG: [clangd] Fix AddUsing in the face of typo-correction Fixes https://github.com/clangd/clangd/issues/559 Differential Revision: https://reviews.llvm.org/D146417 Added: Modified: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp Removed: diff --git a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp index 103e13f44d060..1e51d8fb9a518 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp @@ -8,10 +8,25 @@ #include "AST.h" #include "Config.h" +#include "SourceCode.h" #include "refactor/Tweak.h" #include "support/Logger.h" #include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/Type.h" +#include "clang/AST/TypeLoc.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Tooling/Core/Replacement.h" +#include "clang/Tooling/Syntax/Tokens.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include namespace clang { namespace clangd { @@ -45,8 +60,12 @@ class AddUsing : public Tweak { // All of the following are set by prepare(). // The qualifier to remove. NestedNameSpecifierLoc QualifierToRemove; - // The name following QualifierToRemove. - llvm::StringRef Name; + // Qualified name to use when spelling the using declaration. This might be + // diff erent than SpelledQualifier in presence of error correction. + std::string QualifierToSpell; + // The name and qualifier as spelled in the code. + llvm::StringRef SpelledQualifier; + llvm::StringRef SpelledName; // If valid, the insertion point for "using" statement must come after this. // This is relevant when the type is defined in the main file, to make sure // the type/function is already defined at the point where "using" is added. @@ -56,7 +75,7 @@ REGISTER_TWEAK(AddUsing) std::string AddUsing::title() const { return std::string(llvm::formatv( - "Add using-declaration for {0} and remove qualifier", Name)); + "Add using-declaration for {0} and remove qualifier", SpelledName)); } // Locates all "using" statements relevant to SelectionDeclContext. @@ -269,36 +288,23 @@ bool AddUsing::prepare(const Selection ) { if (Node == nullptr) return false; + SourceRange SpelledNameRange; if (auto *D = Node->ASTNode.get()) { if (auto *II = D->getDecl()->getIdentifier()) { QualifierToRemove = D->getQualifierLoc(); - Name = II->getName(); + SpelledNameRange = D->getSourceRange(); MustInsertAfterLoc = D->getDecl()->getBeginLoc(); } } else if (auto *T = Node->ASTNode.get()) { if (auto E = T->getAs()) { QualifierToRemove = E.getQualifierLoc(); - if (!QualifierToRemove) -return false; - auto NameRange = E.getSourceRange(); + SpelledNameRange = E.getSourceRange(); if (auto T = E.getNamedTypeLoc().getAs()) { // Remove the template arguments from the name. -NameRange.setEnd(T.getLAngleLoc().getLocWithOffset(-1)); +SpelledNameRange.setEnd(T.getLAngleLoc().getLocWithOffset(-1)); } - auto SpelledTokens = TB.spelledForExpanded(TB.expandedTokens(NameRange)); - if (!SpelledTokens) -return false; - auto SpelledRange = syntax::Token::range(SM, SpelledTokens->front(), - SpelledTokens->back()); - Name = SpelledRange.text(SM); - - std::string QualifierToRemoveStr = getNNSLAsString( - QualifierToRemove, Inputs.AST->getASTContext().getPrintingPolicy()); - if (!Name.consume_front(QualifierToRemoveStr)) -return false; // What's spelled doesn't match the qualifier. - if (const auto *ET = E.getTypePtr()) { if (const auto *TDT = dyn_cast(ET->getNamedType().getTypePtr())) { @@ -309,19 +315,14 @@ bool AddUsing::prepare(const Selection ) { } } } - - // FIXME: This only supports removing qualifiers that are made up of just - // namespace names. If qualifier contains a type, we could take the longest - // namespace prefix and remove that. - if (!QualifierToRemove.hasQualifier() || + if (!QualifierToRemove || + // FIXME: This only supports removing qualifiers that are made up of just + // namespace names. If qualifier contains a
[clang] 696f8b3 - Revert "[clang-format] Add a space between an overloaded operator and '>'"
Author: Kadir Cetinkaya Date: 2023-03-20T08:07:44+01:00 New Revision: 696f8b32d4bfe7e96f6fdb425fb4768a0508da83 URL: https://github.com/llvm/llvm-project/commit/696f8b32d4bfe7e96f6fdb425fb4768a0508da83 DIFF: https://github.com/llvm/llvm-project/commit/696f8b32d4bfe7e96f6fdb425fb4768a0508da83.diff LOG: Revert "[clang-format] Add a space between an overloaded operator and '>'" This reverts commit b05dc1b8766a47482cae432011fd2faa04c83a3e. Makes clang-format crash on `struct Foo { operator enum foo{} };` Added: Modified: clang/lib/Format/FormatTokenLexer.cpp clang/lib/Format/FormatTokenLexer.h clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp clang/unittests/Format/TokenAnnotatorTest.cpp Removed: diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index ae54de93daf5..f06f9fb9949d 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -103,8 +103,6 @@ void FormatTokenLexer::tryMergePreviousTokens() { return; if (tryMergeLessLess()) return; - if (tryMergeGreaterGreater()) -return; if (tryMergeForEach()) return; if (Style.isCpp() && tryTransformTryUsageForC()) @@ -462,11 +460,12 @@ bool FormatTokenLexer::tryMergeLessLess() { return false; auto X = Tokens.size() > 3 ? First[-1] : nullptr; - if (X && X->is(tok::less)) + auto Y = First[2]; + if ((X && X->is(tok::less)) || Y->is(tok::less)) return false; - auto Y = First[2]; - if ((!X || X->isNot(tok::kw_operator)) && Y->is(tok::less)) + // Do not remove a whitespace between the two "<" e.g. "operator< <>". + if (X && X->is(tok::kw_operator) && Y->is(tok::greater)) return false; First[0]->Tok.setKind(tok::lessless); @@ -476,30 +475,6 @@ bool FormatTokenLexer::tryMergeLessLess() { return true; } -bool FormatTokenLexer::tryMergeGreaterGreater() { - // Merge kw_operator,greater,greater into kw_operator,greatergreater. - if (Tokens.size() < 2) -return false; - - auto First = Tokens.end() - 2; - if (First[0]->isNot(tok::greater) || First[1]->isNot(tok::greater)) -return false; - - // Only merge if there currently is no whitespace between the first two ">". - if (First[1]->hasWhitespaceBefore()) -return false; - - auto Tok = Tokens.size() > 2 ? First[-1] : nullptr; - if (Tok && Tok->isNot(tok::kw_operator)) -return false; - - First[0]->Tok.setKind(tok::greatergreater); - First[0]->TokenText = ">>"; - First[0]->ColumnWidth += 1; - Tokens.erase(Tokens.end() - 1); - return true; -} - bool FormatTokenLexer::tryMergeTokens(ArrayRef Kinds, TokenType NewType) { if (Tokens.size() < Kinds.size()) diff --git a/clang/lib/Format/FormatTokenLexer.h b/clang/lib/Format/FormatTokenLexer.h index 0a8123fed293..950305a37d68 100644 --- a/clang/lib/Format/FormatTokenLexer.h +++ b/clang/lib/Format/FormatTokenLexer.h @@ -51,7 +51,6 @@ class FormatTokenLexer { void tryMergePreviousTokens(); bool tryMergeLessLess(); - bool tryMergeGreaterGreater(); bool tryMergeNSStringLiteral(); bool tryMergeJSPrivateIdentifier(); bool tryMergeCSharpStringLiteral(); diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 12beeba7c70c..6b6b9eb8d31d 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1215,25 +1215,19 @@ class AnnotatingParser { !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) { if (CurrentToken->isOneOf(tok::star, tok::amp)) CurrentToken->setType(TT_PointerOrReference); -auto Next = CurrentToken->getNextNonComment(); -if (!Next) - break; -if (Next->is(tok::less)) - next(); -else - consumeToken(); -assert(CurrentToken); -auto Previous = CurrentToken->getPreviousNonComment(); -assert(Previous); -if (CurrentToken->is(tok::comma) && Previous->isNot(tok::kw_operator)) +consumeToken(); +if (!CurrentToken) + continue; +if (CurrentToken->is(tok::comma) && +CurrentToken->Previous->isNot(tok::kw_operator)) { break; -if (Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator, tok::comma, - tok::star, tok::arrow, tok::amp, tok::ampamp) || +} +if (CurrentToken->Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator, +tok::comma, tok::star, tok::arrow, +tok::amp, tok::ampamp) || // User defined literal. -Previous->TokenText.startswith("\"\"")) { - Previous->setType(TT_OverloadedOperator); - if (CurrentToken->isOneOf(tok::less, tok::greater)) -break; +
[clang-tools-extra] 9e8bac7 - [clangd] Respect WantDiags when emitting diags from possibly stale preambles
Author: Kadir Cetinkaya Date: 2023-03-15T11:29:16+01:00 New Revision: 9e8bac7480640677e04f4b9f98c41cb94f8180e2 URL: https://github.com/llvm/llvm-project/commit/9e8bac7480640677e04f4b9f98c41cb94f8180e2 DIFF: https://github.com/llvm/llvm-project/commit/9e8bac7480640677e04f4b9f98c41cb94f8180e2.diff LOG: [clangd] Respect WantDiags when emitting diags from possibly stale preambles Differential Revision: https://reviews.llvm.org/D146116 Added: Modified: clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp Removed: diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp index a4f6a93b616a..9b366cdd43eb 100644 --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -948,7 +948,8 @@ void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags, // rebuild. Newly built preamble cannot emit diagnostics before this call // finishes (ast callbacks are called from astpeer thread), hence we // gurantee eventual consistency. -if (LatestPreamble && Config::current().Diagnostics.AllowStalePreamble) +if (LatestPreamble && WantDiags != WantDiagnostics::No && +Config::current().Diagnostics.AllowStalePreamble) generateDiagnostics(std::move(Invocation), std::move(Inputs), std::move(CompilerInvocationDiags)); diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp index ead85a4ce5f2..0538947b7095 100644 --- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp +++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp @@ -1309,6 +1309,13 @@ TEST_F(TUSchedulerTests, PublishWithStalePreamble) { // Make sure that we have eventual consistency. EXPECT_THAT(Collector.diagVersions().back(), Pair(PI.Version, PI.Version)); + + // Check that WantDiagnostics::No doesn't emit any diags. + PI.Version = "4"; + PI.Contents = "#define FOO\n" + PI.Version; + S.update(File, PI, WantDiagnostics::No); + S.blockUntilIdle(timeoutSeconds(5)); + EXPECT_THAT(Collector.diagVersions().back(), Pair("3", "3")); } // If a header file is missing from the CDB (or inferred using heuristics), and ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 82c8bf8 - [clangd] Patch main file macros in preamble
Author: Kadir Cetinkaya Date: 2023-03-15T09:00:15+01:00 New Revision: 82c8bf8fcc91eda75e47856b34a1d68cedd2b46e URL: https://github.com/llvm/llvm-project/commit/82c8bf8fcc91eda75e47856b34a1d68cedd2b46e DIFF: https://github.com/llvm/llvm-project/commit/82c8bf8fcc91eda75e47856b34a1d68cedd2b46e.diff LOG: [clangd] Patch main file macros in preamble Depends on D146026 Fixes https://github.com/clangd/clangd/issues/1537. Differential Revision: https://reviews.llvm.org/D146028 Added: Modified: clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/unittests/PreambleTests.cpp Removed: diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index 85138eeae783..3b0af0ab50a6 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -325,6 +325,7 @@ struct ScannedPreamble { std::vector Lines; PreambleBounds Bounds = {0, false}; std::vector Marks; + MainFileMacros Macros; }; /// Scans the preprocessor directives in the preamble section of the file by @@ -373,14 +374,15 @@ scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand ) { if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) return error("failed BeginSourceFile"); Preprocessor = Clang->getPreprocessor(); + const auto = PP.getSourceManager(); IncludeStructure Includes; Includes.collect(*Clang); ScannedPreamble SP; SP.Bounds = Bounds; PP.addPPCallbacks( std::make_unique(PP, SP.TextualDirectives)); - PP.addPPCallbacks( - collectPragmaMarksCallback(PP.getSourceManager(), SP.Marks)); + PP.addPPCallbacks(collectPragmaMarksCallback(SM, SP.Marks)); + PP.addPPCallbacks(std::make_unique(SM, SP.Macros)); if (llvm::Error Err = Action.Execute()) return std::move(Err); Action.EndSourceFile(); @@ -859,6 +861,7 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName, PP.PatchedDiags = patchDiags(Baseline.Diags, *BaselineScan, *ModifiedScan); PP.PatchedMarks = std::move(ModifiedScan->Marks); + PP.PatchedMacros = std::move(ModifiedScan->Macros); dlog("Created preamble patch: {0}", Patch.str()); Patch.flush(); return PP; @@ -915,11 +918,10 @@ llvm::ArrayRef PreamblePatch::marks() const { return PatchedMarks; } -MainFileMacros PreamblePatch::mainFileMacros() const { +const MainFileMacros ::mainFileMacros() const { if (PatchContents.empty()) return Baseline->Macros; - // FIXME: Patch main file macros. - return MainFileMacros(); + return PatchedMacros; } } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/Preamble.h b/clang-tools-extra/clangd/Preamble.h index 6b189777b4d5..a16f497737aa 100644 --- a/clang-tools-extra/clangd/Preamble.h +++ b/clang-tools-extra/clangd/Preamble.h @@ -164,7 +164,7 @@ class PreamblePatch { static constexpr llvm::StringLiteral HeaderName = "__preamble_patch__.h"; llvm::ArrayRef marks() const; - MainFileMacros mainFileMacros() const; + const MainFileMacros () const; private: static PreamblePatch create(llvm::StringRef FileName, @@ -183,6 +183,7 @@ class PreamblePatch { PreambleBounds ModifiedBounds = {0, false}; const PreambleData *Baseline = nullptr; std::vector PatchedMarks; + MainFileMacros PatchedMacros; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp index fd094fa93881..903d9ef123ee 100644 --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -30,7 +30,6 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/VirtualFileSystem.h" -#include "llvm/Testing/Support/SupportHelpers.h" #include "gmock/gmock.h" #include "gtest/gtest-matchers.h" #include "gtest/gtest.h" @@ -855,11 +854,12 @@ TEST(PreamblePatch, MacroAndMarkHandling) { ]] #pragma $y[[mark YY ]] +#define BAZ #endif)cpp"); auto AST = createPatchedAST(Code.code(), NewCode.code()); -// FIXME: Macros and marks have locations that need to be patched. -EXPECT_THAT(AST->getMacros().Names, IsEmpty()); +EXPECT_THAT(AST->getMacros().Names.keys(), +UnorderedElementsAreArray({"FOO", "BAR", "BAZ"})); EXPECT_THAT(AST->getMarks(), UnorderedElementsAre(Mark(NewCode.range("x"), " XX"), Mark(NewCode.range("y"), " YY"))); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 9c88812 - [clangd] Patch PragmaMarks in preamble section of the file
Author: Kadir Cetinkaya Date: 2023-03-15T09:00:14+01:00 New Revision: 9c888120e3c8cc93f9950590a9192002e7c3d08b URL: https://github.com/llvm/llvm-project/commit/9c888120e3c8cc93f9950590a9192002e7c3d08b DIFF: https://github.com/llvm/llvm-project/commit/9c888120e3c8cc93f9950590a9192002e7c3d08b.diff LOG: [clangd] Patch PragmaMarks in preamble section of the file Differential Revision: https://reviews.llvm.org/D146026 Added: Modified: clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/unittests/PreambleTests.cpp Removed: diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index 94e6839a7f49..85138eeae783 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -15,7 +15,9 @@ #include "Protocol.h" #include "SourceCode.h" #include "clang-include-cleaner/Record.h" +#include "index/CanonicalIncludes.h" #include "support/Logger.h" +#include "support/Path.h" #include "support/ThreadsafeFS.h" #include "support/Trace.h" #include "clang/AST/DeclTemplate.h" @@ -27,6 +29,7 @@ #include "clang/Basic/TokenKinds.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendActions.h" +#include "clang/Frontend/PrecompiledPreamble.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/PPCallbacks.h" @@ -42,6 +45,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormatVariadic.h" @@ -50,10 +54,12 @@ #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include +#include #include #include #include #include +#include #include #include @@ -318,6 +324,7 @@ struct ScannedPreamble { // Literal lines of the preamble contents. std::vector Lines; PreambleBounds Bounds = {0, false}; + std::vector Marks; }; /// Scans the preprocessor directives in the preamble section of the file by @@ -372,6 +379,8 @@ scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand ) { SP.Bounds = Bounds; PP.addPPCallbacks( std::make_unique(PP, SP.TextualDirectives)); + PP.addPPCallbacks( + collectPragmaMarksCallback(PP.getSourceManager(), SP.Marks)); if (llvm::Error Err = Action.Execute()) return std::move(Err); Action.EndSourceFile(); @@ -849,6 +858,7 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName, } PP.PatchedDiags = patchDiags(Baseline.Diags, *BaselineScan, *ModifiedScan); + PP.PatchedMarks = std::move(ModifiedScan->Marks); dlog("Created preamble patch: {0}", Patch.str()); Patch.flush(); return PP; @@ -902,8 +912,7 @@ bool PreamblePatch::preserveDiagnostics() const { llvm::ArrayRef PreamblePatch::marks() const { if (PatchContents.empty()) return Baseline->Marks; - // FIXME: Patch pragma marks. - return {}; + return PatchedMarks; } MainFileMacros PreamblePatch::mainFileMacros() const { diff --git a/clang-tools-extra/clangd/Preamble.h b/clang-tools-extra/clangd/Preamble.h index c0cccebd487a..6b189777b4d5 100644 --- a/clang-tools-extra/clangd/Preamble.h +++ b/clang-tools-extra/clangd/Preamble.h @@ -182,6 +182,7 @@ class PreamblePatch { std::vector PatchedDiags; PreambleBounds ModifiedBounds = {0, false}; const PreambleData *Baseline = nullptr; + std::vector PatchedMarks; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp index bc32671e6a97..fd094fa93881 100644 --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -829,6 +829,10 @@ x>)"); } } +MATCHER_P2(Mark, Range, Text, "") { + return std::tie(arg.Rng, arg.Trivia) == std::tie(Range, Text); +} + TEST(PreamblePatch, MacroAndMarkHandling) { Config Cfg; Cfg.Diagnostics.AllowStalePreamble = true; @@ -847,13 +851,18 @@ TEST(PreamblePatch, MacroAndMarkHandling) { #ifndef FOO #define FOO #define BAR -#pragma mark XX +#pragma $x[[mark XX +]] +#pragma $y[[mark YY +]] #endif)cpp"); auto AST = createPatchedAST(Code.code(), NewCode.code()); // FIXME: Macros and marks have locations that need to be patched. EXPECT_THAT(AST->getMacros().Names, IsEmpty()); -EXPECT_THAT(AST->getMarks(), IsEmpty()); +EXPECT_THAT(AST->getMarks(), +UnorderedElementsAre(Mark(NewCode.range("x"), " XX"), + Mark(NewCode.range("y"), " YY"))); } } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] c11c2f5 - [clangd] Drop stale macro and mark ranges
Author: Kadir Cetinkaya Date: 2023-03-14T13:18:16+01:00 New Revision: c11c2f5f6548a5303517c89ba6629bbfa7fae0d9 URL: https://github.com/llvm/llvm-project/commit/c11c2f5f6548a5303517c89ba6629bbfa7fae0d9 DIFF: https://github.com/llvm/llvm-project/commit/c11c2f5f6548a5303517c89ba6629bbfa7fae0d9.diff LOG: [clangd] Drop stale macro and mark ranges I'll follow up with patching of those ranges, this is to stop bleeding mentioned in https://github.com/clangd/clangd/issues/1537. Differential Revision: https://reviews.llvm.org/D146024 Added: Modified: clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/unittests/PreambleTests.cpp Removed: diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index 640b112ebe715..1671eec133b6e 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -605,16 +605,15 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs , // Copy over the macros in the preamble region of the main file, and combine // with non-preamble macros below. MainFileMacros Macros; - if (Preamble) -Macros = Preamble->Macros; + std::vector Marks; + if (Preamble) { +Macros = Patch->mainFileMacros(); +Marks = Patch->marks(); + } Clang->getPreprocessor().addPPCallbacks( std::make_unique(Clang->getSourceManager(), Macros)); - std::vector Marks; - // FIXME: We need to patch the marks for stale preambles. - if (Preamble) -Marks = Preamble->Marks; Clang->getPreprocessor().addPPCallbacks( collectPragmaMarksCallback(Clang->getSourceManager(), Marks)); diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index eca7f0e6e6e07..94e6839a7f49d 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -7,6 +7,7 @@ //===--===// #include "Preamble.h" +#include "CollectMacros.h" #include "Compiler.h" #include "Config.h" #include "Diagnostics.h" @@ -765,6 +766,7 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName, return PreamblePatch::unmodified(Baseline); PreamblePatch PP; + PP.Baseline = // This shouldn't coincide with any real file name. llvm::SmallString<128> PatchName; llvm::sys::path::append(PatchName, llvm::sys::path::parent_path(FileName), @@ -886,6 +888,7 @@ std::vector PreamblePatch::preambleIncludes() const { PreamblePatch PreamblePatch::unmodified(const PreambleData ) { PreamblePatch PP; + PP.Baseline = PP.PreambleIncludes = Preamble.Includes.MainFileIncludes; PP.ModifiedBounds = Preamble.Preamble.getBounds(); PP.PatchedDiags = Preamble.Diags; @@ -896,5 +899,18 @@ bool PreamblePatch::preserveDiagnostics() const { return PatchContents.empty() || Config::current().Diagnostics.AllowStalePreamble; } +llvm::ArrayRef PreamblePatch::marks() const { + if (PatchContents.empty()) +return Baseline->Marks; + // FIXME: Patch pragma marks. + return {}; +} + +MainFileMacros PreamblePatch::mainFileMacros() const { + if (PatchContents.empty()) +return Baseline->Macros; + // FIXME: Patch main file macros. + return MainFileMacros(); +} } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/Preamble.h b/clang-tools-extra/clangd/Preamble.h index b5a5c107ab48a..c0cccebd487af 100644 --- a/clang-tools-extra/clangd/Preamble.h +++ b/clang-tools-extra/clangd/Preamble.h @@ -163,6 +163,9 @@ class PreamblePatch { static constexpr llvm::StringLiteral HeaderName = "__preamble_patch__.h"; + llvm::ArrayRef marks() const; + MainFileMacros mainFileMacros() const; + private: static PreamblePatch create(llvm::StringRef FileName, const ParseInputs , @@ -178,6 +181,7 @@ class PreamblePatch { // Diags that were attached to a line preserved in Modified contents. std::vector PatchedDiags; PreambleBounds ModifiedBounds = {0, false}; + const PreambleData *Baseline = nullptr; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp index 29ebcb35a88c8..bc32671e6a975 100644 --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -19,6 +19,7 @@ #include "TestFS.h" #include "TestTU.h" #include "XRefs.h" +#include "support/Context.h" #include "clang/Basic/SourceManager.h" #include "clang/Format/Format.h" #include "clang/Frontend/FrontendActions.h" @@ -36,6 +37,7 @@ #include #include #include +#include #include using testing::AllOf; @@ -826,6 +828,35 @@ x>)");
[clang-tools-extra] 9b5a934 - [IncludeCleaner][NFC] Dont rely on implicit conversion of StringRef
Author: Kadir Cetinkaya Date: 2023-03-14T09:20:30+01:00 New Revision: 9b5a934def7ff02f51d972c80021c9d601f91beb URL: https://github.com/llvm/llvm-project/commit/9b5a934def7ff02f51d972c80021c9d601f91beb DIFF: https://github.com/llvm/llvm-project/commit/9b5a934def7ff02f51d972c80021c9d601f91beb.diff LOG: [IncludeCleaner][NFC] Dont rely on implicit conversion of StringRef Fixes https://github.com/llvm/llvm-project/issues/61221 Added: Modified: clang-tools-extra/include-cleaner/unittests/LocateSymbolTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/unittests/LocateSymbolTest.cpp b/clang-tools-extra/include-cleaner/unittests/LocateSymbolTest.cpp index 9961b013b24d..d69e25bf8116 100644 --- a/clang-tools-extra/include-cleaner/unittests/LocateSymbolTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/LocateSymbolTest.cpp @@ -16,15 +16,11 @@ #include "clang/Testing/TestAST.h" #include "clang/Tooling/Inclusions/StandardLibrary.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" #include "llvm/Testing/Annotations/Annotations.h" #include "gmock/gmock.h" #include "gtest/gtest.h" -#include -#include #include -#include -#include -#include #include namespace clang::include_cleaner { @@ -66,8 +62,8 @@ struct LocateExample { ND = TD; if (ND->getName() == NameToFind) { EXPECT_TRUE(Out == nullptr || Out == ND->getCanonicalDecl()) - << "Found multiple matches for " << NameToFind; - Out = cast(ND->getCanonicalDecl()); + << "Found multiple matches for " << NameToFind.str(); + Out = llvm::cast(ND->getCanonicalDecl()); } return true; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] e26dad0 - [clangd] Add missing unittests to build graph
Author: Kadir Cetinkaya Date: 2023-03-13T13:06:31+01:00 New Revision: e26dad0a661e055076002d0de4ceb713b8ca6917 URL: https://github.com/llvm/llvm-project/commit/e26dad0a661e055076002d0de4ceb713b8ca6917 DIFF: https://github.com/llvm/llvm-project/commit/e26dad0a661e055076002d0de4ceb713b8ca6917.diff LOG: [clangd] Add missing unittests to build graph Also fix tests Differential Revision: https://reviews.llvm.org/D145921 Added: Modified: clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp clang-tools-extra/clangd/unittests/CMakeLists.txt clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp clang-tools-extra/clangd/unittests/tweaks/SpecialMembersTests.cpp Removed: diff --git a/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp b/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp index e15605191c75..0b86b4842270 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp @@ -8,10 +8,7 @@ #include "ParsedAST.h" #include "refactor/InsertionPoint.h" #include "refactor/Tweak.h" -#include "support/Logger.h" #include "clang/AST/DeclCXX.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Basic/SourceManager.h" #include "clang/Sema/Sema.h" #include "clang/Tooling/Core/Replacement.h" #include "llvm/ADT/StringRef.h" @@ -84,7 +81,7 @@ std::string buildSpecialMemberDeclarations(const CXXRecordDecl ) { // - to understand the implicit behavior // - to avoid relying on the implicit behavior // - as a baseline for explicit modification -class DeclareCopyMove : public Tweak { +class SpecialMembers : public Tweak { public: const char *id() const final; llvm::StringLiteral kind() const override { @@ -103,7 +100,7 @@ class DeclareCopyMove : public Tweak { // Trigger only on class definitions. if (auto *N = Inputs.ASTSelection.commonAncestor()) Class = const_cast(N->ASTNode.get()); -if (!Class || !Class->isThisDeclarationADefinition()) +if (!Class || !Class->isThisDeclarationADefinition() || Class->isUnion()) return false; // Tweak is only available if some members are missing. @@ -146,7 +143,7 @@ class DeclareCopyMove : public Tweak { bool NeedCopy = false, NeedMove = false; CXXRecordDecl *Class = nullptr; }; -REGISTER_TWEAK(DeclareCopyMove) +REGISTER_TWEAK(SpecialMembers) } // namespace } // namespace clangd diff --git a/clang-tools-extra/clangd/unittests/CMakeLists.txt b/clang-tools-extra/clangd/unittests/CMakeLists.txt index a68d8cb0b78f..39fd6ee85378 100644 --- a/clang-tools-extra/clangd/unittests/CMakeLists.txt +++ b/clang-tools-extra/clangd/unittests/CMakeLists.txt @@ -104,12 +104,13 @@ add_unittest(ClangdUnitTests ClangdTests support/CancellationTests.cpp support/ContextTests.cpp + support/FileCacheTests.cpp support/FunctionTests.cpp support/MarkupTests.cpp support/MemoryTreeTests.cpp support/PathTests.cpp - support/ThreadingTests.cpp support/TestTracer.cpp + support/ThreadingTests.cpp support/TraceTests.cpp tweaks/AddUsingTests.cpp @@ -130,6 +131,7 @@ add_unittest(ClangdUnitTests ClangdTests tweaks/RawStringLiteralTests.cpp tweaks/RemoveUsingNamespaceTests.cpp tweaks/ShowSelectionTreeTests.cpp + tweaks/SpecialMembersTests.cpp tweaks/SwapIfBranchesTests.cpp tweaks/TweakTesting.cpp tweaks/TweakTests.cpp diff --git a/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp b/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp index 840cad623d77..3cdaceb5cf23 100644 --- a/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp +++ b/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp @@ -11,9 +11,9 @@ #include "TestFS.h" #include "gmock/gmock.h" #include "gtest/gtest.h" -#include #include #include +#include namespace clang { namespace clangd { @@ -34,10 +34,10 @@ class TestCache : public FileCache { FS.Files.erase(testPath("foo.cc")); } - std::string get(std::chrono::steady_clock::time_point FreshTime, - bool ExpectParse) const { + std::pair + get(std::chrono::steady_clock::time_point FreshTime) const { bool GotParse = false; -bool GotRead; +bool GotRead = false; std::string Result; read( FS, FreshTime, @@ -49,12 +49,14 @@ class TestCache : public FileCache { GotRead = true; Result = Value; }); -EXPECT_EQ(GotParse, ExpectParse); EXPECT_TRUE(GotRead); -return Result; +return {Result, GotParse}; } }; +MATCHER_P(Parsed, Value, "") { return arg.second && arg.first == Value; } +MATCHER_P(Cached, Value, "") { return !arg.second && arg.first == Value; } + TEST(FileCacheTest, Invalidation) { TestCache C; @@ -62,20 +64,20 @@ TEST(FileCacheTest, Invalidation) { auto MustBeFresh = StaleOK +
[clang] 385c8cd - [Tooling][Inclusions] Add c-header and global namespace alternatives for size_t
Author: Kadir Cetinkaya Date: 2023-02-24T10:44:33+01:00 New Revision: 385c8cd3cd66052dee2dff01bfdbeb258191f2ff URL: https://github.com/llvm/llvm-project/commit/385c8cd3cd66052dee2dff01bfdbeb258191f2ff DIFF: https://github.com/llvm/llvm-project/commit/385c8cd3cd66052dee2dff01bfdbeb258191f2ff.diff LOG: [Tooling][Inclusions] Add c-header and global namespace alternatives for size_t Differential Revision: https://reviews.llvm.org/D144646 Added: Modified: clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc Removed: diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc index c9632bee1cbec..119952be6fe3c 100644 --- a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc +++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc @@ -22,6 +22,20 @@ SYMBOL(size_t, std::, ) SYMBOL(size_t, std::, ) SYMBOL(size_t, std::, ) SYMBOL(size_t, std::, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) +SYMBOL(size_t, None, ) SYMBOL(unwrap_ref_decay, std::, ) SYMBOL(unwrap_ref_decay, std::, ) SYMBOL(unwrap_reference, std::, ) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] f393e1f - [clangd] Fix UB in scanPreamble
Author: Kadir Cetinkaya Date: 2023-02-24T10:43:12+01:00 New Revision: f393e1f6b3b42e8f355e64e2fb479c571ab939bc URL: https://github.com/llvm/llvm-project/commit/f393e1f6b3b42e8f355e64e2fb479c571ab939bc DIFF: https://github.com/llvm/llvm-project/commit/f393e1f6b3b42e8f355e64e2fb479c571ab939bc.diff LOG: [clangd] Fix UB in scanPreamble getMemBufferCopy triggers an UB when it receives a default constructed StringRef. Make sure that we're always passing the null-terminated string created in ParseInputs throughout the scanPreamble. Differential Revision: https://reviews.llvm.org/D144708 Added: Modified: clang-tools-extra/clangd/Preamble.cpp Removed: diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index e97564497954..f50597f9ad20 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -332,6 +332,8 @@ scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand ) { EmptyFS FS; // Build and run Preprocessor over the preamble. ParseInputs PI; + // Memory buffers below expect null-terminated && non-null strings. So make + // sure to always use PI.Contents! PI.Contents = Contents.str(); PI.TFS = PI.CompileCommand = Cmd; @@ -345,8 +347,8 @@ scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand ) { // twice. However, it's important to precisely follow the preamble bounds used // elsewhere. auto Bounds = ComputePreambleBounds(*CI->getLangOpts(), *ContentsBuffer, 0); - auto PreambleContents = - llvm::MemoryBuffer::getMemBufferCopy(Contents.substr(0, Bounds.Size)); + auto PreambleContents = llvm::MemoryBuffer::getMemBufferCopy( + llvm::StringRef(PI.Contents).take_front(Bounds.Size)); auto Clang = prepareCompilerInstance( std::move(CI), nullptr, std::move(PreambleContents), // Provide an empty FS to prevent preprocessor from performing IO. This @@ -739,9 +741,8 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName, // whole preamble, which is terribly slow. // - If scanning for Modified fails, cannot figure out newly added ones so // there's nothing to do but generate an empty patch. - auto BaselineScan = scanPreamble( - // Contents needs to be null-terminated. - Baseline.Preamble.getContents(), Modified.CompileCommand); + auto BaselineScan = + scanPreamble(Baseline.Preamble.getContents(), Modified.CompileCommand); if (!BaselineScan) { elog("Failed to scan baseline of {0}: {1}", FileName, BaselineScan.takeError()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 5a623c2 - Revert "Revert "[Tooling/Inclusion] Handle std::get symbol.""
Author: Kadir Cetinkaya Date: 2023-02-24T01:24:53+01:00 New Revision: 5a623c2a082d007c1cc7a878b666b3581bb8f8dc URL: https://github.com/llvm/llvm-project/commit/5a623c2a082d007c1cc7a878b666b3581bb8f8dc DIFF: https://github.com/llvm/llvm-project/commit/5a623c2a082d007c1cc7a878b666b3581bb8f8dc.diff LOG: Revert "Revert "[Tooling/Inclusion] Handle std::get symbol."" This reverts commit 7c9b15fbaeb2846ad25e797d55ffe1ccef9e1379. Breakage was in downstream code. Added: Modified: clang-tools-extra/clangd/index/CanonicalIncludes.cpp clang/include/clang/Tooling/Inclusions/StandardLibrary.h clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc clang/unittests/Tooling/StandardLibraryTest.cpp Removed: diff --git a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp index 0c61a7bd7e929..4311eb9f481f8 100644 --- a/clang-tools-extra/clangd/index/CanonicalIncludes.cpp +++ b/clang-tools-extra/clangd/index/CanonicalIncludes.cpp @@ -717,7 +717,8 @@ llvm::StringRef CanonicalIncludes::mapSymbol(llvm::StringRef Scope, if (Scope == "std::" && Name == "move") return ""; if (auto StdSym = tooling::stdlib::Symbol::named(Scope, Name, Lang)) -return StdSym->header().name(); +if (auto Header = StdSym->header()) + return Header->name(); return ""; } diff --git a/clang/include/clang/Tooling/Inclusions/StandardLibrary.h b/clang/include/clang/Tooling/Inclusions/StandardLibrary.h index 9d45d84a429be..a39ceb520dcf8 100644 --- a/clang/include/clang/Tooling/Inclusions/StandardLibrary.h +++ b/clang/include/clang/Tooling/Inclusions/StandardLibrary.h @@ -81,7 +81,7 @@ class Symbol { llvm::StringRef name() const; llvm::StringRef qualifiedName() const; // The preferred header for this symbol (e.g. the suggested insertion). - Header header() const; + std::optional header() const; // Some symbols may be provided by multiple headers. llvm::SmallVector headers() const; diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp b/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp index 416b53117d16b..cfcb955831ad2 100644 --- a/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp +++ b/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp @@ -14,6 +14,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" +#include namespace clang { namespace tooling { @@ -120,7 +121,8 @@ static int initialize(Lang Language) { } Mapping->SymbolNames[SymIndex] = { QName.data(), NSLen, static_cast(QName.size() - NSLen)}; -Mapping->SymbolHeaderIDs[SymIndex].push_back(AddHeader(HeaderName)); +if (!HeaderName.empty()) + Mapping->SymbolHeaderIDs[SymIndex].push_back(AddHeader(HeaderName)); NSSymbolMap = AddNS(QName.take_front(NSLen)); NSSymbols.try_emplace(QName.drop_front(NSLen), SymIndex); @@ -205,8 +207,11 @@ std::optional Symbol::named(llvm::StringRef Scope, llvm::StringRef Name, } return std::nullopt; } -Header Symbol::header() const { - return Header(getMappingPerLang(Language)->SymbolHeaderIDs[ID][0], Language); +std::optional Symbol::header() const { + const auto& Headers = getMappingPerLang(Language)->SymbolHeaderIDs[ID]; + if (Headers.empty()) +return std::nullopt; + return Header(Headers.front(), Language); } llvm::SmallVector Symbol::headers() const { llvm::SmallVector Results; diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc index 3d2ea91a94d36..c9632bee1cbec 100644 --- a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc +++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc @@ -218,3 +218,8 @@ SYMBOL(ssize, std::, ) SYMBOL(ssize, std::, ) SYMBOL(ssize, std::, ) SYMBOL(ssize, std::, ) + +// std::get has a few variants for diff erent types (tuple, array, pair etc) +// which is tricky to disambiguate without type information. +// Don't set any header for it, as it comes with the type header. +SYMBOL(get, std::, /*no headers*/) diff --git a/clang/unittests/Tooling/StandardLibraryTest.cpp b/clang/unittests/Tooling/StandardLibraryTest.cpp index 47d064bdd2a92..6d90bbdf3b6eb 100644 --- a/clang/unittests/Tooling/StandardLibraryTest.cpp +++ b/clang/unittests/Tooling/StandardLibraryTest.cpp @@ -58,6 +58,9 @@ TEST(StdlibTest, All) { EXPECT_EQ(Vector->header(), *VectorH); EXPECT_THAT(Vector->headers(), ElementsAre(*VectorH)); + EXPECT_TRUE(stdlib::Symbol::named("std::", "get")); + EXPECT_FALSE(stdlib::Symbol::named("std::", "get")->header()); + EXPECT_THAT(stdlib::Symbol::named("std::", "basic_iostream")->headers(), ElementsAre(stdlib::Header::named(""),
[clang-tools-extra] 981e3a3 - [clangd] Set diag data before emitting
Author: Kadir Cetinkaya Date: 2023-02-23T16:10:11+01:00 New Revision: 981e3a35a14541afc6fa338abf3f31895b80eed9 URL: https://github.com/llvm/llvm-project/commit/981e3a35a14541afc6fa338abf3f31895b80eed9 DIFF: https://github.com/llvm/llvm-project/commit/981e3a35a14541afc6fa338abf3f31895b80eed9.diff LOG: [clangd] Set diag data before emitting Also fixes a benign use-after-free. Differential Revision: https://reviews.llvm.org/D144641 Added: Modified: clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp Removed: diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp index 26b0047951b51..12a865fcf9e50 100644 --- a/clang-tools-extra/clangd/Diagnostics.cpp +++ b/clang-tools-extra/clangd/Diagnostics.cpp @@ -526,6 +526,9 @@ void toLSPDiags( } } Main.tags = D.Tags; + // FIXME: Get rid of the copies here by taking in a mutable clangd::Diag. + for (auto : D.OpaqueData) +Main.data.insert({Entry.first, Entry.second}); OutFn(std::move(Main), D.Fixes); // If we didn't emit the notes as relatedLocations, emit separate diagnostics @@ -540,10 +543,6 @@ void toLSPDiags( Res.message = noteMessage(D, Note, Opts); OutFn(std::move(Res), llvm::ArrayRef()); } - - // FIXME: Get rid of the copies here by taking in a mutable clangd::Diag. - for (auto : D.OpaqueData) -Main.data.insert({Entry.first, Entry.second}); } int getSeverity(DiagnosticsEngine::Level L) { diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp index 610a290f834aa..a20be39722ec3 100644 --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -23,6 +23,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticSema.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/JSON.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/TargetSelect.h" #include "gmock/gmock.h" @@ -1012,6 +1013,7 @@ TEST(DiagnosticsTest, ToLSP) { D.Severity = DiagnosticsEngine::Error; D.File = "foo/bar/main.cpp"; D.AbsFile = std::string(MainFile.file()); + D.OpaqueData["test"] = "bar"; clangd::Note NoteInMain; NoteInMain.Message = "declared somewhere in the main file"; @@ -1050,6 +1052,7 @@ main.cpp:6:7: remark: declared somewhere in the main file ../foo/baz/header.h:10:11: note: declared somewhere in the header file)"; MainLSP.tags = {DiagnosticTag::Unnecessary}; + MainLSP.data = D.OpaqueData; clangd::Diagnostic NoteInMainLSP; NoteInMainLSP.range = NoteInMain.Range; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 48027f0 - [include-cleaner] Dont pass llvm::StringRef to gtest APIs
Author: Kadir Cetinkaya Date: 2023-02-23T10:04:03+01:00 New Revision: 48027f03f2d5fef884ebe118c42f800b90fae2f9 URL: https://github.com/llvm/llvm-project/commit/48027f03f2d5fef884ebe118c42f800b90fae2f9 DIFF: https://github.com/llvm/llvm-project/commit/48027f03f2d5fef884ebe118c42f800b90fae2f9.diff LOG: [include-cleaner] Dont pass llvm::StringRef to gtest APIs Fixes https://github.com/llvm/llvm-project/issues/60884. Added: Modified: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp index 967ae829e778..c34c6c0a29a8 100644 --- a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp @@ -367,7 +367,7 @@ TEST(WalkUsed, FilterRefsNotSpelledInMainFile) { if (RefLoc.isValid()) { EXPECT_THAT(RefLoc, AllOf(expandedAt(MainFID, Main.point("expand"), ), spelledAt(MainFID, Main.point("spell"), ))) - << T.Main; + << T.Main.str(); } else { EXPECT_THAT(Main.points(), testing::IsEmpty()); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 279b498 - [include-cleaner] Always treat constructor calls as implicit
Author: Kadir Cetinkaya Date: 2023-02-23T10:00:50+01:00 New Revision: 279b4985ed4f62eb8e9a71e79379c2adfa8d8b99 URL: https://github.com/llvm/llvm-project/commit/279b4985ed4f62eb8e9a71e79379c2adfa8d8b99 DIFF: https://github.com/llvm/llvm-project/commit/279b4985ed4f62eb8e9a71e79379c2adfa8d8b99.diff LOG: [include-cleaner] Always treat constructor calls as implicit Treating constructor calls when the type name isn't explicitly spelled can cause spurious results, so turn them into implicit references. This doesn't change the behaviour for constructor calls that explicitly spell the type name, as we should see a reference through the typeloc. Fixes https://github.com/llvm/llvm-project/issues/60812 Differential Revision: https://reviews.llvm.org/D144582 Added: Modified: clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index f317b0dc2d07..0ca84145721a 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -102,9 +102,12 @@ class ASTWalker : public RecursiveASTVisitor { } bool VisitCXXConstructExpr(CXXConstructExpr *E) { +// Always treat consturctor calls as implicit. We'll have an explicit +// reference for the constructor calls that mention the type-name (through +// TypeLocs). This reference only matters for cases where there's no +// explicit syntax at all or there're only braces. report(E->getLocation(), getMemberProvider(E->getType()), - E->getParenOrBraceRange().isValid() ? RefType::Explicit - : RefType::Implicit); + RefType::Implicit); return true; } diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index 3b97cc8cdfd5..7dcbf475e986 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -111,6 +111,9 @@ TEST(WalkAST, TagType) { testWalk("struct $explicit^S {};", "^S *y;"); testWalk("enum $explicit^E {};", "^E *y;"); testWalk("struct $explicit^S { static int x; };", "int y = ^S::x;"); + // One explicit call from the TypeLoc in constructor spelling, another + // implicit reference through the constructor call. + testWalk("struct $explicit^$implicit^S { static int x; };", "auto y = ^S();"); } TEST(WalkAST, Alias) { @@ -241,7 +244,7 @@ TEST(WalkAST, MemberExprs) { TEST(WalkAST, ConstructExprs) { testWalk("struct $implicit^S {};", "S ^t;"); testWalk("struct $implicit^S { S(); };", "S ^t;"); - testWalk("struct $explicit^S { S(int); };", "S ^t(42);"); + testWalk("struct $implicit^S { S(int); };", "S ^t(42);"); testWalk("struct $implicit^S { S(int); };", "S t = ^42;"); testWalk("namespace ns { struct S{}; } using ns::$implicit^S;", "S ^t;"); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 961e32c - [include-cleaner] Check macros against stdlib database
Author: Kadir Cetinkaya Date: 2023-02-23T09:34:37+01:00 New Revision: 961e32c587cb2289e8c2873848b660a153ed5618 URL: https://github.com/llvm/llvm-project/commit/961e32c587cb2289e8c2873848b660a153ed5618 DIFF: https://github.com/llvm/llvm-project/commit/961e32c587cb2289e8c2873848b660a153ed5618.diff LOG: [include-cleaner] Check macros against stdlib database Differential Revision: https://reviews.llvm.org/D144579 Added: Modified: clang-tools-extra/include-cleaner/lib/LocateSymbol.cpp clang-tools-extra/include-cleaner/unittests/LocateSymbolTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/lib/LocateSymbol.cpp b/clang-tools-extra/include-cleaner/lib/LocateSymbol.cpp index 60b18c2fe94fb..78e783a62eb27 100644 --- a/clang-tools-extra/include-cleaner/lib/LocateSymbol.cpp +++ b/clang-tools-extra/include-cleaner/lib/LocateSymbol.cpp @@ -7,6 +7,7 @@ //===--===// #include "AnalysisInternal.h" +#include "clang-include-cleaner/Types.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" @@ -53,6 +54,12 @@ std::vector> locateDecl(const Decl ) { return Result; } +std::vector> locateMacro(const Macro ) { + // FIXME: Should we also provide physical locations? + if (auto SS = tooling::stdlib::Symbol::named("", M.Name->getName())) +return {{*SS, Hints::CompleteSymbol}}; + return {{M.Definition, Hints::CompleteSymbol}}; +} } // namespace std::vector> locateSymbol(const Symbol ) { @@ -60,7 +67,7 @@ std::vector> locateSymbol(const Symbol ) { case Symbol::Declaration: return locateDecl(S.declaration()); case Symbol::Macro: -return {{S.macro().Definition, Hints::CompleteSymbol}}; +return locateMacro(S.macro()); } llvm_unreachable("Unknown Symbol::Kind enum"); } diff --git a/clang-tools-extra/include-cleaner/unittests/LocateSymbolTest.cpp b/clang-tools-extra/include-cleaner/unittests/LocateSymbolTest.cpp index 16a185269b5d9..9961b013b24d8 100644 --- a/clang-tools-extra/include-cleaner/unittests/LocateSymbolTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/LocateSymbolTest.cpp @@ -122,9 +122,17 @@ TEST(LocateSymbol, Decl) { } TEST(LocateSymbol, Stdlib) { - LocateExample Test("namespace std { struct vector; }"); - EXPECT_THAT(locateSymbol(Test.findDecl("vector")), - ElementsAre(*tooling::stdlib::Symbol::named("std::", "vector"))); + { +LocateExample Test("namespace std { struct vector; }"); +EXPECT_THAT( +locateSymbol(Test.findDecl("vector")), +ElementsAre(*tooling::stdlib::Symbol::named("std::", "vector"))); + } + { +LocateExample Test("#define assert(x)\nvoid foo() { assert(true); }"); +EXPECT_THAT(locateSymbol(Test.findMacro("assert")), +ElementsAre(*tooling::stdlib::Symbol::named("", "assert"))); + } } TEST(LocateSymbol, Macros) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 465ee9b - [clangd] Publish diagnostics with stale preambles
Author: Kadir Cetinkaya Date: 2023-02-22T15:54:16+01:00 New Revision: 465ee9bfb26d46f2732d8b238dcbadc38373dbb3 URL: https://github.com/llvm/llvm-project/commit/465ee9bfb26d46f2732d8b238dcbadc38373dbb3 DIFF: https://github.com/llvm/llvm-project/commit/465ee9bfb26d46f2732d8b238dcbadc38373dbb3.diff LOG: [clangd] Publish diagnostics with stale preambles This patch achieves this by building an AST and invoking main file callbacks on each update, in addition to preamble updates. It means we might have some extra AST builds now (e.g. if an update was with a stale preamble and there were no reads on it, we would only build an AST once we had the fresh preamble. Now we'll build 2, once with the stale preamble and another with the fresh one, but we'll have one more diagnostics cycle in between.). This patch preserves forward progress of diagnostics by always using the latest main file contents when emitting diagnostics after preamble builds. It also guarantees eventual consistency: - if an update doesn't invalidate preamble, we'll emit diagnostics with fresh preamble already. - if an update invalidates preamble, we'll first emit diagnostics with stale contents, and then once the preamble build finishes it'll emit diagnostics (as preamble has changed) with newest version. This has implications on parsing callbacks, as previously onMainAST callback was called at most once, now it can be called up to 2 times. All of the existing clients can already deal with callback firing multiple times. Differential Revision: https://reviews.llvm.org/D144456 Added: Modified: clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp Removed: diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp index 354638cd7b1e..a4f6a93b616a 100644 --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -49,6 +49,7 @@ #include "TUScheduler.h" #include "CompileCommands.h" #include "Compiler.h" +#include "Config.h" #include "Diagnostics.h" #include "GlobalCompilationDatabase.h" #include "ParsedAST.h" @@ -938,8 +939,19 @@ void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags, return; } -PreamblePeer.update(std::move(Invocation), std::move(Inputs), -std::move(CompilerInvocationDiags), WantDiags); +// Inform preamble peer, before attempting to build diagnostics so that they +// can be built concurrently. +PreamblePeer.update(std::make_unique(*Invocation), +Inputs, CompilerInvocationDiags, WantDiags); + +// Emit diagnostics from (possibly) stale preamble while waiting for a +// rebuild. Newly built preamble cannot emit diagnostics before this call +// finishes (ast callbacks are called from astpeer thread), hence we +// gurantee eventual consistency. +if (LatestPreamble && Config::current().Diagnostics.AllowStalePreamble) + generateDiagnostics(std::move(Invocation), std::move(Inputs), + std::move(CompilerInvocationDiags)); + std::unique_lock Lock(Mutex); PreambleCV.wait(Lock, [this] { // Block until we reiceve a preamble request, unless a preamble already @@ -1118,6 +1130,18 @@ void ASTWorker::updatePreamble(std::unique_ptr CI, // We only need to build the AST if diagnostics were requested. if (WantDiags == WantDiagnostics::No) return; +// The file may have been edited since we started building this preamble. +// If diagnostics need a fresh preamble, we must use the old version that +// matches the preamble. We make forward progress as updatePreamble() +// receives increasing versions, and this is the only place we emit +// diagnostics. +// If diagnostics can use a stale preamble, we use the current contents of +// the file instead. This provides more up-to-date diagnostics, and avoids +// diagnostics going backwards (we may have already emitted staler-preamble +// diagnostics for the new version). We still have eventual consistency: at +// some point updatePreamble() will catch up to the current file. +if (Config::current().Diagnostics.AllowStalePreamble) + PI = FileInputs; // Report diagnostics with the new preamble to ensure progress. Otherwise // diagnostics might get stale indefinitely if user keeps invalidating the // preamble. diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp index 5b3cab16ddb6..ead85a4ce5f2 100644 --- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp +++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp @@ -8,6 +8,8 @@ #include "Annotations.h" #include "ClangdServer.h" +#include "Compiler.h" +#include "Config.h" #include "Diagnostics.h"
[clang-tools-extra] 8c2a12f - [clangd] Provide patched diagnostics with preamble patch
Author: Kadir Cetinkaya Date: 2023-02-22T15:54:15+01:00 New Revision: 8c2a12f7f9b6dc078bfb18df979fdf27c6a3 URL: https://github.com/llvm/llvm-project/commit/8c2a12f7f9b6dc078bfb18df979fdf27c6a3 DIFF: https://github.com/llvm/llvm-project/commit/8c2a12f7f9b6dc078bfb18df979fdf27c6a3.diff LOG: [clangd] Provide patched diagnostics with preamble patch Translates diagnostics from baseline preamble to relevant modified contents. Translation is done by looking for a set of lines that have the same contents in diagnostic/note/fix ranges inside baseline and modified contents. A diagnostic is preserved if its main range is outside of main file or there's a translation from baseline to modified contents. Later on fixes and notes attached to that diagnostic with relevant ranges are also translated and preserved. Depends on D143095 Differential Revision: https://reviews.llvm.org/D143096 Added: Modified: clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/unittests/PreambleTests.cpp Removed: diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index bf639a6fb58e..54a0f979c730 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -675,8 +675,7 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs , Diags = CompilerInvocationDiags; // Add diagnostics from the preamble, if any. if (Preamble) - Diags->insert(Diags->end(), Preamble->Diags.begin(), -Preamble->Diags.end()); + llvm::append_range(*Diags, Patch->patchedDiags()); // Finally, add diagnostics coming from the AST. { std::vector D = ASTDiags.take(&*CTContext); diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index 6a7efcd255d2..e97564497954 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -9,7 +9,9 @@ #include "Preamble.h" #include "Compiler.h" #include "Config.h" +#include "Diagnostics.h" #include "Headers.h" +#include "Protocol.h" #include "SourceCode.h" #include "clang-include-cleaner/Record.h" #include "support/Logger.h" @@ -35,6 +37,9 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" @@ -43,8 +48,9 @@ #include "llvm/Support/Path.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" -#include +#include #include +#include #include #include #include @@ -306,6 +312,8 @@ struct DirectiveCollector : public PPCallbacks { struct ScannedPreamble { std::vector Includes; std::vector TextualDirectives; + // Literal lines of the preamble contents. + std::vector Lines; PreambleBounds Bounds = {0, false}; }; @@ -332,7 +340,7 @@ scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand ) { if (!CI) return error("failed to create compiler invocation"); CI->getDiagnosticOpts().IgnoreWarnings = true; - auto ContentsBuffer = llvm::MemoryBuffer::getMemBuffer(Contents); + auto ContentsBuffer = llvm::MemoryBuffer::getMemBuffer(PI.Contents); // This means we're scanning (though not preprocessing) the preamble section // twice. However, it's important to precisely follow the preamble bounds used // elsewhere. @@ -363,6 +371,7 @@ scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand ) { return std::move(Err); Action.EndSourceFile(); SP.Includes = std::move(Includes.MainFileIncludes); + llvm::append_range(SP.Lines, llvm::split(Contents, "\n")); return SP; } @@ -465,6 +474,93 @@ class TimerFS : public llvm::vfs::ProxyFileSystem { WallTimer Timer; }; +// Helpers for patching diagnostics between two versions of file contents. +class DiagPatcher { + llvm::ArrayRef OldLines; + llvm::ArrayRef CurrentLines; + llvm::StringMap> CurrentContentsToLine; + + // Translates a range from old lines to current lines. + // Finds the consecutive set of lines that corresponds to the same contents in + // old and current, and applies the same translation to the range. + // Returns true if translation succeeded. + bool translateRange(Range ) { +int OldStart = R.start.line; +int OldEnd = R.end.line; +assert(OldStart <= OldEnd); + +size_t RangeLen = OldEnd - OldStart + 1; +auto RangeContents = OldLines.slice(OldStart).take_front(RangeLen); +// Make sure the whole range is covered in old contents. +if (RangeContents.size() < RangeLen) + return false; + +std::optional Closest; +for (int
[clang-tools-extra] 909cd1f - [clangd] Respect preamble-patch when handling diags
Author: Kadir Cetinkaya Date: 2023-02-22T15:54:15+01:00 New Revision: 909cd1f9a8934033a803659da8c54c87013941ef URL: https://github.com/llvm/llvm-project/commit/909cd1f9a8934033a803659da8c54c87013941ef DIFF: https://github.com/llvm/llvm-project/commit/909cd1f9a8934033a803659da8c54c87013941ef.diff LOG: [clangd] Respect preamble-patch when handling diags Depends on D143093 Differential Revision: https://reviews.llvm.org/D143095 Added: Modified: clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/SourceCode.cpp clang-tools-extra/clangd/SourceCode.h clang-tools-extra/clangd/unittests/PreambleTests.cpp Removed: diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp index 652e9e13b6e2..26b0047951b5 100644 --- a/clang-tools-extra/clangd/Diagnostics.cpp +++ b/clang-tools-extra/clangd/Diagnostics.cpp @@ -98,17 +98,22 @@ bool locationInRange(SourceLocation L, CharSourceRange R, // LSP needs a single range. Range diagnosticRange(const clang::Diagnostic , const LangOptions ) { auto = D.getSourceManager(); + auto PatchedRange = [](CharSourceRange ) { +R.setBegin(translatePreamblePatchLocation(R.getBegin(), M)); +R.setEnd(translatePreamblePatchLocation(R.getEnd(), M)); +return R; + }; auto Loc = M.getFileLoc(D.getLocation()); for (const auto : D.getRanges()) { auto R = Lexer::makeFileCharRange(CR, M, L); if (locationInRange(Loc, R, M)) - return halfOpenToRange(M, R); + return halfOpenToRange(M, PatchedRange(R)); } // The range may be given as a fixit hint instead. for (const auto : D.getFixItHints()) { auto R = Lexer::makeFileCharRange(F.RemoveRange, M, L); if (locationInRange(Loc, R, M)) - return halfOpenToRange(M, R); + return halfOpenToRange(M, PatchedRange(R)); } // If the token at the location is not a comment, we use the token. // If we can't get the token at the location, fall back to using the location @@ -117,7 +122,7 @@ Range diagnosticRange(const clang::Diagnostic , const LangOptions ) { if (!Lexer::getRawToken(Loc, Tok, M, L, true) && Tok.isNot(tok::comment)) { R = CharSourceRange::getTokenRange(Tok.getLocation(), Tok.getEndLoc()); } - return halfOpenToRange(M, R); + return halfOpenToRange(M, PatchedRange(R)); } // Try to find a location in the main-file to report the diagnostic D. @@ -213,13 +218,6 @@ bool tryMoveToMainFile(Diag , FullSourceLoc DiagLoc) { return true; } -bool isInsideMainFile(const clang::Diagnostic ) { - if (!D.hasSourceManager()) -return false; - - return clangd::isInsideMainFile(D.getLocation(), D.getSourceManager()); -} - bool isNote(DiagnosticsEngine::Level L) { return L == DiagnosticsEngine::Note || L == DiagnosticsEngine::Remark; } @@ -713,11 +711,15 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, auto FillDiagBase = [&](DiagBase ) { fillNonLocationData(DiagLevel, Info, D); -D.InsideMainFile = isInsideMainFile(Info); +SourceLocation PatchLoc = +translatePreamblePatchLocation(Info.getLocation(), SM); +D.InsideMainFile = isInsideMainFile(PatchLoc, SM); D.Range = diagnosticRange(Info, *LangOpts); -D.File = std::string(SM.getFilename(Info.getLocation())); -D.AbsFile = getCanonicalPath( -SM.getFileEntryForID(SM.getFileID(Info.getLocation())), SM); +auto FID = SM.getFileID(Info.getLocation()); +if (auto *FE = SM.getFileEntryForID(FID)) { + D.File = FE->getName().str(); + D.AbsFile = getCanonicalPath(FE, SM); +} D.ID = Info.getID(); return D; }; diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index d01601e5a037..6a7efcd255d2 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -53,7 +53,6 @@ namespace clang { namespace clangd { namespace { -constexpr llvm::StringLiteral PreamblePatchHeaderName = "__preamble_patch__.h"; bool compileCommandsAreEqual(const tooling::CompileCommand , const tooling::CompileCommand ) { @@ -381,12 +380,6 @@ const char *spellingForIncDirective(tok::PPKeywordKind IncludeDirective) { llvm_unreachable("not an include directive"); } -// Checks whether \p FileName is a valid spelling of main file. -bool isMainFile(llvm::StringRef FileName, const SourceManager ) { - auto FE = SM.getFileManager().getFile(FileName); - return FE && *FE == SM.getFileEntryForID(SM.getMainFileID()); -} - // Accumulating wall time timer. Similar to llvm::Timer, but much cheaper, // it only tracks wall time. // Since this is a generic timer, We may want to move this to support/ if we @@ -660,7 +653,7 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName, //
[clang-tools-extra] 75ae784 - [clangd] #undef macros inside preamble patch
Author: Kadir Cetinkaya Date: 2023-02-22T15:54:15+01:00 New Revision: 75ae784e8f49cf2425f3bf702a1bbf6c581e721a URL: https://github.com/llvm/llvm-project/commit/75ae784e8f49cf2425f3bf702a1bbf6c581e721a DIFF: https://github.com/llvm/llvm-project/commit/75ae784e8f49cf2425f3bf702a1bbf6c581e721a.diff LOG: [clangd] #undef macros inside preamble patch That way we can stop generating false macro redefinition diagnostics. Depends on D142890 Differential Revision: https://reviews.llvm.org/D143093 Added: Modified: clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/unittests/PreambleTests.cpp Removed: diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index f442c852c571..d01601e5a037 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -213,6 +213,9 @@ struct TextualPPDirective { // Full text that's representing the directive, including the `#`. std::string Text; unsigned Offset; + tok::PPKeywordKind Directive = tok::PPKeywordKind::pp_not_keyword; + // Name of the macro being defined in the case of a #define directive. + std::string MacroName; bool operator==(const TextualPPDirective ) const { return std::tie(DirectiveLine, Offset, Text) == @@ -283,6 +286,8 @@ struct DirectiveCollector : public PPCallbacks { return; TextualDirectives.emplace_back(); TextualPPDirective = TextualDirectives.back(); +TD.Directive = tok::pp_define; +TD.MacroName = MacroNameTok.getIdentifierInfo()->getName().str(); const auto *MI = MD->getMacroInfo(); TD.Text = @@ -560,8 +565,8 @@ buildPreamble(PathRef FileName, CompilerInvocation CI, if (BuiltPreamble) { log("Built preamble of size {0} for file {1} version {2} in {3} seconds", - BuiltPreamble->getSize(), FileName, Inputs.Version, - PreambleTimer.getTime()); +BuiltPreamble->getSize(), FileName, Inputs.Version, +PreambleTimer.getTime()); std::vector Diags = PreambleDiagnostics.take(); auto Result = std::make_shared(std::move(*BuiltPreamble)); Result->Version = Inputs.Version; @@ -724,6 +729,10 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName, // reduce complexity. The former might cause problems because scanning is // imprecise and might pick directives from disabled regions. for (const auto : ModifiedScan->TextualDirectives) { + // Introduce an #undef directive before #defines to suppress any + // re-definition warnings. + if (TD.Directive == tok::pp_define) +Patch << "#undef " << TD.MacroName << '\n'; Patch << "#line " << TD.DirectiveLine << '\n'; Patch << TD.Text << '\n'; } diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp index 0bd5a9f80641..68de063f7168 100644 --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -288,6 +288,7 @@ TEST(PreamblePatchTest, Define) { #define BAR [[BAR]])cpp", R"cpp(#line 0 ".*main.cpp" +#undef BAR #line 2 #define BAR )cpp", @@ -299,6 +300,7 @@ TEST(PreamblePatchTest, Define) { [[BAR]])cpp", R"cpp(#line 0 ".*main.cpp" +#undef BAR #line 2 #define BAR )cpp", @@ -310,6 +312,7 @@ TEST(PreamblePatchTest, Define) { BAR [[BAR]])cpp", R"cpp(#line 0 ".*main.cpp" +#undef BAR #line 3 #define BAR )cpp", @@ -342,8 +345,10 @@ TEST(PreamblePatchTest, OrderingPreserved) { )cpp"); llvm::StringLiteral ExpectedPatch(R"cpp(#line 0 ".*main.cpp" +#undef BAR #line 2 #define BAR\(X, Y\) X Y +#undef BAR #line 3 #define BAR\(X\) X )cpp"); @@ -693,23 +698,17 @@ TEST(PreamblePatch, DiagnosticsToPreamble) { { Annotations Code("#define [[FOO]] 1\n"); // Check ranges for notes. -Annotations NewCode(R"(#define $barxyz[[BARXYZ]] 1 +Annotations NewCode(R"(#define BARXYZ 1 #define $foo1[[FOO]] 1 void foo(); #define $foo2[[FOO]] 2)"); auto AST = createPatchedAST(Code.code(), NewCode.code(), AdditionalFiles); EXPECT_THAT( *AST->getDiagnostics(), -ElementsAre( -// FIXME: This diagnostics shouldn't exist. It's emitted from the -// preamble patch to the stale location inside preamble. -AllOf(Field(::Name, Eq("-Wmacro-redefined")), - Field(::File, HasSubstr("_preamble_patch_")), - withNote(Diag(NewCode.range("barxyz", -AllOf( -Diag(NewCode.range("foo2"), "-Wmacro-redefined"), -// FIXME: This should be translated into main file. -withNote(Field(::File, HasSubstr("_preamble_patch_")); +ElementsAre(AllOf( +
[clang-tools-extra] 7177a23 - [clangd] Add config option for fast diagnostics mode
Author: Kadir Cetinkaya Date: 2023-02-22T15:54:14+01:00 New Revision: 7177a237b68f32befcecedba78a875f1bbc4a609 URL: https://github.com/llvm/llvm-project/commit/7177a237b68f32befcecedba78a875f1bbc4a609 DIFF: https://github.com/llvm/llvm-project/commit/7177a237b68f32befcecedba78a875f1bbc4a609.diff LOG: [clangd] Add config option for fast diagnostics mode Also wire it up for use with patched preambles and introduce test cases for behaviour we'd like to improve. Differential Revision: https://reviews.llvm.org/D142890 Added: Modified: clang-tools-extra/clangd/Config.h clang-tools-extra/clangd/ConfigCompile.cpp clang-tools-extra/clangd/ConfigFragment.h clang-tools-extra/clangd/ConfigYAML.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp clang-tools-extra/clangd/unittests/PreambleTests.cpp Removed: diff --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h index f41906b2f0faf..dffd54b01c459 100644 --- a/clang-tools-extra/clangd/Config.h +++ b/clang-tools-extra/clangd/Config.h @@ -88,7 +88,7 @@ struct Config { bool StandardLibrary = true; } Index; - enum UnusedIncludesPolicy { + enum class UnusedIncludesPolicy { /// Diagnose unused includes. Strict, None, @@ -107,7 +107,10 @@ struct Config { llvm::StringMap CheckOptions; } ClangTidy; -UnusedIncludesPolicy UnusedIncludes = None; +UnusedIncludesPolicy UnusedIncludes = UnusedIncludesPolicy::None; + +/// Enable emitting diagnostics using stale preambles. +bool AllowStalePreamble = false; /// IncludeCleaner will not diagnose usages of these headers matched by /// these regexes. diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp index b1876e21ee30d..18de6e4d5c3b6 100644 --- a/clang-tools-extra/clangd/ConfigCompile.cpp +++ b/clang-tools-extra/clangd/ConfigCompile.cpp @@ -441,8 +441,14 @@ struct FragmentCompiler { Out.Apply.push_back([Val](const Params &, Config ) { C.Diagnostics.UnusedIncludes = *Val; }); -compile(std::move(F.Includes)); +if (F.AllowStalePreamble) { + if (auto Val = F.AllowStalePreamble) +Out.Apply.push_back([Val](const Params &, Config ) { + C.Diagnostics.AllowStalePreamble = **Val; +}); +} +compile(std::move(F.Includes)); compile(std::move(F.ClangTidy)); } diff --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h index bcd1a05b4a999..a5597596196fa 100644 --- a/clang-tools-extra/clangd/ConfigFragment.h +++ b/clang-tools-extra/clangd/ConfigFragment.h @@ -232,9 +232,13 @@ struct Fragment { /// /// Valid values are: /// - Strict +/// - Experiment /// - None std::optional> UnusedIncludes; +/// Enable emitting diagnostics using stale preambles. +std::optional> AllowStalePreamble; + /// Controls IncludeCleaner diagnostics. struct IncludesBlock { /// Regexes that will be used to avoid diagnosing certain includes as diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp index ee91753dd88dd..0ec0239fc71e6 100644 --- a/clang-tools-extra/clangd/ConfigYAML.cpp +++ b/clang-tools-extra/clangd/ConfigYAML.cpp @@ -130,6 +130,9 @@ class Parser { }); Dict.handle("Includes", [&](Node ) { parse(F.Includes, N); }); Dict.handle("ClangTidy", [&](Node ) { parse(F.ClangTidy, N); }); +Dict.handle("AllowStalePreamble", [&](Node ) { + F.AllowStalePreamble = boolValue(N, "AllowStalePreamble"); +}); Dict.parse(N); } @@ -268,7 +271,7 @@ class Parser { // If Key is seen twice, Parse runs only once and an error is reported. void handle(llvm::StringLiteral Key, std::function Parse) { for (const auto : Keys) { -(void) Entry; +(void)Entry; assert(Entry.first != Key && "duplicate key handler"); } Keys.emplace_back(Key, std::move(Parse)); diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index f99c4142a4640..f442c852c571a 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -792,5 +792,9 @@ SourceLocation translatePreamblePatchLocation(SourceLocation Loc, return Loc; } +bool PreamblePatch::preserveDiagnostics() const { + return PatchContents.empty() || + Config::current().Diagnostics.AllowStalePreamble; +} } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/Preamble.h b/clang-tools-extra/clangd/Preamble.h index bd5fefcf8f0bc..438a4561cac1c 100644 ---
[clang] 46cdf7f - [Tooling][Stdlib][NFC] Reflow comments and strip clang-format pragmas
Author: Kadir Cetinkaya Date: 2023-02-14T09:46:41+01:00 New Revision: 46cdf7f0991280a3601a777a80fbc460196fb033 URL: https://github.com/llvm/llvm-project/commit/46cdf7f0991280a3601a777a80fbc460196fb033 DIFF: https://github.com/llvm/llvm-project/commit/46cdf7f0991280a3601a777a80fbc460196fb033.diff LOG: [Tooling][Stdlib][NFC] Reflow comments and strip clang-format pragmas Added: Modified: clang/lib/Tooling/Inclusions/Stdlib/StdTsSymbolMap.inc Removed: diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdTsSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdTsSymbolMap.inc index 7fd17ed49c72c..2733cb3f2ec4b 100644 --- a/clang/lib/Tooling/Inclusions/Stdlib/StdTsSymbolMap.inc +++ b/clang/lib/Tooling/Inclusions/Stdlib/StdTsSymbolMap.inc @@ -1,6 +1,5 @@ -// These are derived from N4100[fs.filesystem.synopsis], final -// draft for experimental filesystem. -// clang-format off +// These are derived from N4100[fs.filesystem.synopsis], final draft for +// experimental filesystem. SYMBOL(absolute, std::experimental::filesystem::, ) SYMBOL(canonical, std::experimental::filesystem::, ) SYMBOL(copy, std::experimental::filesystem::, ) @@ -51,4 +50,3 @@ SYMBOL(symlink_status, std::experimental::filesystem::, ) SYMBOL(temp_directory_path, std::experimental::filesystem::, ) SYMBOL(u8path, std::experimental::filesystem::, ) -// clang-format on ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] fae01d1 - [clangd] Fix bugs in main-file include patching for stale preambles
Author: Kadir Cetinkaya Date: 2023-02-13T09:49:13+01:00 New Revision: fae01d175a29270ec01211d3988c7ae57ddabfd3 URL: https://github.com/llvm/llvm-project/commit/fae01d175a29270ec01211d3988c7ae57ddabfd3 DIFF: https://github.com/llvm/llvm-project/commit/fae01d175a29270ec01211d3988c7ae57ddabfd3.diff LOG: [clangd] Fix bugs in main-file include patching for stale preambles - Make sure main file includes are present even when they're not patched (because they didn't change or we're explicitly not patching them). - Populate extra fields for includes, which can be used by include-cleaner. Differential Revision: https://reviews.llvm.org/D143197 Added: Modified: clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/unittests/PreambleTests.cpp Removed: diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index 15eea9bb036bd..cdb8db14722d2 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -671,10 +671,10 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName, // We are only interested in newly added includes, record the ones in // Baseline for exclusion. llvm::DenseMap, - /*Resolved=*/llvm::StringRef> + const Inclusion *> ExistingIncludes; for (const auto : Baseline.Includes.MainFileIncludes) - ExistingIncludes[{Inc.Directive, Inc.Written}] = Inc.Resolved; + ExistingIncludes[{Inc.Directive, Inc.Written}] = // There might be includes coming from disabled regions, record these for // exclusion too. note that we don't have resolved paths for those. for (const auto : BaselineScan->Includes) @@ -685,8 +685,13 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName, // Include already present in the baseline preamble. Set resolved path and // put into preamble includes. if (It != ExistingIncludes.end()) { -Inc.Resolved = It->second.str(); -PP.PreambleIncludes.push_back(Inc); +auto = PP.PreambleIncludes.emplace_back(); +// Copy everything from existing include, apart from the location, when +// it's coming from baseline preamble. +if (It->second) + PatchedInc = *It->second; +PatchedInc.HashLine = Inc.HashLine; +PatchedInc.HashOffset = Inc.HashOffset; continue; } // Include is new in the modified preamble. Inject it into the patch and @@ -696,6 +701,11 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName, Patch << llvm::formatv( "#{0} {1}\n", spellingForIncDirective(Inc.Directive), Inc.Written); } + } else { +// Make sure we have the full set of includes available even when we're not +// patching. As these are used by features we provide afterwards like hover, +// go-to-def or include-cleaner when preamble is stale. +PP.PreambleIncludes = Baseline.Includes.MainFileIncludes; } if (DirectivesChanged) { diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp index 1e95b62884f69..ac46bfd06a138 100644 --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -15,6 +15,7 @@ #include "TestFS.h" #include "TestTU.h" #include "XRefs.h" +#include "clang/Basic/SourceManager.h" #include "clang/Format/Format.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Frontend/PrecompiledPreamble.h" @@ -23,6 +24,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/VirtualFileSystem.h" #include "gmock/gmock.h" +#include "gtest/gtest-matchers.h" #include "gtest/gtest.h" #include #include @@ -166,7 +168,7 @@ TEST(PreamblePatchTest, PatchesPreambleIncludes) { MockFS FS; IgnoreDiagnostics Diags; auto TU = TestTU::withCode(R"cpp( -#include "a.h" +#include "a.h" // IWYU pragma: keep #include "c.h" )cpp"); TU.AdditionalFiles["a.h"] = "#include \"b.h\""; @@ -185,9 +187,14 @@ TEST(PreamblePatchTest, PatchesPreambleIncludes) { *BaselinePreamble); // Only a.h should exists in the preamble, as c.h has been dropped and b.h was // newly introduced. - EXPECT_THAT(PP.preambleIncludes(), - ElementsAre(AllOf(Field(::Written, "\"a.h\""), -Field(::Resolved, testPath("a.h"); + EXPECT_THAT( + PP.preambleIncludes(), + ElementsAre(AllOf( + Field(::Written, "\"a.h\""), + Field(::Resolved, testPath("a.h")), + Field(::HeaderID, testing::Not(testing::Eq(std::nullopt))), + Field(::BehindPragmaKeep, true), + Field(::FileKind, SrcMgr::CharacteristicKind::C_User; } std::optional createPatchedAST(llvm::StringRef Baseline, @@
[clang-tools-extra] 19659b5 - [clangd] Drop includes from disabled PP regions in preamble patch
Author: Kadir Cetinkaya Date: 2023-02-13T09:49:13+01:00 New Revision: 19659b5f0dd1a1dcf745cf058d042ada2d4ff061 URL: https://github.com/llvm/llvm-project/commit/19659b5f0dd1a1dcf745cf058d042ada2d4ff061 DIFF: https://github.com/llvm/llvm-project/commit/19659b5f0dd1a1dcf745cf058d042ada2d4ff061.diff LOG: [clangd] Drop includes from disabled PP regions in preamble patch In rest of the clangd functionality we treat these includes as non-existent. Do so under preamble patching. Depends on D143197 Differential Revision: https://reviews.llvm.org/D143597 Added: Modified: clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/unittests/PreambleTests.cpp Removed: diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index cdb8db14722d..f99c4142a464 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -685,13 +685,16 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName, // Include already present in the baseline preamble. Set resolved path and // put into preamble includes. if (It != ExistingIncludes.end()) { -auto = PP.PreambleIncludes.emplace_back(); -// Copy everything from existing include, apart from the location, when -// it's coming from baseline preamble. -if (It->second) +if (It->second) { + // If this header is included in an active region of the baseline + // preamble, preserve it. + auto = PP.PreambleIncludes.emplace_back(); + // Copy everything from existing include, apart from the location, + // when it's coming from baseline preamble. PatchedInc = *It->second; -PatchedInc.HashLine = Inc.HashLine; -PatchedInc.HashOffset = Inc.HashOffset; + PatchedInc.HashLine = Inc.HashLine; + PatchedInc.HashOffset = Inc.HashOffset; +} continue; } // Include is new in the modified preamble. Inject it into the patch and diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp index ac46bfd06a13..ae353f94ce06 100644 --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -170,6 +170,9 @@ TEST(PreamblePatchTest, PatchesPreambleIncludes) { auto TU = TestTU::withCode(R"cpp( #include "a.h" // IWYU pragma: keep #include "c.h" +#ifdef FOO +#include "d.h" +#endif )cpp"); TU.AdditionalFiles["a.h"] = "#include \"b.h\""; TU.AdditionalFiles["b.h"] = ""; @@ -178,10 +181,14 @@ TEST(PreamblePatchTest, PatchesPreambleIncludes) { auto BaselinePreamble = buildPreamble( TU.Filename, *buildCompilerInvocation(PI, Diags), PI, true, nullptr); // We drop c.h from modified and add a new header. Since the latter is patched - // we should only get a.h in preamble includes. + // we should only get a.h in preamble includes. d.h shouldn't be part of the + // preamble, as it's coming from a disabled region. TU.Code = R"cpp( #include "a.h" #include "b.h" +#ifdef FOO +#include "d.h" +#endif )cpp"; auto PP = PreamblePatch::createFullPatch(testPath(TU.Filename), TU.inputs(FS), *BaselinePreamble); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] c0afb6d - [clangd] Stop filtering lit tests based on target-triple
Author: Kadir Cetinkaya Date: 2023-01-31T08:01:38+01:00 New Revision: c0afb6de4fc837d634d99b76ae73636a1f3ca73d URL: https://github.com/llvm/llvm-project/commit/c0afb6de4fc837d634d99b76ae73636a1f3ca73d DIFF: https://github.com/llvm/llvm-project/commit/c0afb6de4fc837d634d99b76ae73636a1f3ca73d.diff LOG: [clangd] Stop filtering lit tests based on target-triple We are performing this filtering due to having unix style file paths in certain tests. Hence we're actually trying to filter based on host platform and not the target-triple LLVM is using. 2493a7016416c90038be5c816e12a7ad07cee054 introduced filtering based on host platform already, so we can get rid of target-triple based filtering now. Added: Modified: clang-tools-extra/clangd/test/dependency-output.test clang-tools-extra/clangd/test/did-change-configuration-params.test clang-tools-extra/clangd/test/test-uri-posix.test Removed: diff --git a/clang-tools-extra/clangd/test/dependency-output.test b/clang-tools-extra/clangd/test/dependency-output.test index a53315809a5c4..c532cd00db5c1 100644 --- a/clang-tools-extra/clangd/test/dependency-output.test +++ b/clang-tools-extra/clangd/test/dependency-output.test @@ -1,4 +1,4 @@ -# UNSUPPORTED: system-windows, target={{.*-windows-(gnu|msvc)}} +# UNSUPPORTED: system-windows # RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} --- diff --git a/clang-tools-extra/clangd/test/did-change-configuration-params.test b/clang-tools-extra/clangd/test/did-change-configuration-params.test index ae0d37a347a25..08c7b4bcb57ad 100644 --- a/clang-tools-extra/clangd/test/did-change-configuration-params.test +++ b/clang-tools-extra/clangd/test/did-change-configuration-params.test @@ -1,6 +1,6 @@ # RUN: clangd -compile_args_from=lsp -lit-test < %s 2> %t | FileCheck -strict-whitespace %s # RUN: FileCheck --check-prefix=ERR --input-file=%t %s -# UNSUPPORTED: system-windows, target={{.*-windows-(gnu|msvc)}} +# UNSUPPORTED: system-windows {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} --- {"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabaseChanges":{"/clangd-test/foo.c": {"workingDirectory":"/clangd-test", "compilationCommand": ["clang", "-c", "foo.c"]} diff --git a/clang-tools-extra/clangd/test/test-uri-posix.test b/clang-tools-extra/clangd/test/test-uri-posix.test index d321b96c3ca6c..dc7dc7825c99e 100644 --- a/clang-tools-extra/clangd/test/test-uri-posix.test +++ b/clang-tools-extra/clangd/test/test-uri-posix.test @@ -1,5 +1,5 @@ # RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s -# UNSUPPORTED: system-windows, target={{.*-windows-(gnu|msvc)}} +# UNSUPPORTED: system-windows # Test authority-less URI {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} --- ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 749c6a7 - [include-cleaner] Ranking of providers based on hints
Author: Kadir Cetinkaya Date: 2023-01-23T15:22:47+01:00 New Revision: 749c6a708340f772f72e1d33594cdb51bb28e190 URL: https://github.com/llvm/llvm-project/commit/749c6a708340f772f72e1d33594cdb51bb28e190 DIFF: https://github.com/llvm/llvm-project/commit/749c6a708340f772f72e1d33594cdb51bb28e190.diff LOG: [include-cleaner] Ranking of providers based on hints Introduce signals to rank providers of a symbol. Differential Revision: https://reviews.llvm.org/D139921 Added: clang-tools-extra/include-cleaner/lib/TypesInternal.h Modified: clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h clang-tools-extra/include-cleaner/lib/Analysis.cpp clang-tools-extra/include-cleaner/lib/AnalysisInternal.h clang-tools-extra/include-cleaner/lib/FindHeaders.cpp clang-tools-extra/include-cleaner/lib/HTMLReport.cpp clang-tools-extra/include-cleaner/lib/LocateSymbol.cpp clang-tools-extra/include-cleaner/lib/Types.cpp clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp clang-tools-extra/include-cleaner/unittests/LocateSymbolTest.cpp Removed: diff --git a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h index 102f5bc21a84c..05cb96ebec1ff 100644 --- a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h +++ b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h @@ -29,6 +29,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include +#include #include namespace llvm { @@ -71,7 +72,11 @@ struct Symbol { // Order must match Kind enum! std::variant Storage; - Symbol(decltype(Storage) Sentinel) : Storage(std::move(Sentinel)) {} + // Disambiguation tag to make sure we can call the right constructor from + // DenseMapInfo methods. + struct SentinelTag {}; + Symbol(SentinelTag, decltype(Storage) Sentinel) + : Storage(std::move(Sentinel)) {} friend llvm::DenseMapInfo; }; llvm::raw_ostream <<(llvm::raw_ostream &, const Symbol &); @@ -117,6 +122,7 @@ struct Header { Kind kind() const { return static_cast(Storage.index()); } bool operator==(const Header ) const { return Storage == RHS.Storage; } + bool operator<(const Header ) const; const FileEntry *physical() const { return std::get(Storage); } tooling::stdlib::Header standard() const { @@ -127,6 +133,13 @@ struct Header { private: // Order must match Kind enum! std::variant Storage; + + // Disambiguation tag to make sure we can call the right constructor from + // DenseMapInfo methods. + struct SentinelTag {}; + Header(SentinelTag, decltype(Storage) Sentinel) + : Storage(std::move(Sentinel)) {} + friend llvm::DenseMapInfo; }; llvm::raw_ostream <<(llvm::raw_ostream &, const Header &); @@ -178,8 +191,12 @@ template <> struct DenseMapInfo { using Outer = clang::include_cleaner::Symbol; using Base = DenseMapInfo; - static inline Outer getEmptyKey() { return {Base::getEmptyKey()}; } - static inline Outer getTombstoneKey() { return {Base::getTombstoneKey()}; } + static inline Outer getEmptyKey() { +return {Outer::SentinelTag{}, Base::getEmptyKey()}; + } + static inline Outer getTombstoneKey() { +return {Outer::SentinelTag{}, Base::getTombstoneKey()}; + } static unsigned getHashValue(const Outer ) { return Base::getHashValue(Val.Storage); } @@ -202,6 +219,23 @@ template <> struct DenseMapInfo { return Base::isEqual(LHS.Definition, RHS.Definition); } }; +template <> struct DenseMapInfo { + using Outer = clang::include_cleaner::Header; + using Base = DenseMapInfo; + + static inline Outer getEmptyKey() { +return {Outer::SentinelTag{}, Base::getEmptyKey()}; + } + static inline Outer getTombstoneKey() { +return {Outer::SentinelTag{}, Base::getTombstoneKey()}; + } + static unsigned getHashValue(const Outer ) { +return Base::getHashValue(Val.Storage); + } + static bool isEqual(const Outer , const Outer ) { +return Base::isEqual(LHS.Storage, RHS.Storage); + } +}; } // namespace llvm #endif diff --git a/clang-tools-extra/include-cleaner/lib/Analysis.cpp b/clang-tools-extra/include-cleaner/lib/Analysis.cpp index 1c7ac33cfa080..c5559db57e14c 100644 --- a/clang-tools-extra/include-cleaner/lib/Analysis.cpp +++ b/clang-tools-extra/include-cleaner/lib/Analysis.cpp @@ -12,29 +12,19 @@ #include "clang-include-cleaner/Types.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" #include "clang/Basic/SourceManager.h" #include "clang/Format/Format.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Tooling/Core/Replacement.h" -#include "clang/Tooling/Inclusions/HeaderIncludes.h" #include "clang/Tooling/Inclusions/StandardLibrary.h"
[clang] ebd9a24 - [clang] Fix typos in member initializers
Author: Kadir Cetinkaya Date: 2023-01-20T15:20:31+01:00 New Revision: ebd9a2477e69ed35b83256ae93cc7e069f5a37c4 URL: https://github.com/llvm/llvm-project/commit/ebd9a2477e69ed35b83256ae93cc7e069f5a37c4 DIFF: https://github.com/llvm/llvm-project/commit/ebd9a2477e69ed35b83256ae93cc7e069f5a37c4.diff LOG: [clang] Fix typos in member initializers This was regressed in ca619613801233ef2def8c3cc7d311d5ed0033cb. As we attached InitExprs as-is to the AST, without performing transformations. Differential Revision: https://reviews.llvm.org/D142187 Added: clang/test/PCH/typo3.cpp Modified: clang/lib/Sema/SemaDeclCXX.cpp Removed: diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 80cc6b0c01f37..749025c1258ff 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4098,9 +4098,11 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D, return; } - ExprResult Init = InitExpr; - if (!FD->getType()->isDependentType() && !InitExpr->isTypeDependent()) { -Init = ConvertMemberDefaultInitExpression(FD, InitExpr, InitLoc); + ExprResult Init = CorrectDelayedTyposInExpr(InitExpr, /*InitDecl=*/nullptr, + /*RecoverUncorrectedTypos=*/true); + assert(Init.isUsable() && "Init should at least have a RecoveryExpr"); + if (!FD->getType()->isDependentType() && !Init.get()->isTypeDependent()) { +Init = ConvertMemberDefaultInitExpression(FD, Init.get(), InitLoc); // C++11 [class.base.init]p7: // The initialization of each base and member constitutes a // full-expression. @@ -4112,9 +4114,7 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D, } } - InitExpr = Init.get(); - - FD->setInClassInitializer(InitExpr); + FD->setInClassInitializer(Init.get()); } /// Find the direct and/or virtual base specifiers that diff --git a/clang/test/PCH/typo3.cpp b/clang/test/PCH/typo3.cpp new file mode 100644 index 0..c286039400469 --- /dev/null +++ b/clang/test/PCH/typo3.cpp @@ -0,0 +1,8 @@ +// RUN: not %clang_cc1 -emit-pch %s -o %t.pch 2>&1 | FileCheck %s + +struct S { + // Make sure TypoExprs in default init exprs are corrected before serializing + // in PCH. + int y = bar; + // CHECK: use of undeclared identifier 'bar' +}; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 2133e8b - [clangd] Fix shared lib builds
Author: Kadir Cetinkaya Date: 2023-01-20T08:57:21+01:00 New Revision: 2133e8b9f942f91ec54e28c580fccf6d6b26c62e URL: https://github.com/llvm/llvm-project/commit/2133e8b9f942f91ec54e28c580fccf6d6b26c62e DIFF: https://github.com/llvm/llvm-project/commit/2133e8b9f942f91ec54e28c580fccf6d6b26c62e.diff LOG: [clangd] Fix shared lib builds Added: Modified: clang-tools-extra/clangd/CMakeLists.txt clang-tools-extra/clangd/fuzzer/CMakeLists.txt clang-tools-extra/clangd/unittests/CMakeLists.txt Removed: diff --git a/clang-tools-extra/clangd/CMakeLists.txt b/clang-tools-extra/clangd/CMakeLists.txt index af8a188056738..183a3666ee58f 100644 --- a/clang-tools-extra/clangd/CMakeLists.txt +++ b/clang-tools-extra/clangd/CMakeLists.txt @@ -163,7 +163,6 @@ clang_target_link_libraries(clangDaemon clangDriver clangFormat clangFrontend - clangIncludeCleaner clangIndex clangLex clangSema @@ -179,11 +178,11 @@ target_link_libraries(clangDaemon PRIVATE ${LLVM_PTHREAD_LIB} + clangIncludeCleaner + clangPseudo clangTidy clangdSupport - - clangPseudo ) if(CLANGD_TIDY_CHECKS) target_link_libraries(clangDaemon PRIVATE ${ALL_CLANG_TIDY_CHECKS}) diff --git a/clang-tools-extra/clangd/fuzzer/CMakeLists.txt b/clang-tools-extra/clangd/fuzzer/CMakeLists.txt index 72feb52e1f02a..9cfaeca189777 100644 --- a/clang-tools-extra/clangd/fuzzer/CMakeLists.txt +++ b/clang-tools-extra/clangd/fuzzer/CMakeLists.txt @@ -14,7 +14,6 @@ clang_target_link_libraries(clangd-fuzzer clangBasic clangFormat clangFrontend - clangIncludeCleaner clangSema clangTooling clangToolingCore @@ -22,5 +21,6 @@ clang_target_link_libraries(clangd-fuzzer target_link_libraries(clangd-fuzzer PRIVATE clangDaemon + clangIncludeCleaner clangdSupport ) diff --git a/clang-tools-extra/clangd/unittests/CMakeLists.txt b/clang-tools-extra/clangd/unittests/CMakeLists.txt index ee278b4365be7..a68d8cb0b78ff 100644 --- a/clang-tools-extra/clangd/unittests/CMakeLists.txt +++ b/clang-tools-extra/clangd/unittests/CMakeLists.txt @@ -164,11 +164,13 @@ clang_target_link_libraries(ClangdTests ) target_link_libraries(ClangdTests PRIVATE - clangDaemon - clangdSupport - clangTidy LLVMTestingAnnotations LLVMTestingSupport + + clangDaemon + clangIncludeCleaner + clangTidy + clangdSupport ) if (CLANGD_ENABLE_REMOTE) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits