Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
57ba58d
[LV] Modernize version-mem-access.ll tests.
fhahn Oct 27, 2025
6b885c3
RuntimeLibcalls: Make sure _Unwind_Resume entries are mutually exclus…
arsenm Oct 27, 2025
bbf5c41
X86: Make sure compiler-rt div calls are not added for msvc (#164591)
arsenm Oct 27, 2025
b549ea7
ARM: Avoid adding default libcalls overridden by AEABI functions (#16…
arsenm Oct 27, 2025
0a34cbe
AArch64: Use Register in FrameLowering (#165188)
arsenm Oct 27, 2025
3dce567
AArch64: Clean up some casts to target subclasses (#165189)
arsenm Oct 27, 2025
3b8f63d
[clang-tidy][NFC] Remove unused parameter in function (#164202)
localspook Oct 27, 2025
81de861
[clang-tidy] Add new check: `readability-redundant-typename` (#161574)
localspook Oct 27, 2025
a61e016
[libclc] Implement integer __clc_abs using __builtin_elementwise_abs …
wenju-he Oct 27, 2025
0e28c9b
[LAA] Skip undef/poison strides in collectStridedAccess.
fhahn Oct 27, 2025
133ac3a
[ADT] Achieve the "Rule of Zero" in DGNode (#165190)
kazutakahirata Oct 27, 2025
ee25edf
[DebugInfo] Fold a namespace into a std::hash specialization (NFC) (#…
kazutakahirata Oct 27, 2025
8983127
[Support] Use "static constexpr" for a constant in ProcessInfo (NFC) …
kazutakahirata Oct 27, 2025
2bb9531
[llvm] Proofread YamlIO.rst (#165193)
kazutakahirata Oct 27, 2025
f19bce3
[AArch64] Remove an unused local variable (NFC) (#165194)
kazutakahirata Oct 27, 2025
1322e71
[SpecialCaseList] Add RadixTree for substring matching (#164545)
vitalybuka Oct 27, 2025
dbd932c
merge main into amd-staging
z1-cciauto Oct 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions clang-tools-extra/clang-tidy/ClangTidyCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,10 @@ ClangTidyCheck::OptionsView::getLocalOrGlobal(StringRef LocalName) const {
return std::nullopt;
}

static std::optional<bool> getAsBool(StringRef Value,
const llvm::Twine &LookupName) {

static std::optional<bool> getAsBool(StringRef Value) {
if (std::optional<bool> Parsed = llvm::yaml::parseBool(Value))
return Parsed;
// To maintain backwards compatability, we support parsing numbers as
// To maintain backwards compatibility, we support parsing numbers as
// booleans, even though its not supported in YAML.
long long Number = 0;
if (!Value.getAsInteger(10, Number))
Expand All @@ -107,7 +105,7 @@ template <>
std::optional<bool>
ClangTidyCheck::OptionsView::get<bool>(StringRef LocalName) const {
if (std::optional<StringRef> ValueOr = get(LocalName)) {
if (auto Result = getAsBool(*ValueOr, NamePrefix + LocalName))
if (auto Result = getAsBool(*ValueOr))
return Result;
diagnoseBadBooleanOption(NamePrefix + LocalName, *ValueOr);
}
Expand All @@ -119,7 +117,7 @@ std::optional<bool>
ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName) const {
auto Iter = findPriorityOption(CheckOptions, NamePrefix, LocalName, Context);
if (Iter != CheckOptions.end()) {
if (auto Result = getAsBool(Iter->getValue().Value, Iter->getKey()))
if (auto Result = getAsBool(Iter->getValue().Value))
return Result;
diagnoseBadBooleanOption(Iter->getKey(), Iter->getValue().Value);
}
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clang-tidy/readability/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ add_clang_library(clangTidyReadabilityModule STATIC
RedundantSmartptrGetCheck.cpp
RedundantStringCStrCheck.cpp
RedundantStringInitCheck.cpp
RedundantTypenameCheck.cpp
ReferenceToConstructedTemporaryCheck.cpp
SimplifyBooleanExprCheck.cpp
SimplifySubscriptExprCheck.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include "RedundantSmartptrGetCheck.h"
#include "RedundantStringCStrCheck.h"
#include "RedundantStringInitCheck.h"
#include "RedundantTypenameCheck.h"
#include "ReferenceToConstructedTemporaryCheck.h"
#include "SimplifyBooleanExprCheck.h"
#include "SimplifySubscriptExprCheck.h"
Expand Down Expand Up @@ -143,6 +144,8 @@ class ReadabilityModule : public ClangTidyModule {
"readability-redundant-parentheses");
CheckFactories.registerCheck<RedundantPreprocessorCheck>(
"readability-redundant-preprocessor");
CheckFactories.registerCheck<RedundantTypenameCheck>(
"readability-redundant-typename");
CheckFactories.registerCheck<ReferenceToConstructedTemporaryCheck>(
"readability-reference-to-constructed-temporary");
CheckFactories.registerCheck<SimplifySubscriptExprCheck>(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "RedundantTypenameCheck.h"
#include "clang/AST/TypeLoc.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Lex/Lexer.h"
#include "clang/Sema/DeclSpec.h"

using namespace clang::ast_matchers;

namespace clang::tidy::readability {

void RedundantTypenameCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(typeLoc(unless(hasAncestor(decl(isInstantiated()))))
.bind("nonDependentTypeLoc"),
this);

if (!getLangOpts().CPlusPlus20)
return;

const auto InImplicitTypenameContext = anyOf(
hasParent(decl(anyOf(
typedefNameDecl(), templateTypeParmDecl(), nonTypeTemplateParmDecl(),
friendDecl(), fieldDecl(),
varDecl(hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl())),
unless(parmVarDecl())),
parmVarDecl(hasParent(expr(requiresExpr()))),
parmVarDecl(hasParent(typeLoc(hasParent(decl(
anyOf(cxxMethodDecl(), hasParent(friendDecl()),
functionDecl(has(nestedNameSpecifier())),
cxxDeductionGuideDecl(hasDeclContext(recordDecl())))))))),
// Match return types.
functionDecl(unless(cxxConversionDecl()))))),
hasParent(expr(anyOf(cxxNamedCastExpr(), cxxNewExpr()))));
Finder->addMatcher(
typeLoc(InImplicitTypenameContext).bind("dependentTypeLoc"), this);
}

void RedundantTypenameCheck::check(const MatchFinder::MatchResult &Result) {
const SourceLocation ElaboratedKeywordLoc = [&] {
if (const auto *NonDependentTypeLoc =
Result.Nodes.getNodeAs<TypeLoc>("nonDependentTypeLoc")) {
if (const auto TL = NonDependentTypeLoc->getAs<TypedefTypeLoc>())
return TL.getElaboratedKeywordLoc();

if (const auto TL = NonDependentTypeLoc->getAs<TagTypeLoc>())
return TL.getElaboratedKeywordLoc();

if (const auto TL = NonDependentTypeLoc
->getAs<DeducedTemplateSpecializationTypeLoc>())
return TL.getElaboratedKeywordLoc();

if (const auto TL =
NonDependentTypeLoc->getAs<TemplateSpecializationTypeLoc>())
if (!TL.getType()->isDependentType())
return TL.getElaboratedKeywordLoc();
} else {
TypeLoc InnermostTypeLoc =
*Result.Nodes.getNodeAs<TypeLoc>("dependentTypeLoc");
while (const TypeLoc Next = InnermostTypeLoc.getNextTypeLoc())
InnermostTypeLoc = Next;

if (const auto TL = InnermostTypeLoc.getAs<DependentNameTypeLoc>())
return TL.getElaboratedKeywordLoc();

if (const auto TL =
InnermostTypeLoc.getAs<TemplateSpecializationTypeLoc>())
return TL.getElaboratedKeywordLoc();
}

return SourceLocation();
}();

if (ElaboratedKeywordLoc.isInvalid())
return;

if (Token ElaboratedKeyword;
Lexer::getRawToken(ElaboratedKeywordLoc, ElaboratedKeyword,
*Result.SourceManager, getLangOpts()) ||
ElaboratedKeyword.getRawIdentifier() != "typename")
return;

diag(ElaboratedKeywordLoc, "redundant 'typename'")
<< FixItHint::CreateRemoval(ElaboratedKeywordLoc);
}

} // namespace clang::tidy::readability
36 changes: 36 additions & 0 deletions clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTTYPENAMECHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTTYPENAMECHECK_H

#include "../ClangTidyCheck.h"

namespace clang::tidy::readability {

/// Finds redundant uses of the `typename` keyword.
///
/// For the user-facing documentation see:
/// https://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-typename.html
class RedundantTypenameCheck : public ClangTidyCheck {
public:
RedundantTypenameCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus;
}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
std::optional<TraversalKind> getCheckTraversalKind() const override {
return TK_IgnoreUnlessSpelledInSource;
}
};

} // namespace clang::tidy::readability

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTTYPENAMECHECK_H
5 changes: 5 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,11 @@ New checks

Detect redundant parentheses.

- New :doc:`readability-redundant-typename
<clang-tidy/checks/readability/redundant-typename>` check.

Finds redundant uses of the ``typename`` keyword.

New check aliases
^^^^^^^^^^^^^^^^^

Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/docs/clang-tidy/checks/list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ Clang-Tidy Checks
:doc:`readability-redundant-smartptr-get <readability/redundant-smartptr-get>`, "Yes"
:doc:`readability-redundant-string-cstr <readability/redundant-string-cstr>`, "Yes"
:doc:`readability-redundant-string-init <readability/redundant-string-init>`, "Yes"
:doc:`readability-redundant-typename <readability/redundant-typename>`, "Yes"
:doc:`readability-reference-to-constructed-temporary <readability/reference-to-constructed-temporary>`,
:doc:`readability-simplify-boolean-expr <readability/simplify-boolean-expr>`, "Yes"
:doc:`readability-simplify-subscript-expr <readability/simplify-subscript-expr>`, "Yes"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.. title:: clang-tidy - readability-redundant-typename

readability-redundant-typename
==============================

Finds redundant uses of the ``typename`` keyword.

``typename`` is redundant in two cases. First, before non-dependent names:

.. code-block:: c++

/*typename*/ std::vector<int>::size_type size;

And second, since C++20, before dependent names that appear in a context
where only a type is allowed (the following example shows just a few of them):

.. code-block:: c++

template <typename T>
using trait = /*typename*/ T::type;

template <typename T>
/*typename*/ T::underlying_type as_underlying(T n) {
return static_cast</*typename*/ T::underlying_type>(n);
}

template <typename T>
struct S {
/*typename*/ T::type variable;
/*typename*/ T::type function(/*typename*/ T::type);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: %check_clang_tidy -std=c++98,c++03 %s readability-redundant-typename %t \
// RUN: -- -- -fno-delayed-template-parsing

struct NotDependent {
typedef int R;
template <typename = int>
struct T {};
};

template <typename T>
typename T::R f() {
static_cast<typename T::R>(0);

typename NotDependent::R NotDependentVar;
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant 'typename' [readability-redundant-typename]
// CHECK-FIXES: NotDependent::R NotDependentVar;

typename NotDependent::T<int> V1;
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant 'typename' [readability-redundant-typename]
// CHECK-FIXES: NotDependent::T<int> V1;

void notDependentFunctionDeclaration(typename NotDependent::R);
// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: redundant 'typename' [readability-redundant-typename]
// CHECK-FIXES: void notDependentFunctionDeclaration(NotDependent::R);
}
Loading