Skip to content

Commit

Permalink
Reland "[clang-format] Annotate ctors/dtors as CtorDtorDeclName inste…
Browse files Browse the repository at this point in the history
…ad (#67955)"

Reland 6a621ed which failed on Windows but not macOS.

The failures were caused by moving the annotation of the children from the
top to the bottom of TokenAnnotator::annotate(), resulting in invalid lines
including incomplete ones being skipped.
  • Loading branch information
owenca committed Oct 4, 2023
1 parent 9677678 commit 7e856d1
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 39 deletions.
1 change: 1 addition & 0 deletions clang/lib/Format/FormatToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ namespace format {
TYPE(CSharpStringLiteral) \
TYPE(CtorInitializerColon) \
TYPE(CtorInitializerComma) \
TYPE(CtorDtorDeclName) \
TYPE(DesignatedInitializerLSquare) \
TYPE(DesignatedInitializerPeriod) \
TYPE(DictLiteral) \
Expand Down
18 changes: 11 additions & 7 deletions clang/lib/Format/TokenAnnotator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3210,12 +3210,12 @@ static bool isCtorOrDtorName(const FormatToken *Tok) {
}

void TokenAnnotator::annotate(AnnotatedLine &Line) {
for (auto &Child : Line.Children)
annotate(*Child);

AnnotatingParser Parser(Style, Line, Keywords, Scopes);
Line.Type = Parser.parseLine();

for (auto &Child : Line.Children)
annotate(*Child);

// With very deep nesting, ExpressionParser uses lots of stack and the
// formatting algorithm is very slow. We're not going to do a good job here
// anyway - it's probably generated code being formatted by mistake.
Expand All @@ -3233,7 +3233,7 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) {
auto *Tok = getFunctionName(Line);
if (Tok && ((!Scopes.empty() && Scopes.back() == ST_Class) ||
Line.endsWith(TT_FunctionLBrace) || isCtorOrDtorName(Tok))) {
Tok->setFinalizedType(TT_FunctionDeclarationName);
Tok->setFinalizedType(TT_CtorDtorDeclName);
}
}

Expand Down Expand Up @@ -3447,9 +3447,13 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
Tok = Tok->Next) {
if (Tok->Previous->EndsCppAttributeGroup)
AfterLastAttribute = Tok;
if (isFunctionDeclarationName(Style.isCpp(), *Tok, Line, ClosingParen)) {
LineIsFunctionDeclaration = true;
Tok->setFinalizedType(TT_FunctionDeclarationName);
if (const bool IsCtorOrDtor = Tok->is(TT_CtorDtorDeclName);
IsCtorOrDtor ||
isFunctionDeclarationName(Style.isCpp(), *Tok, Line, ClosingParen)) {
if (!IsCtorOrDtor) {
LineIsFunctionDeclaration = true;
Tok->setFinalizedType(TT_FunctionDeclarationName);
}
if (AfterLastAttribute &&
mustBreakAfterAttributes(*AfterLastAttribute, Style)) {
AfterLastAttribute->MustBreakBefore = true;
Expand Down
6 changes: 1 addition & 5 deletions clang/lib/Format/WhitespaceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,11 +975,7 @@ void WhitespaceManager::alignConsecutiveDeclarations() {
AlignTokens(
Style,
[](Change const &C) {
if (C.Tok->is(TT_FunctionDeclarationName) && C.Tok->Previous &&
C.Tok->Previous->isNot(tok::tilde)) {
return true;
}
if (C.Tok->is(TT_FunctionTypeLParen))
if (C.Tok->isOneOf(TT_FunctionDeclarationName, TT_FunctionTypeLParen))
return true;
if (C.Tok->isNot(TT_StartOfName))
return false;
Expand Down
10 changes: 8 additions & 2 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10622,6 +10622,12 @@ TEST_F(FormatTest, WrapsAtNestedNameSpecifiers) {
verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();");

verifyFormat(
"LongClassNameToShowTheIssue::AndAnotherLongClassNameToShowTheIssue::\n"
" AndAnotherLongClassNameToShowTheIssue() {}\n"
"LongClassNameToShowTheIssue::AndAnotherLongClassNameToShowTheIssue::\n"
" ~AndAnotherLongClassNameToShowTheIssue() {}");
}

TEST_F(FormatTest, UnderstandsTemplateParameters) {
Expand Down Expand Up @@ -16339,7 +16345,7 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {

verifyFormat("int f();", SpaceFuncDef);
verifyFormat("void f (int a, T b) {}", SpaceFuncDef);
verifyFormat("A::A () : a(1) {}", SpaceFuncDef);
verifyFormat("A::A() : a(1) {}", SpaceFuncDef);
verifyFormat("void f() __attribute__((asdf));", SpaceFuncDef);
verifyFormat("#define A(x) x", SpaceFuncDef);
verifyFormat("#define A (x) x", SpaceFuncDef);
Expand All @@ -16364,7 +16370,7 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
// verifyFormat("T A::operator() () {}", SpaceFuncDef);
verifyFormat("auto lambda = [] () { return 0; };", SpaceFuncDef);
verifyFormat("int x = int(y);", SpaceFuncDef);
verifyFormat("M (std::size_t R, std::size_t C) : C(C), data(R) {}",
verifyFormat("M(std::size_t R, std::size_t C) : C(C), data(R) {}",
SpaceFuncDef);

FormatStyle SpaceIfMacros = getLLVMStyle();
Expand Down
7 changes: 3 additions & 4 deletions clang/unittests/Format/FormatTestMacroExpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,9 @@ TEST_F(FormatTestMacroExpansion, UnexpandConfiguredMacros) {
{ ID(a *b); });
)",
Style);
verifyIncompleteFormat(R"(ID3({, ID(a *b),
;
});
)",
verifyIncompleteFormat("ID3({, ID(a *b),\n"
" ;\n"
" });",
Style);

verifyFormat("ID(CALL(CALL(return a * b;)));", Style);
Expand Down
54 changes: 33 additions & 21 deletions clang/unittests/Format/TokenAnnotatorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1631,65 +1631,77 @@ TEST_F(TokenAnnotatorTest, UnderstandsFunctionDeclarationNames) {
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName);

Tokens = annotate("class Foo { public: Foo(); };");
Tokens = annotate("#define FOO Foo::\n"
"FOO Foo();");
ASSERT_EQ(Tokens.size(), 11u) << Tokens;
EXPECT_TOKEN(Tokens[6], tok::identifier, TT_FunctionDeclarationName);

Tokens = annotate("struct Foo {\n"
" Bar (*func)();\n"
"};");
ASSERT_EQ(Tokens.size(), 14u) << Tokens;
EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_FunctionTypeLParen);
}

TEST_F(TokenAnnotatorTest, UnderstandsCtorAndDtorDeclNames) {
auto Tokens = annotate("class Foo { public: Foo(); };");
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
EXPECT_TOKEN(Tokens[5], tok::identifier, TT_FunctionDeclarationName);
EXPECT_TOKEN(Tokens[5], tok::identifier, TT_CtorDtorDeclName);

Tokens = annotate("class Foo { public: ~Foo(); };");
ASSERT_EQ(Tokens.size(), 13u) << Tokens;
EXPECT_TOKEN(Tokens[6], tok::identifier, TT_FunctionDeclarationName);
EXPECT_TOKEN(Tokens[6], tok::identifier, TT_CtorDtorDeclName);

Tokens = annotate("struct Foo { [[deprecated]] Foo() {} };");
ASSERT_EQ(Tokens.size(), 16u) << Tokens;
EXPECT_TOKEN(Tokens[8], tok::identifier, TT_FunctionDeclarationName);
EXPECT_TOKEN(Tokens[8], tok::identifier, TT_CtorDtorDeclName);
EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_FunctionLBrace);

Tokens = annotate("struct Foo { [[deprecated]] ~Foo() {} };");
ASSERT_EQ(Tokens.size(), 17u) << Tokens;
EXPECT_TOKEN(Tokens[9], tok::identifier, TT_FunctionDeclarationName);
EXPECT_TOKEN(Tokens[9], tok::identifier, TT_CtorDtorDeclName);
EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_FunctionLBrace);

Tokens = annotate("struct Foo { Foo() [[deprecated]] {} };");
ASSERT_EQ(Tokens.size(), 16u) << Tokens;
EXPECT_TOKEN(Tokens[3], tok::identifier, TT_FunctionDeclarationName);
EXPECT_TOKEN(Tokens[3], tok::identifier, TT_CtorDtorDeclName);
EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_FunctionLBrace);

Tokens = annotate("struct Foo { ~Foo() [[deprecated]] {} };");
ASSERT_EQ(Tokens.size(), 17u) << Tokens;
EXPECT_TOKEN(Tokens[4], tok::identifier, TT_FunctionDeclarationName);
EXPECT_TOKEN(Tokens[4], tok::identifier, TT_CtorDtorDeclName);
EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_FunctionLBrace);

Tokens = annotate("struct Foo { [[deprecated]] explicit Foo() {} };");
ASSERT_EQ(Tokens.size(), 17u) << Tokens;
EXPECT_TOKEN(Tokens[9], tok::identifier, TT_FunctionDeclarationName);
EXPECT_TOKEN(Tokens[9], tok::identifier, TT_CtorDtorDeclName);
EXPECT_TOKEN(Tokens[12], tok::l_brace, TT_FunctionLBrace);

Tokens = annotate("struct Foo { virtual [[deprecated]] ~Foo() {} };");
ASSERT_EQ(Tokens.size(), 18u) << Tokens;
EXPECT_TOKEN(Tokens[10], tok::identifier, TT_FunctionDeclarationName);
EXPECT_TOKEN(Tokens[10], tok::identifier, TT_CtorDtorDeclName);
EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_FunctionLBrace);

Tokens = annotate("Foo::Foo() {}");
ASSERT_EQ(Tokens.size(), 8u) << Tokens;
EXPECT_TOKEN(Tokens[2], tok::identifier, TT_FunctionDeclarationName);
EXPECT_TOKEN(Tokens[2], tok::identifier, TT_CtorDtorDeclName);
EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_FunctionLBrace);

