Skip to content

Commit c0b9c26

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:93c2577020fe into amd-gfx:fb65d18eb39e
Local branch amd-gfx fb65d18 Merged main:c361fd5a7a8d into amd-gfx:b0290dd5dc58 Remote branch main 93c2577 [gn build] Port b9a2658
2 parents fb65d18 + 93c2577 commit c0b9c26

File tree

253 files changed

+3904
-2527
lines changed

Some content is hidden

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

253 files changed

+3904
-2527
lines changed

.github/workflows/libcxx-build-and-test.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ jobs:
4343
fail-fast: false
4444
matrix:
4545
config: [
46+
'frozen-cxx03-headers',
4647
'generic-cxx03',
4748
'generic-cxx26',
4849
'generic-modules'

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

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "UseUsingCheck.h"
10-
#include "clang/AST/ASTContext.h"
10+
#include "../utils/LexerUtils.h"
1111
#include "clang/AST/DeclGroup.h"
12+
#include "clang/Basic/LangOptions.h"
13+
#include "clang/Basic/SourceLocation.h"
14+
#include "clang/Basic/SourceManager.h"
15+
#include "clang/Basic/TokenKinds.h"
1216
#include "clang/Lex/Lexer.h"
17+
#include <string>
1318

1419
using namespace clang::ast_matchers;
1520
namespace {
@@ -83,6 +88,9 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) {
8388
if (!ParentDecl)
8489
return;
8590

91+
const SourceManager &SM = *Result.SourceManager;
92+
const LangOptions &LO = getLangOpts();
93+
8694
// Match CXXRecordDecl only to store the range of the last non-implicit full
8795
// declaration, to later check whether it's within the typdef itself.
8896
const auto *MatchedTagDecl = Result.Nodes.getNodeAs<TagDecl>(TagDeclName);
@@ -119,14 +127,51 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) {
119127
return;
120128
}
121129

122-
PrintingPolicy PrintPolicy(getLangOpts());
123-
PrintPolicy.SuppressScope = true;
124-
PrintPolicy.ConstantArraySizeAsWritten = true;
125-
PrintPolicy.UseVoidForZeroParams = false;
126-
PrintPolicy.PrintInjectedClassNameWithArguments = false;
130+
const TypeLoc TL = MatchedDecl->getTypeSourceInfo()->getTypeLoc();
131+
132+
auto [Type, QualifierStr] = [MatchedDecl, this, &TL, &SM,
133+
&LO]() -> std::pair<std::string, std::string> {
134+
SourceRange TypeRange = TL.getSourceRange();
135+
136+
// Function pointer case, get the left and right side of the identifier
137+
// without the identifier.
138+
if (TypeRange.fullyContains(MatchedDecl->getLocation())) {
139+
const auto RangeLeftOfIdentifier = CharSourceRange::getCharRange(
140+
TypeRange.getBegin(), MatchedDecl->getLocation());
141+
const auto RangeRightOfIdentifier = CharSourceRange::getCharRange(
142+
Lexer::getLocForEndOfToken(MatchedDecl->getLocation(), 0, SM, LO),
143+
Lexer::getLocForEndOfToken(TypeRange.getEnd(), 0, SM, LO));
144+
const std::string VerbatimType =
145+
(Lexer::getSourceText(RangeLeftOfIdentifier, SM, LO) +
146+
Lexer::getSourceText(RangeRightOfIdentifier, SM, LO))
147+
.str();
148+
return {VerbatimType, ""};
149+
}
150+
151+
StringRef ExtraReference = "";
152+
if (MainTypeEndLoc.isValid() && TypeRange.fullyContains(MainTypeEndLoc)) {
153+
// Each type introduced in a typedef can specify being a reference or
154+
// pointer type seperately, so we need to sigure out if the new using-decl
155+
// needs to be to a reference or pointer as well.
156+
const SourceLocation Tok = utils::lexer::findPreviousAnyTokenKind(
157+
MatchedDecl->getLocation(), SM, LO, tok::TokenKind::star,
158+
tok::TokenKind::amp, tok::TokenKind::comma,
159+
tok::TokenKind::kw_typedef);
160+
161+
ExtraReference = Lexer::getSourceText(
162+
CharSourceRange::getCharRange(Tok, Tok.getLocWithOffset(1)), SM, LO);
127163

128-
std::string Type = MatchedDecl->getUnderlyingType().getAsString(PrintPolicy);
129-
std::string Name = MatchedDecl->getNameAsString();
164+
if (ExtraReference != "*" && ExtraReference != "&")
165+
ExtraReference = "";
166+
167+
TypeRange.setEnd(MainTypeEndLoc);
168+
}
169+
return {
170+
Lexer::getSourceText(CharSourceRange::getTokenRange(TypeRange), SM, LO)
171+
.str(),
172+
ExtraReference.str()};
173+
}();
174+
StringRef Name = MatchedDecl->getName();
130175
SourceRange ReplaceRange = MatchedDecl->getSourceRange();
131176

132177
// typedefs with multiple comma-separated definitions produce multiple
@@ -143,7 +188,8 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) {
143188
// This is the first (and possibly the only) TypedefDecl in a typedef. Save
144189
// Type and Name in case we find subsequent TypedefDecl's in this typedef.
145190
FirstTypedefType = Type;
146-
FirstTypedefName = Name;
191+
FirstTypedefName = Name.str();
192+
MainTypeEndLoc = TL.getEndLoc();
147193
} else {
148194
// This is additional TypedefDecl in a comma-separated typedef declaration.
149195
// Start replacement *after* prior replacement and separate with semicolon.
@@ -153,10 +199,10 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) {
153199
// If this additional TypedefDecl's Type starts with the first TypedefDecl's
154200
// type, make this using statement refer back to the first type, e.g. make
155201
// "typedef int Foo, *Foo_p;" -> "using Foo = int;\nusing Foo_p = Foo*;"
156-
if (Type.size() > FirstTypedefType.size() &&
157-
Type.substr(0, FirstTypedefType.size()) == FirstTypedefType)
158-
Type = FirstTypedefName + Type.substr(FirstTypedefType.size() + 1);
202+
if (Type == FirstTypedefType && !QualifierStr.empty())
203+
Type = FirstTypedefName;
159204
}
205+
160206
if (!ReplaceRange.getEnd().isMacroID()) {
161207
const SourceLocation::IntTy Offset =
162208
MatchedDecl->getFunctionType() ? 0 : Name.size();
@@ -171,13 +217,12 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) {
171217
LastTagDeclRange->second.isValid() &&
172218
ReplaceRange.fullyContains(LastTagDeclRange->second)) {
173219
Type = std::string(Lexer::getSourceText(
174-
CharSourceRange::getTokenRange(LastTagDeclRange->second),
175-
*Result.SourceManager, getLangOpts()));
220+
CharSourceRange::getTokenRange(LastTagDeclRange->second), SM, LO));
176221
if (Type.empty())
177222
return;
178223
}
179224

