tamas.petz updated this revision to Diff 247561.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D75364/new/
https://reviews.llvm.org/D75364
Files:
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -7356,6 +7356,10 @@
verifyFormat("void f(const MyFinal &final);");
verifyIndependentOfContext("bool a = f() && override.f();");
verifyIndependentOfContext("bool a = f() && final.f();");
+ verifyFormat("int f(M(x) *p1 = nullptr, M(x) *p2, volatile M(x) *p3);");
+ verifyFormat("M(x) *foo();");
+ verifyFormat("const M(x) *foo(M(x) *a = nullptr);");
+ verifyFormat("const M(x) *foo::bar(M(x) *a = nullptr);");
verifyIndependentOfContext("InvalidRegions[*R] = 0;");
@@ -7396,6 +7400,10 @@
verifyGoogleFormat("void f(Bar* a = nullptr, Bar* b);");
verifyGoogleFormat("template <typename T>\n"
"void f(int i = 0, SomeType** temps = NULL);");
+ verifyGoogleFormat("int f(M(x)* p1 = nullptr, const M(x)* p2);");
+ verifyGoogleFormat("M(x)* foo();");
+ verifyGoogleFormat("const M(x)* foo(M(x)* a = nullptr);");
+ verifyGoogleFormat("const M(x)* foo::bar(M(x)* a = nullptr);");
FormatStyle Left = getLLVMStyle();
Left.PointerAlignment = FormatStyle::PAS_Left;
@@ -7410,6 +7418,11 @@
verifyFormat("auto x(A&&, B&&, C&&) -> D;", Left);
verifyFormat("auto x = [](A&&, B&&, C&&) -> D {};", Left);
verifyFormat("template <class T> X(T&&, T&&, T&&) -> X<T>;", Left);
+ verifyFormat("int f(M(x)* p1 = nullptr, const M(x)* p2, volatile M(x)* p3);",
+ Left);
+ verifyFormat("M(x)* foo();", Left);
+ verifyFormat("const M(x)* foo(M(x)* a = nullptr);", Left);
+ verifyFormat("const M(x)* foo::bar(M(x)* a = nullptr);", Left);
verifyIndependentOfContext("a = *(x + y);");
verifyIndependentOfContext("a = &(x + y);");
@@ -7537,6 +7550,11 @@
verifyFormat("A = new SomeType *[Length]();", PointerMiddle);
verifyFormat("A = new SomeType *[Length];", PointerMiddle);
verifyFormat("T ** t = new T *;", PointerMiddle);
+ verifyFormat("int f(M(x) * p1 = nullptr, const M(x) * p2 = nullptr);",
+ PointerMiddle);
+ verifyFormat("M(x) * foo();", PointerMiddle);
+ verifyFormat("const M(x) * foo(M(x) * a = nullptr);", PointerMiddle);
+ verifyFormat("const M(x) * foo::bar(M(x) * a = nullptr);", PointerMiddle);
// Member function reference qualifiers aren't binary operators.
verifyFormat("string // break\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -160,6 +160,14 @@
return false;
}
+ /// Parses CPP qualified function names.
+ bool parse_function_qname(FormatToken *Tok) const {
+ while (Tok && Tok->isOneOf(tok::coloncolon, tok::identifier)) {
+ Tok = Tok->Next;
+ }
+ return Tok && Tok->is(tok::l_paren);
+ }
+
bool parseParens(bool LookForDecls = false) {
if (!CurrentToken)
return false;
@@ -250,6 +258,7 @@
bool HasMultipleParametersOnALine = false;
bool MightBeObjCForRangeLoop =
Left->Previous && Left->Previous->is(tok::kw_for);
+ bool HasStarToken = false;
FormatToken *PossibleObjCForInToken = nullptr;
while (CurrentToken) {
// LookForDecls is set when "if (" has been seen. Check for
@@ -299,6 +308,55 @@
}
}
+ // Detect cases where macros are used in function parameter lists,
+ // for example:
+ // void f(volatile ElfW(Addr)* addr = nullptr);
+ if (HasStarToken) {
+ for (FormatToken *Tok = Left; Tok != CurrentToken; Tok = Tok->Next) {
+ // Search for ') *' patterns.
+ if (Tok->is(tok::star) && Tok->Previous->is(tok::r_paren)) {
+ // Extend search to left looking for 'X(...) *' patterns.
+ FormatToken *LparenTok = Tok->Previous->MatchingParen;
+ if (LparenTok && LparenTok->is(tok::l_paren) &&
+ LparenTok->Previous) {
+ FormatToken *MacroTok = LparenTok->Previous;
+ // Decide if 'X' is following "l_paren" of this function,
+ // a keyword or a comma.
+ if (MacroTok->is(tok::identifier) && MacroTok->Previous &&
+ (MacroTok->Previous == Left ||
+ MacroTok->Previous->isOneOf(tok::comma, tok::kw_const,
+ tok::kw_volatile))) {
+ Tok->Type = TT_PointerOrReference;
+ LparenTok->Previous->Type = TT_TypenameMacro;
+ }
+ }
+ }
+ }
+ }
+
+ // Detect cases where macros are used in function return types,
+ // for example:
+ // const ElfW(Addr)* f();
+ if (CurrentToken->Next && CurrentToken->Next->is(tok::star)) {
+ if (parse_function_qname(CurrentToken->Next->Next)) {
+ bool Found = true;
+ FormatToken *const Prev = CurrentToken->MatchingParen->Previous;
+ if (Prev && Prev->is(tok::identifier)) {
+ for (FormatToken *Tok = Prev; Tok; Tok = Tok->Previous) {
+ if (!Tok->is(TT_Unknown)) {
+ Found = false;
+ break;
+ } else if (Prev->is(tok::semi))
+ break;
+ }
+ }
+ if (Found) {
+ CurrentToken->Next->Type = TT_PointerOrReference;
+ Prev->Type = TT_TypenameMacro;
+ }
+ }
+ }
+
if (StartsObjCMethodExpr) {
CurrentToken->Type = TT_ObjCMethodExpr;
if (Contexts.back().FirstObjCSelectorName) {
@@ -355,6 +413,9 @@
if (CurrentToken->is(tok::comma))
Contexts.back().CanBeExpression = true;
+ if (CurrentToken->is(tok::star))
+ HasStarToken = true;
+
FormatToken *Tok = CurrentToken;
if (!consumeToken())
return false;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits