Skip to content

Commit 01d9338

Browse files
Merge branch 'llvm:main' into gh-101657
2 parents 0fd991b + 8db7327 commit 01d9338

File tree

671 files changed

+13898
-4859
lines changed

Some content is hidden

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

671 files changed

+13898
-4859
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-doc/Serialize.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -696,13 +696,11 @@ emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
696696

697697
// What this is a specialization of.
698698
auto SpecOf = CTSD->getSpecializedTemplateOrPartial();
699-
if (SpecOf.is<ClassTemplateDecl *>()) {
700-
Specialization.SpecializationOf =
701-
getUSRForDecl(SpecOf.get<ClassTemplateDecl *>());
702-
} else if (SpecOf.is<ClassTemplatePartialSpecializationDecl *>()) {
703-
Specialization.SpecializationOf =
704-
getUSRForDecl(SpecOf.get<ClassTemplatePartialSpecializationDecl *>());
705-
}
699+
if (auto *CTD = dyn_cast<ClassTemplateDecl *>(SpecOf))
700+
Specialization.SpecializationOf = getUSRForDecl(CTD);
701+
else if (auto *CTPSD =
702+
dyn_cast<ClassTemplatePartialSpecializationDecl *>(SpecOf))
703+
Specialization.SpecializationOf = getUSRForDecl(CTPSD);
706704

707705
// Parameters to the specilization. For partial specializations, get the
708706
// parameters "as written" from the ClassTemplatePartialSpecializationDecl

clang-tools-extra/clang-tidy/ClangTidy.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -646,9 +646,9 @@ void exportReplacements(const llvm::StringRef MainFilePath,
646646
YAML << TUD;
647647
}
648648

649-
NamesAndOptions
649+
ChecksAndOptions
650650
getAllChecksAndOptions(bool AllowEnablingAnalyzerAlphaCheckers) {
651-
NamesAndOptions Result;
651+
ChecksAndOptions Result;
652652
ClangTidyOptions Opts;
653653
Opts.Checks = "*";
654654
clang::tidy::ClangTidyContext Context(
@@ -661,7 +661,7 @@ getAllChecksAndOptions(bool AllowEnablingAnalyzerAlphaCheckers) {
661661
}
662662

663663
for (const auto &Factory : Factories)
664-
Result.Names.insert(Factory.getKey());
664+
Result.Checks.insert(Factory.getKey());
665665

666666
#if CLANG_TIDY_ENABLE_STATIC_ANALYZER
667667
SmallString<64> Buffer(AnalyzerCheckNamePrefix);
@@ -670,7 +670,7 @@ getAllChecksAndOptions(bool AllowEnablingAnalyzerAlphaCheckers) {
670670
AllowEnablingAnalyzerAlphaCheckers)) {
671671
Buffer.truncate(DefSize);
672672
Buffer.append(AnalyzerCheck);
673-
Result.Names.insert(Buffer);
673+
Result.Checks.insert(Buffer);
674674
}
675675
for (std::string OptionName : {
676676
#define GET_CHECKER_OPTIONS

clang-tools-extra/clang-tidy/ClangTidy.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ class ClangTidyASTConsumerFactory {
5858
std::vector<std::string> getCheckNames(const ClangTidyOptions &Options,
5959
bool AllowEnablingAnalyzerAlphaCheckers);
6060

61-
struct NamesAndOptions {
62-
llvm::StringSet<> Names;
61+
struct ChecksAndOptions {
62+
llvm::StringSet<> Checks;
6363
llvm::StringSet<> Options;
6464
};
6565

66-
NamesAndOptions
66+
ChecksAndOptions
6767
getAllChecksAndOptions(bool AllowEnablingAnalyzerAlphaCheckers = true);
6868

6969
/// Returns the effective check-specific options.

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/clang-tidy/tool/ClangTidyMain.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,24 @@ static bool verifyFileExtensions(
526526
return AnyInvalid;
527527
}
528528

529+
static bool verifyOptions(const llvm::StringSet<> &ValidOptions,
530+
const ClangTidyOptions::OptionMap &OptionMap,
531+
StringRef Source) {
532+
bool AnyInvalid = false;
533+
for (auto Key : OptionMap.keys()) {
534+
if (ValidOptions.contains(Key))
535+
continue;
536+
AnyInvalid = true;
537+
auto &Output = llvm::WithColor::warning(llvm::errs(), Source)
538+
<< "unknown check option '" << Key << '\'';
539+
llvm::StringRef Closest = closest(Key, ValidOptions);
540+
if (!Closest.empty())
541+
Output << "; did you mean '" << Closest << '\'';
542+
Output << VerifyConfigWarningEnd;
543+
}
544+
return AnyInvalid;
545+
}
546+
529547
static SmallString<256> makeAbsolute(llvm::StringRef Input) {
530548
if (Input.empty())
531549
return {};
@@ -629,29 +647,17 @@ int clangTidyMain(int argc, const char **argv) {
629647
if (VerifyConfig) {
630648
std::vector<ClangTidyOptionsProvider::OptionsSource> RawOptions =
631649
OptionsProvider->getRawOptions(FileName);
632-
NamesAndOptions Valid =
650+
ChecksAndOptions Valid =
633651
getAllChecksAndOptions(AllowEnablingAnalyzerAlphaCheckers);
634652
bool AnyInvalid = false;
635653
for (const auto &[Opts, Source] : RawOptions) {
636654
if (Opts.Checks)
637-
AnyInvalid |= verifyChecks(Valid.Names, *Opts.Checks, Source);
638-
655+
AnyInvalid |= verifyChecks(Valid.Checks, *Opts.Checks, Source);
639656
if (Opts.HeaderFileExtensions && Opts.ImplementationFileExtensions)
640657
AnyInvalid |=
641658
verifyFileExtensions(*Opts.HeaderFileExtensions,
642659
*Opts.ImplementationFileExtensions, Source);
643-
644-
for (auto Key : Opts.CheckOptions.keys()) {
645-
if (Valid.Options.contains(Key))
646-
continue;
647-
AnyInvalid = true;
648-
auto &Output = llvm::WithColor::warning(llvm::errs(), Source)
649-
<< "unknown check option '" << Key << '\'';
650-
llvm::StringRef Closest = closest(Key, Valid.Options);
651-
if (!Closest.empty())
652-
Output << "; did you mean '" << Closest << '\'';
653-
Output << VerifyConfigWarningEnd;
654-
}
660+
AnyInvalid |= verifyOptions(Valid.Options, Opts.CheckOptions, Source);
655661
}
656662
if (AnyInvalid)
657663
return 1;

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/docs/clang-tidy/checks/modernize/use-ranges.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ Calls to the following std library algorithms are checked:
104104
``std::unique``,
105105
``std::upper_bound``.
106106

107+
Note: some range algorithms for ``vector<bool>`` require C++23 because it uses
108+
proxy iterators.
109+
107110
Reverse Iteration
108111
-----------------
109112

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+
}

0 commit comments

Comments
 (0)