Skip to content

Commit eeedbd0

Browse files
committed
[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 clangd/clangd#400 Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D80521
1 parent d8e0ad9 commit eeedbd0

File tree

2 files changed

+45
-11
lines changed

2 files changed

+45
-11
lines changed

clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -317,18 +317,16 @@ SourceRange getDeletionRange(const FunctionDecl *FD,
317317
const syntax::TokenBuffer &TokBuf) {
318318
auto DeletionRange = FD->getBody()->getSourceRange();
319319
if (auto *CD = llvm::dyn_cast<CXXConstructorDecl>(FD)) {
320-
const auto &SM = TokBuf.sourceManager();
321320
// AST doesn't contain the location for ":" in ctor initializers. Therefore
322321
// we find it by finding the first ":" before the first ctor initializer.
323322
SourceLocation InitStart;
324323
// Find the first initializer.
325324
for (const auto *CInit : CD->inits()) {
326-
// We don't care about in-class initializers.
327-
if (CInit->isInClassMemberInitializer())
325+
// SourceOrder is -1 for implicit initializers.
326+
if (CInit->getSourceOrder() != 0)
328327
continue;
329-
if (InitStart.isInvalid() ||
330-
SM.isBeforeInTranslationUnit(CInit->getSourceLocation(), InitStart))
331-
InitStart = CInit->getSourceLocation();
328+
InitStart = CInit->getSourceLocation();
329+
break;
332330
}
333331
if (InitStart.isValid()) {
334332
auto Toks = TokBuf.expandedTokens(CD->getSourceRange());

clang-tools-extra/clangd/unittests/TweakTests.cpp

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,21 +2059,57 @@ TEST_F(DefineOutlineTest, ApplyTest) {
20592059
"void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
20602060
"void foo(int x, int y , int , int (*foo)(int) ) {}",
20612061
},
2062-
// Ctor initializers.
2062+
// Constructors
2063+
{
2064+
R"cpp(
2065+
class Foo {public: Foo(); Foo(int);};
2066+
class Bar {
2067+
Ba^r() {}
2068+
Bar(int x) : f1(x) {}
2069+
Foo f1;
2070+
Foo f2 = 2;
2071+
};)cpp",
2072+
R"cpp(
2073+
class Foo {public: Foo(); Foo(int);};
2074+
class Bar {
2075+
Bar() ;
2076+
Bar(int x) : f1(x) {}
2077+
Foo f1;
2078+
Foo f2 = 2;
2079+
};)cpp",
2080+
"Bar::Bar() {}\n",
2081+
},
2082+
// Ctor with initializer.
2083+
{
2084+
R"cpp(
2085+
class Foo {public: Foo(); Foo(int);};
2086+
class Bar {
2087+
Bar() {}
2088+
B^ar(int x) : f1(x), f2(3) {}
2089+
Foo f1;
2090+
Foo f2 = 2;
2091+
};)cpp",
2092+
R"cpp(
2093+
class Foo {public: Foo(); Foo(int);};
2094+
class Bar {
2095+
Bar() {}
2096+
Bar(int x) ;
2097+
Foo f1;
2098+
Foo f2 = 2;
2099+
};)cpp",
2100+
"Bar::Bar(int x) : f1(x), f2(3) {}\n",
2101+
},
2102+
// Ctor initializer with attribute.
20632103
{
20642104
R"cpp(
20652105
class Foo {
2066-
int y = 2;
20672106
F^oo(int z) __attribute__((weak)) : bar(2){}
20682107
int bar;
2069-
int z = 2;
20702108
};)cpp",
20712109
R"cpp(
20722110
class Foo {
2073-
int y = 2;
20742111
Foo(int z) __attribute__((weak)) ;
20752112
int bar;
2076-
int z = 2;
20772113
};)cpp",
20782114
"Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
20792115
},

0 commit comments

Comments
 (0)