Tokens = annotate("Foo::~Foo() {}");
ASSERT_EQ(Tokens.size(), 9u) << Tokens;
EXPECT_TOKEN(Tokens[3], tok::identifier, TT_FunctionDeclarationName);
EXPECT_TOKEN(Tokens[3], tok::identifier, TT_CtorDtorDeclName);
EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_FunctionLBrace);

Tokens = annotate("#define FOO Foo::\n"
"FOO Foo();");
ASSERT_EQ(Tokens.size(), 11u) << Tokens;
EXPECT_TOKEN(Tokens[6], tok::identifier, TT_FunctionDeclarationName);

Tokens = annotate("struct Foo {\n"
" Bar (*func)();\n"
Tokens = annotate("struct Test {\n"
" Test()\n"
" : l([] {\n"
" Short::foo();\n"
" }) {}\n"
"};");
ASSERT_EQ(Tokens.size(), 14u) << Tokens;
EXPECT_TOKEN(Tokens[3], tok::identifier, TT_Unknown);
EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_FunctionTypeLParen);
ASSERT_EQ(Tokens.size(), 25u) << Tokens;
EXPECT_TOKEN(Tokens[3], tok::identifier, TT_CtorDtorDeclName);
EXPECT_TOKEN(Tokens[14], tok::identifier, TT_Unknown);
}

TEST_F(TokenAnnotatorTest, UnderstandsC11GenericSelection) {
Expand Down

0 comments on commit 7e856d1

Please sign in to comment.