zequanwu updated this revision to Diff 412856.
zequanwu marked 2 inline comments as done.
zequanwu added a comment.

Address comment.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D120931/new/

https://reviews.llvm.org/D120931

Files:
  clang/lib/Format/NamespaceEndCommentsFixer.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp
  clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp

Index: clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp
===================================================================
--- clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp
+++ clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp
@@ -68,6 +68,57 @@
                                     "int i;\n"
                                     "int j;\n"
                                     "}"));
+  EXPECT_EQ("#define M(x) x##x\n"
+            "namespace M(x) {\n"
+            "int i;\n"
+            "int j;\n"
+            "}// namespace M(x)",
+            fixNamespaceEndComments("#define M(x) x##x\n"
+                                    "namespace M(x) {\n"
+                                    "int i;\n"
+                                    "int j;\n"
+                                    "}"));
+  EXPECT_EQ("#define M(x) x##x\n"
+            "namespace A::M(x) {\n"
+            "int i;\n"
+            "int j;\n"
+            "}// namespace A::M(x)",
+            fixNamespaceEndComments("#define M(x) x##x\n"
+                                    "namespace A::M(x) {\n"
+                                    "int i;\n"
+                                    "int j;\n"
+                                    "}"));
+  EXPECT_EQ("#define M(x) x##x\n"
+            "namespace M(x)::A {\n"
+            "int i;\n"
+            "int j;\n"
+            "}// namespace M(x)::A",
+            fixNamespaceEndComments("#define M(x) x##x\n"
+                                    "namespace M(x)::A {\n"
+                                    "int i;\n"
+                                    "int j;\n"
+                                    "}"));
+  EXPECT_EQ("#define M(x) x##x\n"
+            "namespace A::inline M(x)::B {\n"
+            "int i;\n"
+            "int j;\n"
+            "}// namespace A::inline M(x)::B",
+            fixNamespaceEndComments("#define M(x) x##x\n"
+                                    "namespace A::inline M(x)::B {\n"
+                                    "int i;\n"
+                                    "int j;\n"
+                                    "}"));
+  EXPECT_EQ("#define M(x) x##x\n"
+            "namespace [[deprecated(\"foo\")]] A::inline M(x)::A {\n"
+            "int i;\n"
+            "int j;\n"
+            "}// namespace A::inline M(x)::A",
+            fixNamespaceEndComments(
+                "#define M(x) x##x\n"
+                "namespace [[deprecated(\"foo\")]] A::inline M(x)::A {\n"
+                "int i;\n"
+                "int j;\n"
+                "}"));
   EXPECT_EQ("inline namespace A {\n"
             "int i;\n"
             "int j;\n"
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -3738,6 +3738,36 @@
                "void f() { f(); }\n"
                "}",
                LLVMWithNoNamespaceFix);
+  verifyFormat("#define M(x) x##x\n"
+               "namespace M(x) {\n"
+               "class A {};\n"
+               "void f() { f(); }\n"
+               "}",
+               LLVMWithNoNamespaceFix);
+  verifyFormat("#define M(x) x##x\n"
+               "namespace N::inline M(x) {\n"
+               "class A {};\n"
+               "void f() { f(); }\n"
+               "}",
+               LLVMWithNoNamespaceFix);
+  verifyFormat("#define M(x) x##x\n"
+               "namespace M(x)::inline N {\n"
+               "class A {};\n"
+               "void f() { f(); }\n"
+               "}",
+               LLVMWithNoNamespaceFix);
+  verifyFormat("#define M(x) x##x\n"
+               "namespace N::M(x) {\n"
+               "class A {};\n"
+               "void f() { f(); }\n"
+               "}",
+               LLVMWithNoNamespaceFix);
+  verifyFormat("#define M(x) x##x\n"
+               "namespace M::N(x) {\n"
+               "class A {};\n"
+               "void f() { f(); }\n"
+               "}",
+               LLVMWithNoNamespaceFix);
   verifyFormat("namespace N::inline D {\n"
                "class A {};\n"
                "void f() { f(); }\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2597,10 +2597,12 @@
     parseParens();
   } else {
     while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline,
-                              tok::l_square, tok::period) ||
+                              tok::l_square, tok::period, tok::l_paren) ||
            (Style.isCSharp() && FormatTok->is(tok::kw_union)))
       if (FormatTok->is(tok::l_square))
         parseSquare();
+      else if (FormatTok->is(tok::l_paren))
+        parseParens();
       else
         nextToken();
   }
Index: clang/lib/Format/NamespaceEndCommentsFixer.cpp
===================================================================
--- clang/lib/Format/NamespaceEndCommentsFixer.cpp
+++ clang/lib/Format/NamespaceEndCommentsFixer.cpp
@@ -40,12 +40,34 @@
       Tok = Tok->getNextNonComment();
     }
   } else {
+    // Skip attributes.
+    if (Tok && Tok->is(tok::l_square)) {
+      int NestLevel = 1;
+      while (Tok && NestLevel > 0) {
+        Tok = Tok->getNextNonComment();
+        if (Tok) {
+          if (Tok->is(tok::l_square))
+            ++NestLevel;
+          if (Tok->is(tok::r_square))
+            --NestLevel;
+        }
+      }
+      if (Tok)
+        Tok = Tok->getNextNonComment();
+    }
+
+    // Use the string after `namespace` until `{` or `::` or `(` as an name
+    // candicate. If the name is empty, use the candicate.
+    std::string FirstNSName;
     // For `namespace [[foo]] A::B::inline C {` or
     // `namespace MACRO1 MACRO2 A::B::inline C {`, returns "A::B::inline C".
-    // Peek for the first '::' (or '{') and then return all tokens from one
-    // token before that up until the '{'.
+    // Peek for the first '::' (or '{' or '(')) and then return all tokens from
+    // one token before that up until the '{'. A '(' might be a macro with
+    // arguments.
     const FormatToken *FirstNSTok = Tok;
-    while (Tok && !Tok->is(tok::l_brace) && !Tok->is(tok::coloncolon)) {
+    while (Tok && !Tok->is(tok::l_brace) && !Tok->is(tok::coloncolon) &&
+           !Tok->is(tok::l_paren)) {
+      FirstNSName += FirstNSTok->TokenText;
       FirstNSTok = Tok;
       Tok = Tok->getNextNonComment();
     }
@@ -57,6 +79,8 @@
         name += " ";
       Tok = Tok->getNextNonComment();
     }
+    if (name.empty())
+      name = FirstNSName;
   }
   return name;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to