Skip to content

Commit 01d99ea

Browse files
author
git apple-llvm automerger
committed
Merge commit '32aaacc609e7' from llvm.org/main into experimental/cas/main
2 parents cfc6c5c + 32aaacc commit 01d99ea

File tree

89 files changed

+2761
-2321
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+2761
-2321
lines changed

clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,6 @@ static StringRef getRawStringRef(const SourceRange &Range,
3030
return Lexer::getSourceText(TextRange, Sources, LangOpts);
3131
}
3232

33-
static bool unsupportedNamespace(const NamespaceDecl &ND) {
34-
return ND.isAnonymousNamespace() || ND.isInlineNamespace() ||
35-
!ND.attrs().empty();
36-
}
37-
38-
static bool singleNamedNamespaceChild(const NamespaceDecl &ND) {
39-
NamespaceDecl::decl_range Decls = ND.decls();
40-
if (std::distance(Decls.begin(), Decls.end()) != 1)
41-
return false;
42-
43-
const auto *ChildNamespace = dyn_cast<const NamespaceDecl>(*Decls.begin());
44-
return ChildNamespace && !unsupportedNamespace(*ChildNamespace);
45-
}
46-
47-
template <class R, class F>
48-
static void concatNamespace(NamespaceName &ConcatNameSpace, R &&Range,
49-
F &&Stringify) {
50-
for (auto const &V : Range) {
51-
ConcatNameSpace.append(Stringify(V));
52-
if (V != Range.back())
53-
ConcatNameSpace.append("::");
54-
}
55-
}
56-
5733
std::optional<SourceRange>
5834
NS::getCleanedNamespaceFrontRange(const SourceManager &SM,
5935
const LangOptions &LangOpts) const {
@@ -90,19 +66,53 @@ SourceRange NS::getNamespaceBackRange(const SourceManager &SM,
9066
return getDefaultNamespaceBackRange();
9167
SourceRange TokRange = SourceRange{Tok->getLocation(), Tok->getEndLoc()};
9268
StringRef TokText = getRawStringRef(TokRange, SM, LangOpts);
93-
std::string CloseComment = ("namespace " + getName()).str();
69+
NamespaceName CloseComment{"namespace "};
70+
appendCloseComment(CloseComment);
9471
// current fix hint in readability/NamespaceCommentCheck.cpp use single line
9572
// comment
96-
if (TokText != "// " + CloseComment && TokText != "//" + CloseComment)
73+
constexpr size_t L = sizeof("//") - 1U;
74+
if (TokText.take_front(L) == "//" &&
75+
TokText.drop_front(L).trim() != CloseComment)
9776
return getDefaultNamespaceBackRange();
9877
return SourceRange{front()->getRBraceLoc(), Tok->getEndLoc()};
9978
}
10079

101-
NamespaceName NS::getName() const {
102-
NamespaceName Name{};
103-
concatNamespace(Name, *this,
104-
[](const NamespaceDecl *ND) { return ND->getName(); });
105-
return Name;
80+
void NS::appendName(NamespaceName &Str) const {
81+
for (const NamespaceDecl *ND : *this) {
82+
if (ND->isInlineNamespace())
83+
Str.append("inline ");
84+
Str.append(ND->getName());
85+
if (ND != back())
86+
Str.append("::");
87+
}
88+
}
89+
void NS::appendCloseComment(NamespaceName &Str) const {
90+
if (size() == 1)
91+
Str.append(back()->getName());
92+
else
93+
appendName(Str);
94+
}
95+
96+
bool ConcatNestedNamespacesCheck::unsupportedNamespace(const NamespaceDecl &ND,
97+
bool IsChild) const {
98+
if (ND.isAnonymousNamespace() || !ND.attrs().empty())
99+
return true;
100+
if (getLangOpts().CPlusPlus20) {
101+
// C++20 support inline nested namespace
102+
bool IsFirstNS = IsChild || !Namespaces.empty();
103+
return ND.isInlineNamespace() && !IsFirstNS;
104+
}
105+
return ND.isInlineNamespace();
106+
}
107+
108+
bool ConcatNestedNamespacesCheck::singleNamedNamespaceChild(
109+
const NamespaceDecl &ND) const {
110+
NamespaceDecl::decl_range Decls = ND.decls();
111+
if (std::distance(Decls.begin(), Decls.end()) != 1)
112+
return false;
113+
114+
const auto *ChildNamespace = dyn_cast<const NamespaceDecl>(*Decls.begin());
115+
return ChildNamespace && !unsupportedNamespace(*ChildNamespace, true);
106116
}
107117

108118
void ConcatNestedNamespacesCheck::registerMatchers(
@@ -137,8 +147,11 @@ void ConcatNestedNamespacesCheck::reportDiagnostic(
137147
SourceRange LastRBrace = Backs.pop_back_val();
138148

139149
NamespaceName ConcatNameSpace{"namespace "};
140-
concatNamespace(ConcatNameSpace, Namespaces,
141-
[](const NS &NS) { return NS.getName(); });
150+
for (const NS &NS : Namespaces) {
151+
NS.appendName(ConcatNameSpace);
152+
if (&NS != &Namespaces.back()) // compare address directly
153+
ConcatNameSpace.append("::");
154+
}
142155

143156
for (SourceRange const &Front : Fronts)
144157
DB << FixItHint::CreateRemoval(Front);
@@ -159,12 +172,15 @@ void ConcatNestedNamespacesCheck::check(
159172
if (!locationsInSameFile(Sources, ND.getBeginLoc(), ND.getRBraceLoc()))
160173
return;
161174

162-
if (unsupportedNamespace(ND))
175+
if (unsupportedNamespace(ND, false))
163176
return;
164177

165178
if (!ND.isNested())
166179
Namespaces.push_back(NS{});
167-
Namespaces.back().push_back(&ND);
180+
if (!Namespaces.empty())
181+
// Otherwise it will crash with invalid input like `inline namespace
182+
// a::b::c`.
183+
Namespaces.back().push_back(&ND);
168184

169185
if (singleNamedNamespaceChild(ND))
170186
return;

clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@ class NS : public llvm::SmallVector<const NamespaceDecl *, 6> {
2626
SourceRange getNamespaceBackRange(const SourceManager &SM,
2727
const LangOptions &LangOpts) const;
2828
SourceRange getDefaultNamespaceBackRange() const;
29-
NamespaceName getName() const;
29+
void appendName(NamespaceName &Str) const;
30+
void appendCloseComment(NamespaceName &Str) const;
3031
};
3132

3233
class ConcatNestedNamespacesCheck : public ClangTidyCheck {
3334
public:
3435
ConcatNestedNamespacesCheck(StringRef Name, ClangTidyContext *Context)
3536
: ClangTidyCheck(Name, Context) {}
37+
bool unsupportedNamespace(const NamespaceDecl &ND, bool IsChild) const;
38+
bool singleNamedNamespaceChild(const NamespaceDecl &ND) const;
3639
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
3740
return LangOpts.CPlusPlus17;
3841
}

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ Changes in existing checks
314314

315315
- Improved :doc:`modernize-concat-nested-namespaces
316316
<clang-tidy/checks/modernize/concat-nested-namespaces>` to fix incorrect fixes when
317-
using macro between namespace declarations and false positive when using namespace
318-
with attributes.
317+
using macro between namespace declarations, to fix false positive when using namespace
318+
with attributes and to support nested inline namespace introduced in c++20.
319319

320320
- Fixed a false positive in :doc:`performance-no-automatic-move
321321
<clang-tidy/checks/performance/no-automatic-move>` when warning would be

clang-tools-extra/docs/clang-tidy/checks/modernize/concat-nested-namespaces.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ For example:
3030
}
3131
}
3232

33+
// in c++20
34+
namespace n8 {
35+
inline namespace n9 {
36+
void t();
37+
}
38+
}
39+
3340
Will be modified to:
3441

3542
.. code-block:: c++
@@ -47,3 +54,8 @@ Will be modified to:
4754
}
4855
}
4956

57+
// in c++20
58+
namespace n8::inline n9 {
59+
void t();
60+
}
61+

0 commit comments

Comments
 (0)