melver created this revision.
Herald added a subscriber: cfe-commits.

This fixes formatting namespaces with preceding 'inline' and 'export' (Modules 
TS) specifiers.

This change fixes namespaces not being identified as such with preceding 
'inline' or 'export' specifiers.

Motivation: I was experimenting with the Modules TS (-fmodules-ts) and found it 
would be useful if clang-format would correctly format 'export namespace'. 
While making the changes, I noticed that similar issues still exist with 
'inline namespace', and addressed them as well.


Repository:
  rC Clang

https://reviews.llvm.org/D51036

Files:
  lib/Format/Format.cpp
  lib/Format/FormatToken.h
  lib/Format/NamespaceEndCommentsFixer.cpp
  lib/Format/UnwrappedLineFormatter.cpp
  lib/Format/UnwrappedLineParser.cpp
  unittests/Format/FormatTest.cpp

Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -200,6 +200,24 @@
                    "int    i;\n"
                    "}",
                    getGoogleStyle()));
+  EXPECT_EQ("inline namespace N {\n"
+            "\n"
+            "int i;\n"
+            "}",
+            format("inline namespace N {\n"
+                   "\n"
+                   "int    i;\n"
+                   "}",
+                   getGoogleStyle()));
+  EXPECT_EQ("export namespace N {\n"
+            "\n"
+            "int i;\n"
+            "}",
+            format("export namespace N {\n"
+                   "\n"
+                   "int    i;\n"
+                   "}",
+                   getGoogleStyle()));
   EXPECT_EQ("extern /**/ \"C\" /**/ {\n"
             "\n"
             "int i;\n"
@@ -1573,6 +1591,11 @@
                "void f() { f(); }\n"
                "}",
                LLVMWithNoNamespaceFix);
+  verifyFormat("export namespace X {\n"
+               "class A {};\n"
+               "void f() { f(); }\n"
+               "}",
+               LLVMWithNoNamespaceFix);
   verifyFormat("using namespace some_namespace;\n"
                "class A {};\n"
                "void f() { f(); }",
@@ -7556,6 +7579,9 @@
   verifyFormat("inline namespace Foo\n"
                "{};",
                Style);
+  verifyFormat("export namespace Foo\n"
+               "{};",
+               Style);
   verifyFormat("namespace Foo\n"
                "{\n"
                "void Bar();\n"
Index: lib/Format/UnwrappedLineParser.cpp
===================================================================
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -1063,6 +1063,13 @@
       parseJavaScriptEs6ImportExport();
       return;
     }
+    if (Style.isCpp()) {
+      nextToken();
+      if (FormatTok->Tok.is(tok::kw_namespace)) {
+        parseNamespace();
+        return;
+      }
+    }
     break;
   case tok::identifier:
     if (FormatTok->is(TT_ForEachMacro)) {
Index: lib/Format/UnwrappedLineFormatter.cpp
===================================================================
--- lib/Format/UnwrappedLineFormatter.cpp
+++ lib/Format/UnwrappedLineFormatter.cpp
@@ -529,7 +529,10 @@
         Tok->SpacesRequiredBefore = 0;
         Tok->CanBreakBefore = true;
         return 1;
-      } else if (Limit != 0 && !Line.startsWith(tok::kw_namespace) &&
+      } else if (Limit != 0 &&
+                 !(Line.startsWith(tok::kw_namespace) ||
+                   Line.startsWith(tok::kw_inline, tok::kw_namespace) ||
+                   Line.startsWith(tok::kw_export, tok::kw_namespace)) &&
                  !startsExternCBlock(Line)) {
         // We don't merge short records.
         FormatToken *RecordTok = Line.First;
@@ -1154,7 +1157,9 @@
   // Remove empty lines after "{".
   if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&
       PreviousLine->Last->is(tok::l_brace) &&
-      PreviousLine->First->isNot(tok::kw_namespace) &&
+      !(PreviousLine->startsWith(tok::kw_namespace) ||
+        PreviousLine->startsWith(tok::kw_inline, tok::kw_namespace) ||
+        PreviousLine->startsWith(tok::kw_export, tok::kw_namespace)) &&
       !startsExternCBlock(*PreviousLine))
     Newlines = 1;
 
Index: lib/Format/NamespaceEndCommentsFixer.cpp
===================================================================
--- lib/Format/NamespaceEndCommentsFixer.cpp
+++ lib/Format/NamespaceEndCommentsFixer.cpp
@@ -125,8 +125,8 @@
     if (StartLineIndex > 0)
       NamespaceTok = AnnotatedLines[StartLineIndex - 1]->First;
   }
-  // Detect "(inline)? namespace" in the beginning of a line.
-  if (NamespaceTok->is(tok::kw_inline))
+  // Detect "(inline|export)? namespace" in the beginning of a line.
+  if (NamespaceTok->is(tok::kw_inline) || NamespaceTok->is(tok::kw_export))
     NamespaceTok = NamespaceTok->getNextNonComment();
   if (!NamespaceTok || NamespaceTok->isNot(tok::kw_namespace))
     return nullptr;
Index: lib/Format/FormatToken.h
===================================================================
--- lib/Format/FormatToken.h
+++ lib/Format/FormatToken.h
@@ -520,8 +520,9 @@
     const FormatToken *NamespaceTok = this;
     if (is(tok::comment))
       NamespaceTok = NamespaceTok->getNextNonComment();
-    // Detect "(inline)? namespace" in the beginning of a line.
-    if (NamespaceTok && NamespaceTok->is(tok::kw_inline))
+    // Detect "(inline|export)? namespace" in the beginning of a line.
+    if (NamespaceTok &&
+        (NamespaceTok->is(tok::kw_inline) || NamespaceTok->is(tok::kw_export)))
       NamespaceTok = NamespaceTok->getNextNonComment();
     return NamespaceTok && NamespaceTok->is(tok::kw_namespace) ? NamespaceTok
                                                                : nullptr;
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -1310,7 +1310,8 @@
     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
       auto &Line = *AnnotatedLines[i];
       if (Line.startsWith(tok::kw_namespace) ||
-          Line.startsWith(tok::kw_inline, tok::kw_namespace)) {
+          Line.startsWith(tok::kw_inline, tok::kw_namespace) ||
+          Line.startsWith(tok::kw_export, tok::kw_namespace)) {
         checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
       }
     }
@@ -1349,6 +1350,8 @@
 
       if (AnnotatedLines[CurrentLine]->startsWith(tok::kw_namespace) ||
           AnnotatedLines[CurrentLine]->startsWith(tok::kw_inline,
+                                                  tok::kw_namespace) ||
+          AnnotatedLines[CurrentLine]->startsWith(tok::kw_export,
                                                   tok::kw_namespace)) {
         if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
                                  DeletedLines))
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to