diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp --- a/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -217,62 +217,61 @@ if (LeftRightQualifierAlignmentFixer::isPossibleMacro(Tok->Next)) return Tok; - auto AnalyzeTemplate = - [&](const FormatToken *Tok, - const FormatToken *StartTemplate) -> const FormatToken * { - // Read from the TemplateOpener to TemplateCloser. - FormatToken *EndTemplate = StartTemplate->MatchingParen; - if (EndTemplate) { - // Move to the end of any template class members e.g. - // `Foo::iterator`. - if (EndTemplate->startsSequence(TT_TemplateCloser, tok::coloncolon, - tok::identifier)) { - EndTemplate = EndTemplate->Next->Next; - } - } - if (EndTemplate && EndTemplate->Next && - !EndTemplate->Next->isOneOf(tok::equal, tok::l_paren)) { - insertQualifierAfter(SourceMgr, Fixes, EndTemplate, Qualifier); - // Remove the qualifier. - removeToken(SourceMgr, Fixes, Tok); - return Tok; + const FormatToken *PreviousCheck = Tok->Previous; + while (PreviousCheck && llvm::is_contained(ConfiguredQualifierTokens, + PreviousCheck->Tok.getKind())) { + PreviousCheck = PreviousCheck->Previous; + } + + const bool IsEastQualifier = PreviousCheck && [PreviousCheck]() { + if (PreviousCheck->is(tok::r_paren)) { + return true; + } else if (PreviousCheck->is(TT_TemplateCloser)) { + return PreviousCheck->MatchingParen->Previous->isNot(tok::kw_template); + } else if (PreviousCheck->isOneOf(TT_PointerOrReference, tok::identifier, + tok::kw_auto)) { + return true; } - return nullptr; - }; + return false; + }(); - FormatToken *Qual = Tok->Next; - FormatToken *LastQual = Qual; - while (Qual && isQualifierOrType(Qual, ConfiguredQualifierTokens)) { - LastQual = Qual; - Qual = Qual->Next; + const FormatToken *LastQual = Tok; + while (LastQual->Next && llvm::is_contained(ConfiguredQualifierTokens, + LastQual->Next->Tok.getKind())) { + LastQual = LastQual->Next; + } + + if (IsEastQualifier) { + if (LastQual != Tok) + rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false); + return Tok; } - if (LastQual && Qual != LastQual) { - rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false); - Tok = LastQual; - } else if (Tok->startsSequence(QualifierType, tok::identifier, - TT_TemplateCloser)) { - FormatToken *Closer = Tok->Next->Next; - rotateTokens(SourceMgr, Fixes, Tok, Tok->Next, /*Left=*/false); - Tok = Closer; + + const FormatToken *TypeToken = LastQual->Next; + if (!TypeToken) return Tok; - } else if (Tok->startsSequence(QualifierType, tok::identifier, - TT_TemplateOpener)) { - // `const ArrayRef a;` - // `const ArrayRef &a;` - const FormatToken *NewTok = AnalyzeTemplate(Tok, Tok->Next->Next); - if (NewTok) - return NewTok; - } else if (Tok->startsSequence(QualifierType, tok::coloncolon, - tok::identifier, TT_TemplateOpener)) { - // `const ::ArrayRef a;` - // `const ::ArrayRef &a;` - const FormatToken *NewTok = AnalyzeTemplate(Tok, Tok->Next->Next->Next); - if (NewTok) - return NewTok; - } else if (Tok->startsSequence(QualifierType, tok::identifier) || - Tok->startsSequence(QualifierType, tok::coloncolon, - tok::identifier)) { - FormatToken *Next = Tok->Next; + + if (TypeToken->isSimpleTypeSpecifier()) { + const FormatToken *LastSimpleTypeSpecifier = TypeToken; + while (LastSimpleTypeSpecifier->Next && + LastSimpleTypeSpecifier->Next->isSimpleTypeSpecifier()) { + LastSimpleTypeSpecifier = LastSimpleTypeSpecifier->Next; + } + rotateTokens(SourceMgr, Fixes, Tok, LastSimpleTypeSpecifier, + /*Left=*/false); + return LastSimpleTypeSpecifier; + } else if (PreviousCheck && PreviousCheck->isSimpleTypeSpecifier()) { + if (LastQual != Tok) + rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false); + return Tok; + } + + if (TypeToken->is(tok::coloncolon)) + TypeToken = TypeToken->Next; + + if (TypeToken->isOneOf(tok::kw_auto, tok::identifier)) { + const FormatToken *TypeEnd = TypeToken; + // The case `const Foo` -> `Foo const` // The case `const ::Foo` -> `::Foo const` // The case `const Foo *` -> `Foo const *` @@ -280,27 +279,16 @@ // The case `const Foo &&` -> `Foo const &&` // The case `const std::Foo &&` -> `std::Foo const &&` // The case `const std::Foo &&` -> `std::Foo const &&` - while (Next && Next->isOneOf(tok::identifier, tok::coloncolon)) - Next = Next->Next; - if (Next && Next->is(TT_TemplateOpener)) { - Next = Next->MatchingParen; - // Move to the end of any template class members e.g. - // `Foo::iterator`. - if (Next && Next->startsSequence(TT_TemplateCloser, tok::coloncolon, - tok::identifier)) { - return Tok; - } - assert(Next && "Missing template opener"); - Next = Next->Next; - } - if (Next && Next->isOneOf(tok::star, tok::amp, tok::ampamp) && - !Tok->Next->isOneOf(Keywords.kw_override, Keywords.kw_final)) { - if (Next->Previous && !Next->Previous->is(QualifierType)) { - insertQualifierAfter(SourceMgr, Fixes, Next->Previous, Qualifier); - removeToken(SourceMgr, Fixes, Tok); - } - return Next; + while (TypeEnd->Next && + (TypeEnd->Next->startsSequence(tok::coloncolon, tok::identifier) || + TypeEnd->Next->is(TT_TemplateOpener))) { + if (TypeEnd->Next->is(TT_TemplateOpener)) + TypeEnd = TypeEnd->Next->MatchingParen; + else + TypeEnd = TypeEnd->Next->Next; } + insertQualifierAfter(SourceMgr, Fixes, TypeEnd, Qualifier); + removeToken(SourceMgr, Fixes, Tok); } return Tok;