diff options
author | Kadir Cetinkaya <kadircet@google.com> | 2020-05-25 17:25:55 +0200 |
---|---|---|
committer | Sam McCall <sam.mccall@gmail.com> | 2020-06-10 13:57:00 +0200 |
commit | d623a06a8247b1a04e74ad5f02a30ef351697e00 (patch) | |
tree | bab13800b75e6808119cf0b2a621b956c09a1796 /clang-tools-extra | |
parent | cb89646a4a888b8721adbc746e167f31fd484c11 (diff) | |
download | bcm5719-llvm-d623a06a8247b1a04e74ad5f02a30ef351697e00.tar.gz bcm5719-llvm-d623a06a8247b1a04e74ad5f02a30ef351697e00.zip |
[clangd] Make use of SourceOrder to find first initializer in DefineOutline
Summary:
Constructors can have implicit initializers, this was crashing define
outline. Make sure we find the first "written" ctor initializer to figure out
`:` location.
Fixes https://github.com/clangd/clangd/issues/400
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D80521
(cherry picked from commit eeedbd033612e105755156023bdeec2fba4eca21)
Fixes https://github.com/clangd/clangd/issues/418
Diffstat (limited to 'clang-tools-extra')
-rw-r--r-- | clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp | 10 | ||||
-rw-r--r-- | clang-tools-extra/clangd/unittests/TweakTests.cpp | 46 |
2 files changed, 45 insertions, 11 deletions
diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp index ca3d74b8dca..1dd96c5c658 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -306,18 +306,16 @@ SourceRange getDeletionRange(const FunctionDecl *FD, const syntax::TokenBuffer &TokBuf) { auto DeletionRange = FD->getBody()->getSourceRange(); if (auto *CD = llvm::dyn_cast<CXXConstructorDecl>(FD)) { - const auto &SM = TokBuf.sourceManager(); // AST doesn't contain the location for ":" in ctor initializers. Therefore // we find it by finding the first ":" before the first ctor initializer. SourceLocation InitStart; // Find the first initializer. for (const auto *CInit : CD->inits()) { - // We don't care about in-class initializers. - if (CInit->isInClassMemberInitializer()) + // SourceOrder is -1 for implicit initializers. + if (CInit->getSourceOrder() != 0) continue; - if (InitStart.isInvalid() || - SM.isBeforeInTranslationUnit(CInit->getSourceLocation(), InitStart)) - InitStart = CInit->getSourceLocation(); + InitStart = CInit->getSourceLocation(); + break; } if (InitStart.isValid()) { auto Toks = TokBuf.expandedTokens(CD->getSourceRange()); diff --git a/clang-tools-extra/clangd/unittests/TweakTests.cpp b/clang-tools-extra/clangd/unittests/TweakTests.cpp index adbdbe71761..9b2db764cb0 100644 --- a/clang-tools-extra/clangd/unittests/TweakTests.cpp +++ b/clang-tools-extra/clangd/unittests/TweakTests.cpp @@ -2047,21 +2047,57 @@ TEST_F(DefineOutlineTest, ApplyTest) { "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;", "void foo(int x, int y , int , int (*foo)(int) ) {}", }, - // Ctor initializers. + // Constructors + { + R"cpp( + class Foo {public: Foo(); Foo(int);}; + class Bar { + Ba^r() {} + Bar(int x) : f1(x) {} + Foo f1; + Foo f2 = 2; + };)cpp", + R"cpp( + class Foo {public: Foo(); Foo(int);}; + class Bar { + Bar() ; + Bar(int x) : f1(x) {} + Foo f1; + Foo f2 = 2; + };)cpp", + "Bar::Bar() {}\n", + }, + // Ctor with initializer. + { + R"cpp( + class Foo {public: Foo(); Foo(int);}; + class Bar { + Bar() {} + B^ar(int x) : f1(x), f2(3) {} + Foo f1; + Foo f2 = 2; + };)cpp", + R"cpp( + class Foo {public: Foo(); Foo(int);}; + class Bar { + Bar() {} + Bar(int x) ; + Foo f1; + Foo f2 = 2; + };)cpp", + "Bar::Bar(int x) : f1(x), f2(3) {}\n", + }, + // Ctor initializer with attribute. { R"cpp( class Foo { - int y = 2; F^oo(int z) __attribute__((weak)) : bar(2){} int bar; - int z = 2; };)cpp", R"cpp( class Foo { - int y = 2; Foo(int z) __attribute__((weak)) ; int bar; - int z = 2; };)cpp", "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n", }, |