diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -460,6 +460,12 @@ void VisitPseudoObjectExpr(const PseudoObjectExpr *POE) { Outer.add(POE->getSyntacticForm(), Flags); } + void VisitCXXNewExpr(const CXXNewExpr *CNE) { + Outer.add(CNE->getOperatorNew(), Flags); + } + void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE) { + Outer.add(CDE->getOperatorDelete(), Flags); + } }; Visitor(*this, Flags).Visit(S); } diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -238,6 +238,10 @@ llvm::DenseMap ResultIndex; auto AddResultDecl = [&](const NamedDecl *D) { + // FIXME: Canonical declarations of some symbols might refer to built-in + // decls with possibly-invalid source locations (e.g. global new operator). + // In such cases we should pick up a redecl with valid source location + // instead of failing. D = llvm::cast(D->getCanonicalDecl()); auto Loc = makeLocation(AST.getASTContext(), nameLocation(*D, SM), MainFilePath); diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -535,6 +535,7 @@ // FIXME: Auto-completion in a template requires disabling delayed template // parsing. Flags = {"-fno-delayed-template-parsing"}; + Flags.push_back("--target=x86_64-pc-linux-gnu"); Code = R"cpp( void func(int*); @@ -559,6 +560,36 @@ }; )cpp"; EXPECT_DECLS("UnresolvedMemberExpr", "void func(int *)", "void func(char *)"); + + Code = R"cpp( + struct X { + static void *operator new(unsigned long); + }; + auto* k = [[new]] X(); + )cpp"; + EXPECT_DECLS("CXXNewExpr", "static void *operator new(unsigned long)"); + Code = R"cpp( + void *operator new(unsigned long); + auto* k = [[new]] int(); + )cpp"; + EXPECT_DECLS("CXXNewExpr", "void *operator new(unsigned long)"); + + Code = R"cpp( + struct X { + static void operator delete(void *) noexcept; + }; + void k(X* x) { + [[delete]] x; + } + )cpp"; + EXPECT_DECLS("CXXDeleteExpr", "static void operator delete(void *) noexcept"); + Code = R"cpp( + void operator delete(void *) noexcept; + void k(int* x) { + [[delete]] x; + } + )cpp"; + EXPECT_DECLS("CXXDeleteExpr", "void operator delete(void *) noexcept"); } TEST_F(TargetDeclTest, DependentExprs) {