180-
std::string Replacement = Using + Name + " = " + Type;
225+
std::string Replacement = (Using + Name + " = " + Type + QualifierStr).str();
181226
Diag << FixItHint::CreateReplacement(ReplaceRange, Replacement);
182227
}
183228
} // namespace clang::tidy::modernize

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class UseUsingCheck : public ClangTidyCheck {
2626

2727
std::string FirstTypedefType;
2828
std::string FirstTypedefName;
29+
SourceLocation MainTypeEndLoc;
2930

3031
public:
3132
UseUsingCheck(StringRef Name, ClangTidyContext *Context);

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,9 @@ Changes in existing checks
317317
member function calls too and to only expand macros starting with ``PRI``
318318
and ``__PRI`` from ``<inttypes.h>`` in the format string.
319319

320+
- Improved :doc:`modernize-use-using
321+
<clang-tidy/checks/modernize/use-using>` check by not expanding macros.
322+
320323
- Improved :doc:`performance-avoid-endl
321324
<clang-tidy/checks/performance/avoid-endl>` check to use ``std::endl`` as
322325
placeholder when lexer cannot get source text.

clang-tools-extra/test/clang-tidy/checkers/modernize/use-using.cpp

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ typedef Test<my_class *> another;
8080

8181
typedef int* PInt;
8282
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
83-
// CHECK-FIXES: using PInt = int *;
83+
// CHECK-FIXES: using PInt = int*;
8484

8585
typedef int bla1, bla2, bla3;
8686
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
@@ -112,7 +112,7 @@ TYPEDEF Foo Bak;
112112
typedef FOO Bam;
113113
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
114114
// CHECK-FIXES: #define FOO Foo
115-
// CHECK-FIXES: using Bam = Foo;
115+
// CHECK-FIXES: using Bam = FOO;
116116

117117
typedef struct Foo Bap;
118118
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
@@ -247,7 +247,7 @@ typedef Q<T{0 < 0}.b> Q3_t;
247247

248248
typedef TwoArgTemplate<TwoArgTemplate<int, Q<T{0 < 0}.b> >, S<(0 < 0), Q<b[0 < 0]> > > Nested_t;
249249
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
250-
// CHECK-FIXES: using Nested_t = TwoArgTemplate<TwoArgTemplate<int, Q<T{0 < 0}.b>>, S<(0 < 0), Q<b[0 < 0]>>>;
250+
// CHECK-FIXES: using Nested_t = TwoArgTemplate<TwoArgTemplate<int, Q<T{0 < 0}.b> >, S<(0 < 0), Q<b[0 < 0]> > >;
251251

252252
template <typename a>
253253
class TemplateKeyword {
@@ -265,12 +265,12 @@ class Variadic {};
265265

266266
typedef Variadic<Variadic<int, bool, Q<T{0 < 0}.b> >, S<(0 < 0), Variadic<Q<b[0 < 0]> > > > Variadic_t;
267267
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
268-
// CHECK-FIXES: using Variadic_t = Variadic<Variadic<int, bool, Q<T{0 < 0}.b>>, S<(0 < 0), Variadic<Q<b[0 < 0]>>>>
268+
// CHECK-FIXES: using Variadic_t = Variadic<Variadic<int, bool, Q<T{0 < 0}.b> >, S<(0 < 0), Variadic<Q<b[0 < 0]> > > >
269269

270270
typedef Variadic<Variadic<int, bool, Q<T{0 < 0}.b> >, S<(0 < 0), Variadic<Q<b[0 < 0]> > > > Variadic_t, *Variadic_p;
271271
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
272272
// CHECK-MESSAGES: :[[@LINE-2]]:103: warning: use 'using' instead of 'typedef'
273-
// CHECK-FIXES: using Variadic_t = Variadic<Variadic<int, bool, Q<T{0 < 0}.b>>, S<(0 < 0), Variadic<Q<b[0 < 0]>>>>;
273+
// CHECK-FIXES: using Variadic_t = Variadic<Variadic<int, bool, Q<T{0 < 0}.b> >, S<(0 < 0), Variadic<Q<b[0 < 0]> > > >;
274274
// CHECK-FIXES-NEXT: using Variadic_p = Variadic_t*;
275275

276276
typedef struct { int a; } R_t, *R_p;
@@ -383,3 +383,57 @@ namespace ISSUE_72179
383383
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use 'using' instead of 'typedef' [modernize-use-using]
384384
// CHECK-FIXES: const auto foo4 = [](int a){using d = int;};
385385
}
386+
387+
388+
typedef int* int_ptr, *int_ptr_ptr;
389+
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
390+
// CHECK-MESSAGES: :[[@LINE-2]]:21: warning: use 'using' instead of 'typedef' [modernize-use-using]
391+
// CHECK-FIXES: using int_ptr = int*;
392+
// CHECK-FIXES-NEXT: using int_ptr_ptr = int_ptr*;
393+
394+
#ifndef SpecialMode
395+
#define SomeMacro(x) x
396+
#else
397+
#define SomeMacro(x) SpecialType
398+
#endif
399+
400+
class SomeMacro(GH33760) { };
401+
402+
typedef void(SomeMacro(GH33760)::* FunctionType)(float, int);
403+
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
404+
// CHECK-FIXES: using FunctionType = void(SomeMacro(GH33760)::* )(float, int);
405+
406+
#define CDECL __attribute((cdecl))
407+
408+
// GH37846 & GH41685
409+
typedef void (CDECL *GH37846)(int);
410+
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
411+
// CHECK-FIXES: using GH37846 = void (CDECL *)(int);
412+
413+
typedef void (__attribute((cdecl)) *GH41685)(int);
414+
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
415+
// CHECK-FIXES: using GH41685 = void (__attribute((cdecl)) *)(int);
416+
417+
namespace GH83568 {
418+
typedef int(*name)(int arg1, int arg2);
419+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef' [modernize-use-using]
420+
// CHECK-FIXES: using name = int(*)(int arg1, int arg2);
421+
}
422+
423+
#ifdef FOO
424+
#define GH95716 float
425+
#else
426+
#define GH95716 double
427+
#endif
428+
429+
typedef GH95716 foo;
430+
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
431+
// CHECK-FIXES: using foo = GH95716;
432+
433+
namespace GH97009 {
434+
typedef double PointType[3];
435+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef' [modernize-use-using]
436+
typedef bool (*Function)(PointType, PointType);
437+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef' [modernize-use-using]
438+
// CHECK-FIXES: using Function = bool (*)(PointType, PointType);
439+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
set(LIBCXX_TEST_PARAMS "std=c++03;test_frozen_cxx03_headers=True" CACHE STRING "")
2+
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")

0 commit comments

Comments
 (0)