aboutsummaryrefslogtreecommitdiff
path: root/lib/Format
diff options
context:
space:
mode:
authorSam McCall <sam.mccall@gmail.com>2018-09-05 07:44:02 +0000
committerSam McCall <sam.mccall@gmail.com>2018-09-05 07:44:02 +0000
commit024b9a4311cfd57ecb7f29d1138dc975fede4752 (patch)
tree804387147fa35e7c2beb81b7119f14de5b4fdf25 /lib/Format
parent6164bba681ecdc6c7904973062a8e2f1807a85bd (diff)
clang-format: Fix formatting C++ namespaces with preceding 'inline' or 'export' specifier
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. Patch by Marco Elver! Reviewers: klimek, djasper, owenpan, sammccall Reviewed By: owenpan, sammccall Subscribers: owenpan, cfe-commits Differential Revision: https://reviews.llvm.org/D51036 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@341450 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format')
-rw-r--r--lib/Format/Format.cpp7
-rw-r--r--lib/Format/FormatToken.h4
-rw-r--r--lib/Format/NamespaceEndCommentsFixer.cpp7
-rw-r--r--lib/Format/TokenAnnotator.h7
-rw-r--r--lib/Format/UnwrappedLineFormatter.cpp4
-rw-r--r--lib/Format/UnwrappedLineParser.cpp17
6 files changed, 24 insertions, 22 deletions
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 4a67cdeedf..0637f76f07 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -1309,8 +1309,7 @@ private:
std::set<unsigned> DeletedLines;
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)) {
+ if (Line.startsWithNamespace()) {
checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
}
}
@@ -1347,9 +1346,7 @@ private:
if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
break;
- if (AnnotatedLines[CurrentLine]->startsWith(tok::kw_namespace) ||
- AnnotatedLines[CurrentLine]->startsWith(tok::kw_inline,
- tok::kw_namespace)) {
+ if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
DeletedLines))
return false;
diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h
index 9094e7689e..d9bff0112c 100644
--- a/lib/Format/FormatToken.h
+++ b/lib/Format/FormatToken.h
@@ -520,8 +520,8 @@ struct FormatToken {
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->isOneOf(tok::kw_inline, tok::kw_export))
NamespaceTok = NamespaceTok->getNextNonComment();
return NamespaceTok && NamespaceTok->is(tok::kw_namespace) ? NamespaceTok
: nullptr;
diff --git a/lib/Format/NamespaceEndCommentsFixer.cpp b/lib/Format/NamespaceEndCommentsFixer.cpp
index 995b3219a1..dd364866d1 100644
--- a/lib/Format/NamespaceEndCommentsFixer.cpp
+++ b/lib/Format/NamespaceEndCommentsFixer.cpp
@@ -125,12 +125,7 @@ getNamespaceToken(const AnnotatedLine *Line,
if (StartLineIndex > 0)
NamespaceTok = AnnotatedLines[StartLineIndex - 1]->First;
}
- // Detect "(inline)? namespace" in the beginning of a line.
- if (NamespaceTok->is(tok::kw_inline))
- NamespaceTok = NamespaceTok->getNextNonComment();
- if (!NamespaceTok || NamespaceTok->isNot(tok::kw_namespace))
- return nullptr;
- return NamespaceTok;
+ return NamespaceTok->getNamespaceToken();
}
NamespaceEndCommentsFixer::NamespaceEndCommentsFixer(const Environment &Env,
diff --git a/lib/Format/TokenAnnotator.h b/lib/Format/TokenAnnotator.h
index a3124fcb3d..e2f2c469d2 100644
--- a/lib/Format/TokenAnnotator.h
+++ b/lib/Format/TokenAnnotator.h
@@ -105,6 +105,13 @@ public:
return !Last->isOneOf(tok::semi, tok::comment);
}
+ /// \c true if this line starts a namespace definition.
+ bool startsWithNamespace() const {
+ return startsWith(tok::kw_namespace) ||
+ startsWith(tok::kw_inline, tok::kw_namespace) ||
+ startsWith(tok::kw_export, tok::kw_namespace);
+ }
+
FormatToken *First;
FormatToken *Last;
diff --git a/lib/Format/UnwrappedLineFormatter.cpp b/lib/Format/UnwrappedLineFormatter.cpp
index 1b7daf67d9..f0d93a1f4f 100644
--- a/lib/Format/UnwrappedLineFormatter.cpp
+++ b/lib/Format/UnwrappedLineFormatter.cpp
@@ -535,7 +535,7 @@ private:
Tok->SpacesRequiredBefore = 0;
Tok->CanBreakBefore = true;
return 1;
- } else if (Limit != 0 && !Line.startsWith(tok::kw_namespace) &&
+ } else if (Limit != 0 && !Line.startsWithNamespace() &&
!startsExternCBlock(Line)) {
// We don't merge short records.
FormatToken *RecordTok = Line.First;
@@ -1160,7 +1160,7 @@ void UnwrappedLineFormatter::formatFirstToken(
// Remove empty lines after "{".
if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&
PreviousLine->Last->is(tok::l_brace) &&
- PreviousLine->First->isNot(tok::kw_namespace) &&
+ !PreviousLine->startsWithNamespace() &&
!startsExternCBlock(*PreviousLine))
Newlines = 1;
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index 07109daf6f..752357c1af 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -992,13 +992,6 @@ void UnwrappedLineParser::parseStructuralElement() {
case tok::kw_namespace:
parseNamespace();
return;
- case tok::kw_inline:
- nextToken();
- if (FormatTok->Tok.is(tok::kw_namespace)) {
- parseNamespace();
- return;
- }
- break;
case tok::kw_public:
case tok::kw_protected:
case tok::kw_private:
@@ -1066,6 +1059,16 @@ void UnwrappedLineParser::parseStructuralElement() {
parseJavaScriptEs6ImportExport();
return;
}
+ if (!Style.isCpp())
+ break;
+ // Handle C++ "(inline|export) namespace".
+ LLVM_FALLTHROUGH;
+ case tok::kw_inline:
+ nextToken();
+ if (FormatTok->Tok.is(tok::kw_namespace)) {
+ parseNamespace();
+ return;
+ }
break;
case tok::identifier:
if (FormatTok->is(TT_ForEachMacro)) {