From 613f791131ee6911f3cbb0c52245335ecfd791af Mon Sep 17 00:00:00 2001 From: Whitney Tsang Date: Tue, 3 Mar 2020 14:06:13 +0000 Subject: [PATCH 01/29] Revert "[LoopNest]: Analysis to discover properties of a loop nest." This reverts commit 3a063d68e3c97136d10a2e770f389e6c13c3b317. Broke the build with modules enabled: http://green.lab.llvm.org/green/job/lldb-cmake/10655/console . --- llvm/include/llvm/Analysis/LoopNestAnalysis.h | 162 ------ llvm/lib/Analysis/CMakeLists.txt | 1 - llvm/lib/Analysis/LoopNestAnalysis.cpp | 296 ----------- llvm/lib/Passes/PassBuilder.cpp | 1 - llvm/lib/Passes/PassRegistry.def | 1 - .../LoopNestAnalysis/imperfectnest.ll | 493 ------------------ .../Analysis/LoopNestAnalysis/infinite.ll | 35 -- .../Analysis/LoopNestAnalysis/perfectnest.ll | 275 ---------- llvm/unittests/Analysis/CMakeLists.txt | 1 - llvm/unittests/Analysis/LoopNestTest.cpp | 194 ------- 10 files changed, 1459 deletions(-) delete mode 100644 llvm/include/llvm/Analysis/LoopNestAnalysis.h delete mode 100644 llvm/lib/Analysis/LoopNestAnalysis.cpp delete mode 100644 llvm/test/Analysis/LoopNestAnalysis/imperfectnest.ll delete mode 100644 llvm/test/Analysis/LoopNestAnalysis/infinite.ll delete mode 100644 llvm/test/Analysis/LoopNestAnalysis/perfectnest.ll delete mode 100644 llvm/unittests/Analysis/LoopNestTest.cpp diff --git a/llvm/include/llvm/Analysis/LoopNestAnalysis.h b/llvm/include/llvm/Analysis/LoopNestAnalysis.h deleted file mode 100644 index 5b2ec3a265364d..00000000000000 --- a/llvm/include/llvm/Analysis/LoopNestAnalysis.h +++ /dev/null @@ -1,162 +0,0 @@ -//===- llvm/Analysis/LoopNestAnalysis.h -------------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file defines the interface for the loop nest analysis. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ANALYSIS_LOOPNESTANALYSIS_H -#define LLVM_ANALYSIS_LOOPNESTANALYSIS_H - -#include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/Transforms/Scalar/LoopPassManager.h" - -namespace llvm { - -using LoopVectorTy = SmallVector; - -/// This class represents a loop nest and can be used to query its properties. -class LoopNest { -public: - /// Construct a loop nest rooted by loop \p Root. - LoopNest(Loop &Root, ScalarEvolution &SE); - - LoopNest() = delete; - LoopNest &operator=(const LoopNest &) = delete; - - /// Construct a LoopNest object. - static std::unique_ptr getLoopNest(Loop &Root, ScalarEvolution &SE); - - /// Return true if the given loops \p OuterLoop and \p InnerLoop are - /// perfectly nested with respect to each other, and false otherwise. - /// Example: - /// \code - /// for(i) - /// for(j) - /// for(k) - /// \endcode - /// arePerfectlyNested(loop_i, loop_j, SE) would return true. - /// arePerfectlyNested(loop_j, loop_k, SE) would return true. - /// arePerfectlyNested(loop_i, loop_k, SE) would return false. - static bool arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop, - ScalarEvolution &SE); - - /// Return the maximum nesting depth of the loop nest rooted by loop \p Root. - /// For example given the loop nest: - /// \code - /// for(i) // loop at level 1 and Root of the nest - /// for(j) // loop at level 2 - /// - /// for(k) // loop at level 3 - /// \endcode - /// getMaxPerfectDepth(Loop_i) would return 2. - static unsigned getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE); - - /// Return the outermost loop in the loop nest. - Loop &getOutermostLoop() const { return *Loops.front(); } - - /// Return the innermost loop in the loop nest if the nest has only one - /// innermost loop, and a nullptr otherwise. - /// Note: the innermost loop returned is not necessarily perfectly nested. - Loop *getInnermostLoop() const { - if (Loops.size() == 1) - return Loops.back(); - - // The loops in the 'Loops' vector have been collected in breadth first - // order, therefore if the last 2 loops in it have the same nesting depth - // there isn't a unique innermost loop in the nest. - Loop *LastLoop = Loops.back(); - auto SecondLastLoopIter = ++Loops.rbegin(); - return (LastLoop->getLoopDepth() == (*SecondLastLoopIter)->getLoopDepth()) - ? nullptr - : LastLoop; - } - - /// Return the loop at the given \p Index. - Loop *getLoop(unsigned Index) const { - assert(Index < Loops.size() && "Index is out of bounds"); - return Loops[Index]; - } - - /// Return the number of loops in the nest. - size_t getNumLoops() const { return Loops.size(); } - - /// Get the loops in the nest. - ArrayRef getLoops() const { return Loops; } - - /// Retrieve a vector of perfect loop nests contained in the current loop - /// nest. For example, given the following nest containing 4 loops, this - /// member function would return {{L1,L2},{L3,L4}}. - /// \code - /// for(i) // L1 - /// for(j) // L2 - /// - /// for(k) // L3 - /// for(l) // L4 - /// \endcode - SmallVector getPerfectLoops(ScalarEvolution &SE) const; - - /// Return the loop nest depth (i.e. the loop depth of the 'deepest' loop) - /// For example given the loop nest: - /// \code - /// for(i) // loop at level 1 and Root of the nest - /// for(j1) // loop at level 2 - /// for(k) // loop at level 3 - /// for(j2) // loop at level 2 - /// \endcode - /// getNestDepth() would return 3. - unsigned getNestDepth() const { - int NestDepth = - Loops.back()->getLoopDepth() - Loops.front()->getLoopDepth() + 1; - assert(NestDepth > 0 && "Expecting NestDepth to be at least 1"); - return NestDepth; - } - - /// Return the maximum perfect nesting depth. - unsigned getMaxPerfectDepth() const { return MaxPerfectDepth; } - - /// Return true if all loops in the loop nest are in simplify form. - bool areAllLoopsSimplifyForm() const { - return llvm::all_of(Loops, - [](const Loop *L) { return L->isLoopSimplifyForm(); }); - } - -protected: - const unsigned MaxPerfectDepth; // maximum perfect nesting depth level. - LoopVectorTy Loops; // the loops in the nest (in breadth first order). -}; - -raw_ostream &operator<<(raw_ostream &, const LoopNest &); - -/// This analysis provides information for a loop nest. The analysis runs on -/// demand and can be initiated via AM.getResult. -class LoopNestAnalysis : public AnalysisInfoMixin { - friend AnalysisInfoMixin; - static AnalysisKey Key; - -public: - using Result = LoopNest; - Result run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR); -}; - -/// Printer pass for the \c LoopNest results. -class LoopNestPrinterPass : public PassInfoMixin { - raw_ostream &OS; - -public: - explicit LoopNestPrinterPass(raw_ostream &OS) : OS(OS) {} - - PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, - LoopStandardAnalysisResults &AR, LPMUpdater &U); -}; - -} // namespace llvm - -#endif // LLVM_ANALYSIS_LOOPNESTANALYSIS_H diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt index 969049f9078217..34140e18677d26 100644 --- a/llvm/lib/Analysis/CMakeLists.txt +++ b/llvm/lib/Analysis/CMakeLists.txt @@ -53,7 +53,6 @@ add_llvm_component_library(LLVMAnalysis LoopAccessAnalysis.cpp LoopAnalysisManager.cpp LoopCacheAnalysis.cpp - LoopNestAnalysis.cpp LoopUnrollAnalyzer.cpp LoopInfo.cpp LoopPass.cpp diff --git a/llvm/lib/Analysis/LoopNestAnalysis.cpp b/llvm/lib/Analysis/LoopNestAnalysis.cpp deleted file mode 100644 index 61e53de93151aa..00000000000000 --- a/llvm/lib/Analysis/LoopNestAnalysis.cpp +++ /dev/null @@ -1,296 +0,0 @@ -//===- LoopNestAnalysis.cpp - Loop Nest Analysis --------------------------==// -// -// 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 -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// The implementation for the loop nest analysis. -/// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/LoopNestAnalysis.h" -#include "llvm/ADT/BreadthFirstIterator.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Analysis/PostDominators.h" -#include "llvm/Analysis/ValueTracking.h" - -using namespace llvm; - -#define DEBUG_TYPE "loopnest" -#ifndef NDEBUG -static const char *VerboseDebug = DEBUG_TYPE "-verbose"; -#endif - -/// Determine whether the loops structure violates basic requirements for -/// perfect nesting: -/// - the inner loop should be the outer loop's only child -/// - the outer loop header should 'flow' into the inner loop preheader -/// or jump around the inner loop to the outer loop latch -/// - if the inner loop latch exits the inner loop, it should 'flow' into -/// the outer loop latch. -/// Returns true if the loop structure satisfies the basic requirements and -/// false otherwise. -static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop, - ScalarEvolution &SE); - -//===----------------------------------------------------------------------===// -// LoopNest implementation -// - -LoopNest::LoopNest(Loop &Root, ScalarEvolution &SE) - : MaxPerfectDepth(getMaxPerfectDepth(Root, SE)) { - for (Loop *L : breadth_first(&Root)) - Loops.push_back(L); -} - -std::unique_ptr LoopNest::getLoopNest(Loop &Root, - ScalarEvolution &SE) { - return std::make_unique(Root, SE); -} - -bool LoopNest::arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop, - ScalarEvolution &SE) { - assert(!OuterLoop.getSubLoops().empty() && "Outer loop should have subloops"); - assert(InnerLoop.getParentLoop() && "Inner loop should have a parent"); - LLVM_DEBUG(dbgs() << "Checking whether loop '" << OuterLoop.getName() - << "' and '" << InnerLoop.getName() - << "' are perfectly nested.\n"); - - // Determine whether the loops structure satisfies the following requirements: - // - the inner loop should be the outer loop's only child - // - the outer loop header should 'flow' into the inner loop preheader - // or jump around the inner loop to the outer loop latch - // - if the inner loop latch exits the inner loop, it should 'flow' into - // the outer loop latch. - if (!checkLoopsStructure(OuterLoop, InnerLoop, SE)) { - LLVM_DEBUG(dbgs() << "Not perfectly nested: invalid loop structure.\n"); - return false; - } - - // Bail out if we cannot retrieve the outer loop bounds. - auto OuterLoopLB = OuterLoop.getBounds(SE); - if (OuterLoopLB == None) { - LLVM_DEBUG(dbgs() << "Cannot compute loop bounds of OuterLoop: " - << OuterLoop << "\n";); - return false; - } - - // Identify the outer loop latch comparison instruction. - const BasicBlock *Latch = OuterLoop.getLoopLatch(); - assert(Latch && "Expecting a valid loop latch"); - const BranchInst *BI = dyn_cast(Latch->getTerminator()); - assert(BI && BI->isConditional() && - "Expecting loop latch terminator to be a branch instruction"); - - const CmpInst *OuterLoopLatchCmp = dyn_cast(BI->getCondition()); - DEBUG_WITH_TYPE( - VerboseDebug, if (OuterLoopLatchCmp) { - dbgs() << "Outer loop latch compare instruction: " << *OuterLoopLatchCmp - << "\n"; - }); - - // Identify the inner loop guard instruction. - BranchInst *InnerGuard = InnerLoop.getLoopGuardBranch(); - const CmpInst *InnerLoopGuardCmp = - (InnerGuard) ? dyn_cast(InnerGuard->getCondition()) : nullptr; - - DEBUG_WITH_TYPE( - VerboseDebug, if (InnerLoopGuardCmp) { - dbgs() << "Inner loop guard compare instruction: " << *InnerLoopGuardCmp - << "\n"; - }); - - // Determine whether instructions in a basic block are one of: - // - the inner loop guard comparison - // - the outer loop latch comparison - // - the outer loop induction variable increment - // - a phi node, a cast or a branch - auto containsOnlySafeInstructions = [&](const BasicBlock &BB) { - return llvm::all_of(BB, [&](const Instruction &I) { - bool isAllowed = isSafeToSpeculativelyExecute(&I) || isa(I) || - isa(I); - if (!isAllowed) { - DEBUG_WITH_TYPE(VerboseDebug, { - dbgs() << "Instruction: " << I << "\nin basic block: " << BB - << " is considered unsafe.\n"; - }); - return false; - } - - // The only binary instruction allowed is the outer loop step instruction, - // the only comparison instructions allowed are the inner loop guard - // compare instruction and the outer loop latch compare instruction. - if ((isa(I) && &I != &OuterLoopLB->getStepInst()) || - (isa(I) && &I != OuterLoopLatchCmp && - &I != InnerLoopGuardCmp)) { - DEBUG_WITH_TYPE(VerboseDebug, { - dbgs() << "Instruction: " << I << "\nin basic block:" << BB - << "is unsafe.\n"; - }); - return false; - } - return true; - }); - }; - - // Check the code surrounding the inner loop for instructions that are deemed - // unsafe. - const BasicBlock *OuterLoopHeader = OuterLoop.getHeader(); - const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch(); - const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader(); - - if (!containsOnlySafeInstructions(*OuterLoopHeader) || - !containsOnlySafeInstructions(*OuterLoopLatch) || - (InnerLoopPreHeader != OuterLoopHeader && - !containsOnlySafeInstructions(*InnerLoopPreHeader)) || - !containsOnlySafeInstructions(*InnerLoop.getExitBlock())) { - LLVM_DEBUG(dbgs() << "Not perfectly nested: code surrounding inner loop is " - "unsafe\n";); - return false; - } - - LLVM_DEBUG(dbgs() << "Loop '" << OuterLoop.getName() << "' and '" - << InnerLoop.getName() << "' are perfectly nested.\n"); - - return true; -} - -SmallVector -LoopNest::getPerfectLoops(ScalarEvolution &SE) const { - SmallVector LV; - LoopVectorTy PerfectNest; - - for (Loop *L : depth_first(const_cast(Loops.front()))) { - if (PerfectNest.empty()) - PerfectNest.push_back(L); - - auto &SubLoops = L->getSubLoops(); - if (SubLoops.size() == 1 && arePerfectlyNested(*L, *SubLoops.front(), SE)) { - PerfectNest.push_back(SubLoops.front()); - } else { - LV.push_back(PerfectNest); - PerfectNest.clear(); - } - } - - return LV; -} - -unsigned LoopNest::getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE) { - LLVM_DEBUG(dbgs() << "Get maximum perfect depth of loop nest rooted by loop '" - << Root.getName() << "'\n"); - - const Loop *CurrentLoop = &Root; - const auto *SubLoops = &CurrentLoop->getSubLoops(); - unsigned CurrentDepth = 1; - - while (SubLoops->size() == 1) { - const Loop *InnerLoop = SubLoops->front(); - if (!arePerfectlyNested(*CurrentLoop, *InnerLoop, SE)) { - LLVM_DEBUG({ - dbgs() << "Not a perfect nest: loop '" << CurrentLoop->getName() - << "' is not perfectly nested with loop '" - << InnerLoop->getName() << "'\n"; - }); - break; - } - - CurrentLoop = InnerLoop; - SubLoops = &CurrentLoop->getSubLoops(); - ++CurrentDepth; - } - - return CurrentDepth; -} - -static bool checkLoopsStructure(const Loop &OuterLoop, const Loop &InnerLoop, - ScalarEvolution &SE) { - // The inner loop must be the only outer loop's child. - if ((OuterLoop.getSubLoops().size() != 1) || - (InnerLoop.getParentLoop() != &OuterLoop)) - return false; - - // We expect loops in normal form which have a preheader, header, latch... - if (!OuterLoop.isLoopSimplifyForm() || !InnerLoop.isLoopSimplifyForm()) - return false; - - const BasicBlock *OuterLoopHeader = OuterLoop.getHeader(); - const BasicBlock *OuterLoopLatch = OuterLoop.getLoopLatch(); - const BasicBlock *InnerLoopPreHeader = InnerLoop.getLoopPreheader(); - const BasicBlock *InnerLoopLatch = InnerLoop.getLoopLatch(); - const BasicBlock *InnerLoopExit = InnerLoop.getExitBlock(); - - // We expect rotated loops. The inner loop should have a single exit block. - if (OuterLoop.getExitingBlock() != OuterLoopLatch || - InnerLoop.getExitingBlock() != InnerLoopLatch || !InnerLoopExit) - return false; - - // Ensure the only branch that may exist between the loops is the inner loop - // guard. - if (OuterLoopHeader != InnerLoopPreHeader) { - const BranchInst *BI = - dyn_cast(OuterLoopHeader->getTerminator()); - - if (!BI || BI != InnerLoop.getLoopGuardBranch()) - return false; - - // The successors of the inner loop guard should be the inner loop - // preheader and the outer loop latch. - for (const BasicBlock *Succ : BI->successors()) { - if (Succ == InnerLoopPreHeader) - continue; - if (Succ == OuterLoopLatch) - continue; - - DEBUG_WITH_TYPE(VerboseDebug, { - dbgs() << "Inner loop guard successor " << Succ->getName() - << " doesn't lead to inner loop preheader or " - "outer loop latch.\n"; - }); - return false; - } - } - - // Ensure the inner loop exit block leads to the outer loop latch. - if (InnerLoopExit->getSingleSuccessor() != OuterLoopLatch) { - DEBUG_WITH_TYPE( - VerboseDebug, - dbgs() << "Inner loop exit block " << *InnerLoopExit - << " does not directly lead to the outer loop latch.\n";); - return false; - } - - return true; -} - -raw_ostream &llvm::operator<<(raw_ostream &OS, const LoopNest &LN) { - OS << "IsPerfect="; - if (LN.getMaxPerfectDepth() == LN.getNestDepth()) - OS << "true"; - else - OS << "false"; - OS << ", Depth=" << LN.getNestDepth(); - OS << ", OutermostLoop: " << LN.getOutermostLoop().getName(); - OS << ", Loops: ( "; - for (const Loop *L : LN.getLoops()) - OS << L->getName() << " "; - OS << ")"; - - return OS; -} - -//===----------------------------------------------------------------------===// -// LoopNestPrinterPass implementation -// - -PreservedAnalyses LoopNestPrinterPass::run(Loop &L, LoopAnalysisManager &AM, - LoopStandardAnalysisResults &AR, - LPMUpdater &U) { - if (auto LN = LoopNest::getLoopNest(L, AR.SE)) - OS << *LN << "\n"; - - return PreservedAnalyses::all(); -} diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index e0ef37a9562b92..446d349500bacc 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -38,7 +38,6 @@ #include "llvm/Analysis/LoopAccessAnalysis.h" #include "llvm/Analysis/LoopCacheAnalysis.h" #include "llvm/Analysis/LoopInfo.h" -#include "llvm/Analysis/LoopNestAnalysis.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/ModuleSummaryAnalysis.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 056e8833ab83e4..12f4f85548f319 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -325,7 +325,6 @@ LOOP_PASS("unroll-full", LoopFullUnrollPass()) LOOP_PASS("print-access-info", LoopAccessInfoPrinterPass(dbgs())) LOOP_PASS("print", DDGAnalysisPrinterPass(dbgs())) LOOP_PASS("print", IVUsersPrinterPass(dbgs())) -LOOP_PASS("print", LoopNestPrinterPass(dbgs())) LOOP_PASS("print", LoopCachePrinterPass(dbgs())) LOOP_PASS("loop-predication", LoopPredicationPass()) LOOP_PASS("guard-widening", GuardWideningPass()) diff --git a/llvm/test/Analysis/LoopNestAnalysis/imperfectnest.ll b/llvm/test/Analysis/LoopNestAnalysis/imperfectnest.ll deleted file mode 100644 index 4c8066ec58775e..00000000000000 --- a/llvm/test/Analysis/LoopNestAnalysis/imperfectnest.ll +++ /dev/null @@ -1,493 +0,0 @@ -; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s - -; Test an imperfect 2-dim loop nest of the form: -; for (int i = 0; i < nx; ++i) { -; x[i] = i; -; for (int j = 0; j < ny; ++j) -; y[j][i] = x[i] + j; -; } - -define void @imperf_nest_1(i32 signext %nx, i32 signext %ny) { -; CHECK-LABEL: IsPerfect=false, Depth=2, OutermostLoop: imperf_nest_1_loop_i, Loops: ( imperf_nest_1_loop_i imperf_nest_1_loop_j ) -entry: - %0 = zext i32 %ny to i64 - %1 = zext i32 %nx to i64 - %2 = mul nuw i64 %0, %1 - %vla = alloca double, i64 %2, align 8 - %3 = zext i32 %ny to i64 - %vla1 = alloca double, i64 %3, align 8 - br label %imperf_nest_1_loop_i - -imperf_nest_1_loop_i: - %i2.0 = phi i32 [ 0, %entry ], [ %inc16, %for.inc15 ] - %cmp = icmp slt i32 %i2.0, %nx - br i1 %cmp, label %for.body, label %for.end17 - -for.body: - %conv = sitofp i32 %i2.0 to double - %idxprom = sext i32 %i2.0 to i64 - %arrayidx = getelementptr inbounds double, double* %vla1, i64 %idxprom - store double %conv, double* %arrayidx, align 8 - br label %imperf_nest_1_loop_j - -imperf_nest_1_loop_j: - %j3.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ] - %cmp5 = icmp slt i32 %j3.0, %ny - br i1 %cmp5, label %for.body7, label %for.end - -for.body7: - %idxprom8 = sext i32 %i2.0 to i64 - %arrayidx9 = getelementptr inbounds double, double* %vla1, i64 %idxprom8 - %4 = load double, double* %arrayidx9, align 8 - %conv10 = sitofp i32 %j3.0 to double - %add = fadd double %4, %conv10 - %idxprom11 = sext i32 %j3.0 to i64 - %5 = mul nsw i64 %idxprom11, %1 - %arrayidx12 = getelementptr inbounds double, double* %vla, i64 %5 - %idxprom13 = sext i32 %i2.0 to i64 - %arrayidx14 = getelementptr inbounds double, double* %arrayidx12, i64 %idxprom13 - store double %add, double* %arrayidx14, align 8 - br label %for.inc - -for.inc: - %inc = add nsw i32 %j3.0, 1 - br label %imperf_nest_1_loop_j - -for.end: - br label %for.inc15 - -for.inc15: - %inc16 = add nsw i32 %i2.0, 1 - br label %imperf_nest_1_loop_i - -for.end17: - ret void -} - -; Test an imperfect 2-dim loop nest of the form: -; for (int i = 0; i < nx; ++i) { -; for (int j = 0; j < ny; ++j) -; y[j][i] = x[i] + j; -; y[0][i] += i; -; } - -define void @imperf_nest_2(i32 signext %nx, i32 signext %ny) { -; CHECK-LABEL: IsPerfect=false, Depth=2, OutermostLoop: imperf_nest_2_loop_i, Loops: ( imperf_nest_2_loop_i imperf_nest_2_loop_j ) -entry: - %0 = zext i32 %ny to i64 - %1 = zext i32 %nx to i64 - %2 = mul nuw i64 %0, %1 - %vla = alloca double, i64 %2, align 8 - %3 = zext i32 %ny to i64 - %vla1 = alloca double, i64 %3, align 8 - br label %imperf_nest_2_loop_i - -imperf_nest_2_loop_i: - %i2.0 = phi i32 [ 0, %entry ], [ %inc17, %for.inc16 ] - %cmp = icmp slt i32 %i2.0, %nx - br i1 %cmp, label %for.body, label %for.end18 - -for.body: - br label %imperf_nest_2_loop_j - -imperf_nest_2_loop_j: - %j3.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ] - %cmp5 = icmp slt i32 %j3.0, %ny - br i1 %cmp5, label %for.body6, label %for.end - -for.body6: - %idxprom = sext i32 %i2.0 to i64 - %arrayidx = getelementptr inbounds double, double* %vla1, i64 %idxprom - %4 = load double, double* %arrayidx, align 8 - %conv = sitofp i32 %j3.0 to double - %add = fadd double %4, %conv - %idxprom7 = sext i32 %j3.0 to i64 - %5 = mul nsw i64 %idxprom7, %1 - %arrayidx8 = getelementptr inbounds double, double* %vla, i64 %5 - %idxprom9 = sext i32 %i2.0 to i64 - %arrayidx10 = getelementptr inbounds double, double* %arrayidx8, i64 %idxprom9 - store double %add, double* %arrayidx10, align 8 - br label %for.inc - -for.inc: - %inc = add nsw i32 %j3.0, 1 - br label %imperf_nest_2_loop_j - -for.end: - %conv11 = sitofp i32 %i2.0 to double - %6 = mul nsw i64 0, %1 - %arrayidx12 = getelementptr inbounds double, double* %vla, i64 %6 - %idxprom13 = sext i32 %i2.0 to i64 - %arrayidx14 = getelementptr inbounds double, double* %arrayidx12, i64 %idxprom13 - %7 = load double, double* %arrayidx14, align 8 - %add15 = fadd double %7, %conv11 - store double %add15, double* %arrayidx14, align 8 - br label %for.inc16 - -for.inc16: - %inc17 = add nsw i32 %i2.0, 1 - br label %imperf_nest_2_loop_i - -for.end18: - ret void -} - -; Test an imperfect 2-dim loop nest of the form: -; for (i = 0; i < nx; ++i) { -; for (j = 0; j < ny-nk; ++j) -; y[i][j] = x[i] + j; -; for (j = ny-nk; j < ny; ++j) -; y[i][j] = x[i] - j; -; } - -define void @imperf_nest_3(i32 signext %nx, i32 signext %ny, i32 signext %nk) { -; CHECK-LABEL: IsPerfect=false, Depth=2, OutermostLoop: imperf_nest_3_loop_i, Loops: ( imperf_nest_3_loop_i imperf_nest_3_loop_j imperf_nest_3_loop_k ) -entry: - %0 = zext i32 %nx to i64 - %1 = zext i32 %ny to i64 - %2 = mul nuw i64 %0, %1 - %vla = alloca double, i64 %2, align 8 - %3 = zext i32 %ny to i64 - %vla1 = alloca double, i64 %3, align 8 - br label %imperf_nest_3_loop_i - -imperf_nest_3_loop_i: ; preds = %for.inc25, %entry - %i.0 = phi i32 [ 0, %entry ], [ %inc26, %for.inc25 ] - %cmp = icmp slt i32 %i.0, %nx - br i1 %cmp, label %for.body, label %for.end27 - -for.body: ; preds = %for.cond - br label %imperf_nest_3_loop_j - -imperf_nest_3_loop_j: ; preds = %for.inc, %for.body - %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ] - %sub = sub nsw i32 %ny, %nk - %cmp3 = icmp slt i32 %j.0, %sub - br i1 %cmp3, label %for.body4, label %for.end - -for.body4: ; preds = %imperf_nest_3_loop_j - %idxprom = sext i32 %i.0 to i64 - %arrayidx = getelementptr inbounds double, double* %vla1, i64 %idxprom - %4 = load double, double* %arrayidx, align 8 - %conv = sitofp i32 %j.0 to double - %add = fadd double %4, %conv - %idxprom5 = sext i32 %i.0 to i64 - %5 = mul nsw i64 %idxprom5, %1 - %arrayidx6 = getelementptr inbounds double, double* %vla, i64 %5 - %idxprom7 = sext i32 %j.0 to i64 - %arrayidx8 = getelementptr inbounds double, double* %arrayidx6, i64 %idxprom7 - store double %add, double* %arrayidx8, align 8 - br label %for.inc - -for.inc: ; preds = %for.body4 - %inc = add nsw i32 %j.0, 1 - br label %imperf_nest_3_loop_j - -for.end: ; preds = %imperf_nest_3_loop_j - %sub9 = sub nsw i32 %ny, %nk - br label %imperf_nest_3_loop_k - -imperf_nest_3_loop_k: ; preds = %for.inc22, %for.end - %j.1 = phi i32 [ %sub9, %for.end ], [ %inc23, %for.inc22 ] - %cmp11 = icmp slt i32 %j.1, %ny - br i1 %cmp11, label %for.body13, label %for.end24 - -for.body13: ; preds = %imperf_nest_3_loop_k - %idxprom14 = sext i32 %i.0 to i64 - %arrayidx15 = getelementptr inbounds double, double* %vla1, i64 %idxprom14 - %6 = load double, double* %arrayidx15, align 8 - %conv16 = sitofp i32 %j.1 to double - %sub17 = fsub double %6, %conv16 - %idxprom18 = sext i32 %i.0 to i64 - %7 = mul nsw i64 %idxprom18, %1 - %arrayidx19 = getelementptr inbounds double, double* %vla, i64 %7 - %idxprom20 = sext i32 %j.1 to i64 - %arrayidx21 = getelementptr inbounds double, double* %arrayidx19, i64 %idxprom20 - store double %sub17, double* %arrayidx21, align 8 - br label %for.inc22 - -for.inc22: ; preds = %for.body13 - %inc23 = add nsw i32 %j.1, 1 - br label %imperf_nest_3_loop_k - -for.end24: ; preds = %imperf_nest_3_loop_k - br label %for.inc25 - -for.inc25: ; preds = %for.end24 - %inc26 = add nsw i32 %i.0, 1 - br label %imperf_nest_3_loop_i - -for.end27: ; preds = %for.cond - ret void -} - -; Test an imperfect loop nest of the form: -; for (i = 0; i < nx; ++i) { -; for (j = 0; j < ny-nk; ++j) -; for (k = 0; k < nk; ++k) -; y[i][j][k] = x[i+j] + k; -; for (j = ny-nk; j < ny; ++j) -; y[i][j][0] = x[i] - j; -; } - -define void @imperf_nest_4(i32 signext %nx, i32 signext %ny, i32 signext %nk) { -; CHECK-LABEL: IsPerfect=false, Depth=2, OutermostLoop: imperf_nest_4_loop_j, Loops: ( imperf_nest_4_loop_j imperf_nest_4_loop_k ) -; CHECK-LABEL: IsPerfect=false, Depth=3, OutermostLoop: imperf_nest_4_loop_i, Loops: ( imperf_nest_4_loop_i imperf_nest_4_loop_j imperf_nest_4_loop_j2 imperf_nest_4_loop_k ) -entry: - %0 = zext i32 %nx to i64 - %1 = zext i32 %ny to i64 - %2 = zext i32 %nk to i64 - %3 = mul nuw i64 %0, %1 - %4 = mul nuw i64 %3, %2 - %vla = alloca double, i64 %4, align 8 - %5 = zext i32 %ny to i64 - %vla1 = alloca double, i64 %5, align 8 - %cmp5 = icmp slt i32 0, %nx - br i1 %cmp5, label %imperf_nest_4_loop_i.lr.ph, label %for.end37 - -imperf_nest_4_loop_i.lr.ph: - br label %imperf_nest_4_loop_i - -imperf_nest_4_loop_i: - %i.0 = phi i32 [ 0, %imperf_nest_4_loop_i.lr.ph ], [ %inc36, %for.inc35 ] - %sub2 = sub nsw i32 %ny, %nk - %cmp33 = icmp slt i32 0, %sub2 - br i1 %cmp33, label %imperf_nest_4_loop_j.lr.ph, label %for.end17 - -imperf_nest_4_loop_j.lr.ph: - br label %imperf_nest_4_loop_j - -imperf_nest_4_loop_j: - %j.0 = phi i32 [ 0, %imperf_nest_4_loop_j.lr.ph ], [ %inc16, %for.inc15 ] - %cmp61 = icmp slt i32 0, %nk - br i1 %cmp61, label %imperf_nest_4_loop_k.lr.ph, label %for.end - -imperf_nest_4_loop_k.lr.ph: - br label %imperf_nest_4_loop_k - -imperf_nest_4_loop_k: - %k.0 = phi i32 [ 0, %imperf_nest_4_loop_k.lr.ph ], [ %inc, %for.inc ] - %add = add nsw i32 %i.0, %j.0 - %idxprom = sext i32 %add to i64 - %arrayidx = getelementptr inbounds double, double* %vla1, i64 %idxprom - %6 = load double, double* %arrayidx, align 8 - %conv = sitofp i32 %k.0 to double - %add8 = fadd double %6, %conv - %idxprom9 = sext i32 %i.0 to i64 - %7 = mul nuw i64 %1, %2 - %8 = mul nsw i64 %idxprom9, %7 - %arrayidx10 = getelementptr inbounds double, double* %vla, i64 %8 - %idxprom11 = sext i32 %j.0 to i64 - %9 = mul nsw i64 %idxprom11, %2 - %arrayidx12 = getelementptr inbounds double, double* %arrayidx10, i64 %9 - %idxprom13 = sext i32 %k.0 to i64 - %arrayidx14 = getelementptr inbounds double, double* %arrayidx12, i64 %idxprom13 - store double %add8, double* %arrayidx14, align 8 - br label %for.inc - -for.inc: - %inc = add nsw i32 %k.0, 1 - %cmp6 = icmp slt i32 %inc, %nk - br i1 %cmp6, label %imperf_nest_4_loop_k, label %for.cond5.for.end_crit_edge - -for.cond5.for.end_crit_edge: - br label %for.end - -for.end: - br label %for.inc15 - -for.inc15: - %inc16 = add nsw i32 %j.0, 1 - %sub = sub nsw i32 %ny, %nk - %cmp3 = icmp slt i32 %inc16, %sub - br i1 %cmp3, label %imperf_nest_4_loop_j, label %for.cond2.for.end17_crit_edge - -for.cond2.for.end17_crit_edge: - br label %for.end17 - -for.end17: - %sub18 = sub nsw i32 %ny, %nk - %cmp204 = icmp slt i32 %sub18, %ny - br i1 %cmp204, label %imperf_nest_4_loop_j2.lr.ph, label %for.end34 - -imperf_nest_4_loop_j2.lr.ph: - br label %imperf_nest_4_loop_j2 - -imperf_nest_4_loop_j2: - %j.1 = phi i32 [ %sub18, %imperf_nest_4_loop_j2.lr.ph ], [ %inc33, %for.inc32 ] - %idxprom23 = sext i32 %i.0 to i64 - %arrayidx24 = getelementptr inbounds double, double* %vla1, i64 %idxprom23 - %10 = load double, double* %arrayidx24, align 8 - %conv25 = sitofp i32 %j.1 to double - %sub26 = fsub double %10, %conv25 - %idxprom27 = sext i32 %i.0 to i64 - %idxprom29 = sext i32 %j.1 to i64 - %11 = mul nsw i64 %idxprom29, %2 - %12 = mul nuw i64 %1, %2 - %13 = mul nsw i64 %idxprom27, %12 - %arrayidx28 = getelementptr inbounds double, double* %vla, i64 %13 - %arrayidx30 = getelementptr inbounds double, double* %arrayidx28, i64 %11 - %arrayidx31 = getelementptr inbounds double, double* %arrayidx30, i64 0 - store double %sub26, double* %arrayidx31, align 8 - br label %for.inc32 - -for.inc32: - %inc33 = add nsw i32 %j.1, 1 - %cmp20 = icmp slt i32 %inc33, %ny - br i1 %cmp20, label %imperf_nest_4_loop_j2, label %for.cond19.for.end34_crit_edge - -for.cond19.for.end34_crit_edge: - br label %for.end34 - -for.end34: - br label %for.inc35 - -for.inc35: - %inc36 = add nsw i32 %i.0, 1 - %cmp = icmp slt i32 %inc36, %nx - br i1 %cmp, label %imperf_nest_4_loop_i, label %for.cond.for.end37_crit_edge - -for.cond.for.end37_crit_edge: - br label %for.end37 - -for.end37: - ret void -} - -; Test an imperfect loop nest of the form: -; for (int i = 0; i < nx; ++i) -; if (i > 5) { -; for (int j = 0; j < ny; ++j) -; y[j][i] = x[i][j] + j; -; } - -define void @imperf_nest_5(i32** %y, i32** %x, i32 signext %nx, i32 signext %ny) { -; CHECK-LABEL: IsPerfect=false, Depth=2, OutermostLoop: imperf_nest_5_loop_i, Loops: ( imperf_nest_5_loop_i imperf_nest_5_loop_j ) -entry: - %cmp2 = icmp slt i32 0, %nx - br i1 %cmp2, label %imperf_nest_5_loop_i.lr.ph, label %for.end13 - -imperf_nest_5_loop_i.lr.ph: - br label %imperf_nest_5_loop_i - -imperf_nest_5_loop_i: - %i.0 = phi i32 [ 0, %imperf_nest_5_loop_i.lr.ph ], [ %inc12, %for.inc11 ] - %cmp1 = icmp sgt i32 %i.0, 5 - br i1 %cmp1, label %if.then, label %if.end - -if.then: - %cmp31 = icmp slt i32 0, %ny - br i1 %cmp31, label %imperf_nest_5_loop_j.lr.ph, label %for.end - -imperf_nest_5_loop_j.lr.ph: - br label %imperf_nest_5_loop_j - -imperf_nest_5_loop_j: - %j.0 = phi i32 [ 0, %imperf_nest_5_loop_j.lr.ph ], [ %inc, %for.inc ] - %idxprom = sext i32 %i.0 to i64 - %arrayidx = getelementptr inbounds i32*, i32** %x, i64 %idxprom - %0 = load i32*, i32** %arrayidx, align 8 - %idxprom5 = sext i32 %j.0 to i64 - %arrayidx6 = getelementptr inbounds i32, i32* %0, i64 %idxprom5 - %1 = load i32, i32* %arrayidx6, align 4 - %add = add nsw i32 %1, %j.0 - %idxprom7 = sext i32 %j.0 to i64 - %arrayidx8 = getelementptr inbounds i32*, i32** %y, i64 %idxprom7 - %2 = load i32*, i32** %arrayidx8, align 8 - %idxprom9 = sext i32 %i.0 to i64 - %arrayidx10 = getelementptr inbounds i32, i32* %2, i64 %idxprom9 - store i32 %add, i32* %arrayidx10, align 4 - br label %for.inc - -for.inc: - %inc = add nsw i32 %j.0, 1 - %cmp3 = icmp slt i32 %inc, %ny - br i1 %cmp3, label %imperf_nest_5_loop_j, label %for.cond2.for.end_crit_edge - -for.cond2.for.end_crit_edge: - br label %for.end - -for.end: - br label %if.end - -if.end: - br label %for.inc11 - -for.inc11: - %inc12 = add nsw i32 %i.0, 1 - %cmp = icmp slt i32 %inc12, %nx - br i1 %cmp, label %imperf_nest_5_loop_i, label %for.cond.for.end13_crit_edge - -for.cond.for.end13_crit_edge: - br label %for.end13 - -for.end13: - ret void -} - -; Test an imperfect loop nest of the form: -; for (int i = 0; i < nx; ++i) -; if (i > 5) { // user branch -; for (int j = 1; j <= 5; j+=2) -; y[j][i] = x[i][j] + j; -; } - -define void @imperf_nest_6(i32** %y, i32** %x, i32 signext %nx, i32 signext %ny) { -; CHECK-LABEL: IsPerfect=false, Depth=2, OutermostLoop: imperf_nest_6_loop_i, Loops: ( imperf_nest_6_loop_i imperf_nest_6_loop_j ) -entry: - %cmp2 = icmp slt i32 0, %nx - br i1 %cmp2, label %imperf_nest_6_loop_i.lr.ph, label %for.end13 - -imperf_nest_6_loop_i.lr.ph: - br label %imperf_nest_6_loop_i - -imperf_nest_6_loop_i: - %i.0 = phi i32 [ 0, %imperf_nest_6_loop_i.lr.ph ], [ %inc12, %for.inc11 ] - %cmp1 = icmp sgt i32 %i.0, 5 - br i1 %cmp1, label %imperf_nest_6_loop_j.lr.ph, label %if.end - -imperf_nest_6_loop_j.lr.ph: - br label %imperf_nest_6_loop_j - -imperf_nest_6_loop_j: - %j.0 = phi i32 [ 1, %imperf_nest_6_loop_j.lr.ph ], [ %inc, %for.inc ] - %idxprom = sext i32 %i.0 to i64 - %arrayidx = getelementptr inbounds i32*, i32** %x, i64 %idxprom - %0 = load i32*, i32** %arrayidx, align 8 - %idxprom5 = sext i32 %j.0 to i64 - %arrayidx6 = getelementptr inbounds i32, i32* %0, i64 %idxprom5 - %1 = load i32, i32* %arrayidx6, align 4 - %add = add nsw i32 %1, %j.0 - %idxprom7 = sext i32 %j.0 to i64 - %arrayidx8 = getelementptr inbounds i32*, i32** %y, i64 %idxprom7 - %2 = load i32*, i32** %arrayidx8, align 8 - %idxprom9 = sext i32 %i.0 to i64 - %arrayidx10 = getelementptr inbounds i32, i32* %2, i64 %idxprom9 - store i32 %add, i32* %arrayidx10, align 4 - br label %for.inc - -for.inc: - %inc = add nsw i32 %j.0, 2 - %cmp3 = icmp sle i32 %inc, 5 - br i1 %cmp3, label %imperf_nest_6_loop_j, label %for.cond2.for.end_crit_edge - -for.cond2.for.end_crit_edge: - br label %for.end - -for.end: - br label %if.end - -if.end: - br label %for.inc11 - -for.inc11: - %inc12 = add nsw i32 %i.0, 1 - %cmp = icmp slt i32 %inc12, %nx - br i1 %cmp, label %imperf_nest_6_loop_i, label %for.cond.for.end13_crit_edge - -for.cond.for.end13_crit_edge: - br label %for.end13 - -for.end13: - ret void -} diff --git a/llvm/test/Analysis/LoopNestAnalysis/infinite.ll b/llvm/test/Analysis/LoopNestAnalysis/infinite.ll deleted file mode 100644 index 7a6cf21584fff2..00000000000000 --- a/llvm/test/Analysis/LoopNestAnalysis/infinite.ll +++ /dev/null @@ -1,35 +0,0 @@ -; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s - -; Test that the loop nest analysis is able to analyze an infinite loop in a loop nest. -define void @test1(i32** %A, i1 %cond) { -; CHECK-LABEL: IsPerfect=true, Depth=1, OutermostLoop: for.inner, Loops: ( for.inner ) -; CHECK-LABEL: IsPerfect=false, Depth=2, OutermostLoop: for.outer, Loops: ( for.outer for.inner ) -; CHECK-LABEL: IsPerfect=true, Depth=1, OutermostLoop: for.infinite, Loops: ( for.infinite ) -entry: - br label %for.outer - -for.outer: - %i = phi i64 [ 0, %entry ], [ %inc_i, %for.outer.latch ] - br i1 %cond, label %for.inner, label %for.infinite - -for.inner: - %j = phi i64 [ 0, %for.outer ], [ %inc_j, %for.inner ] - %arrayidx_i = getelementptr inbounds i32*, i32** %A, i64 %i - %0 = load i32*, i32** %arrayidx_i, align 8 - %arrayidx_j = getelementptr inbounds i32, i32* %0, i64 %j - store i32 0, i32* %arrayidx_j, align 4 - %inc_j = add nsw i64 %j, 1 - %cmp_j = icmp slt i64 %inc_j, 100 - br i1 %cmp_j, label %for.inner, label %for.outer.latch - -for.infinite: - br label %for.infinite - -for.outer.latch: - %inc_i = add nsw i64 %i, 1 - %cmp_i = icmp slt i64 %inc_i, 100 - br i1 %cmp_i, label %for.outer, label %for.end - -for.end: - ret void -} diff --git a/llvm/test/Analysis/LoopNestAnalysis/perfectnest.ll b/llvm/test/Analysis/LoopNestAnalysis/perfectnest.ll deleted file mode 100644 index b7b3b7a7c93e0c..00000000000000 --- a/llvm/test/Analysis/LoopNestAnalysis/perfectnest.ll +++ /dev/null @@ -1,275 +0,0 @@ -; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s - -; Test a perfect 2-dim loop nest of the form: -; for(i=0; i Test) { - auto *F = M.getFunction(FuncName); - ASSERT_NE(F, nullptr) << "Could not find " << FuncName; - - TargetLibraryInfoImpl TLII; - TargetLibraryInfo TLI(TLII); - AssumptionCache AC(*F); - DominatorTree DT(*F); - LoopInfo LI(DT); - ScalarEvolution SE(*F, TLI, AC, DT, LI); - - Test(*F, LI, SE); -} - -static std::unique_ptr makeLLVMModule(LLVMContext &Context, - const char *ModuleStr) { - SMDiagnostic Err; - return parseAssemblyString(ModuleStr, Err, Context); -} - -TEST(LoopNestTest, PerfectLoopNest) { - const char *ModuleStr = - "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n" - "define void @foo(i64 signext %nx, i64 signext %ny) {\n" - "entry:\n" - " br label %for.outer\n" - "for.outer:\n" - " %i = phi i64 [ 0, %entry ], [ %inc13, %for.outer.latch ]\n" - " %cmp21 = icmp slt i64 0, %ny\n" - " br i1 %cmp21, label %for.inner.preheader, label %for.outer.latch\n" - "for.inner.preheader:\n" - " br label %for.inner\n" - "for.inner:\n" - " %j = phi i64 [ 0, %for.inner.preheader ], [ %inc, %for.inner.latch ]\n" - " br label %for.inner.latch\n" - "for.inner.latch:\n" - " %inc = add nsw i64 %j, 1\n" - " %cmp2 = icmp slt i64 %inc, %ny\n" - " br i1 %cmp2, label %for.inner, label %for.inner.exit\n" - "for.inner.exit:\n" - " br label %for.outer.latch\n" - "for.outer.latch:\n" - " %inc13 = add nsw i64 %i, 1\n" - " %cmp = icmp slt i64 %inc13, %nx\n" - " br i1 %cmp, label %for.outer, label %for.outer.exit\n" - "for.outer.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runTest(*M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) { - Function::iterator FI = F.begin(); - // Skip the first basic block (entry), get to the outer loop header. - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.outer"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - LoopNest LN(*L, SE); - EXPECT_TRUE(LN.areAllLoopsSimplifyForm()); - - // Ensure that we can identify the outermost loop in the nest. - const Loop &OL = LN.getOutermostLoop(); - EXPECT_EQ(OL.getName(), "for.outer"); - - // Ensure that we can identify the innermost loop in the nest. - const Loop *IL = LN.getInnermostLoop(); - EXPECT_NE(IL, nullptr); - EXPECT_EQ(IL->getName(), "for.inner"); - - // Ensure the loop nest is recognized as having 2 loops. - const ArrayRef Loops = LN.getLoops(); - EXPECT_EQ(Loops.size(), 2ull); - - // Ensure the loop nest is recognized as perfect in its entirety. - const SmallVector &PLV = LN.getPerfectLoops(SE); - EXPECT_EQ(PLV.size(), 1ull); - EXPECT_EQ(PLV.front().size(), 2ull); - - // Ensure the nest depth and perfect nest depth are computed correctly. - EXPECT_EQ(LN.getNestDepth(), 2u); - EXPECT_EQ(LN.getMaxPerfectDepth(), 2u); - }); -} - -TEST(LoopNestTest, ImperfectLoopNest) { - const char *ModuleStr = - "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n" - "define void @foo(i32 signext %nx, i32 signext %ny, i32 signext %nk) {\n" - "entry:\n" - " br label %loop.i\n" - "loop.i:\n" - " %i = phi i32 [ 0, %entry ], [ %inci, %for.inci ]\n" - " %cmp21 = icmp slt i32 0, %ny\n" - " br i1 %cmp21, label %loop.j.preheader, label %for.inci\n" - "loop.j.preheader:\n" - " br label %loop.j\n" - "loop.j:\n" - " %j = phi i32 [ %incj, %for.incj ], [ 0, %loop.j.preheader ]\n" - " %cmp22 = icmp slt i32 0, %nk\n" - " br i1 %cmp22, label %loop.k.preheader, label %for.incj\n" - "loop.k.preheader:\n" - " call void @bar()\n" - " br label %loop.k\n" - "loop.k:\n" - " %k = phi i32 [ %inck, %for.inck ], [ 0, %loop.k.preheader ]\n" - " br label %for.inck\n" - "for.inck:\n" - " %inck = add nsw i32 %k, 1\n" - " %cmp5 = icmp slt i32 %inck, %nk\n" - " br i1 %cmp5, label %loop.k, label %for.incj.loopexit\n" - "for.incj.loopexit:\n" - " br label %for.incj\n" - "for.incj:\n" - " %incj = add nsw i32 %j, 1\n" - " %cmp2 = icmp slt i32 %incj, %ny\n" - " br i1 %cmp2, label %loop.j, label %for.inci.loopexit\n" - "for.inci.loopexit:\n" - " br label %for.inci\n" - "for.inci:\n" - " %inci = add nsw i32 %i, 1\n" - " %cmp = icmp slt i32 %inci, %nx\n" - " br i1 %cmp, label %loop.i, label %loop.i.end\n" - "loop.i.end:\n" - " ret void\n" - "}\n" - "declare void @bar()\n"; - - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runTest(*M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) { - Function::iterator FI = F.begin(); - // Skip the first basic block (entry), get to the outermost loop header. - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "loop.i"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - LoopNest LN(*L, SE); - EXPECT_TRUE(LN.areAllLoopsSimplifyForm()); - - dbgs() << "LN: " << LN << "\n"; - - // Ensure that we can identify the outermost loop in the nest. - const Loop &OL = LN.getOutermostLoop(); - EXPECT_EQ(OL.getName(), "loop.i"); - - // Ensure that we can identify the innermost loop in the nest. - const Loop *IL = LN.getInnermostLoop(); - EXPECT_NE(IL, nullptr); - EXPECT_EQ(IL->getName(), "loop.k"); - - // Ensure the loop nest is recognized as having 3 loops. - const ArrayRef Loops = LN.getLoops(); - EXPECT_EQ(Loops.size(), 3ull); - - // Ensure the loop nest is recognized as having 2 separate perfect loops groups. - const SmallVector &PLV = LN.getPerfectLoops(SE); - EXPECT_EQ(PLV.size(), 2ull); - EXPECT_EQ(PLV.front().size(), 2ull); - EXPECT_EQ(PLV.back().size(), 1ull); - - // Ensure the nest depth and perfect nest depth are computed correctly. - EXPECT_EQ(LN.getNestDepth(), 3u); - EXPECT_EQ(LN.getMaxPerfectDepth(), 2u); - }); -} - From 075c281859de54e410cd60967ffedaff9c1e3328 Mon Sep 17 00:00:00 2001 From: Clement Courbet Date: Tue, 3 Mar 2020 15:09:17 +0100 Subject: [PATCH 02/29] [ExpandMemCmp][NFC] Regenerate tests. --- llvm/test/CodeGen/X86/memcmp-minsize.ll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/CodeGen/X86/memcmp-minsize.ll b/llvm/test/CodeGen/X86/memcmp-minsize.ll index 01e6085fb5d013..21957921ff080c 100644 --- a/llvm/test/CodeGen/X86/memcmp-minsize.ll +++ b/llvm/test/CodeGen/X86/memcmp-minsize.ll @@ -612,7 +612,7 @@ define i1 @length32_eq(i8* %x, i8* %y) nounwind minsize { ; X64-AVX1: # %bb.0: ; X64-AVX1-NEXT: vmovups (%rdi), %ymm0 ; X64-AVX1-NEXT: vxorps (%rsi), %ymm0, %ymm0 -; X64-AVX1-NEXT: vptest %ymm0, %ymm +; X64-AVX1-NEXT: vptest %ymm0, %ymm0 ; X64-AVX1-NEXT: sete %al ; X64-AVX1-NEXT: vzeroupper ; X64-AVX1-NEXT: retq @@ -621,7 +621,7 @@ define i1 @length32_eq(i8* %x, i8* %y) nounwind minsize { ; X64-AVX2: # %bb.0: ; X64-AVX2-NEXT: vmovdqu (%rdi), %ymm0 ; X64-AVX2-NEXT: vpxor (%rsi), %ymm0, %ymm0 -; X64-AVX2-NEXT: vptest %ymm0, %ymm +; X64-AVX2-NEXT: vptest %ymm0, %ymm0 ; X64-AVX2-NEXT: sete %al ; X64-AVX2-NEXT: vzeroupper ; X64-AVX2-NEXT: retq From b917d5e1a4f73365dc3661495bb99280d80a9551 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Tue, 3 Mar 2020 15:13:38 +0100 Subject: [PATCH 03/29] [llvm-ar] Remove unused variable. NFC. --- llvm/tools/llvm-ar/llvm-ar.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp index 8e7a85f5a9b06d..6e1d328320cc38 100644 --- a/llvm/tools/llvm-ar/llvm-ar.cpp +++ b/llvm/tools/llvm-ar/llvm-ar.cpp @@ -1150,8 +1150,6 @@ static int ar_main(int argc, char **argv) { cl::ExpandResponseFiles(Saver, getRspQuoting(makeArrayRef(argv, argc)), Argv); - ArrayRef ArgsArr = makeArrayRef(argv, argc); - for (ArrayRef::iterator ArgIt = Argv.begin(); ArgIt != Argv.end(); ++ArgIt) { const char *Match = nullptr; From f2cd0850789d8ee9257db2d87fbd2c40b3ad6a76 Mon Sep 17 00:00:00 2001 From: LLVM GN Syncbot Date: Tue, 3 Mar 2020 14:16:22 +0000 Subject: [PATCH 04/29] [gn build] Port 613f791131e --- llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn | 1 - llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn | 1 - 2 files changed, 2 deletions(-) diff --git a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn index 82bf99de1bc9b9..328d819fd1f057 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn @@ -68,7 +68,6 @@ static_library("Analysis") { "LoopAnalysisManager.cpp", "LoopCacheAnalysis.cpp", "LoopInfo.cpp", - "LoopNestAnalysis.cpp", "LoopPass.cpp", "LoopUnrollAnalyzer.cpp", "MemDepPrinter.cpp", diff --git a/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn index d73088885aa869..47bc50212651df 100644 --- a/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn @@ -25,7 +25,6 @@ unittest("AnalysisTests") { "LazyCallGraphTest.cpp", "LoadsTest.cpp", "LoopInfoTest.cpp", - "LoopNestTest.cpp", "MemoryBuiltinsTest.cpp", "MemorySSATest.cpp", "OrderedInstructionsTest.cpp", From 9a8f2965f623cbe8afeac5ce821ad8a2f899cee9 Mon Sep 17 00:00:00 2001 From: Nicolas Vasilache Date: Mon, 2 Mar 2020 22:47:16 -0500 Subject: [PATCH 05/29] [mlir] Hotfix - Fix Windows build This revision adds a static `mlir_c_runner_utils_static` library for the sole purpose of being linked into `mlir_runner_utils` on Windows. It was previously reported that: ``` `add_llvm_library(mlir_c_runner_utils SHARED CRunnerUtils.cpp)` produces *only* a dll on windows, the linking of mlir_runner_utils fails because target_link_libraries is looking for a .lib file as opposed to a .dll file. I think this may be a case where either we need to use LINK_LIBS or explicitly build a static lib as well, but I haven't tried either yet. ``` --- mlir/lib/ExecutionEngine/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mlir/lib/ExecutionEngine/CMakeLists.txt b/mlir/lib/ExecutionEngine/CMakeLists.txt index dc20e5fd46226e..37df716424408a 100644 --- a/mlir/lib/ExecutionEngine/CMakeLists.txt +++ b/mlir/lib/ExecutionEngine/CMakeLists.txt @@ -36,11 +36,12 @@ target_link_libraries(MLIRExecutionEngine ${outlibs}) add_llvm_library(mlir_c_runner_utils SHARED CRunnerUtils.cpp) +add_llvm_library(mlir_c_runner_utils_static CRunnerUtils.cpp) target_compile_definitions(mlir_c_runner_utils PRIVATE mlir_c_runner_utils_EXPORTS) add_llvm_library(mlir_runner_utils SHARED RunnerUtils.cpp) target_link_libraries(mlir_runner_utils - mlir_c_runner_utils + mlir_c_runner_utils_static ) target_compile_definitions(mlir_runner_utils PRIVATE mlir_runner_utils_EXPORTS) From 63b2ff07e88e31715a41bafc575878fd4bcc6517 Mon Sep 17 00:00:00 2001 From: Nicolas Vasilache Date: Mon, 2 Mar 2020 09:59:01 -0500 Subject: [PATCH 06/29] [mlir] Add padding to 1-D Vector in CRunnerUtils.h Summary: This revision fixes a -Wzero-length-array compile error that caused e459596917a72f11bd8251a81bdb521401abdd3d which reverted 78f9e5d098af95610f4542ee41479d7931261066. Also fixes a struct vs class mismatch that broke compilation with -Werror for Windows that caused 57397eba7a8a7525cee69e10ad90697ff74bb521. This revision adds padding for 1-D Vector in the common case of x86 execution with a stadard data layout. This supports properly interfacing codegen with arrays of e.g. `vector<9xf32>`. Such vectors are already assumed padded to the next power of 2 by LLVM codegen with the default x86 data layout: ``` define void @test_vector_add_1d_2_3(<3 x float>* nocapture readnone %0, <3 x float>* nocapture readonly %1, i64 %2, i64 %3, i64 %4, <3 x float>* nocapture readnone %5, <3 x float>* nocapture readonly %6, i64 %7, i64 %8, i64 %9, <3 x float>* nocapture readnone %10, <3 x float>* nocapture %11, i64 %12, i64 %13, i64 %14) local_unnamed_addr { %16 = getelementptr <3 x float>, <3 x float>* %6, i64 1 %17 = load <3 x float>, <3 x float>* %16, align 16 %18 = getelementptr <3 x float>, <3 x float>* %1, i64 1 %19 = load <3 x float>, <3 x float>* %18, align 16 %20 = fadd <3 x float> %17, %19 %21 = getelementptr <3 x float>, <3 x float>* %11, i64 1 ``` The pointer addressing a `vector<3xf32>` is assumed aligned `@16`. Similarly, the pointer addressing a `vector<65xf32>` is assumed aligned `@512`. This revision allows using objects such as `vector<3xf32>` properly with the standard x86 data layout used in the JitRunner. Integration testing is done out of tree, at the moment such testing fails without this change. Differential Revision: https://reviews.llvm.org/D75459 --- .../mlir/ExecutionEngine/CRunnerUtils.h | 69 ++++++++++++++++++- .../mlir/ExecutionEngine/RunnerUtils.h | 6 +- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/mlir/include/mlir/ExecutionEngine/CRunnerUtils.h b/mlir/include/mlir/ExecutionEngine/CRunnerUtils.h index d82963b1aa037b..f4da435b6fbc8f 100644 --- a/mlir/include/mlir/ExecutionEngine/CRunnerUtils.h +++ b/mlir/include/mlir/ExecutionEngine/CRunnerUtils.h @@ -39,15 +39,78 @@ template void dropFront(int64_t arr[N], int64_t *res) { //===----------------------------------------------------------------------===// // Codegen-compatible structures for Vector type. //===----------------------------------------------------------------------===// +namespace detail { +template +constexpr bool isPowerOf2() { + return (!(N & (N - 1))); +} + +template +constexpr unsigned nextPowerOf2(); +template <> +constexpr unsigned nextPowerOf2<0>() { + return 1; +} +template <> +constexpr unsigned nextPowerOf2<1>() { + return 1; +} +template constexpr unsigned nextPowerOf2() { + return isPowerOf2() ? N : 2 * nextPowerOf2<(N + 1) / 2>(); +} + +template +struct Vector1D; + +template +struct Vector1D { + Vector1D() { + static_assert(detail::nextPowerOf2() == sizeof(T[Dim]), + "size error"); + } + constexpr T &operator[](unsigned i) { return vector[i]; } + constexpr const T &operator[](unsigned i) const { return vector[i]; } + +private: + T vector[Dim]; +}; + +// 1-D vector, padded to the next power of 2 allocation. +// Specialization occurs to avoid zero size arrays (which fail in -Werror). +template +struct Vector1D { + Vector1D() { + static_assert(detail::nextPowerOf2() > sizeof(T[Dim]), + "size error"); + static_assert(detail::nextPowerOf2() < 2 * sizeof(T[Dim]), + "size error"); + } + constexpr T &operator[](unsigned i) { return vector[i]; } + constexpr const T &operator[](unsigned i) const { return vector[i]; } + +private: + T vector[Dim]; + char padding[detail::nextPowerOf2() - sizeof(T[Dim])]; +}; +} // end namespace detail + +// N-D vectors recurse down to 1-D. template struct Vector { + constexpr Vector &operator[](unsigned i) { return vector[i]; } + constexpr const Vector &operator[](unsigned i) const { + return vector[i]; + } + +private: Vector vector[Dim]; }; +// 1-D vectors in LLVM are automatically padded to the next power of 2. +// We insert explicit padding in to account for this. template -struct Vector { - T vector[Dim]; -}; +struct Vector + : public detail::Vector1D()> {}; template using Vector1D = Vector; diff --git a/mlir/include/mlir/ExecutionEngine/RunnerUtils.h b/mlir/include/mlir/ExecutionEngine/RunnerUtils.h index 2676e648930c25..16dc54f20da74f 100644 --- a/mlir/include/mlir/ExecutionEngine/RunnerUtils.h +++ b/mlir/include/mlir/ExecutionEngine/RunnerUtils.h @@ -92,7 +92,7 @@ void VectorDataPrinter::print(std::ostream &os, static_assert(sizeof(val) == M * StaticSizeMult::value * sizeof(T), "Incorrect vector size!"); // First - os << "(" << val.vector[0]; + os << "(" << val[0]; if (M > 1) os << ", "; if (sizeof...(Dims) > 1) @@ -100,14 +100,14 @@ void VectorDataPrinter::print(std::ostream &os, // Kernel for (unsigned i = 1; i + 1 < M; ++i) { printSpace(os, 2 * sizeof...(Dims)); - os << val.vector[i] << ", "; + os << val[i] << ", "; if (sizeof...(Dims) > 1) os << "\n"; } // Last if (M > 1) { printSpace(os, sizeof...(Dims)); - os << val.vector[M - 1]; + os << val[M - 1]; } os << ")"; } From 0145a26c652e11bbb4457202f89629318a6325b7 Mon Sep 17 00:00:00 2001 From: Alexander Belyaev Date: Tue, 3 Mar 2020 15:26:10 +0100 Subject: [PATCH 07/29] [MLIR] Add explicit initial values for loop.parallel op. Differential Revision: https://reviews.llvm.org/D75206 --- mlir/include/mlir/Dialect/LoopOps/LoopOps.td | 92 ++++++++++---------- mlir/lib/Dialect/LoopOps/LoopOps.cpp | 66 ++++++++++---- mlir/test/Dialect/Loops/invalid.mlir | 49 ++++++++--- mlir/test/Dialect/Loops/ops.mlir | 21 +++-- 4 files changed, 143 insertions(+), 85 deletions(-) diff --git a/mlir/include/mlir/Dialect/LoopOps/LoopOps.td b/mlir/include/mlir/Dialect/LoopOps/LoopOps.td index 3fa8b16ecde516..79e6192d728c8d 100644 --- a/mlir/include/mlir/Dialect/LoopOps/LoopOps.td +++ b/mlir/include/mlir/Dialect/LoopOps/LoopOps.td @@ -52,7 +52,7 @@ def ForOp : Loop_Op<"for", The body region must contain exactly one block that terminates with "loop.yield". Calling ForOp::build will create such a region and insert - the terminator implicitly if none is defined, so will the parsing even + the terminator implicitly if none is defined, so will the parsing even in cases when it is absent from the custom format. For example: ```mlir @@ -62,17 +62,17 @@ def ForOp : Loop_Op<"for", ``` "loop.for" can also operate on loop-carried variables and returns the final values - after loop termination. The initial values of the variables are passed as additional SSA + after loop termination. The initial values of the variables are passed as additional SSA operands to the "loop.for" following the 3 loop control SSA values mentioned above - (lower bound, upper bound and step). The operation region has equivalent arguments + (lower bound, upper bound and step). The operation region has equivalent arguments for each variable representing the value of the variable at the current iteration. - - The region must terminate with a "loop.yield" that passes all the current iteration + + The region must terminate with a "loop.yield" that passes all the current iteration variables to the next iteration, or to the "loop.for" result, if at the last iteration. - "loop.for" results hold the final values after the last iteration. - + "loop.for" results hold the final values after the last iteration. + For example, to sum-reduce a memref: - + ```mlir func @reduce(%buffer: memref<1024xf32>, %lb: index, %ub: index, %step: index) -> (f32) { // Initial sum set to 0. @@ -85,14 +85,14 @@ def ForOp : Loop_Op<"for", loop.yield %sum_next : f32 } return %sum : f32 - } + } ``` - If the "loop.for" defines any values, a yield must be explicitly present. - The number and types of the "loop.for" results must match the initial values + If the "loop.for" defines any values, a yield must be explicitly present. + The number and types of the "loop.for" results must match the initial values in the "iter_args" binding and the yield operands. - - Another example with a nested "loop.if" (see "loop.if" for details) + + Another example with a nested "loop.if" (see "loop.if" for details) to perform conditional reduction: ```mlir @@ -118,7 +118,7 @@ def ForOp : Loop_Op<"for", Index:$upperBound, Index:$step, Variadic:$initArgs); - let results = (outs Variadic:$results); + let results = (outs Variadic:$results); let regions = (region SizedRegion<1>:$region); let skipDefaultBuilders = 1; @@ -143,15 +143,15 @@ def ForOp : Loop_Op<"for", void setLowerBound(Value bound) { getOperation()->setOperand(0, bound); } void setUpperBound(Value bound) { getOperation()->setOperand(1, bound); } void setStep(Value step) { getOperation()->setOperand(2, step); } - + /// Number of region arguments for loop-carried values unsigned getNumRegionIterArgs() { - return getBody()->getNumArguments() - 1; + return getBody()->getNumArguments() - 1; } /// Number of operands controlling the loop: lb, ub, step unsigned getNumControlOperands() { return 3; } /// Does the operation hold operands for loop-carried values - bool hasIterOperands() { + bool hasIterOperands() { return getOperation()->getNumOperands() > getNumControlOperands(); } /// Get Number of loop-carried values @@ -178,7 +178,7 @@ def IfOp : Loop_Op<"if", ``` "loop.if" may also return results that are defined in its regions. The values - defined are determined by which execution path is taken. + defined are determined by which execution path is taken. For example: ```mlir %x, %y = loop.if %b -> (f32, f32) { @@ -186,8 +186,8 @@ def IfOp : Loop_Op<"if", %y_true = ... loop.yield %x_true, %y_true : f32, f32 } else { - %x_false = ... - %y_false = ... + %x_false = ... + %y_false = ... loop.yield %x_false, %y_false : f32, f32 } ``` @@ -196,7 +196,7 @@ def IfOp : Loop_Op<"if", defines no values, the "loop.yield" can be left out, and will be inserted implicitly. Otherwise, it must be explicit. Also, if "loop.if" defines one or more values, the 'else' block cannot - be omitted. + be omitted. For example: ```mlir @@ -230,18 +230,20 @@ def IfOp : Loop_Op<"if", } def ParallelOp : Loop_Op<"parallel", - [SameVariadicOperandSize, SingleBlockImplicitTerminator<"YieldOp">]> { + [AttrSizedOperandSegments, SingleBlockImplicitTerminator<"YieldOp">]> { let summary = "parallel for operation"; let description = [{ - The "loop.parallel" operation represents a loop nest taking 3 groups of SSA - values as operands that represent the lower bounds, upper bounds and steps, - respectively. The operation defines a variadic number of SSA values for its - induction variables. It has one region capturing the loop body. The - induction variables are represented as an argument of this region. These SSA - values always have type index, which is the size of the machine word. The - steps are values of type index, required to be positive. - The lower and upper bounds specify a half-open range: the range includes the - lower bound but does not include the upper bound. + The "loop.parallel" operation represents a loop nest taking 4 groups of SSA + values as operands that represent the lower bounds, upper bounds, steps and + initial values, respectively. The operation defines a variadic number of + SSA values for its induction variables. It has one region capturing the + loop body. The induction variables are represented as an argument of this + region. These SSA values always have type index, which is the size of the + machine word. The steps are values of type index, required to be positive. + The lower and upper bounds specify a half-open range: the range includes + the lower bound but does not include the upper bound. The initial values + have the same types as results of "loop.parallel". If there are no results, + the keyword `init` can be omitted. Semantically we require that the iteration space can be iterated in any order, and the loop body can be executed in parallel. If there are data @@ -250,10 +252,11 @@ def ParallelOp : Loop_Op<"parallel", The parallel loop operation supports reduction of values produced by individual iterations into a single result. This is modeled using the loop.reduce operation (see loop.reduce for details). Each result of a - loop.parallel operation is associated with a reduce operation that is an - immediate child. Reduces are matched to result values in order of their - appearance in the body. Consequently, we require that the body region has - the same number of results as it has reduce operations. + loop.parallel operation is associated with an initial value operand and + reduce operation that is an immediate child. Reductions are matched to result + and initial values in order of their appearance in the body. Consequently, + we require that the body region has the same number of results and initial + values as it has reduce operations. The body region must contain exactly one block that terminates with "loop.yield" without operands. Parsing ParallelOp will create such a region @@ -273,7 +276,8 @@ def ParallelOp : Loop_Op<"parallel", let arguments = (ins Variadic:$lowerBound, Variadic:$upperBound, - Variadic:$step); + Variadic:$step, + Variadic:$initVals); let results = (outs Variadic:$results); let regions = (region SizedRegion<1>:$region); @@ -281,10 +285,7 @@ def ParallelOp : Loop_Op<"parallel", let builders = [ OpBuilder<"Builder *builder, OperationState &result, " "ValueRange lowerBounds, ValueRange upperBounds, " - "ValueRange steps">, - OpBuilder<"Builder *builder, OperationState &result, " - "ValueRange lowerBounds, ValueRange upperBounds, " - "ValueRange steps, ArrayRef resultTypes"> + "ValueRange steps, ValueRange initVals = {}">, ]; let extraClassDeclaration = [{ @@ -293,9 +294,10 @@ def ParallelOp : Loop_Op<"parallel", return getBody()->getNumArguments(); } iterator_range getInductionVars() { - return {getBody()->args_begin(), getBody()->args_end()}; + return getBody()->getArguments(); } unsigned getNumLoops() { return step().size(); } + unsigned getNumReductions() { return initVals().size(); } }]; } @@ -369,13 +371,13 @@ def YieldOp : Loop_Op<"yield", [Terminator]> { let description = [{ "loop.yield" yields an SSA value from a loop dialect op region and terminates the regions. The semantics of how the values are yielded - is defined by the parent operation. + is defined by the parent operation. If "loop.yield" has any operands, the operands must match the parent - operation's results. - If the parent operation defines no values, then the "loop.yield" may be + operation's results. + If the parent operation defines no values, then the "loop.yield" may be left out in the custom syntax and the builders will insert one implicitly. Otherwise, it has to be present in the syntax to indicate which values - are yielded. + are yielded. }]; let arguments = (ins Variadic:$results); diff --git a/mlir/lib/Dialect/LoopOps/LoopOps.cpp b/mlir/lib/Dialect/LoopOps/LoopOps.cpp index 9bf7687e5b1481..16323e02032c02 100644 --- a/mlir/lib/Dialect/LoopOps/LoopOps.cpp +++ b/mlir/lib/Dialect/LoopOps/LoopOps.cpp @@ -304,21 +304,23 @@ static void print(OpAsmPrinter &p, IfOp op) { //===----------------------------------------------------------------------===// void ParallelOp::build(Builder *builder, OperationState &result, ValueRange lbs, - ValueRange ubs, ValueRange steps) { + ValueRange ubs, ValueRange steps, ValueRange initVals) { result.addOperands(lbs); result.addOperands(ubs); result.addOperands(steps); + result.addOperands(initVals); + result.addAttribute( + ParallelOp::getOperandSegmentSizeAttr(), + builder->getI32VectorAttr({static_cast(lbs.size()), + static_cast(ubs.size()), + static_cast(steps.size()), + static_cast(initVals.size())})); Region *bodyRegion = result.addRegion(); ParallelOp::ensureTerminator(*bodyRegion, *builder, result.location); for (size_t i = 0, e = steps.size(); i < e; ++i) bodyRegion->front().addArgument(builder->getIndexType()); -} - -void ParallelOp::build(Builder *builder, OperationState &result, ValueRange lbs, - ValueRange ubs, ValueRange steps, - ArrayRef resultTypes) { - result.addTypes(resultTypes); - build(builder, result, lbs, ubs, steps); + for (Value init : initVals) + result.addTypes(init.getType()); } static LogicalResult verify(ParallelOp op) { @@ -340,9 +342,10 @@ static LogicalResult verify(ParallelOp op) { // number of tuple elements in step. Block *body = op.getBody(); if (body->getNumArguments() != stepValues.size()) - return op.emitOpError( - "expects the same number of induction variables as bound and step " - "values"); + return op.emitOpError() + << "expects the same number of induction variables: " + << body->getNumArguments() + << " as bound and step values: " << stepValues.size(); for (auto arg : body->getArguments()) if (!arg.getType().isIndex()) return op.emitOpError( @@ -350,9 +353,17 @@ static LogicalResult verify(ParallelOp op) { // Check that the number of results is the same as the number of ReduceOps. SmallVector reductions(body->getOps()); - if (op.results().size() != reductions.size()) - return op.emitOpError( - "expects number of results to be the same as number of reductions"); + auto resultsSize = op.results().size(); + auto reductionsSize = reductions.size(); + auto initValsSize = op.initVals().size(); + if (resultsSize != reductionsSize) + return op.emitOpError() + << "expects number of results: " << resultsSize + << " to be the same as number of reductions: " << reductionsSize; + if (resultsSize != initValsSize) + return op.emitOpError() + << "expects number of results: " << resultsSize + << " to be the same as number of initial values: " << initValsSize; // Check that the types of the results and reductions are the same. for (auto resultAndReduce : llvm::zip(op.results(), reductions)) { @@ -361,8 +372,8 @@ static LogicalResult verify(ParallelOp op) { auto reduceType = reduceOp.operand().getType(); if (resultType != reduceType) return reduceOp.emitOpError() - << "expects type of reduce to be the same as result type: " - << resultType; + << "expects type of reduce: " << reduceType + << " to be the same as result type: " << resultType; } return success(); } @@ -399,17 +410,35 @@ static ParseResult parseParallelOp(OpAsmParser &parser, parser.resolveOperands(steps, builder.getIndexType(), result.operands)) return failure(); + // Parse step value. + SmallVector initVals; + if (succeeded(parser.parseOptionalKeyword("init"))) { + if (parser.parseOperandList(initVals, -1, OpAsmParser::Delimiter::Paren)) + return failure(); + } + // Now parse the body. Region *body = result.addRegion(); SmallVector types(ivs.size(), builder.getIndexType()); if (parser.parseRegion(*body, ivs, types)) return failure(); + // Set `operand_segment_sizes` attribute. + result.addAttribute( + ParallelOp::getOperandSegmentSizeAttr(), + builder.getI32VectorAttr({static_cast(lower.size()), + static_cast(upper.size()), + static_cast(steps.size()), + static_cast(initVals.size())})); + // Parse attributes and optional results (in case there is a reduce). if (parser.parseOptionalAttrDict(result.attributes) || parser.parseOptionalColonTypeList(result.types)) return failure(); + if (!initVals.empty()) + parser.resolveOperands(initVals, result.types, parser.getNameLoc(), + result.operands); // Add a terminator if none was parsed. ForOp::ensureTerminator(*body, builder, result.location); @@ -420,8 +449,11 @@ static void print(OpAsmPrinter &p, ParallelOp op) { p << op.getOperationName() << " (" << op.getBody()->getArguments() << ") = (" << op.lowerBound() << ") to (" << op.upperBound() << ") step (" << op.step() << ")"; + if (!op.initVals().empty()) + p << " init (" << op.initVals() << ")"; p.printRegion(op.region(), /*printEntryBlockArgs=*/false); - p.printOptionalAttrDict(op.getAttrs()); + p.printOptionalAttrDict( + op.getAttrs(), /*elidedAttrs=*/ParallelOp::getOperandSegmentSizeAttr()); if (!op.results().empty()) p << " : " << op.getResultTypes(); } diff --git a/mlir/test/Dialect/Loops/invalid.mlir b/mlir/test/Dialect/Loops/invalid.mlir index 28947640fb0998..9b170275c9f66e 100644 --- a/mlir/test/Dialect/Loops/invalid.mlir +++ b/mlir/test/Dialect/Loops/invalid.mlir @@ -131,7 +131,7 @@ func @parallel_body_arguments_wrong_type( "loop.parallel"(%arg0, %arg1, %arg2) ({ ^bb0(%i0: f32): loop.yield - }): (index, index, index) -> () + }) {operand_segment_sizes = dense<[1, 1, 1, 0]>: vector<4xi32>}: (index, index, index) -> () return } @@ -139,11 +139,11 @@ func @parallel_body_arguments_wrong_type( func @parallel_body_wrong_number_of_arguments( %arg0: index, %arg1: index, %arg2: index) { - // expected-error@+1 {{'loop.parallel' op expects the same number of induction variables as bound and step values}} + // expected-error@+1 {{'loop.parallel' op expects the same number of induction variables: 2 as bound and step values: 1}} "loop.parallel"(%arg0, %arg1, %arg2) ({ ^bb0(%i0: index, %i1: index): loop.yield - }): (index, index, index) -> () + }) {operand_segment_sizes = dense<[1, 1, 1, 0]>: vector<4xi32>}: (index, index, index) -> () return } @@ -172,7 +172,7 @@ func @parallel_step_not_positive( func @parallel_fewer_results_than_reduces( %arg0 : index, %arg1: index, %arg2: index) { - // expected-error@+1 {{expects number of results to be the same as number of reductions}} + // expected-error@+1 {{expects number of results: 0 to be the same as number of reductions: 1}} loop.parallel (%i0) = (%arg0) to (%arg1) step (%arg2) { %c0 = constant 1.0 : f32 loop.reduce(%c0) { @@ -187,8 +187,9 @@ func @parallel_fewer_results_than_reduces( func @parallel_more_results_than_reduces( %arg0 : index, %arg1 : index, %arg2 : index) { - // expected-error@+1 {{expects number of results to be the same as number of reductions}} - %res = loop.parallel (%i0) = (%arg0) to (%arg1) step (%arg2) { + // expected-error@+2 {{expects number of results: 1 to be the same as number of reductions: 0}} + %zero = constant 1.0 : f32 + %res = loop.parallel (%i0) = (%arg0) to (%arg1) step (%arg2) init (%zero) { } : f32 return @@ -196,10 +197,25 @@ func @parallel_more_results_than_reduces( // ----- -func @parallel_different_types_of_results_and_reduces( +func @parallel_more_results_than_initial_values( %arg0 : index, %arg1: index, %arg2: index) { + // expected-error@+1 {{expects number of results: 1 to be the same as number of initial values: 0}} %res = loop.parallel (%i0) = (%arg0) to (%arg1) step (%arg2) { - // expected-error@+1 {{expects type of reduce to be the same as result type: 'f32'}} + loop.reduce(%arg0) { + ^bb0(%lhs: index, %rhs: index): + loop.reduce.return %lhs : index + } : index + } : f32 + return +} + +// ----- + +func @parallel_different_types_of_results_and_reduces( + %arg0 : index, %arg1: index, %arg2: index) { + %zero = constant 0.0 : f32 + %res = loop.parallel (%i0) = (%arg0) to (%arg1) step (%arg2) init (%zero) { + // expected-error@+1 {{expects type of reduce: 'index' to be the same as result type: 'f32'}} loop.reduce(%arg0) { ^bb0(%lhs: index, %rhs: index): loop.reduce.return %lhs : index @@ -222,7 +238,8 @@ func @top_level_reduce(%arg0 : f32) { // ----- func @reduce_empty_block(%arg0 : index, %arg1 : f32) { - %res = loop.parallel (%i0) = (%arg0) to (%arg0) step (%arg0) { + %zero = constant 0.0 : f32 + %res = loop.parallel (%i0) = (%arg0) to (%arg0) step (%arg0) init (%zero) { // expected-error@+1 {{the block inside reduce should not be empty}} loop.reduce(%arg1) { ^bb0(%lhs : f32, %rhs : f32): @@ -234,7 +251,8 @@ func @reduce_empty_block(%arg0 : index, %arg1 : f32) { // ----- func @reduce_too_many_args(%arg0 : index, %arg1 : f32) { - %res = loop.parallel (%i0) = (%arg0) to (%arg0) step (%arg0) { + %zero = constant 0.0 : f32 + %res = loop.parallel (%i0) = (%arg0) to (%arg0) step (%arg0) init (%zero) { // expected-error@+1 {{expects two arguments to reduce block of type 'f32'}} loop.reduce(%arg1) { ^bb0(%lhs : f32, %rhs : f32, %other : f32): @@ -247,7 +265,8 @@ func @reduce_too_many_args(%arg0 : index, %arg1 : f32) { // ----- func @reduce_wrong_args(%arg0 : index, %arg1 : f32) { - %res = loop.parallel (%i0) = (%arg0) to (%arg0) step (%arg0) { + %zero = constant 0.0 : f32 + %res = loop.parallel (%i0) = (%arg0) to (%arg0) step (%arg0) init (%zero) { // expected-error@+1 {{expects two arguments to reduce block of type 'f32'}} loop.reduce(%arg1) { ^bb0(%lhs : f32, %rhs : i32): @@ -261,7 +280,8 @@ func @reduce_wrong_args(%arg0 : index, %arg1 : f32) { // ----- func @reduce_wrong_terminator(%arg0 : index, %arg1 : f32) { - %res = loop.parallel (%i0) = (%arg0) to (%arg0) step (%arg0) { + %zero = constant 0.0 : f32 + %res = loop.parallel (%i0) = (%arg0) to (%arg0) step (%arg0) init (%zero) { // expected-error@+1 {{the block inside reduce should be terminated with a 'loop.reduce.return' op}} loop.reduce(%arg1) { ^bb0(%lhs : f32, %rhs : f32): @@ -274,7 +294,8 @@ func @reduce_wrong_terminator(%arg0 : index, %arg1 : f32) { // ----- func @reduceReturn_wrong_type(%arg0 : index, %arg1: f32) { - %res = loop.parallel (%i0) = (%arg0) to (%arg0) step (%arg0) { + %zero = constant 0.0 : f32 + %res = loop.parallel (%i0) = (%arg0) to (%arg0) step (%arg0) init (%zero) { loop.reduce(%arg1) { ^bb0(%lhs : f32, %rhs : f32): %c0 = constant 1 : index @@ -377,4 +398,4 @@ func @parallel_invalid_yield( loop.yield %c0 : f32 } return -} \ No newline at end of file +} diff --git a/mlir/test/Dialect/Loops/ops.mlir b/mlir/test/Dialect/Loops/ops.mlir index 22944c6fa9a4a1..40aef314d273c9 100644 --- a/mlir/test/Dialect/Loops/ops.mlir +++ b/mlir/test/Dialect/Loops/ops.mlir @@ -1,8 +1,8 @@ -// RUN: mlir-opt %s | FileCheck %s +// RUN: mlir-opt %s | FileCheck %s --dump-input-on-failure // Verify the printed output can be parsed. -// RUN: mlir-opt %s | mlir-opt | FileCheck %s +// RUN: mlir-opt %s | mlir-opt | FileCheck %s --dump-input-on-failure // Verify the generic form can be parsed. -// RUN: mlir-opt -mlir-print-op-generic %s | mlir-opt | FileCheck %s +// RUN: mlir-opt -mlir-print-op-generic %s | mlir-opt | FileCheck %s --dump-input-on-failure func @std_for(%arg0 : index, %arg1 : index, %arg2 : index) { loop.for %i0 = %arg0 to %arg1 step %arg2 { @@ -59,9 +59,10 @@ func @std_parallel_loop(%arg0 : index, %arg1 : index, %arg2 : index, %min = select %min_cmp, %i0, %i1 : index %max_cmp = cmpi "sge", %i0, %i1 : index %max = select %max_cmp, %i0, %i1 : index - %red = loop.parallel (%i2) = (%min) to (%max) step (%i1) { - %zero = constant 0.0 : f32 - loop.reduce(%zero) { + %zero = constant 0.0 : f32 + %red = loop.parallel (%i2) = (%min) to (%max) step (%i1) init (%zero) { + %one = constant 1.0 : f32 + loop.reduce(%one) { ^bb0(%lhs : f32, %rhs: f32): %res = addf %lhs, %rhs : f32 loop.reduce.return %res : f32 @@ -83,9 +84,11 @@ func @std_parallel_loop(%arg0 : index, %arg1 : index, %arg2 : index, // CHECK-NEXT: %[[MIN:.*]] = select %[[MIN_CMP]], %[[I0]], %[[I1]] : index // CHECK-NEXT: %[[MAX_CMP:.*]] = cmpi "sge", %[[I0]], %[[I1]] : index // CHECK-NEXT: %[[MAX:.*]] = select %[[MAX_CMP]], %[[I0]], %[[I1]] : index -// CHECK-NEXT: loop.parallel (%{{.*}}) = (%[[MIN]]) to (%[[MAX]]) step (%[[I1]]) { -// CHECK-NEXT: %[[ZERO:.*]] = constant 0.000000e+00 : f32 -// CHECK-NEXT: loop.reduce(%[[ZERO]]) { +// CHECK-NEXT: %[[ZERO:.*]] = constant 0.000000e+00 : f32 +// CHECK-NEXT: loop.parallel (%{{.*}}) = (%[[MIN]]) to (%[[MAX]]) +// CHECK-SAME: step (%[[I1]]) init (%[[ZERO]]) { +// CHECK-NEXT: %[[ONE:.*]] = constant 1.000000e+00 : f32 +// CHECK-NEXT: loop.reduce(%[[ONE]]) { // CHECK-NEXT: ^bb0(%[[LHS:.*]]: f32, %[[RHS:.*]]: f32): // CHECK-NEXT: %[[RES:.*]] = addf %[[LHS]], %[[RHS]] : f32 // CHECK-NEXT: loop.reduce.return %[[RES]] : f32 From d481e59863ac0eaca813a972f0dc79b763012d30 Mon Sep 17 00:00:00 2001 From: Sid Manning Date: Fri, 21 Feb 2020 13:36:41 -0600 Subject: [PATCH 08/29] [hexagon] Add default paths to support musl target Pickup the default crt and libs when the target is musl. Resubmitting after updating the testcase. Differential Revision: https://reviews.llvm.org/D75139 --- clang/lib/Driver/ToolChains/Hexagon.cpp | 29 ++++++++-- clang/test/Driver/hexagon-toolchain-elf.c | 67 +++++++++++++++++++++++ 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp index 88523cd4bb1c2f..1e2e7c84b00641 100644 --- a/clang/lib/Driver/ToolChains/Hexagon.cpp +++ b/clang/lib/Driver/ToolChains/Hexagon.cpp @@ -264,18 +264,39 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA, UseG0 = G.getValue() == 0; } - //---------------------------------------------------------------------------- - // - //---------------------------------------------------------------------------- CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); + if (HTC.getTriple().isMusl()) { + if (!Args.hasArg(options::OPT_shared, options::OPT_static)) + CmdArgs.push_back("-dynamic-linker=/lib/ld-musl-hexagon.so.1"); + + if (!Args.hasArg(options::OPT_shared, options::OPT_nostartfiles, + options::OPT_nostdlib)) + CmdArgs.push_back(Args.MakeArgString(D.SysRoot + "/lib/crt1.o")); + else if (Args.hasArg(options::OPT_shared) && + !Args.hasArg(options::OPT_nostartfiles, options::OPT_nostdlib)) + CmdArgs.push_back(Args.MakeArgString(D.SysRoot + "/lib/Scrt1.o")); + + CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + D.SysRoot + "/lib")); + Args.AddAllArgs(CmdArgs, + {options::OPT_T_Group, options::OPT_e, options::OPT_s, + options::OPT_t, options::OPT_u_Group}); + AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA); + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { + CmdArgs.push_back("-lclang_rt.builtins-hexagon"); + CmdArgs.push_back("-lc"); + } + + return; + } + //---------------------------------------------------------------------------- // moslib //---------------------------------------------------------------------------- std::vector OsLibs; bool HasStandalone = false; - for (const Arg *A : Args.filtered(options::OPT_moslib_EQ)) { A->claim(); OsLibs.emplace_back(A->getValue()); diff --git a/clang/test/Driver/hexagon-toolchain-elf.c b/clang/test/Driver/hexagon-toolchain-elf.c index 0a6c8642495513..93c9da2250f59b 100644 --- a/clang/test/Driver/hexagon-toolchain-elf.c +++ b/clang/test/Driver/hexagon-toolchain-elf.c @@ -597,3 +597,70 @@ // RUN: %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK084 %s // CHECK084: "-fno-use-init-array" +// ----------------------------------------------------------------------------- +// Passing --musl +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-linux-musl \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/Tools/bin \ +// RUN: -mcpu=hexagonv60 \ +// RUN: -fuse-ld=lld \ +// RUN: --sysroot=/hexagon \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK085 %s +// CHECK085-NOT: /hexagon{{/|\\\\}}lib{{/|\\\\}}Scrt1.o +// CHECK085: "-dynamic-linker={{/|\\\\}}lib{{/|\\\\}}ld-musl-hexagon.so.1" +// CHECK085: "/hexagon{{/|\\\\}}lib{{/|\\\\}}crt1.o" +// CHECK085: "-lclang_rt.builtins-hexagon" "-lc" +// ----------------------------------------------------------------------------- +// Passing --musl --shared +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-linux-musl \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/Tools/bin \ +// RUN: -mcpu=hexagonv60 \ +// RUN: --sysroot=/hexagon -shared \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK086 %s +// CHECK086-NOT: -dynamic-linker={{/|\\\\}}lib{{/|\\\\}}ld-musl-hexagon.so.1 +// CHECK086: "/hexagon{{/|\\\\}}lib{{/|\\\\}}Scrt1.o" +// CHECK086: "-lclang_rt.builtins-hexagon" "-lc" +// CHECK086-NOT: /hexagon{{/|\\\\}}lib{{/|\\\\}}crt1.o +// ----------------------------------------------------------------------------- +// Passing --musl -nostdlib +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-linux-musl \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/Tools/bin \ +// RUN: -mcpu=hexagonv60 \ +// RUN: --sysroot=/hexagon -nostdlib \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK087 %s +// CHECK087: "-dynamic-linker={{/|\\\\}}lib{{/|\\\\}}ld-musl-hexagon.so.1" +// CHECK087-NOT: /hexagon{{/|\\\\}}lib{{/|\\\\}}Scrt1.o +// CHECK087-NOT: /hexagon{{/|\\\\}}lib{{/|\\\\}}crt1.o +// CHECK087-NOT: -lclang_rt.builtins-hexagon +// CHECK087-NOT: -lc +// ----------------------------------------------------------------------------- +// Passing --musl -nostartfiles +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-linux-musl \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/Tools/bin \ +// RUN: -mcpu=hexagonv60 \ +// RUN: --sysroot=/hexagon -nostartfiles \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK088 %s +// CHECK088: "-dynamic-linker={{/|\\\\}}lib{{/|\\\\}}ld-musl-hexagon.so.1" +// CHECK088-NOT: /hexagon{{/|\\\\}}lib{{/|\\\\}}Scrt1.o +// CHECK088-NOT: /hexagon{{/|\\\\}}lib{{/|\\\\}}crt1.o +// CHECK088: "-lclang_rt.builtins-hexagon" "-lc" +// ----------------------------------------------------------------------------- +// Passing --musl -nodefaultlibs +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-linux-musl \ +// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/Tools/bin \ +// RUN: -mcpu=hexagonv60 \ +// RUN: --sysroot=/hexagon -nodefaultlibs \ +// RUN: %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK089 %s +// CHECK089: "-dynamic-linker={{/|\\\\}}lib{{/|\\\\}}ld-musl-hexagon.so.1" +// CHECK089: "/hexagon{{/|\\\\}}lib{{/|\\\\}}crt1.o" +// CHECK089-NOT: -lclang_rt.builtins-hexagon +// CHECK089-NOT: -lc From f9896435c99b3288e1eba2b9226b56f603329cf1 Mon Sep 17 00:00:00 2001 From: diggerlin Date: Tue, 3 Mar 2020 10:02:40 -0500 Subject: [PATCH 09/29] [AIX][XCOFF] Fix XCOFFObjectWriter assertion failure with alignment-related gap and improve text section output testing SUMMARY: 1.if there is a gap between the end virtual address of one section and the beginning virtual address of the next section, the XCOFFObjectWriter.cpp will hit a assert. 2.as discussed in the patch https://reviews.llvm.org/D66969, since implemented the function description. We can output the raw object data for function. we need to create a test for raw text section content and test section header for xcoff object file. Reviewer: daltenty,hubert.reinterpretcast,jasonliu Differential Revision: https://reviews.llvm.org/D71845 --- llvm/lib/MC/XCOFFObjectWriter.cpp | 10 +++- llvm/test/CodeGen/PowerPC/aix-return55.ll | 59 ++++++++++++++++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp index bd9229d0d0e350..2c054426fa2a04 100644 --- a/llvm/lib/MC/XCOFFObjectWriter.cpp +++ b/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -439,8 +439,14 @@ void XCOFFObjectWriter::writeSections(const MCAssembler &Asm, if (Section->Index == Section::UninitializedIndex || Section->IsVirtual) continue; - assert(CurrentAddressLocation == Section->Address && - "Sections should be written consecutively."); + // There could be a gap (without corresponding zero padding) between + // sections. + assert(CurrentAddressLocation <= Section->Address && + "CurrentAddressLocation should be less than or equal to section " + "address."); + + CurrentAddressLocation = Section->Address; + for (const auto *Group : Section->Groups) { for (const auto &Csect : *Group) { if (uint32_t PaddingSize = Csect.Address - CurrentAddressLocation) diff --git a/llvm/test/CodeGen/PowerPC/aix-return55.ll b/llvm/test/CodeGen/PowerPC/aix-return55.ll index b16f2fa66e7246..e1a74f0989a563 100644 --- a/llvm/test/CodeGen/PowerPC/aix-return55.ll +++ b/llvm/test/CodeGen/PowerPC/aix-return55.ll @@ -1,5 +1,15 @@ -; RUN: llc -mcpu=pwr9 -mtriple=powerpc-ibm-aix-xcoff -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mcpu=pwr4 -mtriple=powerpc-ibm-aix-xcoff -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mcpu=pwr4 -mtriple=powerpc-ibm-aix-xcoff -verify-machineinstrs -filetype=obj -o %t.o < %s +; RUN: llvm-objdump -D %t.o | FileCheck --check-prefix=CHECKOBJ %s +; RUN: llvm-readobj -sections %t.o | FileCheck --check-prefix=CHECKSECT %s +; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff -filetype=obj < %s 2>&1 | \ +; RUN: FileCheck --check-prefix=XCOFF64 %s +; XCOFF64: LLVM ERROR: 64-bit XCOFF object files are not supported yet. + +@a = global i64 320255973571806, align 8 +@d = global double 5.000000e+00, align 8 +@strA = private unnamed_addr constant [10 x i8] c"hellowor\0A\00", align 1 define dso_local signext i32 @foo() { entry: @@ -9,3 +19,50 @@ entry: ; CHECK: blr } +;CHECKOBJ: 00000000 .text: +;CHECKOBJ-NEXT: 0: 38 60 00 37 li 3, 55 +;CHECKOBJ-NEXT: 4: 4e 80 00 20 blr{{[[:space:]] *}} +;CHECKOBJ-NEXT: 00000008 .rodata.str1.1: +;CHECKOBJ-NEXT: 8: 68 65 6c 6c xori 5, 3, 27756 +;CHECKOBJ-NEXT: c: 6f 77 6f 72 xoris 23, 27, 28530 +;CHECKOBJ-NEXT: 10: 0a 00 00 00 tdlti 0, 0{{[[:space:]] *}} +;CHECKOBJ-NEXT: Disassembly of section .data:{{[[:space:]] *}} +;CHECKOBJ-NEXT: 00000018 a: +;CHECKOBJ-NEXT: 18: 00 01 23 45 +;CHECKOBJ-NEXT: 1c: 67 8a bc de oris 10, 28, 48350{{[[:space:]] *}} +;CHECKOBJ-NEXT: 00000020 d: +;CHECKOBJ-NEXT: 20: 40 14 00 00 bdnzf 20, .+0 +;CHECKOBJ-NEXT: 24: 00 00 00 00 {{[[:space:]] *}} +;CHECKOBJ-NEXT: 00000028 foo: +;CHECKOBJ-NEXT: 28: 00 00 00 00 +;CHECKOBJ-NEXT: 2c: 00 00 00 34 +;CHECKOBJ-NEXT: 30: 00 00 00 00 + +;CHECKSECT: Sections [ +;CHECKSECT-NEXT: Section { +;CHECKSECT-NEXT: Index: 1 +;CHECKSECT-NEXT: Name: .text +;CHECKSECT-NEXT: PhysicalAddress: 0x0 +;CHECKSECT-NEXT: VirtualAddress: 0x0 +;CHECKSECT-NEXT: Size: 0x14 +;CHECKSECT-NEXT: RawDataOffset: 0x64 +;CHECKSECT-NEXT: RelocationPointer: 0x0 +;CHECKSECT-NEXT: LineNumberPointer: 0x0 +;CHECKSECT-NEXT: NumberOfRelocations: 0 +;CHECKSECT-NEXT: NumberOfLineNumbers: 0 +;CHECKSECT-NEXT: Type: STYP_TEXT (0x20) +;CHECKSECT-NEXT: } +;CHECKSECT-NEXT: Section { +;CHECKSECT-NEXT: Index: 2 +;CHECKSECT-NEXT: Name: .data +;CHECKSECT-NEXT: PhysicalAddress: 0x18 +;CHECKSECT-NEXT: VirtualAddress: 0x18 +;CHECKSECT-NEXT: Size: 0x1C +;CHECKSECT-NEXT: RawDataOffset: 0x78 +;CHECKSECT-NEXT: RelocationPointer: 0x94 +;CHECKSECT-NEXT: LineNumberPointer: 0x0 +;CHECKSECT-NEXT: NumberOfRelocations: 2 +;CHECKSECT-NEXT: NumberOfLineNumbers: 0 +;CHECKSECT-NEXT: Type: STYP_DATA (0x40) +;CHECKSECT-NEXT: } +;CHECKSECT-NEXT: ] From dfe8f5da4c707c447b80ff5bf78313b35621d9c4 Mon Sep 17 00:00:00 2001 From: Sam Parker Date: Thu, 27 Feb 2020 10:54:08 +0000 Subject: [PATCH 10/29] [ARM][RDA] Allow multiple killed users In RDA, check against the already decided dead instructions when looking at users. This allows an instruction to be removed if it has multiple users, but they're all dead. This means that IT instructions can be considered killed once all the itstate using instructions are dead. Differential Revision: https://reviews.llvm.org/D75245 --- llvm/lib/CodeGen/ReachingDefAnalysis.cpp | 7 +++++-- llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp | 3 --- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp index 84029a0ac150b3..5f0b4a92f3eead 100644 --- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp +++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp @@ -547,7 +547,7 @@ ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, InstSet &Visited, void ReachingDefAnalysis::collectLocalKilledOperands(MachineInstr *MI, InstSet &Dead) const { Dead.insert(MI); - auto IsDead = [this](MachineInstr *Def, int PhysReg) { + auto IsDead = [this, &Dead](MachineInstr *Def, int PhysReg) { unsigned LiveDefs = 0; for (auto &MO : Def->operands()) { if (!isValidRegDef(MO)) @@ -561,7 +561,10 @@ void ReachingDefAnalysis::collectLocalKilledOperands(MachineInstr *MI, SmallPtrSet Uses; getGlobalUses(Def, PhysReg, Uses); - return Uses.size() == 1; + for (auto *Use : Uses) + if (!Dead.count(Use)) + return false; + return true; }; for (auto &MO : MI->operands()) { diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp index 2a2179f7d19c29..92eb2e2cffed4f 100644 --- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp +++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp @@ -943,11 +943,8 @@ void ARMLowOverheadLoops::IterationCountDCE(LowOverheadLoop &LoLoop) { if (ModifiedITs.empty()) { LLVM_DEBUG(dbgs() << "ARM Loops: Will remove iteration count:\n"; for (auto *MI : Killed) - dbgs() << " - " << *MI; - for (auto *MI : DeadITs) dbgs() << " - " << *MI); LoLoop.ToRemove.insert(Killed.begin(), Killed.end()); - LoLoop.ToRemove.insert(DeadITs.begin(), DeadITs.end()); } // Collect and remove the users of iteration count. From caf5a4d57fe0ac0ca8c8d45fd31e5dbbc6bb6bec Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Tue, 3 Mar 2020 15:57:39 +0100 Subject: [PATCH 11/29] [clangd] Propagate versions into DraftStore, assigning where missing. NFC This prepares for propagating versions through the server so diagnostics etc can be versioned. --- clang-tools-extra/clangd/ClangdLSPServer.cpp | 36 ++++---- clang-tools-extra/clangd/DraftStore.cpp | 38 ++++++-- clang-tools-extra/clangd/DraftStore.h | 21 +++-- clang-tools-extra/clangd/Protocol.cpp | 14 +++ clang-tools-extra/clangd/Protocol.h | 18 +++- .../clangd/unittests/DraftStoreTests.cpp | 90 ++++++++++++++----- 6 files changed, 159 insertions(+), 58 deletions(-) diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 9d93b8592fdcd8..44288eb7274d96 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -117,7 +117,7 @@ llvm::Error validateEdits(const DraftStore &DraftMgr, const FileEdits &FE) { // If the file is open in user's editor, make sure the version we // saw and current version are compatible as this is the text that // will be replaced by editors. - if (!It.second.canApplyTo(*Draft)) { + if (!It.second.canApplyTo(Draft->Contents)) { ++InvalidFileCount; LastInvalidFile = It.first(); } @@ -630,7 +630,7 @@ void ClangdLSPServer::onDocumentDidOpen( const std::string &Contents = Params.textDocument.text; - DraftMgr.addDraft(File, Contents); + DraftMgr.addDraft(File, Params.textDocument.version, Contents); Server->addDocument(File, Contents, WantDiagnostics::Yes); } @@ -642,19 +642,19 @@ void ClangdLSPServer::onDocumentDidChange( : WantDiagnostics::No; PathRef File = Params.textDocument.uri.file(); - llvm::Expected Contents = - DraftMgr.updateDraft(File, Params.contentChanges); - if (!Contents) { + llvm::Expected Draft = DraftMgr.updateDraft( + File, Params.textDocument.version, Params.contentChanges); + if (!Draft) { // If this fails, we are most likely going to be not in sync anymore with // the client. It is better to remove the draft and let further operations // fail rather than giving wrong results. DraftMgr.removeDraft(File); Server->removeDocument(File); - elog("Failed to update {0}: {1}", File, Contents.takeError()); + elog("Failed to update {0}: {1}", File, Draft.takeError()); return; } - Server->addDocument(File, *Contents, WantDiags, Params.forceRebuild); + Server->addDocument(File, Draft->Contents, WantDiags, Params.forceRebuild); } void ClangdLSPServer::onFileEvent(const DidChangeWatchedFilesParams &Params) { @@ -773,8 +773,7 @@ void ClangdLSPServer::onPrepareRename(const TextDocumentPositionParams &Params, void ClangdLSPServer::onRename(const RenameParams &Params, Callback Reply) { Path File = std::string(Params.textDocument.uri.file()); - llvm::Optional Code = DraftMgr.getDraft(File); - if (!Code) + if (!DraftMgr.getDraft(File)) return Reply(llvm::make_error( "onRename called for non-added file", ErrorCode::InvalidParams)); Server->rename( @@ -829,7 +828,7 @@ void ClangdLSPServer::onDocumentOnTypeFormatting( "onDocumentOnTypeFormatting called for non-added file", ErrorCode::InvalidParams)); - Reply(Server->formatOnType(*Code, File, Params.position, Params.ch)); + Reply(Server->formatOnType(Code->Contents, File, Params.position, Params.ch)); } void ClangdLSPServer::onDocumentRangeFormatting( @@ -842,9 +841,10 @@ void ClangdLSPServer::onDocumentRangeFormatting( "onDocumentRangeFormatting called for non-added file", ErrorCode::InvalidParams)); - auto ReplacementsOrError = Server->formatRange(*Code, File, Params.range); + auto ReplacementsOrError = + Server->formatRange(Code->Contents, File, Params.range); if (ReplacementsOrError) - Reply(replacementsToEdits(*Code, ReplacementsOrError.get())); + Reply(replacementsToEdits(Code->Contents, ReplacementsOrError.get())); else Reply(ReplacementsOrError.takeError()); } @@ -859,9 +859,9 @@ void ClangdLSPServer::onDocumentFormatting( "onDocumentFormatting called for non-added file", ErrorCode::InvalidParams)); - auto ReplacementsOrError = Server->formatFile(*Code, File); + auto ReplacementsOrError = Server->formatFile(Code->Contents, File); if (ReplacementsOrError) - Reply(replacementsToEdits(*Code, ReplacementsOrError.get())); + Reply(replacementsToEdits(Code->Contents, ReplacementsOrError.get())); else Reply(ReplacementsOrError.takeError()); } @@ -1328,7 +1328,7 @@ bool ClangdLSPServer::shouldRunCompletion( // Running the lexer here would be more robust (e.g. we can detect comments // and avoid triggering completion there), but we choose to err on the side // of simplicity here. - auto Offset = positionToOffset(*Code, Params.position, + auto Offset = positionToOffset(Code->Contents, Params.position, /*AllowColumnsBeyondLineLength=*/false); if (!Offset) { vlog("could not convert position '{0}' to offset for file '{1}'", @@ -1339,9 +1339,9 @@ bool ClangdLSPServer::shouldRunCompletion( return false; if (Trigger == ">") - return (*Code)[*Offset - 2] == '-'; // trigger only on '->'. + return Code->Contents[*Offset - 2] == '-'; // trigger only on '->'. if (Trigger == ":") - return (*Code)[*Offset - 2] == ':'; // trigger only on '::'. + return Code->Contents[*Offset - 2] == ':'; // trigger only on '::'. assert(false && "unhandled trigger character"); return true; } @@ -1475,7 +1475,7 @@ void ClangdLSPServer::reparseOpenedFiles( // Reparse only opened files that were modified. for (const Path &FilePath : DraftMgr.getActiveFiles()) if (ModifiedFiles.find(FilePath) != ModifiedFiles.end()) - Server->addDocument(FilePath, *DraftMgr.getDraft(FilePath), + Server->addDocument(FilePath, DraftMgr.getDraft(FilePath)->Contents, WantDiagnostics::Auto); } diff --git a/clang-tools-extra/clangd/DraftStore.cpp b/clang-tools-extra/clangd/DraftStore.cpp index d4a5d0c73b80fb..03867dcd286e31 100644 --- a/clang-tools-extra/clangd/DraftStore.cpp +++ b/clang-tools-extra/clangd/DraftStore.cpp @@ -7,13 +7,14 @@ //===----------------------------------------------------------------------===// #include "DraftStore.h" +#include "Logger.h" #include "SourceCode.h" #include "llvm/Support/Errc.h" namespace clang { namespace clangd { -llvm::Optional DraftStore::getDraft(PathRef File) const { +llvm::Optional DraftStore::getDraft(PathRef File) const { std::lock_guard Lock(Mutex); auto It = Drafts.find(File); @@ -33,14 +34,32 @@ std::vector DraftStore::getActiveFiles() const { return ResultVector; } -void DraftStore::addDraft(PathRef File, llvm::StringRef Contents) { +static void updateVersion(DraftStore::Draft &D, + llvm::Optional Version) { + if (Version) { + // We treat versions as opaque, but the protocol says they increase. + if (*Version <= D.Version) + log("File version went from {0} to {1}", D.Version, Version); + D.Version = *Version; + } else { + // Note that if D was newly-created, this will bump D.Version from -1 to 0. + ++D.Version; + } +} + +int64_t DraftStore::addDraft(PathRef File, llvm::Optional Version, + llvm::StringRef Contents) { std::lock_guard Lock(Mutex); - Drafts[File] = std::string(Contents); + Draft &D = Drafts[File]; + updateVersion(D, Version); + D.Contents = Contents.str(); + return D.Version; } -llvm::Expected DraftStore::updateDraft( - PathRef File, llvm::ArrayRef Changes) { +llvm::Expected DraftStore::updateDraft( + PathRef File, llvm::Optional Version, + llvm::ArrayRef Changes) { std::lock_guard Lock(Mutex); auto EntryIt = Drafts.find(File); @@ -49,8 +68,8 @@ llvm::Expected DraftStore::updateDraft( "Trying to do incremental update on non-added document: " + File, llvm::errc::invalid_argument); } - - std::string Contents = EntryIt->second; + Draft &D = EntryIt->second; + std::string Contents = EntryIt->second.Contents; for (const TextDocumentContentChangeEvent &Change : Changes) { if (!Change.range) { @@ -104,8 +123,9 @@ llvm::Expected DraftStore::updateDraft( Contents = std::move(NewContents); } - EntryIt->second = Contents; - return Contents; + updateVersion(D, Version); + D.Contents = std::move(Contents); + return D; } void DraftStore::removeDraft(PathRef File) { diff --git a/clang-tools-extra/clangd/DraftStore.h b/clang-tools-extra/clangd/DraftStore.h index 1578ce9fad6b79..babc679ed7639b 100644 --- a/clang-tools-extra/clangd/DraftStore.h +++ b/clang-tools-extra/clangd/DraftStore.h @@ -23,26 +23,37 @@ namespace clangd { /// A thread-safe container for files opened in a workspace, addressed by /// filenames. The contents are owned by the DraftStore. This class supports /// both whole and incremental updates of the documents. +/// Each time a draft is updated, it is assigned a version number. This can be +/// specified by the caller or incremented from the previous version. class DraftStore { public: + struct Draft { + std::string Contents; + int64_t Version = -1; + }; + /// \return Contents of the stored document. /// For untracked files, a llvm::None is returned. - llvm::Optional getDraft(PathRef File) const; + llvm::Optional getDraft(PathRef File) const; /// \return List of names of the drafts in this store. std::vector getActiveFiles() const; /// Replace contents of the draft for \p File with \p Contents. - void addDraft(PathRef File, StringRef Contents); + /// If no version is specified, one will be automatically assigned. + /// Returns the version. + int64_t addDraft(PathRef File, llvm::Optional Version, + StringRef Contents); /// Update the contents of the draft for \p File based on \p Changes. /// If a position in \p Changes is invalid (e.g. out-of-range), the /// draft is not modified. + /// If no version is specified, one will be automatically assigned. /// /// \return The new version of the draft for \p File, or an error if the /// changes couldn't be applied. - llvm::Expected - updateDraft(PathRef File, + llvm::Expected + updateDraft(PathRef File, llvm::Optional Version, llvm::ArrayRef Changes); /// Remove the draft from the store. @@ -50,7 +61,7 @@ class DraftStore { private: mutable std::mutex Mutex; - llvm::StringMap Drafts; + llvm::StringMap Drafts; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index 5a867c52c1ed26..ba96f495c14876 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -90,6 +90,20 @@ bool fromJSON(const llvm::json::Value &Params, TextDocumentIdentifier &R) { return O && O.map("uri", R.uri); } +llvm::json::Value toJSON(const VersionedTextDocumentIdentifier &R) { + auto Result = toJSON(static_cast(R)); + if (R.version) + Result.getAsObject()->try_emplace("version", R.version); + return Result; +} + +bool fromJSON(const llvm::json::Value &Params, + VersionedTextDocumentIdentifier &R) { + llvm::json::ObjectMapper O(Params); + return fromJSON(Params, static_cast(R)) && O && + O.map("version", R.version); +} + bool fromJSON(const llvm::json::Value &Params, Position &R) { llvm::json::ObjectMapper O(Params); return O && O.map("line", R.line) && O.map("character", R.character); diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h index 596c7e9004e79d..5d3914da699f9b 100644 --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -124,6 +124,20 @@ struct TextDocumentIdentifier { llvm::json::Value toJSON(const TextDocumentIdentifier &); bool fromJSON(const llvm::json::Value &, TextDocumentIdentifier &); +struct VersionedTextDocumentIdentifier : public TextDocumentIdentifier { + // The version number of this document. If a versioned text document + // identifier is sent from the server to the client and the file is not open + // in the editor (the server has not received an open notification before) the + // server can send `null` to indicate that the version is known and the + // content on disk is the master (as speced with document content ownership). + // + // The version number of a document will increase after each change, including + // undo/redo. The number doesn't need to be consecutive. + llvm::Optional version; +}; +llvm::json::Value toJSON(const VersionedTextDocumentIdentifier &); +bool fromJSON(const llvm::json::Value &, VersionedTextDocumentIdentifier &); + struct Position { /// Line position in a document (zero-based). int line = 0; @@ -223,7 +237,7 @@ struct TextDocumentItem { std::string languageId; /// The version number of this document (it will strictly increase after each - int version = 0; + std::int64_t version = 0; /// The content of the opened text document. std::string text; @@ -643,7 +657,7 @@ struct DidChangeTextDocumentParams { /// The document that did change. The version number points /// to the version after all provided content changes have /// been applied. - TextDocumentIdentifier textDocument; + VersionedTextDocumentIdentifier textDocument; /// The actual content changes. std::vector contentChanges; diff --git a/clang-tools-extra/clangd/unittests/DraftStoreTests.cpp b/clang-tools-extra/clangd/unittests/DraftStoreTests.cpp index 1840892cd5e904..5ff9f254b55da4 100644 --- a/clang-tools-extra/clangd/unittests/DraftStoreTests.cpp +++ b/clang-tools-extra/clangd/unittests/DraftStoreTests.cpp @@ -9,6 +9,7 @@ #include "Annotations.h" #include "DraftStore.h" #include "SourceCode.h" +#include "llvm/Testing/Support/Error.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -36,7 +37,7 @@ void stepByStep(llvm::ArrayRef Steps) { constexpr llvm::StringLiteral Path("/hello.cpp"); // Set the initial content. - DS.addDraft(Path, InitialSrc.code()); + EXPECT_EQ(0, DS.addDraft(Path, llvm::None, InitialSrc.code())); for (size_t i = 1; i < Steps.size(); i++) { Annotations SrcBefore(Steps[i - 1].Src); @@ -48,10 +49,12 @@ void stepByStep(llvm::ArrayRef Steps) { Contents.str(), }; - llvm::Expected Result = DS.updateDraft(Path, {Event}); + llvm::Expected Result = + DS.updateDraft(Path, llvm::None, {Event}); ASSERT_TRUE(!!Result); - EXPECT_EQ(*Result, SrcAfter.code()); - EXPECT_EQ(*DS.getDraft(Path), SrcAfter.code()); + EXPECT_EQ(Result->Contents, SrcAfter.code()); + EXPECT_EQ(DS.getDraft(Path)->Contents, SrcAfter.code()); + EXPECT_EQ(Result->Version, static_cast(i)); } } @@ -75,13 +78,15 @@ void allAtOnce(llvm::ArrayRef Steps) { } // Set the initial content. - DS.addDraft(Path, InitialSrc.code()); + EXPECT_EQ(0, DS.addDraft(Path, llvm::None, InitialSrc.code())); - llvm::Expected Result = DS.updateDraft(Path, Changes); + llvm::Expected Result = + DS.updateDraft(Path, llvm::None, Changes); ASSERT_TRUE(!!Result) << llvm::toString(Result.takeError()); - EXPECT_EQ(*Result, FinalSrc.code()); - EXPECT_EQ(*DS.getDraft(Path), FinalSrc.code()); + EXPECT_EQ(Result->Contents, FinalSrc.code()); + EXPECT_EQ(DS.getDraft(Path)->Contents, FinalSrc.code()); + EXPECT_EQ(Result->Version, 1); } TEST(DraftStoreIncrementalUpdateTest, Simple) { @@ -184,7 +189,7 @@ TEST(DraftStoreIncrementalUpdateTest, WrongRangeLength) { DraftStore DS; Path File = "foo.cpp"; - DS.addDraft(File, "int main() {}\n"); + DS.addDraft(File, llvm::None, "int main() {}\n"); TextDocumentContentChangeEvent Change; Change.range.emplace(); @@ -194,7 +199,8 @@ TEST(DraftStoreIncrementalUpdateTest, WrongRangeLength) { Change.range->end.character = 2; Change.rangeLength = 10; - Expected Result = DS.updateDraft(File, {Change}); + Expected Result = + DS.updateDraft(File, llvm::None, {Change}); EXPECT_TRUE(!Result); EXPECT_EQ( @@ -206,7 +212,7 @@ TEST(DraftStoreIncrementalUpdateTest, EndBeforeStart) { DraftStore DS; Path File = "foo.cpp"; - DS.addDraft(File, "int main() {}\n"); + DS.addDraft(File, llvm::None, "int main() {}\n"); TextDocumentContentChangeEvent Change; Change.range.emplace(); @@ -215,7 +221,7 @@ TEST(DraftStoreIncrementalUpdateTest, EndBeforeStart) { Change.range->end.line = 0; Change.range->end.character = 3; - Expected Result = DS.updateDraft(File, {Change}); + auto Result = DS.updateDraft(File, llvm::None, {Change}); EXPECT_TRUE(!Result); EXPECT_EQ(toString(Result.takeError()), @@ -226,7 +232,7 @@ TEST(DraftStoreIncrementalUpdateTest, StartCharOutOfRange) { DraftStore DS; Path File = "foo.cpp"; - DS.addDraft(File, "int main() {}\n"); + DS.addDraft(File, llvm::None, "int main() {}\n"); TextDocumentContentChangeEvent Change; Change.range.emplace(); @@ -236,7 +242,7 @@ TEST(DraftStoreIncrementalUpdateTest, StartCharOutOfRange) { Change.range->end.character = 100; Change.text = "foo"; - Expected Result = DS.updateDraft(File, {Change}); + auto Result = DS.updateDraft(File, llvm::None, {Change}); EXPECT_TRUE(!Result); EXPECT_EQ(toString(Result.takeError()), @@ -247,7 +253,7 @@ TEST(DraftStoreIncrementalUpdateTest, EndCharOutOfRange) { DraftStore DS; Path File = "foo.cpp"; - DS.addDraft(File, "int main() {}\n"); + DS.addDraft(File, llvm::None, "int main() {}\n"); TextDocumentContentChangeEvent Change; Change.range.emplace(); @@ -257,7 +263,7 @@ TEST(DraftStoreIncrementalUpdateTest, EndCharOutOfRange) { Change.range->end.character = 100; Change.text = "foo"; - Expected Result = DS.updateDraft(File, {Change}); + auto Result = DS.updateDraft(File, llvm::None, {Change}); EXPECT_TRUE(!Result); EXPECT_EQ(toString(Result.takeError()), @@ -268,7 +274,7 @@ TEST(DraftStoreIncrementalUpdateTest, StartLineOutOfRange) { DraftStore DS; Path File = "foo.cpp"; - DS.addDraft(File, "int main() {}\n"); + DS.addDraft(File, llvm::None, "int main() {}\n"); TextDocumentContentChangeEvent Change; Change.range.emplace(); @@ -278,7 +284,7 @@ TEST(DraftStoreIncrementalUpdateTest, StartLineOutOfRange) { Change.range->end.character = 0; Change.text = "foo"; - Expected Result = DS.updateDraft(File, {Change}); + auto Result = DS.updateDraft(File, llvm::None, {Change}); EXPECT_TRUE(!Result); EXPECT_EQ(toString(Result.takeError()), "Line value is out of range (100)"); @@ -288,7 +294,7 @@ TEST(DraftStoreIncrementalUpdateTest, EndLineOutOfRange) { DraftStore DS; Path File = "foo.cpp"; - DS.addDraft(File, "int main() {}\n"); + DS.addDraft(File, llvm::None, "int main() {}\n"); TextDocumentContentChangeEvent Change; Change.range.emplace(); @@ -298,7 +304,7 @@ TEST(DraftStoreIncrementalUpdateTest, EndLineOutOfRange) { Change.range->end.character = 0; Change.text = "foo"; - Expected Result = DS.updateDraft(File, {Change}); + auto Result = DS.updateDraft(File, llvm::None, {Change}); EXPECT_TRUE(!Result); EXPECT_EQ(toString(Result.takeError()), "Line value is out of range (100)"); @@ -311,7 +317,7 @@ TEST(DraftStoreIncrementalUpdateTest, InvalidRangeInASequence) { Path File = "foo.cpp"; StringRef OriginalContents = "int main() {}\n"; - DS.addDraft(File, OriginalContents); + EXPECT_EQ(0, DS.addDraft(File, llvm::None, OriginalContents)); // The valid change TextDocumentContentChangeEvent Change1; @@ -331,15 +337,51 @@ TEST(DraftStoreIncrementalUpdateTest, InvalidRangeInASequence) { Change2.range->end.character = 100; Change2.text = "something"; - Expected Result = DS.updateDraft(File, {Change1, Change2}); + auto Result = DS.updateDraft(File, llvm::None, {Change1, Change2}); EXPECT_TRUE(!Result); EXPECT_EQ(toString(Result.takeError()), "utf-16 offset 100 is invalid for line 0"); - Optional Contents = DS.getDraft(File); + Optional Contents = DS.getDraft(File); EXPECT_TRUE(Contents); - EXPECT_EQ(*Contents, OriginalContents); + EXPECT_EQ(Contents->Contents, OriginalContents); + EXPECT_EQ(Contents->Version, 0); +} + +TEST(DraftStore, Version) { + DraftStore DS; + Path File = "foo.cpp"; + + EXPECT_EQ(25, DS.addDraft(File, 25, "")); + EXPECT_EQ(25, DS.getDraft(File)->Version); + + EXPECT_EQ(26, DS.addDraft(File, llvm::None, "")); + EXPECT_EQ(26, DS.getDraft(File)->Version); + + // We allow versions to go backwards. + EXPECT_EQ(7, DS.addDraft(File, 7, "")); + EXPECT_EQ(7, DS.getDraft(File)->Version); + + // Valid (no-op) change modifies version. + auto Result = DS.updateDraft(File, 10, {}); + EXPECT_TRUE(!!Result); + EXPECT_EQ(10, Result->Version); + EXPECT_EQ(10, DS.getDraft(File)->Version); + + Result = DS.updateDraft(File, llvm::None, {}); + EXPECT_TRUE(!!Result); + EXPECT_EQ(11, Result->Version); + EXPECT_EQ(11, DS.getDraft(File)->Version); + + TextDocumentContentChangeEvent InvalidChange; + InvalidChange.range.emplace(); + InvalidChange.rangeLength = 99; + + Result = DS.updateDraft(File, 15, {InvalidChange}); + EXPECT_FALSE(!!Result); + consumeError(Result.takeError()); + EXPECT_EQ(11, DS.getDraft(File)->Version); } } // namespace From 5618e9be37502ede1b56a3ec1c809be461461c0e Mon Sep 17 00:00:00 2001 From: Sam Parker Date: Tue, 3 Mar 2020 15:19:57 +0000 Subject: [PATCH 12/29] [RDA][ARM] collectKilledOperands across multiple blocks Use MIOperand in collectLocalKilledOperands to make the search global, as we already have to search for global uses too. This allows us to delete more dead code when tail predicating. Differential Revision: https://reviews.llvm.org/D75167 --- .../llvm/CodeGen/ReachingDefAnalysis.h | 2 +- llvm/lib/CodeGen/ReachingDefAnalysis.cpp | 16 ++-- llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp | 73 ++++++++++--------- .../LowOverheadLoops/it-block-itercount.mir | 2 - .../Thumb2/LowOverheadLoops/it-block-mov.mir | 14 +--- .../LowOverheadLoops/multiple-do-loops.mir | 2 - llvm/test/CodeGen/Thumb2/mve-postinc-lsr.ll | 8 -- 7 files changed, 48 insertions(+), 69 deletions(-) diff --git a/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h b/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h index 3c6ab064e91fe6..44127bfdd48e0a 100644 --- a/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h +++ b/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h @@ -176,7 +176,7 @@ class ReachingDefAnalysis : public MachineFunctionPass { /// Assuming MI is dead, recursively search the incoming operands which are /// killed by MI and collect those that would become dead. - void collectLocalKilledOperands(MachineInstr *MI, InstSet &Dead) const; + void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const; /// Return whether removing this instruction will have no effect on the /// program, returning the redundant use-def chain. diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp index 5f0b4a92f3eead..a1c0c21df9127b 100644 --- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp +++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp @@ -33,10 +33,6 @@ bool isValidRegUseOf(const MachineOperand &MO, int PhysReg) { return isValidRegUse(MO) && MO.getReg() == PhysReg; } -bool isKilledRegUse(const MachineOperand &MO) { - return isValidRegUse(MO) && MO.isKill(); -} - bool isValidRegDef(const MachineOperand &MO) { return isValidReg(MO) && MO.isDef(); } @@ -353,7 +349,7 @@ MachineInstr *ReachingDefAnalysis::getUniqueReachingMIDef(MachineInstr *MI, int PhysReg) const { // If there's a local def before MI, return it. MachineInstr *LocalDef = getReachingLocalMIDef(MI, PhysReg); - if (InstIds.lookup(LocalDef) < InstIds.lookup(MI)) + if (LocalDef && InstIds.lookup(LocalDef) < InstIds.lookup(MI)) return LocalDef; SmallPtrSet VisitedBBs; @@ -544,8 +540,8 @@ ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, InstSet &Visited, return true; } -void ReachingDefAnalysis::collectLocalKilledOperands(MachineInstr *MI, - InstSet &Dead) const { +void ReachingDefAnalysis::collectKilledOperands(MachineInstr *MI, + InstSet &Dead) const { Dead.insert(MI); auto IsDead = [this, &Dead](MachineInstr *Def, int PhysReg) { unsigned LiveDefs = 0; @@ -568,11 +564,11 @@ void ReachingDefAnalysis::collectLocalKilledOperands(MachineInstr *MI, }; for (auto &MO : MI->operands()) { - if (!isKilledRegUse(MO)) + if (!isValidRegUse(MO)) continue; - if (MachineInstr *Def = getReachingLocalMIDef(MI, MO.getReg())) + if (MachineInstr *Def = getMIOperand(MI, MO)) if (IsDead(Def, MO.getReg())) - collectLocalKilledOperands(Def, Dead); + collectKilledOperands(Def, Dead); } } diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp index 92eb2e2cffed4f..67cb883329363f 100644 --- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp +++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp @@ -900,40 +900,53 @@ void ARMLowOverheadLoops::IterationCountDCE(LowOverheadLoop &LoLoop) { if (!LoLoop.IsTailPredicationLegal()) return; + LLVM_DEBUG(dbgs() << "ARM Loops: Trying DCE on loop iteration count.\n"); + MachineInstr *Def = RDA->getMIOperand(LoLoop.Start, 0); - if (!Def) + if (!Def) { + LLVM_DEBUG(dbgs() << "ARM Loops: Couldn't find iteration count.\n"); + return; + } + + // Collect and remove the users of iteration count. + SmallPtrSet Killed = { LoLoop.Start, LoLoop.Dec, + LoLoop.End, LoLoop.InsertPt }; + SmallPtrSet Remove; + if (RDA->isSafeToRemove(Def, Remove, Killed)) + LoLoop.ToRemove.insert(Remove.begin(), Remove.end()); + else { + LLVM_DEBUG(dbgs() << "ARM Loops: Unsafe to remove loop iteration count.\n"); return; + } - // Collect IT blocks. + // Collect the dead code and the MBBs in which they reside. + RDA->collectKilledOperands(Def, Killed); + SmallPtrSet BasicBlocks; + for (auto *MI : Killed) + BasicBlocks.insert(MI->getParent()); + + // Collect IT blocks in all affected basic blocks. std::map> ITBlocks; - std::map Predicates; - MachineInstr *IT = nullptr; - for (auto &MI : *Def->getParent()) { - if (MI.getOpcode() == ARM::t2IT) - IT = &MI; - else if (TII->getPredicate(MI) != ARMCC::AL) { - ITBlocks[IT].insert(&MI); - Predicates[&MI] = IT; + for (auto *MBB : BasicBlocks) { + for (auto &MI : *MBB) { + if (MI.getOpcode() != ARM::t2IT) + continue; + RDA->getReachingLocalUses(&MI, ARM::ITSTATE, ITBlocks[&MI]); } } // If we're removing all of the instructions within an IT block, then // also remove the IT instruction. SmallPtrSet ModifiedITs; - SmallPtrSet DeadITs; - SmallPtrSet Killed; - RDA->collectLocalKilledOperands(Def, Killed); for (auto *MI : Killed) { - if (!Predicates.count(MI)) - continue; - - MachineInstr *IT = Predicates[MI]; - auto &CurrentBlock = ITBlocks[IT]; - CurrentBlock.erase(MI); - ModifiedITs.insert(IT); - if (CurrentBlock.empty()) { - DeadITs.insert(IT); - ModifiedITs.erase(IT); + if (MachineOperand *MO = MI->findRegisterUseOperand(ARM::ITSTATE)) { + MachineInstr *IT = RDA->getMIOperand(MI, *MO); + auto &CurrentBlock = ITBlocks[IT]; + CurrentBlock.erase(MI); + if (CurrentBlock.empty()) + ModifiedITs.erase(IT); + else + ModifiedITs.insert(IT); } } @@ -945,14 +958,8 @@ void ARMLowOverheadLoops::IterationCountDCE(LowOverheadLoop &LoLoop) { for (auto *MI : Killed) dbgs() << " - " << *MI); LoLoop.ToRemove.insert(Killed.begin(), Killed.end()); - } - - // Collect and remove the users of iteration count. - SmallPtrSet Ignore = { LoLoop.Start, LoLoop.Dec, - LoLoop.End, LoLoop.InsertPt }; - SmallPtrSet Remove; - if (RDA->isSafeToRemove(Def, Remove, Ignore)) - LoLoop.ToRemove.insert(Remove.begin(), Remove.end()); + } else + LLVM_DEBUG(dbgs() << "ARM Loops: Would need to modify IT block(s).\n"); } MachineInstr* ARMLowOverheadLoops::ExpandLoopStart(LowOverheadLoop &LoLoop) { @@ -1076,8 +1083,8 @@ void ARMLowOverheadLoops::Expand(LowOverheadLoop &LoLoop) { MIB.add(End->getOperand(0)); MIB.add(End->getOperand(1)); LLVM_DEBUG(dbgs() << "ARM Loops: Inserted LE: " << *MIB); - LoLoop.Dec->eraseFromParent(); - End->eraseFromParent(); + LoLoop.ToRemove.insert(LoLoop.Dec); + LoLoop.ToRemove.insert(End); return &*MIB; }; diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-itercount.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-itercount.mir index 456fe593443eca..d5bc54820182ab 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-itercount.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-itercount.mir @@ -104,8 +104,6 @@ body: | ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 ; CHECK: frame-setup CFI_INSTRUCTION offset $r7, -8 ; CHECK: renamable $r3, dead $cpsr = tLSLri killed renamable $r2, 1, 14 /* CC::al */, $noreg - ; CHECK: dead renamable $r12 = t2MOVi 4, 14 /* CC::al */, $noreg, $noreg - ; CHECK: tCMPi8 renamable $r3, 4, 14 /* CC::al */, $noreg, implicit-def dead $cpsr ; CHECK: renamable $r2 = tLEApcrel %const.0, 14 /* CC::al */, $noreg ; CHECK: renamable $q0 = MVE_VLDRWU32 killed renamable $r2, 0, 0, $noreg :: (load 16 from constant-pool) ; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3 diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir index bed94f989858ba..e5d629c8730c6b 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir @@ -45,12 +45,7 @@ body: | ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 ; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -8 - ; CHECK: tCMPi8 renamable $r1, 4, 14 /* CC::al */, $noreg, implicit-def $cpsr - ; CHECK: renamable $r3 = t2MOVi 4, 14 /* CC::al */, $noreg, $noreg - ; CHECK: t2IT 11, 8, implicit-def $itstate - ; CHECK: dead $r3 = tMOVr renamable $r1, 11 /* CC::lt */, killed $cpsr, implicit killed renamable $r3, implicit killed $itstate ; CHECK: tCMPi8 renamable $r1, 2, 14 /* CC::al */, $noreg, implicit-def $cpsr - ; CHECK: renamable $r12 = t2MOVi 4, 14 /* CC::al */, $noreg, $noreg ; CHECK: tBcc %bb.2, 2 /* CC::hs */, killed $cpsr ; CHECK: bb.1: ; CHECK: liveins: $r2 @@ -59,15 +54,8 @@ body: | ; CHECK: tPOP_RET 14 /* CC::al */, $noreg, def $r4, def $pc ; CHECK: bb.2: ; CHECK: successors: %bb.3(0x80000000) - ; CHECK: liveins: $r0, $r1, $r2, $r12 - ; CHECK: renamable $r4, dead $cpsr = tMOVi8 1, 14 /* CC::al */, $noreg - ; CHECK: tCMPi8 renamable $r1, 4, 14 /* CC::al */, $noreg, implicit-def $cpsr - ; CHECK: t2IT 11, 8, implicit-def $itstate - ; CHECK: $r12 = tMOVr renamable $r1, 11 /* CC::lt */, killed $cpsr, implicit killed renamable $r12, implicit killed $itstate - ; CHECK: renamable $r3 = t2SUBrr renamable $r1, killed renamable $r12, 14 /* CC::al */, $noreg, $noreg - ; CHECK: renamable $r3, dead $cpsr = tADDi8 killed renamable $r3, 3, 14 /* CC::al */, $noreg + ; CHECK: liveins: $r0, $r1, $r2 ; CHECK: $r12 = tMOVr $r1, 14 /* CC::al */, $noreg - ; CHECK: dead renamable $r4 = nuw nsw t2ADDrs killed renamable $r4, killed renamable $r3, 19, 14 /* CC::al */, $noreg, $noreg ; CHECK: renamable $q0 = MVE_VMOVimmi32 0, 0, $noreg, undef renamable $q0 ; CHECK: $r3 = tMOVr $r0, 14 /* CC::al */, $noreg ; CHECK: $lr = MVE_DLSTP_32 killed renamable $r12 diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/multiple-do-loops.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/multiple-do-loops.mir index e9ee082479b87b..087db2ae509d09 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/multiple-do-loops.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/multiple-do-loops.mir @@ -563,7 +563,6 @@ body: | ; CHECK: early-clobber $sp = frame-setup t2STR_PRE killed $r8, $sp, -4, 14 /* CC::al */, $noreg ; CHECK: frame-setup CFI_INSTRUCTION offset $r8, -24 ; CHECK: renamable $r6, dead $cpsr = tMOVi8 0, 14 /* CC::al */, $noreg - ; CHECK: dead renamable $r12 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg ; CHECK: t2CMPrs killed renamable $r6, renamable $r3, 11, 14 /* CC::al */, $noreg, implicit-def $cpsr ; CHECK: tBcc %bb.3, 0 /* CC::eq */, killed $cpsr ; CHECK: bb.1.vector.ph: @@ -801,7 +800,6 @@ body: | ; CHECK: successors: %bb.6(0x30000000), %bb.4(0x50000000) ; CHECK: liveins: $r0, $r1, $r2, $r3 ; CHECK: renamable $r6, dead $cpsr = tMOVi8 0, 14 /* CC::al */, $noreg - ; CHECK: dead renamable $r8 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg ; CHECK: t2CMPrs killed renamable $r6, renamable $r3, 11, 14 /* CC::al */, $noreg, implicit-def $cpsr ; CHECK: tBcc %bb.6, 0 /* CC::eq */, killed $cpsr ; CHECK: bb.4.vector.ph66: diff --git a/llvm/test/CodeGen/Thumb2/mve-postinc-lsr.ll b/llvm/test/CodeGen/Thumb2/mve-postinc-lsr.ll index d74f3bbfb2e0e3..13f0243139487d 100644 --- a/llvm/test/CodeGen/Thumb2/mve-postinc-lsr.ll +++ b/llvm/test/CodeGen/Thumb2/mve-postinc-lsr.ll @@ -576,15 +576,7 @@ define i32 @arm_nn_mat_mul_core_4x_s8(i32 %row_elements, i32 %offset, i8* %row_b ; CHECK: @ %bb.0: @ %entry ; CHECK-NEXT: .save {r4, r5, r6, r7, r8, r10, lr} ; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r10, lr} -; CHECK-NEXT: add.w r7, r0, #15 ; CHECK-NEXT: ldr.w r12, [sp, #32] -; CHECK-NEXT: mov.w lr, #1 -; CHECK-NEXT: asrs r6, r7, #31 -; CHECK-NEXT: add.w r4, r7, r6, lsr #28 -; CHECK-NEXT: asrs r5, r4, #4 -; CHECK-NEXT: cmp r5, #1 -; CHECK-NEXT: it gt -; CHECK-NEXT: asrgt.w lr, r4, #4 ; CHECK-NEXT: cmp r0, #1 ; CHECK-NEXT: blt .LBB4_3 ; CHECK-NEXT: @ %bb.1: @ %for.body.preheader From 779e2c7a1a2638092fcb33f488ce51a50d140ea0 Mon Sep 17 00:00:00 2001 From: Francesco Petrogalli Date: Mon, 2 Mar 2020 22:13:47 +0000 Subject: [PATCH 13/29] [llvm][CodeGen][SVE] Constrain prefetch intrinsic argument to immediate values. Summary: The argument that sets the prefetch type of a prefetch intrinsic must be an immediate value. Reviewers: andwar, sdesmalen, efriedma Subscribers: tschuett, hiraditya, rkruppe, psnobl, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D75482 --- llvm/include/llvm/IR/IntrinsicsAArch64.td | 6 +++--- llvm/lib/Target/AArch64/SVEInstrFormats.td | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index 3976dde3d75018..12756e3406bed3 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -1273,9 +1273,9 @@ def int_aarch64_sve_stnt1 : AdvSIMD_1Vec_PredStore_Intrinsic; // Prefetch // -def int_aarch64_sve_prf : Intrinsic<[], [llvm_anyvector_ty, - llvm_ptr_ty, - llvm_i32_ty], [IntrArgMemOnly]>; +def int_aarch64_sve_prf + : Intrinsic<[], [llvm_anyvector_ty, llvm_ptr_ty, llvm_i32_ty], + [IntrArgMemOnly, ImmArg<2>]>; // // Scalar to vector operations diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index b055012ad85574..289c5aafa5a4c6 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -33,7 +33,7 @@ def SVEPrefetchOperand : AsmOperandClass { let RenderMethod = "addPrefetchOperands"; } -def sve_prfop : Operand, ImmLeaf, TImmLeaf { let PrintMethod = "printPrefetchOp"; From 573e0776996425dd0567448d4a1f805a1f613e6d Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 3 Mar 2020 16:23:00 +0100 Subject: [PATCH 14/29] [lldb] Add detailed tests for the "disassemble" command While we have some tests for this command already, they are very vague. This is not surprising -- it's hard to make strict assertions about the assembly if your input is a c++ source file. This means that the tests can more-or-less only detect when the command breaks completely, and not when there is a subtle change in meaning due to e.g. a code refactor -- which is something that I am getting ready to do. This tests in this patch create binaries with well known data (via assembler and yaml2obj). This means that we are able to make precise assertions about the text that lldb is supposed to print. As some of the features of this command are only available with a real process, I use a minidump core file to create a sufficiently realistic process object. --- .../command-disassemble-process.lldbinit | 7 + .../Inputs/command-disassemble.lldbinit | 12 ++ .../Commands/command-disassemble-process.yaml | 120 ++++++++++++++++++ .../test/Shell/Commands/command-disassemble.s | 104 +++++++++++++++ lldb/test/Shell/Commands/lit.local.cfg | 1 + 5 files changed, 244 insertions(+) create mode 100644 lldb/test/Shell/Commands/Inputs/command-disassemble-process.lldbinit create mode 100644 lldb/test/Shell/Commands/Inputs/command-disassemble.lldbinit create mode 100644 lldb/test/Shell/Commands/command-disassemble-process.yaml create mode 100644 lldb/test/Shell/Commands/command-disassemble.s create mode 100644 lldb/test/Shell/Commands/lit.local.cfg diff --git a/lldb/test/Shell/Commands/Inputs/command-disassemble-process.lldbinit b/lldb/test/Shell/Commands/Inputs/command-disassemble-process.lldbinit new file mode 100644 index 00000000000000..a8f314a7759f64 --- /dev/null +++ b/lldb/test/Shell/Commands/Inputs/command-disassemble-process.lldbinit @@ -0,0 +1,7 @@ +disassemble +disassemble --line +disassemble --frame +disassemble --pc +disassemble --address 0x4004 +disassemble --address 0xdead +disassemble --pc --count 7 diff --git a/lldb/test/Shell/Commands/Inputs/command-disassemble.lldbinit b/lldb/test/Shell/Commands/Inputs/command-disassemble.lldbinit new file mode 100644 index 00000000000000..6a328ffc7c3293 --- /dev/null +++ b/lldb/test/Shell/Commands/Inputs/command-disassemble.lldbinit @@ -0,0 +1,12 @@ +disassemble +disassemble --line +disassemble --frame +disassemble --pc +disassemble --start-address 0x0 +disassemble --start-address 0x4 --end-address 0x8 +disassemble --start-address 0x8 --end-address 0x4 +disassemble --address 0x0 +disassemble --address 0xdead +disassemble --start-address 0x0 --count 7 +disassemble --start-address 0x0 --end-address 0x20 --count 7 +disassemble --address 0x0 --count 7 diff --git a/lldb/test/Shell/Commands/command-disassemble-process.yaml b/lldb/test/Shell/Commands/command-disassemble-process.yaml new file mode 100644 index 00000000000000..9f932dca02897d --- /dev/null +++ b/lldb/test/Shell/Commands/command-disassemble-process.yaml @@ -0,0 +1,120 @@ +# REQUIRES: x86 + +# RUN: yaml2obj --docnum=1 %s > %T/command-disassemble-process.exe +# RUN: yaml2obj --docnum=2 %s > %t + +# RUN: %lldb -c %t %T/command-disassemble-process.exe \ +# RUN: -o "settings set interpreter.stop-command-source-on-error false" \ +# RUN: -s %S/Inputs/command-disassemble-process.lldbinit -o exit 2>&1 \ +# RUN: | FileCheck %s + +# CHECK: (lldb) disassemble +# CHECK-NEXT: command-disassemble-process.exe`main: +# CHECK-NEXT: 0x4002 <+0>: addb %al, (%rcx) +# CHECK-NEXT: -> 0x4004 <+2>: addb %al, (%rdx) +# CHECK-NEXT: 0x4006 <+4>: addb %al, (%rbx) +# CHECK-NEXT: 0x4008 <+6>: addb %al, (%rsi) +# CHECK-NEXT: (lldb) disassemble --line +# CHECK-NEXT: command-disassemble-process.exe`main: +# CHECK-NEXT: -> 0x4004 <+2>: addb %al, (%rdx) +# CHECK-NEXT: 0x4006 <+4>: addb %al, (%rbx) +# CHECK-NEXT: 0x4008 <+6>: addb %al, (%rsi) +# CHECK-NEXT: 0x400a: addb %al, (%rdi) +# CHECK-NEXT: (lldb) disassemble --frame +# CHECK-NEXT: command-disassemble-process.exe`main: +# CHECK-NEXT: 0x4002 <+0>: addb %al, (%rcx) +# CHECK-NEXT: -> 0x4004 <+2>: addb %al, (%rdx) +# CHECK-NEXT: 0x4006 <+4>: addb %al, (%rbx) +# CHECK-NEXT: 0x4008 <+6>: addb %al, (%rsi) +# CHECK-NEXT: (lldb) disassemble --pc +# CHECK-NEXT: command-disassemble-process.exe`main: +# CHECK-NEXT: -> 0x4004 <+2>: addb %al, (%rdx) +# CHECK-NEXT: 0x4006 <+4>: addb %al, (%rbx) +# CHECK-NEXT: 0x4008 <+6>: addb %al, (%rsi) +# CHECK-NEXT: 0x400a: addb %al, (%rdi) +# CHECK-NEXT: (lldb) disassemble --address 0x4004 +# CHECK-NEXT: command-disassemble-process.exe`main: +# CHECK-NEXT: 0x4002 <+0>: addb %al, (%rcx) +# CHECK-NEXT: -> 0x4004 <+2>: addb %al, (%rdx) +# CHECK-NEXT: 0x4006 <+4>: addb %al, (%rbx) +# CHECK-NEXT: 0x4008 <+6>: addb %al, (%rsi) +# CHECK-NEXT: (lldb) disassemble --address 0xdead +# CHECK-NEXT: error: Could not find function bounds for address 0xdead +# CHECK-NEXT: (lldb) disassemble --pc --count 7 +# CHECK-NEXT: command-disassemble-process.exe`main: +# CHECK-NEXT: -> 0x4004 <+2>: addb %al, (%rdx) +# CHECK-NEXT: 0x4006 <+4>: addb %al, (%rbx) +# CHECK-NEXT: 0x4008 <+6>: addb %al, (%rsi) +# CHECK-NEXT: 0x400a: addb %al, (%rdi) +# CHECK-NEXT: 0x400c: addb %cl, (%rax) +# CHECK-NEXT: 0x400e: addb %cl, (%rcx) +# CHECK-NEXT: 0x4010: addb %cl, (%rdx) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000004000 + AddressAlign: 0x0000000000001000 + Content: 00000001000200030006000700080009000A000B000E000F00100011001200130016001700180019001A001B001E001F00200021002200230026002700280029002A002B002E002F + - Name: .note.gnu.build-id + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x0000000000005000 + AddressAlign: 0x0000000000001000 + Content: 040000000800000003000000474E5500DEADBEEFBAADF00D +Symbols: + - Name: main + Type: STT_FUNC + Section: .text + Value: 0x0000000000004002 + Size: 0x0000000000000008 +ProgramHeaders: + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + VAddr: 0x4000 + Align: 0x1000 + Sections: + - Section: .text + - Type: PT_LOAD + Flags: [ PF_W, PF_R ] + VAddr: 0x5000 + Align: 0x1000 + Sections: + - Section: .note.gnu.build-id +... + +--- !minidump +Streams: + - Type: ModuleList + Modules: + - Base of Image: 0x0000000000004000 + Size of Image: 0x00002000 + Module Name: 'command-disassemble-process.yaml' + CodeView Record: 4C457042DEADBEEFBAADF00D + + - Type: SystemInfo + Processor Arch: AMD64 + Platform ID: Linux + CPU: + Vendor ID: GenuineIntel + Version Info: 0x00000000 + Feature Info: 0x00000000 + - Type: ThreadList + Threads: + - Thread Id: 0x000074F3 + Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B001000000000006CAE000000006B7FC05A0000C81D415A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2BF9E5A6B7F0000000000000000000000000000000000008850C14BFD7F00009850C14BFD7F00000100000000000000B04AC14BFD7F0000000000000000000060812D01000000000800000000000000B065E05A6B7F00008004400000000000E050C14BFD7F00000000000000000000000000000000000004400000000000007F03FFFF0000FFFFFFFFFFFF000000000000000000000000801F00006B7F00000400000000000000B84CC14BFD7F0000304D405A6B7F0000C84DC14BFD7F0000C0AA405A6B7F00004F033D0000000000B84DC14BFD7F0000E84DC14BFD7F0000000000000000000000000000000000000070E05A6B7F000078629E5A6B7F0000C81D415A6B7F0000804F9E5A6B7F00000000000001000000E603000001000000E093115A6B7F0000804EC14BFD7F0000584EC14BFD7F000099ADC05A6B7F00000100000000000000AAAAD77D0000000002000000000000000800000000000000B065E05A6B7F0000E6B7C05A6B7F0000010000006B7F0000884DC14BFD7F0000106F7C5A6B7F0000984EC14BFD7F0000488B7C5A6B7F0000C4A71CB90000000001000000000000000800000000000000B065E05A6B7F000048B6C05A6B7F0000702AE25A6B7F0000D84DC14BFD7F000030489E5A6B7F0000E84EC14BFD7F0000E05E9E5A6B7F00000991F0460000000001000000000000000800000000000000B065E05A6B7F000048B6C05A6B7F00000100000000000000284EC14BFD7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Stack: + Start of Memory Range: 0x00007FFD4BC15080 + Content: 30044000000000000000000000000000 + - Type: MemoryList + Memory Ranges: + - Start of Memory Range: 0x00007FFD4BC15080 + Content: 30044000000000000000000000000000 +... diff --git a/lldb/test/Shell/Commands/command-disassemble.s b/lldb/test/Shell/Commands/command-disassemble.s new file mode 100644 index 00000000000000..51053c7b8af39e --- /dev/null +++ b/lldb/test/Shell/Commands/command-disassemble.s @@ -0,0 +1,104 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux %s -o %t +# RUN: %lldb %t -o "settings set interpreter.stop-command-source-on-error false" \ +# RUN: -s %S/Inputs/command-disassemble.lldbinit -o exit 2>&1 | FileCheck %s + +# CHECK: (lldb) disassemble +# CHECK-NEXT: error: Cannot disassemble around the current function without a selected frame. +# CHECK-EMPTY: +# CHECK-NEXT: (lldb) disassemble --line +# CHECK-NEXT: error: Cannot disassemble around the current line without a selected frame. +# CHECK-EMPTY: +# CHECK-NEXT: (lldb) disassemble --frame +# CHECK-NEXT: error: Cannot disassemble around the current function without a selected frame. +# CHECK-EMPTY: +# CHECK-NEXT: (lldb) disassemble --pc +# CHECK-NEXT: error: Cannot disassemble around the current PC without a selected frame. +# CHECK-EMPTY: +# CHECK-NEXT: (lldb) disassemble --start-address 0x0 +# CHECK-NEXT: command-disassemble.s.tmp`foo: +# CHECK-NEXT: command-disassemble.s.tmp[0x0] <+0>: int $0x10 +# CHECK-NEXT: command-disassemble.s.tmp[0x2] <+2>: int $0x11 +# CHECK-NEXT: command-disassemble.s.tmp[0x4] <+4>: int $0x12 +# CHECK-NEXT: command-disassemble.s.tmp[0x6] <+6>: int $0x13 +# CHECK-NEXT: command-disassemble.s.tmp[0x8] <+8>: int $0x14 +# CHECK-NEXT: command-disassemble.s.tmp[0xa] <+10>: int $0x15 +# CHECK-NEXT: command-disassemble.s.tmp[0xc] <+12>: int $0x16 +# CHECK-EMPTY: +# CHECK-NEXT: command-disassemble.s.tmp`bar: +# CHECK-NEXT: command-disassemble.s.tmp[0xe] <+0>: int $0x17 +# CHECK-NEXT: command-disassemble.s.tmp[0x10] <+2>: int $0x18 +# CHECK-NEXT: command-disassemble.s.tmp[0x12] <+4>: int $0x19 +# CHECK-NEXT: command-disassemble.s.tmp[0x14] <+6>: int $0x1a +# CHECK-NEXT: command-disassemble.s.tmp[0x16] <+8>: int $0x1b +# CHECK-NEXT: command-disassemble.s.tmp[0x18] <+10>: int $0x1c +# CHECK-NEXT: command-disassemble.s.tmp[0x1a] <+12>: int $0x1d +# CHECK-NEXT: command-disassemble.s.tmp[0x1c] <+14>: int $0x1e +# CHECK-NEXT: command-disassemble.s.tmp[0x1e] <+16>: int $0x1f +# CHECK-NEXT: (lldb) disassemble --start-address 0x4 --end-address 0x8 +# CHECK-NEXT: command-disassemble.s.tmp`foo: +# CHECK-NEXT: command-disassemble.s.tmp[0x4] <+4>: int $0x12 +# CHECK-NEXT: command-disassemble.s.tmp[0x6] <+6>: int $0x13 +# CHECK-NEXT: (lldb) disassemble --start-address 0x8 --end-address 0x4 +# CHECK-NEXT: error: End address before start address. +# CHECK-NEXT: (lldb) disassemble --address 0x0 +# CHECK-NEXT: command-disassemble.s.tmp`foo: +# CHECK-NEXT: command-disassemble.s.tmp[0x0] <+0>: int $0x10 +# CHECK-NEXT: command-disassemble.s.tmp[0x2] <+2>: int $0x11 +# CHECK-NEXT: command-disassemble.s.tmp[0x4] <+4>: int $0x12 +# CHECK-NEXT: command-disassemble.s.tmp[0x6] <+6>: int $0x13 +# CHECK-NEXT: command-disassemble.s.tmp[0x8] <+8>: int $0x14 +# CHECK-NEXT: command-disassemble.s.tmp[0xa] <+10>: int $0x15 +# CHECK-NEXT: command-disassemble.s.tmp[0xc] <+12>: int $0x16 +# CHECK-NEXT: (lldb) disassemble --address 0xdead +# CHECK-NEXT: error: invalid frame +# CHECK-NEXT: (lldb) disassemble --start-address 0x0 --count 7 +# CHECK-NEXT: command-disassemble.s.tmp`foo: +# CHECK-NEXT: command-disassemble.s.tmp[0x0] <+0>: int $0x10 +# CHECK-NEXT: command-disassemble.s.tmp[0x2] <+2>: int $0x11 +# CHECK-NEXT: command-disassemble.s.tmp[0x4] <+4>: int $0x12 +# CHECK-NEXT: command-disassemble.s.tmp[0x6] <+6>: int $0x13 +# CHECK-NEXT: command-disassemble.s.tmp[0x8] <+8>: int $0x14 +# CHECK-NEXT: command-disassemble.s.tmp[0xa] <+10>: int $0x15 +# CHECK-NEXT: command-disassemble.s.tmp[0xc] <+12>: int $0x16 +# CHECK-NEXT: (lldb) disassemble --start-address 0x0 --end-address 0x20 --count 7 +# CHECK-NEXT: error: invalid combination of options for the given command +# CHECK-NEXT: (lldb) disassemble --address 0x0 --count 7 +# CHECK-NEXT: error: invalid combination of options for the given command + + .text +foo: + int $0x10 + int $0x11 + int $0x12 + int $0x13 + int $0x14 + int $0x15 + int $0x16 +bar: + int $0x17 + int $0x18 + int $0x19 + int $0x1a + int $0x1b + int $0x1c + int $0x1d + int $0x1e + int $0x1f + int $0x20 + int $0x21 + int $0x22 + int $0x23 + int $0x24 + int $0x25 + int $0x26 + int $0x27 + int $0x28 + int $0x29 + int $0x2a + int $0x2b + int $0x2c + int $0x2d + int $0x2e + int $0x2f diff --git a/lldb/test/Shell/Commands/lit.local.cfg b/lldb/test/Shell/Commands/lit.local.cfg new file mode 100644 index 00000000000000..60e87e4624e521 --- /dev/null +++ b/lldb/test/Shell/Commands/lit.local.cfg @@ -0,0 +1 @@ +config.suffixes = ['.s', '.test', '.yaml'] From ae4d39c9e4ad391b817a798aa4b5fecfbe9c6cf4 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Thu, 20 Feb 2020 17:42:51 -0800 Subject: [PATCH 15/29] [SystemZ] Copy Access registers and CC with the correct register class. On SystemZ there are a set of "access registers" that can be copied in and out of 32-bit GPRs with special instructions. These instructions can only perform the copy using low 32-bit parts of the 64-bit GPRs. However, the default register class for 32-bit integers is GRX32, which also contains the high 32-bit part registers. In order to never end up with a case of such a COPY into a high reg, this patch adds a new simple pre-RA pass that selects such COPYs into target instructions. This pass also handles COPYs from CC (Condition Code register), and COPYs to CC can now also be emitted from a high reg in copyPhysReg(). Fixes: https://bugs.llvm.org/show_bug.cgi?id=44254 Review: Ulrich Weigand. Differential Revision: https://reviews.llvm.org/D75014 --- llvm/lib/Target/SystemZ/CMakeLists.txt | 1 + llvm/lib/Target/SystemZ/SystemZ.h | 1 + .../Target/SystemZ/SystemZCopyPhysRegs.cpp | 120 ++++++++++++++++++ llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp | 21 +-- .../Target/SystemZ/SystemZTargetMachine.cpp | 5 + llvm/test/CodeGen/SystemZ/tls-08.ll | 24 ++++ llvm/test/CodeGen/SystemZ/tls-09.ll | 37 ++++++ llvm/test/CodeGen/SystemZ/tls-10.mir | 24 ++++ llvm/test/CodeGen/SystemZ/tls-11.mir | 18 +++ 9 files changed, 234 insertions(+), 17 deletions(-) create mode 100644 llvm/lib/Target/SystemZ/SystemZCopyPhysRegs.cpp create mode 100644 llvm/test/CodeGen/SystemZ/tls-08.ll create mode 100644 llvm/test/CodeGen/SystemZ/tls-09.ll create mode 100644 llvm/test/CodeGen/SystemZ/tls-10.mir create mode 100644 llvm/test/CodeGen/SystemZ/tls-11.mir diff --git a/llvm/lib/Target/SystemZ/CMakeLists.txt b/llvm/lib/Target/SystemZ/CMakeLists.txt index 03e5e31831f651..6922b1ca2c36a1 100644 --- a/llvm/lib/Target/SystemZ/CMakeLists.txt +++ b/llvm/lib/Target/SystemZ/CMakeLists.txt @@ -16,6 +16,7 @@ add_llvm_target(SystemZCodeGen SystemZAsmPrinter.cpp SystemZCallingConv.cpp SystemZConstantPoolValue.cpp + SystemZCopyPhysRegs.cpp SystemZElimCompare.cpp SystemZFrameLowering.cpp SystemZHazardRecognizer.cpp diff --git a/llvm/lib/Target/SystemZ/SystemZ.h b/llvm/lib/Target/SystemZ/SystemZ.h index 0808160f627cb7..bedbd061ea5c11 100644 --- a/llvm/lib/Target/SystemZ/SystemZ.h +++ b/llvm/lib/Target/SystemZ/SystemZ.h @@ -193,6 +193,7 @@ FunctionPass *createSystemZElimComparePass(SystemZTargetMachine &TM); FunctionPass *createSystemZShortenInstPass(SystemZTargetMachine &TM); FunctionPass *createSystemZLongBranchPass(SystemZTargetMachine &TM); FunctionPass *createSystemZLDCleanupPass(SystemZTargetMachine &TM); +FunctionPass *createSystemZCopyPhysRegsPass(SystemZTargetMachine &TM); FunctionPass *createSystemZPostRewritePass(SystemZTargetMachine &TM); FunctionPass *createSystemZTDCPass(); } // end namespace llvm diff --git a/llvm/lib/Target/SystemZ/SystemZCopyPhysRegs.cpp b/llvm/lib/Target/SystemZ/SystemZCopyPhysRegs.cpp new file mode 100644 index 00000000000000..7d21d29d270e34 --- /dev/null +++ b/llvm/lib/Target/SystemZ/SystemZCopyPhysRegs.cpp @@ -0,0 +1,120 @@ +//===---------- SystemZPhysRegCopy.cpp - Handle phys reg copies -----------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This pass makes sure that a COPY of a physical register will be +// implementable after register allocation in copyPhysReg() (this could be +// done in EmitInstrWithCustomInserter() instead if COPY instructions would +// be passed to it). +// +//===----------------------------------------------------------------------===// + +#include "SystemZMachineFunctionInfo.h" +#include "SystemZTargetMachine.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/Target/TargetMachine.h" + +using namespace llvm; + +#define SYSTEMZ_COPYPHYSREGS_NAME "SystemZ Copy Physregs" + +namespace llvm { + void initializeSystemZCopyPhysRegsPass(PassRegistry&); +} + +namespace { + +class SystemZCopyPhysRegs : public MachineFunctionPass { +public: + static char ID; + SystemZCopyPhysRegs() + : MachineFunctionPass(ID), TII(nullptr), MRI(nullptr) { + initializeSystemZCopyPhysRegsPass(*PassRegistry::getPassRegistry()); + } + + StringRef getPassName() const override { return SYSTEMZ_COPYPHYSREGS_NAME; } + + bool runOnMachineFunction(MachineFunction &MF) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; + +private: + + bool visitMBB(MachineBasicBlock &MBB); + + const SystemZInstrInfo *TII; + MachineRegisterInfo *MRI; +}; + +char SystemZCopyPhysRegs::ID = 0; + +} // end anonymous namespace + +INITIALIZE_PASS(SystemZCopyPhysRegs, "systemz-copy-physregs", + SYSTEMZ_COPYPHYSREGS_NAME, false, false) + +FunctionPass *llvm::createSystemZCopyPhysRegsPass(SystemZTargetMachine &TM) { + return new SystemZCopyPhysRegs(); +} + +void SystemZCopyPhysRegs::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + MachineFunctionPass::getAnalysisUsage(AU); +} + +bool SystemZCopyPhysRegs::visitMBB(MachineBasicBlock &MBB) { + bool Modified = false; + + // Certain special registers can only be copied from a subset of the + // default register class of the type. It is therefore necessary to create + // the target copy instructions before regalloc instead of in copyPhysReg(). + for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); + MBBI != E; ) { + MachineInstr *MI = &*MBBI++; + if (!MI->isCopy()) + continue; + + DebugLoc DL = MI->getDebugLoc(); + Register SrcReg = MI->getOperand(1).getReg(); + Register DstReg = MI->getOperand(0).getReg(); + if (DstReg.isVirtual() && + (SrcReg == SystemZ::CC || SystemZ::AR32BitRegClass.contains(SrcReg))) { + Register Tmp = MRI->createVirtualRegister(&SystemZ::GR32BitRegClass); + if (SrcReg == SystemZ::CC) + BuildMI(MBB, MI, DL, TII->get(SystemZ::IPM), Tmp); + else + BuildMI(MBB, MI, DL, TII->get(SystemZ::EAR), Tmp).addReg(SrcReg); + MI->getOperand(1).setReg(Tmp); + Modified = true; + } + else if (SrcReg.isVirtual() && + SystemZ::AR32BitRegClass.contains(DstReg)) { + Register Tmp = MRI->createVirtualRegister(&SystemZ::GR32BitRegClass); + MI->getOperand(0).setReg(Tmp); + BuildMI(MBB, MBBI, DL, TII->get(SystemZ::SAR), DstReg).addReg(Tmp); + Modified = true; + } + } + + return Modified; +} + +bool SystemZCopyPhysRegs::runOnMachineFunction(MachineFunction &F) { + TII = static_cast(F.getSubtarget().getInstrInfo()); + MRI = &F.getRegInfo(); + + bool Modified = false; + for (auto &MBB : F) + Modified |= visitMBB(MBB); + + return Modified; +} + diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index 8b30196474df6b..7161afe6f5e50f 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -820,18 +820,11 @@ void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB, return; } - // Move CC value from/to a GR32. - if (SrcReg == SystemZ::CC) { - auto MIB = BuildMI(MBB, MBBI, DL, get(SystemZ::IPM), DestReg); - if (KillSrc) { - const MachineFunction *MF = MBB.getParent(); - const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); - MIB->addRegisterKilled(SrcReg, TRI); - } - return; - } + // Move CC value from a GR32. if (DestReg == SystemZ::CC) { - BuildMI(MBB, MBBI, DL, get(SystemZ::TMLH)) + unsigned Opcode = + SystemZ::GR32BitRegClass.contains(SrcReg) ? SystemZ::TMLH : SystemZ::TMHH; + BuildMI(MBB, MBBI, DL, get(Opcode)) .addReg(SrcReg, getKillRegState(KillSrc)) .addImm(3 << (SystemZ::IPM_CC - 16)); return; @@ -856,12 +849,6 @@ void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB, Opcode = SystemZ::VLR; else if (SystemZ::AR32BitRegClass.contains(DestReg, SrcReg)) Opcode = SystemZ::CPYA; - else if (SystemZ::AR32BitRegClass.contains(DestReg) && - SystemZ::GR32BitRegClass.contains(SrcReg)) - Opcode = SystemZ::SAR; - else if (SystemZ::GR32BitRegClass.contains(DestReg) && - SystemZ::AR32BitRegClass.contains(SrcReg)) - Opcode = SystemZ::EAR; else llvm_unreachable("Impossible reg-to-reg copy"); diff --git a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp index 9fc56167665682..3f467b200852d2 100644 --- a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp +++ b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp @@ -222,6 +222,7 @@ class SystemZPassConfig : public TargetPassConfig { void addIRPasses() override; bool addInstSelector() override; bool addILPOpts() override; + void addPreRegAlloc() override; void addPostRewrite() override; void addPostRegAlloc() override; void addPreSched2() override; @@ -253,6 +254,10 @@ bool SystemZPassConfig::addILPOpts() { return true; } +void SystemZPassConfig::addPreRegAlloc() { + addPass(createSystemZCopyPhysRegsPass(getSystemZTargetMachine())); +} + void SystemZPassConfig::addPostRewrite() { addPass(createSystemZPostRewritePass(getSystemZTargetMachine())); } diff --git a/llvm/test/CodeGen/SystemZ/tls-08.ll b/llvm/test/CodeGen/SystemZ/tls-08.ll new file mode 100644 index 00000000000000..57dd552740f20a --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/tls-08.ll @@ -0,0 +1,24 @@ +; RUN: llc < %s -mcpu=z196 -mtriple=s390x-linux-gnu -O0 \ +; RUN: -stop-before=regallocfast 2>&1 | FileCheck %s +; RUN: llc < %s -mcpu=z196 -mtriple=s390x-linux-gnu -O3 \ +; RUN: -stop-before=livevars 2>&1 | FileCheck %s +; +; Test that copies to/from access registers are handled before regalloc with +; GR32 regs. + +@x = dso_local thread_local global i32 0, align 4 +define weak_odr hidden i32* @fun0() { +; CHECK: name: fun0 +; CHECK: {{%[0-9]+}}:gr32bit = EAR $a0 +; CHECK: {{%[0-9]+}}:gr32bit = EAR $a1 + ret i32* @x +} + +define i32 @fun1() { +; CHECK: name: fun1 +; CHECK: [[VREG0:%[0-9]+]]:gr32bit = COPY %0 +; CHECK-NEXT: $a1 = SAR [[VREG0]] +; CHECK: {{%[0-9]+}}:gr32bit = EAR $a0 + %val = call i32 asm "blah", "={a0}, {a1}" (i32 0) + ret i32 %val +} diff --git a/llvm/test/CodeGen/SystemZ/tls-09.ll b/llvm/test/CodeGen/SystemZ/tls-09.ll new file mode 100644 index 00000000000000..4512206c275c9f --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/tls-09.ll @@ -0,0 +1,37 @@ +; RUN: llc < %s -mcpu=z196 -mtriple=s390x-linux-gnu -O0 +; +; Test that a0 and a1 are copied successfully into GR32 registers. + +@x = dso_local thread_local global i32 0, align 4 +define i32 @fun0(i32 signext, i32 signext, i32 signext, i32 signext, i32 signext, i32 signext, i32 signext) { + %8 = alloca i32, align 4 + %9 = alloca i32, align 4 + %10 = alloca i32, align 4 + %11 = alloca i32, align 4 + %12 = alloca i32, align 4 + %13 = alloca i32, align 4 + %14 = alloca i32, align 4 + %15 = load i32, i32* @x, align 4 + store i32 %0, i32* %8, align 4 + store i32 %1, i32* %9, align 4 + store i32 %2, i32* %10, align 4 + store i32 %3, i32* %11, align 4 + store i32 %4, i32* %12, align 4 + store i32 %5, i32* %13, align 4 + store i32 %6, i32* %14, align 4 + %16 = load i32, i32* %8, align 4 + %17 = add nsw i32 %15, %16 + %18 = load i32, i32* %9, align 4 + %19 = add nsw i32 %17, %18 + %20 = load i32, i32* %10, align 4 + %21 = add nsw i32 %19, %20 + %22 = load i32, i32* %11, align 4 + %23 = add nsw i32 %21, %22 + %24 = load i32, i32* %12, align 4 + %25 = add nsw i32 %23, %24 + %26 = load i32, i32* %13, align 4 + %27 = add nsw i32 %25, %26 + %28 = load i32, i32* %14, align 4 + %29 = add nsw i32 %27, %28 + ret i32 %29 +} diff --git a/llvm/test/CodeGen/SystemZ/tls-10.mir b/llvm/test/CodeGen/SystemZ/tls-10.mir new file mode 100644 index 00000000000000..33094aff058de3 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/tls-10.mir @@ -0,0 +1,24 @@ +# RUN: llc -mtriple=s390x-linux-gnu -mcpu=z196 -O0 -start-after=finalize-isel \ +# RUN: -stop-before=regallocfast -o - %s | FileCheck %s +# RUN: llc -mtriple=s390x-linux-gnu -mcpu=z196 -O3 -start-after=finalize-isel \ +# RUN: -stop-before=livevars -o - %s | FileCheck %s +# +# Test that a COPY from CC gets implemented with an IPM to a GR32 reg. + +--- +name: fun0 +tracksRegLiveness: true +registers: + - { id: 0, class: grx32bit } +body: | + bb.0: + liveins: $cc + ; CHECK-LABEL: name: fun0 + ; CHECK: %1:gr32bit = IPM implicit $cc + ; CHECK-NEXT: %0:grx32bit = COPY %1 + ; CHECK-NEXT: $r2l = COPY %0 + ; CHECK-NEXT: Return implicit $r2l + %0:grx32bit = COPY $cc + $r2l = COPY %0 + Return implicit $r2l +... diff --git a/llvm/test/CodeGen/SystemZ/tls-11.mir b/llvm/test/CodeGen/SystemZ/tls-11.mir new file mode 100644 index 00000000000000..623a8ab519f733 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/tls-11.mir @@ -0,0 +1,18 @@ +# RUN: llc -mtriple=s390x-linux-gnu -mcpu=z196 -O0 -start-before=prologepilog \ +# RUN: -o - %s | FileCheck %s +# +# Test that a COPY to CC gets implemented with a tmlh or tmhh depending on +# the source register. + +--- +name: fun0 +tracksRegLiveness: true +body: | + bb.0: + liveins: $r3l, $r4h + ; CHECK-LABEL: fun0 + ; CHECK: tmlh %r3, 12288 + ; CHECK: tmhh %r4, 12288 + $cc = COPY $r3l + $cc = COPY $r4h +... From 680a75e1e45b36ffeea95b5d0c0744d7f7e83be1 Mon Sep 17 00:00:00 2001 From: LLVM GN Syncbot Date: Tue, 3 Mar 2020 15:41:46 +0000 Subject: [PATCH 16/29] [gn build] Port ae4d39c9e4a --- llvm/utils/gn/secondary/llvm/lib/Target/SystemZ/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/SystemZ/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/SystemZ/BUILD.gn index 51f65f954c9089..b6d2345d79a6bf 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/SystemZ/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/SystemZ/BUILD.gn @@ -34,6 +34,7 @@ static_library("LLVMSystemZCodeGen") { "SystemZAsmPrinter.cpp", "SystemZCallingConv.cpp", "SystemZConstantPoolValue.cpp", + "SystemZCopyPhysRegs.cpp", "SystemZElimCompare.cpp", "SystemZFrameLowering.cpp", "SystemZHazardRecognizer.cpp", From efa2d533773163fafa182bd66003cf4527d46a0f Mon Sep 17 00:00:00 2001 From: Alex Zinenko Date: Mon, 2 Mar 2020 15:18:41 +0100 Subject: [PATCH 17/29] [mlir] error out on unsupported attribute kinds in LLVM global translation Some attribute kinds are not supported as "value" attributes of `llvm.mlir.constant` when translating to LLVM IR. We were correctly reporting an error, but continuing the translation using an "undef" value instead, leading to a surprising mix of error messages and output IR. Abort the translation after the error is reported. Differential Revision: https://reviews.llvm.org/D75450 --- .../mlir/Target/LLVMIR/ModuleTranslation.h | 5 +++-- mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 15 ++++++++------- mlir/test/Target/llvmir-invalid.mlir | 5 +++++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h index 5eda0f6bb30c8b..84ee37a8cc54eb 100644 --- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h @@ -56,7 +56,8 @@ class ModuleTranslation { return nullptr; T translator(m, std::move(llvmModule)); - translator.convertGlobals(); + if (failed(translator.convertGlobals())) + return nullptr; if (failed(translator.convertFunctions())) return nullptr; @@ -87,7 +88,7 @@ class ModuleTranslation { static LogicalResult checkSupportedModuleOps(Operation *m); LogicalResult convertFunctions(); - void convertGlobals(); + LogicalResult convertGlobals(); LogicalResult convertOneFunction(LLVMFuncOp func); void connectPHINodes(LLVMFuncOp func); LogicalResult convertBlock(Block &bb, bool ignoreArguments); diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index cbcc2e64463654..84985fc68651a0 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -421,7 +421,7 @@ LogicalResult ModuleTranslation::convertBlock(Block &bb, bool ignoreArguments) { /// Create named global variables that correspond to llvm.mlir.global /// definitions. -void ModuleTranslation::convertGlobals() { +LogicalResult ModuleTranslation::convertGlobals() { for (auto op : getModuleBody(mlirModule).getOps()) { llvm::Type *type = op.getType().getUnderlyingType(); llvm::Constant *cst = llvm::UndefValue::get(type); @@ -432,17 +432,16 @@ void ModuleTranslation::convertGlobals() { cst = llvm::ConstantDataArray::getString( llvmModule->getContext(), strAttr.getValue(), /*AddNull=*/false); type = cst->getType(); - } else { - cst = getLLVMConstant(type, op.getValueOrNull(), op.getLoc()); + } else if (!(cst = getLLVMConstant(type, op.getValueOrNull(), + op.getLoc()))) { + return failure(); } } else if (Block *initializer = op.getInitializerBlock()) { llvm::IRBuilder<> builder(llvmModule->getContext()); for (auto &op : initializer->without_terminator()) { if (failed(convertOperation(op, builder)) || - !isa(valueMapping.lookup(op.getResult(0)))) { - emitError(op.getLoc(), "unemittable constant value"); - return; - } + !isa(valueMapping.lookup(op.getResult(0)))) + return emitError(op.getLoc(), "unemittable constant value"); } ReturnOp ret = cast(initializer->getTerminator()); cst = cast(valueMapping.lookup(ret.getOperand(0))); @@ -460,6 +459,8 @@ void ModuleTranslation::convertGlobals() { globalsMapping.try_emplace(op, var); } + + return success(); } /// Get the SSA value passed to the current block from the terminator operation diff --git a/mlir/test/Target/llvmir-invalid.mlir b/mlir/test/Target/llvmir-invalid.mlir index f236982d086db5..dce4189f733fe0 100644 --- a/mlir/test/Target/llvmir-invalid.mlir +++ b/mlir/test/Target/llvmir-invalid.mlir @@ -12,3 +12,8 @@ llvm.func @no_nested_struct() -> !llvm<"[2 x [2 x [2 x {i32}]]]"> { %0 = llvm.mlir.constant(dense<[[[1, 2], [3, 4]], [[42, 43], [44, 45]]]> : tensor<2x2x2xi32>) : !llvm<"[2 x [2 x [2 x {i32}]]]"> llvm.return %0 : !llvm<"[2 x [2 x [2 x {i32}]]]"> } + +// ----- + +// expected-error @+1 {{unsupported constant value}} +llvm.mlir.global internal constant @test([2.5, 7.4]) : !llvm<"[2 x double]"> From d7fbfbb171492fd1dfa1a0d131faf84facb6f356 Mon Sep 17 00:00:00 2001 From: Alex Zinenko Date: Tue, 3 Mar 2020 10:58:33 +0100 Subject: [PATCH 18/29] [mlir] ExecutionEngine: fix assertion on the error path MLIR ExecutionEngine and derived tools (e.g., mlir-cpu-runner) would trigger an assertion inside ORC JIT while ExecutionEngine is being destructed after a failed linking due to a missing function definition. The reason for this is the JIT lookup that may return an Error referring to strings stored internally by the JIT. If the Error outlives the ExecutionEngine, it would want have a dangling reference, which is currently caught by an assertion inside JIT thanks to hand-rolled reference counting. Rewrap the error message into a string before returning. Differential Revision: https://reviews.llvm.org/D75508 --- mlir/lib/ExecutionEngine/ExecutionEngine.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp index eda4cd187adbe6..5399693802ed8d 100644 --- a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp @@ -294,8 +294,21 @@ Expected> ExecutionEngine::create( Expected ExecutionEngine::lookup(StringRef name) const { auto expectedSymbol = jit->lookup(makePackedFunctionName(name)); - if (!expectedSymbol) - return expectedSymbol.takeError(); + + // JIT lookup may return an Error referring to strings stored internally by + // the JIT. If the Error outlives the ExecutionEngine, it would want have a + // dangling reference, which is currently caught by an assertion inside JIT + // thanks to hand-rolled reference counting. Rewrap the error message into a + // string before returning. Alternatively, ORC JIT should consider copying + // the string into the error message. + if (!expectedSymbol) { + std::string errorMessage; + llvm::raw_string_ostream os(errorMessage); + llvm::handleAllErrors(expectedSymbol.takeError(), + [&os](llvm::ErrorInfoBase &ei) { ei.log(os); }); + return make_string_error(os.str()); + } + auto rawFPtr = expectedSymbol->getAddress(); auto fptr = reinterpret_cast(rawFPtr); if (!fptr) From 65dd63fb33f063d3b3595edbc5cc20ed8ae8c6dc Mon Sep 17 00:00:00 2001 From: Chris Bowler Date: Tue, 3 Mar 2020 10:38:29 -0500 Subject: [PATCH 19/29] [PowerPC][NFC] Lexically order expected output for AIX stack arg test. --- llvm/test/CodeGen/PowerPC/aix-cc-abi.ll | 130 ++++++++++++------------ 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll index 83fd8359097a2f..fa2e2b161ff292 100644 --- a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll +++ b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll @@ -971,30 +971,30 @@ declare void @test_stackarg_int(i32, i32, i32, i32, i32, i32, i32, i32, i8 zeroe ; CHECK-LABEL: name: call_test_stackarg_int{{.*}} ; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. +; 32BIT-DAG: ADJCALLSTACKDOWN 80, 0, implicit-def dead $r1, implicit $r1 +; 32BIT-DAG: $r3 = LI 1 +; 32BIT-DAG: $r4 = LI 2 +; 32BIT-DAG: $r5 = LI 3 +; 32BIT-DAG: $r6 = LI 4 +; 32BIT-DAG: $r7 = LI 5 +; 32BIT-DAG: $r8 = LI 6 +; 32BIT-DAG: $r9 = LI 7 +; 32BIT-DAG: $r10 = LI 8 ; 32BIT-DAG: renamable $r[[REGCADDR:[0-9]+]] = LWZtoc @c, $r2 :: (load 4 from got) ; 32BIT-DAG: renamable $r[[REGC:[0-9]+]] = LBZ 0, killed renamable $r[[REGCADDR]] :: (dereferenceable load 1 from @c) +; 32BIT-DAG: STW killed renamable $r[[REGC]], 56, $r1 :: (store 4) ; 32BIT-DAG: renamable $r[[REGSIADDR:[0-9]+]] = LWZtoc @si, $r2 :: (load 4 from got) ; 32BIT-DAG: renamable $r[[REGSI:[0-9]+]] = LHA 0, killed renamable $r[[REGSIADDR]] :: (dereferenceable load 2 from @si) +; 32BIT-DAG: STW killed renamable $r[[REGSI]], 60, $r1 :: (store 4) ; 32BIT-DAG: renamable $r[[REGIADDR:[0-9]+]] = LWZtoc @i, $r2 :: (load 4 from got) ; 32BIT-DAG: renamable $r[[REGI:[0-9]+]] = LWZ 0, killed renamable $r[[REGIADDR]] :: (dereferenceable load 4 from @i) +; 32BIT-DAG: STW killed renamable $r[[REGI]], 64, $r1 :: (store 4) ; 32BIT-DAG: renamable $r[[REGLLIADDR:[0-9]+]] = LWZtoc @lli, $r2 :: (load 4 from got) ; 32BIT-DAG: renamable $r[[REGLLI1:[0-9]+]] = LWZ 0, renamable $r[[REGLLIADDR]] :: (dereferenceable load 4 from @lli, align 8) -; 32BIT-DAG: renamable $r[[REGLLI2:[0-9]+]] = LWZ 4, killed renamable $r[[REGLLIADDR]] :: (dereferenceable load 4 from @lli + 4) -; 32BIT-NEXT: ADJCALLSTACKDOWN 80, 0, implicit-def dead $r1, implicit $r1 -; 32BIT-DAG: STW killed renamable $r[[REGC]], 56, $r1 :: (store 4) -; 32BIT-DAG: STW killed renamable $r[[REGSI]], 60, $r1 :: (store 4) -; 32BIT-DAG: STW killed renamable $r[[REGI]], 64, $r1 :: (store 4) ; 32BIT-DAG: STW killed renamable $r[[REGLLI1]], 68, $r1 :: (store 4) +; 32BIT-DAG: renamable $r[[REGLLI2:[0-9]+]] = LWZ 4, killed renamable $r[[REGLLIADDR]] :: (dereferenceable load 4 from @lli + 4) ; 32BIT-DAG: STW killed renamable $r[[REGLLI2]], 72, $r1 :: (store 4) ; 32BIT-DAG: STW renamable $r[[REGI]], 76, $r1 :: (store 4) -; 32BIT-DAG: $r3 = LI 1 -; 32BIT-DAG: $r4 = LI 2 -; 32BIT-DAG: $r5 = LI 3 -; 32BIT-DAG: $r6 = LI 4 -; 32BIT-DAG: $r7 = LI 5 -; 32BIT-DAG: $r8 = LI 6 -; 32BIT-DAG: $r9 = LI 7 -; 32BIT-DAG: $r10 = LI 8 ; 32BIT-NEXT: BL_NOP , csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit $r5, implicit $r6, implicit $r7, implicit $r8, implicit $r9, implicit $r10, implicit $r2, implicit-def $r1 ; 32BIT-NEXT: ADJCALLSTACKUP 80, 0, implicit-def dead $r1, implicit $r1 @@ -1013,13 +1013,7 @@ declare void @test_stackarg_float(i32, i32, i32, i32, i32, i32, i32, i32, float, ; CHECK-LABEL: name: call_test_stackarg_float ; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. -; 32BIT-DAG: renamable $r[[REGF:[0-9]+]] = LWZtoc @f, $r2 :: (load 4 from got) -; 32BIT-DAG: renamable $f1 = LFS 0, killed renamable $r[[REGF]] :: (dereferenceable load 4 from @f) -; 32BIT-DAG: renamable $r[[REGD:[0-9]+]] = LWZtoc @d, $r2 :: (load 4 from got) -; 32BIT-DAG: renamable $f2 = LFD 0, killed renamable $r[[REGD]] :: (dereferenceable load 8 from @d) -; 32BIT-NEXT: ADJCALLSTACKDOWN 68, 0, implicit-def dead $r1, implicit $r1 -; 32BIT-DAG: STFS renamable $f1, 56, $r1 :: (store 4) -; 32BIT-DAG: STFD renamable $f2, 60, $r1 :: (store 8) +; 32BIT-DAG: ADJCALLSTACKDOWN 68, 0, implicit-def dead $r1, implicit $r1 ; 32BIT-DAG: $r3 = LI 1 ; 32BIT-DAG: $r4 = LI 2 ; 32BIT-DAG: $r5 = LI 3 @@ -1028,6 +1022,12 @@ declare void @test_stackarg_float(i32, i32, i32, i32, i32, i32, i32, i32, float, ; 32BIT-DAG: $r8 = LI 6 ; 32BIT-DAG: $r9 = LI 7 ; 32BIT-DAG: $r10 = LI 8 +; 32BIT-DAG: renamable $r[[REGF:[0-9]+]] = LWZtoc @f, $r2 :: (load 4 from got) +; 32BIT-DAG: renamable $f1 = LFS 0, killed renamable $r[[REGF]] :: (dereferenceable load 4 from @f) +; 32BIT-DAG: renamable $r[[REGD:[0-9]+]] = LWZtoc @d, $r2 :: (load 4 from got) +; 32BIT-DAG: renamable $f2 = LFD 0, killed renamable $r[[REGD]] :: (dereferenceable load 8 from @d) +; 32BIT-DAG: STFS renamable $f1, 56, $r1 :: (store 4) +; 32BIT-DAG: STFD renamable $f2, 60, $r1 :: (store 8) ; 32BIT-NEXT: BL_NOP , csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit killed $r5, implicit killed $r6, implicit killed $r7, implicit killed $r8, implicit killed $r9, implicit killed $r10, implicit $f1, implicit $f2, implicit $r2, implicit-def $r1 ; 32BIT-NEXT: ADJCALLSTACKUP 68, 0, implicit-def dead $r1, implicit $r1 @@ -1035,12 +1035,6 @@ declare void @test_stackarg_float(i32, i32, i32, i32, i32, i32, i32, i32, float, ; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. ; ASM32PWR4: stwu 1, -80(1) -; ASM32PWR4-DAG: lwz [[REGF:[0-9]+]], LC8(2) -; ASM32PWR4-DAG: lfs 1, 0([[REGF]]) -; ASM32PWR4-DAG: lwz [[REGD:[0-9]+]], LC9(2) -; ASM32PWR4-DAG: lfd 2, 0([[REGD:[0-9]+]]) -; ASM32PWR4-DAG: stfs 1, 56(1) -; ASM32PWR4-DAG: stfd 2, 60(1) ; ASM32PWR4-DAG: li 3, 1 ; ASM32PWR4-DAG: li 4, 2 ; ASM32PWR4-DAG: li 5, 3 @@ -1049,18 +1043,18 @@ declare void @test_stackarg_float(i32, i32, i32, i32, i32, i32, i32, i32, float, ; ASM32PWR4-DAG: li 8, 6 ; ASM32PWR4-DAG: li 9, 7 ; ASM32PWR4-DAG: li 10, 8 +; ASM32PWR4-DAG: lwz [[REGF:[0-9]+]], LC8(2) +; ASM32PWR4-DAG: lfs 1, 0([[REGF]]) +; ASM32PWR4-DAG: lwz [[REGD:[0-9]+]], LC9(2) +; ASM32PWR4-DAG: lfd 2, 0([[REGD:[0-9]+]]) +; ASM32PWR4-DAG: stfs 1, 56(1) +; ASM32PWR4-DAG: stfd 2, 60(1) ; ASM32PWR4-NEXT: bl .test_stackarg_float ; ASM32PWR4-NEXT: nop ; ASM32PWR4-NEXT: addi 1, 1, 80 ; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. -; 64BIT-DAG: renamable $x[[REGF:[0-9]+]] = LDtoc @f, $x2 :: (load 8 from got) -; 64BIT-DAG: renamable $f1 = LFS 0, killed renamable $x[[REGF]] :: (dereferenceable load 4 from @f) -; 64BIT-DAG: renamable $x[[REGD:[0-9]+]] = LDtoc @d, $x2 :: (load 8 from got) -; 64BIT-DAG: renamable $f2 = LFD 0, killed renamable $x[[REGD]] :: (dereferenceable load 8 from @d) -; 64BIT-NEXT: ADJCALLSTACKDOWN 128, 0, implicit-def dead $r1, implicit $r1 -; 64BIT-DAG: STFS renamable $f1, 112, $x1 :: (store 4) -; 64BIT-DAG: STFD renamable $f2, 120, $x1 :: (store 8) +; 64BIT-DAG: ADJCALLSTACKDOWN 128, 0, implicit-def dead $r1, implicit $r1 ; 64BIT-DAG: $x3 = LI8 1 ; 64BIT-DAG: $x4 = LI8 2 ; 64BIT-DAG: $x5 = LI8 3 @@ -1069,17 +1063,17 @@ declare void @test_stackarg_float(i32, i32, i32, i32, i32, i32, i32, i32, float, ; 64BIT-DAG: $x8 = LI8 6 ; 64BIT-DAG: $x9 = LI8 7 ; 64BIT-DAG: $x10 = LI8 8 +; 64BIT-DAG: renamable $x[[REGF:[0-9]+]] = LDtoc @f, $x2 :: (load 8 from got) +; 64BIT-DAG: renamable $f1 = LFS 0, killed renamable $x[[REGF]] :: (dereferenceable load 4 from @f) +; 64BIT-DAG: renamable $x[[REGD:[0-9]+]] = LDtoc @d, $x2 :: (load 8 from got) +; 64BIT-DAG: renamable $f2 = LFD 0, killed renamable $x[[REGD]] :: (dereferenceable load 8 from @d) +; 64BIT-DAG: STFS renamable $f1, 112, $x1 :: (store 4) +; 64BIT-DAG: STFD renamable $f2, 120, $x1 :: (store 8) ; 64BIT-NEXT: BL8_NOP , csr_aix64, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit $x4, implicit killed $x5, implicit killed $x6, implicit killed $x7, implicit killed $x8, implicit killed $x9, implicit killed $x10, implicit $f1, implicit $f2, implicit $x2, implicit-def $r1 ; 64BIT-NEXT: ADJCALLSTACKUP 128, 0, implicit-def dead $r1, implicit $r1 ; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. ; ASM64PWR4: stdu 1, -128(1) -; ASM64PWR4-DAG: ld [[REGF:[0-9]+]], LC7(2) -; ASM64PWR4-DAG: lfs 1, 0([[REGF]]) -; ASM64PWR4-DAG: ld [[REGD:[0-9]+]], LC8(2) -; ASM64PWR4-DAG: lfd 2, 0([[REGD]]) -; ASM64PWR4-DAG: stfs 1, 112(1) -; ASM64PWR4-DAG: stfd 2, 120(1) ; ASM64PWR4-DAG: li 3, 1 ; ASM64PWR4-DAG: li 4, 2 ; ASM64PWR4-DAG: li 5, 3 @@ -1088,6 +1082,12 @@ declare void @test_stackarg_float(i32, i32, i32, i32, i32, i32, i32, i32, float, ; ASM64PWR4-DAG: li 8, 6 ; ASM64PWR4-DAG: li 9, 7 ; ASM64PWR4-DAG: li 10, 8 +; ASM64PWR4-DAG: ld [[REGF:[0-9]+]], LC7(2) +; ASM64PWR4-DAG: lfs 1, 0([[REGF]]) +; ASM64PWR4-DAG: ld [[REGD:[0-9]+]], LC8(2) +; ASM64PWR4-DAG: lfd 2, 0([[REGD]]) +; ASM64PWR4-DAG: stfs 1, 112(1) +; ASM64PWR4-DAG: stfd 2, 120(1) ; ASM64PWR4-NEXT: bl .test_stackarg_float ; ASM64PWR4-NEXT: nop ; ASM64PWR4-NEXT: addi 1, 1, 128 @@ -1104,8 +1104,6 @@ declare void @test_stackarg_float2(i32, i32, i32, i32, i32, i32, ...) ; CHECK-LABEL: name: call_test_stackarg_float2{{.*}} ; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. -; 32BIT-DAG: renamable $r[[REG:[0-9]+]] = LWZtoc @d, $r2 :: (load 4 from got) -; 32BIT-DAG: renamable $f1 = LFD 0, killed renamable $r[[REG]] :: (dereferenceable load 8 from @d) ; 32BIT-DAG: ADJCALLSTACKDOWN 56, 0, implicit-def dead $r1, implicit $r1 ; 32BIT-DAG: $r3 = LI 1 ; 32BIT-DAG: $r4 = LI 2 @@ -1113,6 +1111,8 @@ declare void @test_stackarg_float2(i32, i32, i32, i32, i32, i32, ...) ; 32BIT-DAG: $r6 = LI 4 ; 32BIT-DAG: $r7 = LI 5 ; 32BIT-DAG: $r8 = LI 6 +; 32BIT-DAG: renamable $r[[REG:[0-9]+]] = LWZtoc @d, $r2 :: (load 4 from got) +; 32BIT-DAG: renamable $f1 = LFD 0, killed renamable $r[[REG]] :: (dereferenceable load 8 from @d) ; 32BIT-DAG: STFD renamable $f1, 0, %stack.0 :: (store 8 into %stack.0) ; 32BIT-DAG: renamable $r9 = LWZ 0, %stack.0 :: (load 4 from %stack.0, align 8) ; 32BIT-DAG: renamable $r10 = LWZ 4, %stack.0 :: (load 4 from %stack.0 + 4) @@ -1139,8 +1139,6 @@ declare void @test_stackarg_float2(i32, i32, i32, i32, i32, i32, ...) ; ASM32PWR4-NEXT: addi 1, 1, 64 ; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. -; 64BIT-DAG: renamable $x[[REG:[0-9]+]] = LDtoc @d, $x2 :: (load 8 from got) -; 64BIT-DAG: renamable $f1 = LFD 0, killed renamable $x[[REG]] :: (dereferenceable load 8 from @d) ; 64BIT-DAG: ADJCALLSTACKDOWN 112, 0, implicit-def dead $r1, implicit $r1 ; 64BIT-DAG: $x3 = LI8 1 ; 64BIT-DAG: $x4 = LI8 2 @@ -1148,6 +1146,8 @@ declare void @test_stackarg_float2(i32, i32, i32, i32, i32, i32, ...) ; 64BIT-DAG: $x6 = LI8 4 ; 64BIT-DAG: $x7 = LI8 5 ; 64BIT-DAG: $x8 = LI8 6 +; 64BIT-DAG: renamable $x[[REG:[0-9]+]] = LDtoc @d, $x2 :: (load 8 from got) +; 64BIT-DAG: renamable $f1 = LFD 0, killed renamable $x[[REG]] :: (dereferenceable load 8 from @d) ; 64BIT-DAG: STFD renamable $f1, 0, %stack.0 :: (store 8 into %stack.0) ; 64BIT-DAG: renamable $x9 = LD 0, %stack.0 :: (load 8 from %stack.0) ; 64BIT-NEXT: BL8_NOP , csr_aix64, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit killed $x4, implicit killed $x5, implicit killed $x6, implicit killed $x7, implicit killed $x8, implicit $f1, implicit $x9, implicit $x2, implicit-def $r1 @@ -1184,13 +1184,7 @@ declare void @test_stackarg_float3(i32, i32, i32, i32, i32, i32, i32, ...) ; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. ; In 32-bit the double arg is written to memory because it cannot be fully stored in the last 32-bit GPR. -; 32BIT-DAG: renamable $r[[REGD:[0-9]+]] = LWZtoc @d, $r2 :: (load 4 from got) -; 32BIT-DAG: renamable $f1 = LFD 0, killed renamable $r[[REGD]] :: (dereferenceable load 8 from @d) -; 32BIT-DAG: renamable $r[[REGF:[0-9]+]] = LWZtoc @f, $r2 :: (load 4 from got) -; 32BIT-DAG: renamable $f2 = LFS 0, killed renamable $r[[REGF]] :: (dereferenceable load 4 from @f) ; 32BIT-DAG: ADJCALLSTACKDOWN 64, 0, implicit-def dead $r1, implicit $r1 -; 32BIT-DAG: STFD renamable $f1, 52, $r1 :: (store 8) -; 32BIT-DAG: STFS renamable $f2, 60, $r1 :: (store 4) ; 32BIT-DAG: $r3 = LI 1 ; 32BIT-DAG: $r4 = LI 2 ; 32BIT-DAG: $r5 = LI 3 @@ -1198,6 +1192,12 @@ declare void @test_stackarg_float3(i32, i32, i32, i32, i32, i32, i32, ...) ; 32BIT-DAG: $r7 = LI 5 ; 32BIT-DAG: $r8 = LI 6 ; 32BIT-DAG: $r9 = LI 7 +; 32BIT-DAG: renamable $r[[REGD:[0-9]+]] = LWZtoc @d, $r2 :: (load 4 from got) +; 32BIT-DAG: renamable $f1 = LFD 0, killed renamable $r[[REGD]] :: (dereferenceable load 8 from @d) +; 32BIT-DAG: renamable $r[[REGF:[0-9]+]] = LWZtoc @f, $r2 :: (load 4 from got) +; 32BIT-DAG: renamable $f2 = LFS 0, killed renamable $r[[REGF]] :: (dereferenceable load 4 from @f) +; 32BIT-DAG: STFD renamable $f1, 52, $r1 :: (store 8) +; 32BIT-DAG: STFS renamable $f2, 60, $r1 :: (store 4) ; 32BIT-DAG: STFD renamable $f1, 0, %stack.0 :: (store 8 into %stack.0) ; 32BIT-DAG: renamable $r10 = LWZ 0, %stack.0 :: (load 4 from %stack.0, align 8) ; 32BIT-NEXT: BL_NOP , csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit killed $r4, implicit killed $r5, implicit killed $r6, implicit killed $r7, implicit killed $r8, implicit killed $r9, implicit $f1, implicit $r10, implicit $f2, implicit $r2, implicit-def $r1 @@ -1207,12 +1207,6 @@ declare void @test_stackarg_float3(i32, i32, i32, i32, i32, i32, i32, ...) ; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. ; ASM32PWR4: stwu 1, -80(1) -; ASM32PWR4-DAG: lwz [[REGD:[0-9]+]], LC9(2) -; ASM32PWR4-DAG: lfd 1, 0([[REGD]]) -; ASM32PWR4-DAG: lwz [[REGF:[0-9]+]], LC8(2) -; ASM32PWR4-DAG: lfs 2, 0([[REGF]]) -; ASM32PWR4-DAG: stfd 1, 52(1) -; ASM32PWR4-DAG: stfs 2, 60(1) ; ASM32PWR4-DAG: li 3, 1 ; ASM32PWR4-DAG: li 4, 2 ; ASM32PWR4-DAG: li 5, 3 @@ -1220,6 +1214,12 @@ declare void @test_stackarg_float3(i32, i32, i32, i32, i32, i32, i32, ...) ; ASM32PWR4-DAG: li 7, 5 ; ASM32PWR4-DAG: li 8, 6 ; ASM32PWR4-DAG: li 9, 7 +; ASM32PWR4-DAG: lwz [[REGD:[0-9]+]], LC9(2) +; ASM32PWR4-DAG: lfd 1, 0([[REGD]]) +; ASM32PWR4-DAG: lwz [[REGF:[0-9]+]], LC8(2) +; ASM32PWR4-DAG: lfs 2, 0([[REGF]]) +; ASM32PWR4-DAG: stfd 1, 52(1) +; ASM32PWR4-DAG: stfs 2, 60(1) ; ASM32PWR4-DAG: stfd 1, 72(1) ; ASM32PWR4-DAG: lwz 10, 72(1) ; ASM32PWR4-NEXT: bl .test_stackarg_float3 @@ -1228,12 +1228,7 @@ declare void @test_stackarg_float3(i32, i32, i32, i32, i32, i32, i32, ...) ; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. ; In 64-bit the double arg is not written to memory because it is fully stored in the last 64-bit GPR. -; 64BIT-DAG: renamable $x[[REGD:[0-9]+]] = LDtoc @d, $x2 :: (load 8 from got) -; 64BIT-DAG: renamable $f1 = LFD 0, killed renamable $x[[REGD]] :: (dereferenceable load 8 from @d) -; 64BIT-DAG: renamable $x[[REGF:[0-9]+]] = LDtoc @f, $x2 :: (load 8 from got) -; 64BIT-DAG: renamable $f2 = LFS 0, killed renamable $x[[REGF]] :: (dereferenceable load 4 from @f) ; 64BIT-DAG: ADJCALLSTACKDOWN 120, 0, implicit-def dead $r1, implicit $r1 -; 64BIT-DAG: STFS renamable $f2, 112, $x1 :: (store 4) ; 64BIT-DAG: $x3 = LI8 1 ; 64BIT-DAG: $x4 = LI8 2 ; 64BIT-DAG: $x5 = LI8 3 @@ -1241,6 +1236,11 @@ declare void @test_stackarg_float3(i32, i32, i32, i32, i32, i32, i32, ...) ; 64BIT-DAG: $x7 = LI8 5 ; 64BIT-DAG: $x8 = LI8 6 ; 64BIT-DAG: $x9 = LI8 7 +; 64BIT-DAG: renamable $x[[REGD:[0-9]+]] = LDtoc @d, $x2 :: (load 8 from got) +; 64BIT-DAG: renamable $f1 = LFD 0, killed renamable $x[[REGD]] :: (dereferenceable load 8 from @d) +; 64BIT-DAG: renamable $x[[REGF:[0-9]+]] = LDtoc @f, $x2 :: (load 8 from got) +; 64BIT-DAG: renamable $f2 = LFS 0, killed renamable $x[[REGF]] :: (dereferenceable load 4 from @f) +; 64BIT-DAG: STFS renamable $f2, 112, $x1 :: (store 4) ; 64BIT-DAG: STFD renamable $f1, 0, %stack.0 :: (store 8 into %stack.0) ; 64BIT-DAG: renamable $x10 = LD 0, %stack.0 :: (load 8 from %stack.0) ; 64BIT-NEXT: BL8_NOP , csr_aix64, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit killed $x4, implicit killed $x5, implicit killed $x6, implicit killed $x7, implicit killed $x8, implicit killed $x9, implicit $f1, implicit $x10, implicit $f2, implicit $x2, implicit-def $r1 @@ -1249,11 +1249,6 @@ declare void @test_stackarg_float3(i32, i32, i32, i32, i32, i32, i32, ...) ; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. ; ASM64PWR4: stdu 1, -128(1) -; ASM64PWR4-DAG: ld [[REGD:[0-9]+]], LC8(2) -; ASM64PWR4-DAG: lfd 1, 0([[REGD]]) -; ASM64PWR4-DAG: ld [[REGF:[0-9]+]], LC7(2) -; ASM64PWR4-DAG: lfs 2, 0([[REGF]]) -; ASM64PWR4-DAG: stfs 2, 112(1) ; ASM64PWR4-DAG: li 3, 1 ; ASM64PWR4-DAG: li 4, 2 ; ASM64PWR4-DAG: li 5, 3 @@ -1261,6 +1256,11 @@ declare void @test_stackarg_float3(i32, i32, i32, i32, i32, i32, i32, ...) ; ASM64PWR4-DAG: li 7, 5 ; ASM64PWR4-DAG: li 8, 6 ; ASM64PWR4-DAG: li 9, 7 +; ASM64PWR4-DAG: ld [[REGD:[0-9]+]], LC8(2) +; ASM64PWR4-DAG: lfd 1, 0([[REGD]]) +; ASM64PWR4-DAG: ld [[REGF:[0-9]+]], LC7(2) +; ASM64PWR4-DAG: lfs 2, 0([[REGF]]) +; ASM64PWR4-DAG: stfs 2, 112(1) ; ASM64PWR4-DAG: stfd 1, 120(1) ; ASM64PWR4-DAG: ld 10, 120(1) ; ASM64PWR4-NEXT: bl .test_stackarg_float3 From 383e3ec1b2ade6c5cd473de8b8edfa98ad595aef Mon Sep 17 00:00:00 2001 From: Chris Bowler Date: Tue, 3 Mar 2020 11:25:41 -0500 Subject: [PATCH 20/29] [PowerPC][NFC] Add missing expected output for AIX int stack arg test. The expected output is erroneous and will be corrected alongside a fix to ensure stack arguments are widened to register width before writing to the parameter save area. --- llvm/test/CodeGen/PowerPC/aix-cc-abi.ll | 82 +++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll index fa2e2b161ff292..2a770cbb6de6fe 100644 --- a/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll +++ b/llvm/test/CodeGen/PowerPC/aix-cc-abi.ll @@ -998,6 +998,88 @@ declare void @test_stackarg_int(i32, i32, i32, i32, i32, i32, i32, i32, i8 zeroe ; 32BIT-NEXT: BL_NOP , csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit $r5, implicit $r6, implicit $r7, implicit $r8, implicit $r9, implicit $r10, implicit $r2, implicit-def $r1 ; 32BIT-NEXT: ADJCALLSTACKUP 80, 0, implicit-def dead $r1, implicit $r1 +; CHECKASM-LABEL: .call_test_stackarg_int: + +; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. +; ASM32PWR4: stwu 1, -80(1) +; ASM32PWR4-DAG: li 3, 1 +; ASM32PWR4-DAG: li 4, 2 +; ASM32PWR4-DAG: li 5, 3 +; ASM32PWR4-DAG: li 6, 4 +; ASM32PWR4-DAG: li 7, 5 +; ASM32PWR4-DAG: li 8, 6 +; ASM32PWR4-DAG: li 9, 7 +; ASM32PWR4-DAG: li 10, 8 +; ASM32PWR4-DAG: lwz [[REGCADDR:[0-9]+]], LC6(2) +; ASM32PWR4-DAG: lbz [[REGC:[0-9]+]], 0([[REGCADDR]]) +; ASM32PWR4-DAG: stw [[REGC]], 56(1) +; ASM32PWR4-DAG: lwz [[REGSIADDR:[0-9]+]], LC4(2) +; ASM32PWR4-DAG: lha [[REGSI:[0-9]+]], 0([[REGSIADDR]]) +; ASM32PWR4-DAG: stw [[REGSI]], 60(1) +; ASM32PWR4-DAG: lwz [[REGIADDR:[0-9]+]], LC5(2) +; ASM32PWR4-DAG: lwz [[REGI:[0-9]+]], 0([[REGIADDR]]) +; ASM32PWR4-DAG: stw [[REGI]], 64(1) +; ASM32PWR4-DAG: lwz [[REGLLIADDR:[0-9]+]], LC7(2) +; ASM32PWR4-DAG: lwz [[REGLLI1:[0-9]+]], 0([[REGLLIADDR]]) +; ASM32PWR4-DAG: stw [[REGLLI1]], 68(1) +; ASM32PWR4-DAG: lwz [[REGLLI2:[0-9]+]], 4([[REGLLIADDR]]) +; ASM32PWR4-DAG: stw [[REGLLI2]], 72(1) +; ASM32PWR4-DAG: stw [[REGI]], 76(1) +; ASM32PWR4-NEXT: bl .test_stackarg_int +; ASM32PWR4-NEXT: nop + +; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. +; 64BIT-DAG: ADJCALLSTACKDOWN 152, 0, implicit-def dead $r1, implicit $r1 +; 64BIT-DAG: $x3 = LI8 1 +; 64BIT-DAG: $x4 = LI8 2 +; 64BIT-DAG: $x5 = LI8 3 +; 64BIT-DAG: $x6 = LI8 4 +; 64BIT-DAG: $x7 = LI8 5 +; 64BIT-DAG: $x8 = LI8 6 +; 64BIT-DAG: $x9 = LI8 7 +; 64BIT-DAG: $x10 = LI8 8 +; 64BIT-DAG: renamable $x[[REGCADDR:[0-9]+]] = LDtoc @c, $x2 :: (load 8 from got) +; 64BIT-DAG: renamable $r[[REGC:[0-9]+]] = LBZ 0, killed renamable $x[[REGCADDR]] :: (dereferenceable load 1 from @c) +; 64BIT-DAG: STW killed renamable $r[[REGC]], 112, $x1 :: (store 4) +; 64BIT-DAG: renamable $x[[REGSIADDR:[0-9]+]] = LDtoc @si, $x2 :: (load 8 from got) +; 64BIT-DAG: renamable $r[[REGSI:[0-9]+]] = LHA 0, killed renamable $x[[REGSIADDR]] :: (dereferenceable load 2 from @si) +; 64BIT-DAG: STW killed renamable $r[[REGSI]], 120, $x1 :: (store 4) +; 64BIT-DAG: renamable $x[[REGIADDR:[0-9]+]] = LDtoc @i, $x2 :: (load 8 from got) +; 64BIT-DAG: renamable $r[[REGI:[0-9]+]] = LWZ 0, killed renamable $x[[REGIADDR]] :: (dereferenceable load 4 from @i) +; 64BIT-DAG: STW killed renamable $r[[REGI]], 128, $x1 :: (store 4) +; 64BIT-DAG: renamable $x[[REGLLIADDR:[0-9]+]] = LDtoc @lli, $x2 :: (load 8 from got) +; 64BIT-DAG: renamable $x[[REGLLI:[0-9]+]] = LD 0, killed renamable $x[[REGLLIADDR]] :: (dereferenceable load 8 from @lli) +; 64BIT-DAG: STD killed renamable $x[[REGLLI]], 136, $x1 :: (store 8) +; 64BIT-DAG: STW renamable $r[[REGI]], 144, $x1 :: (store 4) +; 64BIT-NEXT: BL8_NOP , csr_aix64, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit $x4, implicit $x5, implicit $x6, implicit $x7, implicit $x8, implicit $x9, implicit $x10, implicit $x2, implicit-def $r1 +; 64BIT-NEXT: ADJCALLSTACKUP 152, 0, implicit-def dead $r1, implicit $r1 + +; The DAG block permits some invalid inputs for the benefit of allowing more valid orderings. +; ASM64PWR4-DAG: stdu 1, -160(1) +; ASM64PWR4-DAG: li 3, 1 +; ASM64PWR4-DAG: li 4, 2 +; ASM64PWR4-DAG: li 5, 3 +; ASM64PWR4-DAG: li 6, 4 +; ASM64PWR4-DAG: li 7, 5 +; ASM64PWR4-DAG: li 8, 6 +; ASM64PWR4-DAG: li 9, 7 +; ASM64PWR4-DAG: li 10, 8 +; ASM64PWR4-DAG: ld [[REGCADDR:[0-9]+]], LC5(2) +; ASM64PWR4-DAG: lbz [[REGC:[0-9]+]], 0([[REGCADDR]]) +; ASM64PWR4-DAG: stw [[REGC]], 112(1) +; ASM64PWR4-DAG: ld [[REGSIADDR:[0-9]+]], LC3(2) +; ASM64PWR4-DAG: lha [[REGSI:[0-9]+]], 0([[REGSIADDR]]) +; ASM64PWR4-DAG: stw [[REGSI]], 120(1) +; ASM64PWR4-DAG: ld [[REGIADDR:[0-9]+]], LC4(2) +; ASM64PWR4-DAG: lwz [[REGI:[0-9]+]], 0([[REGIADDR]]) +; ASM64PWR4-DAG: stw [[REGI]], 128(1) +; ASM64PWR4-DAG: ld [[REGLLIADDR:[0-9]+]], LC6(2) +; ASM64PWR4-DAG: ld [[REGLLI:[0-9]+]], 0([[REGLLIADDR]]) +; ASM64PWR4-DAG: std [[REGLLI]], 136(1) +; ASM64PWR4-DAG: stw [[REGI]], 144(1) +; ASM64PWR4-NEXT: bl .test_stackarg_int +; ASM64PWR4-NEXT: nop + ; Basic saving of floating point type arguments to the parameter save area. ; The float and double arguments will pass in both fpr as well as parameter save area. define void @call_test_stackarg_float() { From 68aeaab888094fa192bf9257ffd5929b93778a70 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 2 Mar 2020 22:28:43 -0800 Subject: [PATCH 21/29] [X86] Don't count the chain uses when forming broadcast loads in lowerBuildVectorAsBroadcast. The build_vector needs to be the only user of the data, but the chain will likely have another use. So we can't make sure the build_vector is the only user of the node. --- llvm/lib/Target/X86/X86ISelLowering.cpp | 10 +++++++--- llvm/test/CodeGen/X86/pr35443.ll | 3 +-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 4c3fd0d75e784e..cef768e95dda2e 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -8621,10 +8621,12 @@ static SDValue lowerBuildVectorAsBroadcast(BuildVectorSDNode *BVOp, bool ConstSplatVal = (Ld.getOpcode() == ISD::Constant || Ld.getOpcode() == ISD::ConstantFP); + bool IsLoad = ISD::isNormalLoad(Ld.getNode()); // Make sure that all of the users of a non-constant load are from the // BUILD_VECTOR node. - if (!ConstSplatVal && !BVOp->isOnlyUserOf(Ld.getNode())) + // FIXME: Is the use count needed for non-constant, non-load case? + if (!ConstSplatVal && !IsLoad && !BVOp->isOnlyUserOf(Ld.getNode())) return SDValue(); unsigned ScalarSize = Ld.getValueSizeInBits(); @@ -8674,8 +8676,6 @@ static SDValue lowerBuildVectorAsBroadcast(BuildVectorSDNode *BVOp, } } - bool IsLoad = ISD::isNormalLoad(Ld.getNode()); - // Handle AVX2 in-register broadcasts. if (!IsLoad && Subtarget.hasInt256() && (ScalarSize == 32 || (IsGE256 && ScalarSize == 64))) @@ -8685,6 +8685,10 @@ static SDValue lowerBuildVectorAsBroadcast(BuildVectorSDNode *BVOp, if (!IsLoad) return SDValue(); + // Make sure the non-chain result is only used by this build vector. + if (!Ld->hasNUsesOfValue(NumElts - NumUndefElts, 0)) + return SDValue(); + if (ScalarSize == 32 || (IsGE256 && ScalarSize == 64) || (Subtarget.hasVLX() && ScalarSize == 64)) return DAG.getNode(X86ISD::VBROADCAST, dl, VT, Ld); diff --git a/llvm/test/CodeGen/X86/pr35443.ll b/llvm/test/CodeGen/X86/pr35443.ll index a42a14bdbcab93..01001b021beca9 100644 --- a/llvm/test/CodeGen/X86/pr35443.ll +++ b/llvm/test/CodeGen/X86/pr35443.ll @@ -8,8 +8,7 @@ define void @pr35443() { ; CHECK-LABEL: pr35443: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: movzbl ac+{{.*}}(%rip), %eax -; CHECK-NEXT: vmovd %eax, %xmm0 +; CHECK-NEXT: vpbroadcastb ac+{{.*}}(%rip), %xmm0 ; CHECK-NEXT: vpmovzxbq {{.*#+}} ymm0 = xmm0[0],zero,zero,zero,zero,zero,zero,zero,xmm0[1],zero,zero,zero,zero,zero,zero,zero,xmm0[2],zero,zero,zero,zero,zero,zero,zero,xmm0[3],zero,zero,zero,zero,zero,zero,zero ; CHECK-NEXT: vpxor %xmm1, %xmm1, %xmm1 ; CHECK-NEXT: vpsubq %ymm0, %ymm1, %ymm0 From d8ad7cc0885f32104a7cd83c77191aec15fd684f Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 3 Mar 2020 07:43:08 -0800 Subject: [PATCH 22/29] [DAGCombiner][X86] Improve narrowExtractedVectorLoad to handle cases where the element size isn't byte sized by the subvector is. Summary: Follow up from D75377. If the subvector is byte sized and the index is aligned to the subvector size, we can shrink the load. Reviewers: spatel, RKSimon Reviewed By: RKSimon Subscribers: dbabokin, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D75434 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 24 ++++-- .../avx512-extract-subvector-load-store.ll | 76 +++++++------------ llvm/test/CodeGen/X86/avx512-mask-op.ll | 5 +- .../X86/avx512bw-intrinsics-upgrade.ll | 10 +-- 4 files changed, 51 insertions(+), 64 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 3b0b84e705f82a..0265a6f18f33ba 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -18662,10 +18662,23 @@ static SDValue narrowExtractedVectorLoad(SDNode *Extract, SelectionDAG &DAG) { // Allow targets to opt-out. EVT VT = Extract->getValueType(0); - // Only handle byte sized scalars otherwise the offset is incorrect. - // FIXME: We might be able to do better if the VT is byte sized and the index - // is aligned. - if (!VT.getScalarType().isByteSized()) + // We can only create byte sized loads. + if (!VT.isByteSized()) + return SDValue(); + + unsigned Index = ExtIdx->getZExtValue(); + unsigned NumElts = VT.getVectorNumElements(); + + // If the index is a multiple of the extract element count, we can offset the + // address by the store size multiplied by the subvector index. Otherwise if + // the scalar type is byte sized, we can just use the index multiplied by + // the element size in bytes as the offset. + unsigned Offset; + if (Index % NumElts == 0) + Offset = (Index / NumElts) * VT.getStoreSize(); + else if (VT.getScalarType().isByteSized()) + Offset = Index * VT.getScalarType().getStoreSize(); + else return SDValue(); const TargetLowering &TLI = DAG.getTargetLoweringInfo(); @@ -18675,8 +18688,7 @@ static SDValue narrowExtractedVectorLoad(SDNode *Extract, SelectionDAG &DAG) { // The narrow load will be offset from the base address of the old load if // we are extracting from something besides index 0 (little-endian). SDLoc DL(Extract); - SDValue BaseAddr = Ld->getOperand(1); - unsigned Offset = ExtIdx->getZExtValue() * VT.getScalarType().getStoreSize(); + SDValue BaseAddr = Ld->getBasePtr(); // TODO: Use "BaseIndexOffset" to make this more effective. SDValue NewAddr = DAG.getMemBasePlusOffset(BaseAddr, Offset, DL); diff --git a/llvm/test/CodeGen/X86/avx512-extract-subvector-load-store.ll b/llvm/test/CodeGen/X86/avx512-extract-subvector-load-store.ll index b2728400d2562d..b30a81932d89b8 100644 --- a/llvm/test/CodeGen/X86/avx512-extract-subvector-load-store.ll +++ b/llvm/test/CodeGen/X86/avx512-extract-subvector-load-store.ll @@ -237,8 +237,7 @@ define void @load_v32i1_broadcast_16_v4i1(<32 x i1>* %a0,<4 x float> %a1,<4 x fl define void @load_v32i1_broadcast_16_v8i1(<32 x i1>* %a0,<8 x float> %a1,<8 x float> %a2,<8 x float>* %a3) { ; AVX512-LABEL: load_v32i1_broadcast_16_v8i1: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovd (%rdi), %k0 -; AVX512-NEXT: kshiftrd $16, %k0, %k0 +; AVX512-NEXT: kmovb 2(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %ymm2 ; AVX512-NEXT: vpbroadcastd %xmm2, %ymm2 ; AVX512-NEXT: vpmovd2m %ymm2, %k1 @@ -249,8 +248,7 @@ define void @load_v32i1_broadcast_16_v8i1(<32 x i1>* %a0,<8 x float> %a1,<8 x fl ; ; AVX512NOTDQ-LABEL: load_v32i1_broadcast_16_v8i1: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovd (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrd $16, %k0, %k1 +; AVX512NOTDQ-NEXT: kmovw 2(%rdi), %k1 ; AVX512NOTDQ-NEXT: vpcmpeqd %ymm2, %ymm2, %ymm2 ; AVX512NOTDQ-NEXT: vmovdqa32 %ymm2, %ymm2 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd %xmm2, %ymm2 @@ -326,8 +324,7 @@ define void @load_v32i1_broadcast_31_v4i1(<32 x i1>* %a0,<4 x float> %a1,<4 x fl define void @load_v32i1_broadcast_31_v8i1(<32 x i1>* %a0,<8 x float> %a1,<8 x float> %a2,<8 x float>* %a3) { ; AVX512-LABEL: load_v32i1_broadcast_31_v8i1: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovd (%rdi), %k0 -; AVX512-NEXT: kshiftrd $24, %k0, %k0 +; AVX512-NEXT: kmovb 3(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %ymm2 ; AVX512-NEXT: vpbroadcastd {{.*#+}} ymm3 = [7,7,7,7,7,7,7,7] ; AVX512-NEXT: vpermd %ymm2, %ymm3, %ymm2 @@ -339,8 +336,8 @@ define void @load_v32i1_broadcast_31_v8i1(<32 x i1>* %a0,<8 x float> %a1,<8 x fl ; ; AVX512NOTDQ-LABEL: load_v32i1_broadcast_31_v8i1: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovd (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrd $24, %k0, %k1 +; AVX512NOTDQ-NEXT: movzbl 3(%rdi), %eax +; AVX512NOTDQ-NEXT: kmovd %eax, %k1 ; AVX512NOTDQ-NEXT: vpcmpeqd %ymm2, %ymm2, %ymm2 ; AVX512NOTDQ-NEXT: vmovdqa32 %ymm2, %ymm2 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd {{.*#+}} ymm3 = [7,7,7,7,7,7,7,7] @@ -417,8 +414,7 @@ define void @load_v64i1_broadcast_32_v4i1(<64 x i1>* %a0,<4 x float> %a1,<4 x fl define void @load_v64i1_broadcast_32_v8i1(<64 x i1>* %a0,<8 x float> %a1,<8 x float> %a2,<8 x float>* %a3) { ; AVX512-LABEL: load_v64i1_broadcast_32_v8i1: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovq (%rdi), %k0 -; AVX512-NEXT: kshiftrq $32, %k0, %k0 +; AVX512-NEXT: kmovb 4(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %ymm2 ; AVX512-NEXT: vpbroadcastd %xmm2, %ymm2 ; AVX512-NEXT: vpmovd2m %ymm2, %k1 @@ -429,8 +425,7 @@ define void @load_v64i1_broadcast_32_v8i1(<64 x i1>* %a0,<8 x float> %a1,<8 x fl ; ; AVX512NOTDQ-LABEL: load_v64i1_broadcast_32_v8i1: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovq (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrq $32, %k0, %k1 +; AVX512NOTDQ-NEXT: kmovw 4(%rdi), %k1 ; AVX512NOTDQ-NEXT: vpcmpeqd %ymm2, %ymm2, %ymm2 ; AVX512NOTDQ-NEXT: vmovdqa32 %ymm2, %ymm2 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd %xmm2, %ymm2 @@ -448,8 +443,7 @@ define void @load_v64i1_broadcast_32_v8i1(<64 x i1>* %a0,<8 x float> %a1,<8 x fl define void @load_v64i1_broadcast_32_v16i1(<64 x i1>* %a0,<16 x float> %a1,<16 x float> %a2,<16 x float>* %a3) { ; AVX512-LABEL: load_v64i1_broadcast_32_v16i1: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovq (%rdi), %k0 -; AVX512-NEXT: kshiftrq $32, %k0, %k0 +; AVX512-NEXT: kmovw 4(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %zmm2 ; AVX512-NEXT: vpbroadcastd %xmm2, %zmm2 ; AVX512-NEXT: vpmovd2m %zmm2, %k1 @@ -460,8 +454,7 @@ define void @load_v64i1_broadcast_32_v16i1(<64 x i1>* %a0,<16 x float> %a1,<16 x ; ; AVX512NOTDQ-LABEL: load_v64i1_broadcast_32_v16i1: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovq (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrq $32, %k0, %k1 +; AVX512NOTDQ-NEXT: kmovw 4(%rdi), %k1 ; AVX512NOTDQ-NEXT: vpternlogd $255, %zmm2, %zmm2, %zmm2 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd %xmm2, %zmm2 ; AVX512NOTDQ-NEXT: vptestmd %zmm2, %zmm2, %k1 @@ -536,8 +529,7 @@ define void @load_v64i1_broadcast_63_v4i1(<64 x i1>* %a0,<4 x float> %a1,<4 x fl define void @load_v64i1_broadcast_63_v8i1(<64 x i1>* %a0,<8 x float> %a1,<8 x float> %a2,<8 x float>* %a3) { ; AVX512-LABEL: load_v64i1_broadcast_63_v8i1: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovq (%rdi), %k0 -; AVX512-NEXT: kshiftrq $56, %k0, %k0 +; AVX512-NEXT: kmovb 7(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %ymm2 ; AVX512-NEXT: vpbroadcastd {{.*#+}} ymm3 = [7,7,7,7,7,7,7,7] ; AVX512-NEXT: vpermd %ymm2, %ymm3, %ymm2 @@ -549,8 +541,8 @@ define void @load_v64i1_broadcast_63_v8i1(<64 x i1>* %a0,<8 x float> %a1,<8 x fl ; ; AVX512NOTDQ-LABEL: load_v64i1_broadcast_63_v8i1: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovq (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrq $56, %k0, %k1 +; AVX512NOTDQ-NEXT: movzbl 7(%rdi), %eax +; AVX512NOTDQ-NEXT: kmovd %eax, %k1 ; AVX512NOTDQ-NEXT: vpcmpeqd %ymm2, %ymm2, %ymm2 ; AVX512NOTDQ-NEXT: vmovdqa32 %ymm2, %ymm2 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd {{.*#+}} ymm3 = [7,7,7,7,7,7,7,7] @@ -569,8 +561,7 @@ define void @load_v64i1_broadcast_63_v8i1(<64 x i1>* %a0,<8 x float> %a1,<8 x fl define void @load_v64i1_broadcast_63_v16i1(<64 x i1>* %a0,<16 x float> %a1,<16 x float> %a2,<16 x float>* %a3) { ; AVX512-LABEL: load_v64i1_broadcast_63_v16i1: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovq (%rdi), %k0 -; AVX512-NEXT: kshiftrq $48, %k0, %k0 +; AVX512-NEXT: kmovw 6(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %zmm2 ; AVX512-NEXT: vpbroadcastd {{.*#+}} zmm3 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15] ; AVX512-NEXT: vpermd %zmm2, %zmm3, %zmm2 @@ -582,8 +573,7 @@ define void @load_v64i1_broadcast_63_v16i1(<64 x i1>* %a0,<16 x float> %a1,<16 x ; ; AVX512NOTDQ-LABEL: load_v64i1_broadcast_63_v16i1: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovq (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrq $48, %k0, %k1 +; AVX512NOTDQ-NEXT: kmovw 6(%rdi), %k1 ; AVX512NOTDQ-NEXT: vpternlogd $255, %zmm2, %zmm2, %zmm2 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd {{.*#+}} zmm3 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15] ; AVX512NOTDQ-NEXT: vpermd %zmm2, %zmm3, %zmm2 @@ -1037,8 +1027,7 @@ define void @load_v32i1_broadcast_16_v4i1_store(<32 x i1>* %a0,<4 x i1>* %a1) { define void @load_v32i1_broadcast_16_v8i1_store(<32 x i1>* %a0,<8 x i1>* %a1) { ; AVX512-LABEL: load_v32i1_broadcast_16_v8i1_store: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovd (%rdi), %k0 -; AVX512-NEXT: kshiftrd $16, %k0, %k0 +; AVX512-NEXT: kmovb 2(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %ymm0 ; AVX512-NEXT: vpbroadcastd %xmm0, %ymm0 ; AVX512-NEXT: vpmovd2m %ymm0, %k0 @@ -1048,8 +1037,7 @@ define void @load_v32i1_broadcast_16_v8i1_store(<32 x i1>* %a0,<8 x i1>* %a1) { ; ; AVX512NOTDQ-LABEL: load_v32i1_broadcast_16_v8i1_store: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovd (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrd $16, %k0, %k1 +; AVX512NOTDQ-NEXT: kmovw 2(%rdi), %k1 ; AVX512NOTDQ-NEXT: vpcmpeqd %ymm0, %ymm0, %ymm0 ; AVX512NOTDQ-NEXT: vmovdqa32 %ymm0, %ymm0 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd %xmm0, %ymm0 @@ -1140,8 +1128,7 @@ define void @load_v32i1_broadcast_31_v4i1_store(<32 x i1>* %a0,<4 x i1>* %a1) { define void @load_v32i1_broadcast_31_v8i1_store(<32 x i1>* %a0,<8 x i1>* %a1) { ; AVX512-LABEL: load_v32i1_broadcast_31_v8i1_store: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovd (%rdi), %k0 -; AVX512-NEXT: kshiftrd $24, %k0, %k0 +; AVX512-NEXT: kmovb 3(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %ymm0 ; AVX512-NEXT: vpbroadcastd {{.*#+}} ymm1 = [7,7,7,7,7,7,7,7] ; AVX512-NEXT: vpermd %ymm0, %ymm1, %ymm0 @@ -1152,8 +1139,8 @@ define void @load_v32i1_broadcast_31_v8i1_store(<32 x i1>* %a0,<8 x i1>* %a1) { ; ; AVX512NOTDQ-LABEL: load_v32i1_broadcast_31_v8i1_store: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovd (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrd $24, %k0, %k1 +; AVX512NOTDQ-NEXT: movzbl 3(%rdi), %eax +; AVX512NOTDQ-NEXT: kmovd %eax, %k1 ; AVX512NOTDQ-NEXT: vpcmpeqd %ymm0, %ymm0, %ymm0 ; AVX512NOTDQ-NEXT: vmovdqa32 %ymm0, %ymm0 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd {{.*#+}} ymm1 = [7,7,7,7,7,7,7,7] @@ -1245,8 +1232,7 @@ define void @load_v64i1_broadcast_32_v4i1_store(<64 x i1>* %a0,<4 x i1>* %a1) { define void @load_v64i1_broadcast_32_v8i1_store(<64 x i1>* %a0,<8 x i1>* %a1) { ; AVX512-LABEL: load_v64i1_broadcast_32_v8i1_store: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovq (%rdi), %k0 -; AVX512-NEXT: kshiftrq $32, %k0, %k0 +; AVX512-NEXT: kmovb 4(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %ymm0 ; AVX512-NEXT: vpbroadcastd %xmm0, %ymm0 ; AVX512-NEXT: vpmovd2m %ymm0, %k0 @@ -1256,8 +1242,7 @@ define void @load_v64i1_broadcast_32_v8i1_store(<64 x i1>* %a0,<8 x i1>* %a1) { ; ; AVX512NOTDQ-LABEL: load_v64i1_broadcast_32_v8i1_store: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovq (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrq $32, %k0, %k1 +; AVX512NOTDQ-NEXT: kmovw 4(%rdi), %k1 ; AVX512NOTDQ-NEXT: vpcmpeqd %ymm0, %ymm0, %ymm0 ; AVX512NOTDQ-NEXT: vmovdqa32 %ymm0, %ymm0 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd %xmm0, %ymm0 @@ -1274,8 +1259,7 @@ define void @load_v64i1_broadcast_32_v8i1_store(<64 x i1>* %a0,<8 x i1>* %a1) { define void @load_v64i1_broadcast_32_v16i1_store(<64 x i1>* %a0,<16 x i1>* %a1) { ; AVX512-LABEL: load_v64i1_broadcast_32_v16i1_store: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovq (%rdi), %k0 -; AVX512-NEXT: kshiftrq $32, %k0, %k0 +; AVX512-NEXT: kmovw 4(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %zmm0 ; AVX512-NEXT: vpbroadcastd %xmm0, %zmm0 ; AVX512-NEXT: vpmovd2m %zmm0, %k0 @@ -1285,8 +1269,7 @@ define void @load_v64i1_broadcast_32_v16i1_store(<64 x i1>* %a0,<16 x i1>* %a1) ; ; AVX512NOTDQ-LABEL: load_v64i1_broadcast_32_v16i1_store: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovq (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrq $32, %k0, %k1 +; AVX512NOTDQ-NEXT: kmovw 4(%rdi), %k1 ; AVX512NOTDQ-NEXT: vpternlogd $255, %zmm0, %zmm0, %zmm0 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd %xmm0, %zmm0 ; AVX512NOTDQ-NEXT: vptestmd %zmm0, %zmm0, %k0 @@ -1375,8 +1358,7 @@ define void @load_v64i1_broadcast_63_v4i1_store(<64 x i1>* %a0,<4 x i1>* %a1) { define void @load_v64i1_broadcast_63_v8i1_store(<64 x i1>* %a0,<8 x i1>* %a1) { ; AVX512-LABEL: load_v64i1_broadcast_63_v8i1_store: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovq (%rdi), %k0 -; AVX512-NEXT: kshiftrq $56, %k0, %k0 +; AVX512-NEXT: kmovb 7(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %ymm0 ; AVX512-NEXT: vpbroadcastd {{.*#+}} ymm1 = [7,7,7,7,7,7,7,7] ; AVX512-NEXT: vpermd %ymm0, %ymm1, %ymm0 @@ -1387,8 +1369,8 @@ define void @load_v64i1_broadcast_63_v8i1_store(<64 x i1>* %a0,<8 x i1>* %a1) { ; ; AVX512NOTDQ-LABEL: load_v64i1_broadcast_63_v8i1_store: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovq (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrq $56, %k0, %k1 +; AVX512NOTDQ-NEXT: movzbl 7(%rdi), %eax +; AVX512NOTDQ-NEXT: kmovd %eax, %k1 ; AVX512NOTDQ-NEXT: vpcmpeqd %ymm0, %ymm0, %ymm0 ; AVX512NOTDQ-NEXT: vmovdqa32 %ymm0, %ymm0 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd {{.*#+}} ymm1 = [7,7,7,7,7,7,7,7] @@ -1406,8 +1388,7 @@ define void @load_v64i1_broadcast_63_v8i1_store(<64 x i1>* %a0,<8 x i1>* %a1) { define void @load_v64i1_broadcast_63_v16i1_store(<64 x i1>* %a0,<16 x i1>* %a1) { ; AVX512-LABEL: load_v64i1_broadcast_63_v16i1_store: ; AVX512: # %bb.0: -; AVX512-NEXT: kmovq (%rdi), %k0 -; AVX512-NEXT: kshiftrq $48, %k0, %k0 +; AVX512-NEXT: kmovw 6(%rdi), %k0 ; AVX512-NEXT: vpmovm2d %k0, %zmm0 ; AVX512-NEXT: vpbroadcastd {{.*#+}} zmm1 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15] ; AVX512-NEXT: vpermd %zmm0, %zmm1, %zmm0 @@ -1418,8 +1399,7 @@ define void @load_v64i1_broadcast_63_v16i1_store(<64 x i1>* %a0,<16 x i1>* %a1) ; ; AVX512NOTDQ-LABEL: load_v64i1_broadcast_63_v16i1_store: ; AVX512NOTDQ: # %bb.0: -; AVX512NOTDQ-NEXT: kmovq (%rdi), %k0 -; AVX512NOTDQ-NEXT: kshiftrq $48, %k0, %k1 +; AVX512NOTDQ-NEXT: kmovw 6(%rdi), %k1 ; AVX512NOTDQ-NEXT: vpternlogd $255, %zmm0, %zmm0, %zmm0 {%k1} {z} ; AVX512NOTDQ-NEXT: vpbroadcastd {{.*#+}} zmm1 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15] ; AVX512NOTDQ-NEXT: vpermd %zmm0, %zmm1, %zmm0 diff --git a/llvm/test/CodeGen/X86/avx512-mask-op.ll b/llvm/test/CodeGen/X86/avx512-mask-op.ll index 35ecdae61a300a..b9f9ffba55d852 100644 --- a/llvm/test/CodeGen/X86/avx512-mask-op.ll +++ b/llvm/test/CodeGen/X86/avx512-mask-op.ll @@ -278,10 +278,7 @@ define i8 @shuf_test1(i16 %v) nounwind { ; ; X86-LABEL: shuf_test1: ; X86: ## %bb.0: -; X86-NEXT: kmovw {{[0-9]+}}(%esp), %k0 -; X86-NEXT: kshiftrw $8, %k0, %k0 -; X86-NEXT: kmovd %k0, %eax -; X86-NEXT: ## kill: def $al killed $al killed $eax +; X86-NEXT: movb {{[0-9]+}}(%esp), %al ; X86-NEXT: retl %v1 = bitcast i16 %v to <16 x i1> %mask = shufflevector <16 x i1> %v1, <16 x i1> undef, <8 x i32> diff --git a/llvm/test/CodeGen/X86/avx512bw-intrinsics-upgrade.ll b/llvm/test/CodeGen/X86/avx512bw-intrinsics-upgrade.ll index 22081b43720ff1..0ca1f7be88529a 100644 --- a/llvm/test/CodeGen/X86/avx512bw-intrinsics-upgrade.ll +++ b/llvm/test/CodeGen/X86/avx512bw-intrinsics-upgrade.ll @@ -7,8 +7,8 @@ declare i32 @llvm.x86.avx512.kunpck.wd(i32, i32) define i32@test_int_x86_avx512_kunpck_wd(i32 %x0, i32 %x1) { ; X86-LABEL: test_int_x86_avx512_kunpck_wd: ; X86: # %bb.0: -; X86-NEXT: kmovd {{[0-9]+}}(%esp), %k0 # encoding: [0xc4,0xe1,0xf9,0x90,0x44,0x24,0x04] -; X86-NEXT: kmovd {{[0-9]+}}(%esp), %k1 # encoding: [0xc4,0xe1,0xf9,0x90,0x4c,0x24,0x08] +; X86-NEXT: kmovw {{[0-9]+}}(%esp), %k0 # encoding: [0xc5,0xf8,0x90,0x44,0x24,0x04] +; X86-NEXT: kmovw {{[0-9]+}}(%esp), %k1 # encoding: [0xc5,0xf8,0x90,0x4c,0x24,0x08] ; X86-NEXT: kunpckwd %k1, %k0, %k0 # encoding: [0xc5,0xfc,0x4b,0xc1] ; X86-NEXT: kmovd %k0, %eax # encoding: [0xc5,0xfb,0x93,0xc0] ; X86-NEXT: retl # encoding: [0xc3] @@ -29,10 +29,8 @@ declare i64 @llvm.x86.avx512.kunpck.dq(i64, i64) define i64@test_int_x86_avx512_kunpck_qd(i64 %x0, i64 %x1) { ; X86-LABEL: test_int_x86_avx512_kunpck_qd: ; X86: # %bb.0: -; X86-NEXT: kmovq {{[0-9]+}}(%esp), %k0 # encoding: [0xc4,0xe1,0xf8,0x90,0x44,0x24,0x04] -; X86-NEXT: kmovq {{[0-9]+}}(%esp), %k1 # encoding: [0xc4,0xe1,0xf8,0x90,0x4c,0x24,0x0c] -; X86-NEXT: kmovd %k0, %edx # encoding: [0xc5,0xfb,0x93,0xd0] -; X86-NEXT: kmovd %k1, %eax # encoding: [0xc5,0xfb,0x93,0xc1] +; X86-NEXT: movl {{[0-9]+}}(%esp), %edx # encoding: [0x8b,0x54,0x24,0x04] +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax # encoding: [0x8b,0x44,0x24,0x0c] ; X86-NEXT: retl # encoding: [0xc3] ; ; X64-LABEL: test_int_x86_avx512_kunpck_qd: From b4b9fa5e11abab38e4f5dcd65b57c0226a0aee15 Mon Sep 17 00:00:00 2001 From: Pierre-vh Date: Mon, 2 Mar 2020 17:06:06 +0000 Subject: [PATCH 23/29] [debuginfo-tests][dexter] Add --builder gcc support for POSIX Differential Revision: https://reviews.llvm.org/D75339 --- .../dexter/dex/builder/scripts/posix/gcc.sh | 16 ++++++++++++++++ .../dexter/dex/tools/clang_opt_bisect/Tool.py | 12 +++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100755 debuginfo-tests/dexter/dex/builder/scripts/posix/gcc.sh diff --git a/debuginfo-tests/dexter/dex/builder/scripts/posix/gcc.sh b/debuginfo-tests/dexter/dex/builder/scripts/posix/gcc.sh new file mode 100755 index 00000000000000..c18e333127e03b --- /dev/null +++ b/debuginfo-tests/dexter/dex/builder/scripts/posix/gcc.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -e + +if test -z "$PATHTOGCC"; then + PATHTOGCC=gcc +fi + +for INDEX in $SOURCE_INDEXES +do + CFLAGS=$(eval echo "\$COMPILER_OPTIONS_$INDEX") + SRCFILE=$(eval echo "\$SOURCE_FILE_$INDEX") + OBJFILE=$(eval echo "\$OBJECT_FILE_$INDEX") + $PATHTOGCC -std=gnu++11 -c $CFLAGS $SRCFILE -o $OBJFILE +done + +$PATHTOGCC $LINKER_OPTIONS $OBJECT_FILES -o $EXECUTABLE_FILE diff --git a/debuginfo-tests/dexter/dex/tools/clang_opt_bisect/Tool.py b/debuginfo-tests/dexter/dex/tools/clang_opt_bisect/Tool.py index a2fc2969e965e8..a8bdd027d16493 100644 --- a/debuginfo-tests/dexter/dex/tools/clang_opt_bisect/Tool.py +++ b/debuginfo-tests/dexter/dex/tools/clang_opt_bisect/Tool.py @@ -77,6 +77,13 @@ def _get_bisect_limits(self): return limits + def handle_options(self, defaults): + options = self.context.options + if "clang" not in options.builder.lower(): + raise Error("--builder %s is not supported by the clang-opt-bisect tool - only 'clang' is " + "supported " % options.builder) + super(Tool, self).handle_options(defaults) + def _run_test(self, test_name): # noqa options = self.context.options @@ -177,7 +184,7 @@ def _run_test(self, test_name): # noqa file_name = ''.join( c for c in file_name if c.isalnum() or c in '()-_./ ').strip().replace( - ' ', '_').replace('/', '_') + ' ', '_').replace('/', '_') output_text_path = os.path.join(options.results_directory, '{}.txt'.format(file_name)) @@ -188,7 +195,7 @@ def _run_test(self, test_name): # noqa heuristic_verbose_output + '\n', stream=Stream(fp)) output_dextIR_path = os.path.join(options.results_directory, - '{}.dextIR'.format(file_name)) + '{}.dextIR'.format(file_name)) with open(output_dextIR_path, 'wb') as fp: pickle.dump(steps, fp, protocol=pickle.HIGHEST_PROTOCOL) @@ -229,7 +236,6 @@ def _handle_results(self) -> ReturnCode: self._all_bisect_pass_summary) return ReturnCode.OK - def _clang_opt_bisect_build(self, opt_bisect_limits): options = self.context.options compiler_options = [ From e40a742a5008c5a4cf647c0ea805486498786393 Mon Sep 17 00:00:00 2001 From: Nathan James Date: Tue, 3 Mar 2020 16:39:32 +0000 Subject: [PATCH 24/29] [clang-tidy] Change checks to use new isLanguageVersionSupported restriction Summary: Modifies all checks that are language version dependent to use `isLanguageVersionSupported` Reviewers: jdoerfert, lebedev.ri, aaron.ballman, gribozavr2, Eugene.Zelenko Reviewed By: gribozavr2 Subscribers: wuzish, nemanjai, xazax.hun, hiraditya, kbarton, steven_wu, dexonsmith, arphaman, lebedev.ri, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D75340 --- .../abseil/DurationDivisionCheck.cpp | 3 --- .../clang-tidy/abseil/DurationDivisionCheck.h | 3 +++ .../abseil/FasterStrsplitDelimiterCheck.cpp | 3 --- .../abseil/FasterStrsplitDelimiterCheck.h | 3 +++ .../abseil/NoInternalDependenciesCheck.cpp | 3 --- .../abseil/NoInternalDependenciesCheck.h | 3 +++ .../clang-tidy/abseil/NoNamespaceCheck.cpp | 3 --- .../clang-tidy/abseil/NoNamespaceCheck.h | 3 +++ .../abseil/RedundantStrcatCallsCheck.cpp | 2 -- .../abseil/RedundantStrcatCallsCheck.h | 3 +++ .../clang-tidy/abseil/StrCatAppendCheck.cpp | 2 -- .../clang-tidy/abseil/StrCatAppendCheck.h | 3 +++ .../UpgradeDurationConversionsCheck.cpp | 3 --- .../abseil/UpgradeDurationConversionsCheck.h | 3 +++ .../clang-tidy/boost/UseToStringCheck.cpp | 3 --- .../clang-tidy/boost/UseToStringCheck.h | 3 +++ .../bugprone/CopyConstructorInitCheck.cpp | 3 --- .../bugprone/CopyConstructorInitCheck.h | 3 +++ .../DynamicStaticInitializersCheck.cpp | 2 -- .../bugprone/DynamicStaticInitializersCheck.h | 3 +++ .../bugprone/ExceptionEscapeCheck.cpp | 3 --- .../bugprone/ExceptionEscapeCheck.h | 3 +++ .../ForwardingReferenceOverloadCheck.cpp | 4 ---- .../ForwardingReferenceOverloadCheck.h | 3 +++ .../bugprone/InaccurateEraseCheck.cpp | 5 ----- .../bugprone/InaccurateEraseCheck.h | 3 +++ .../bugprone/MoveForwardingReferenceCheck.cpp | 3 --- .../bugprone/MoveForwardingReferenceCheck.h | 3 +++ .../bugprone/StringConstructorCheck.cpp | 3 --- .../bugprone/StringConstructorCheck.h | 3 +++ .../bugprone/StringIntegerAssignmentCheck.cpp | 2 -- .../bugprone/StringIntegerAssignmentCheck.h | 3 +++ .../bugprone/ThrowKeywordMissingCheck.cpp | 3 --- .../bugprone/ThrowKeywordMissingCheck.h | 3 +++ .../bugprone/UndelegatedConstructorCheck.cpp | 5 ----- .../bugprone/UndelegatedConstructorCheck.h | 3 +++ .../bugprone/UnhandledSelfAssignmentCheck.cpp | 3 --- .../bugprone/UnhandledSelfAssignmentCheck.h | 3 +++ .../clang-tidy/bugprone/UnusedRaiiCheck.cpp | 5 ----- .../clang-tidy/bugprone/UnusedRaiiCheck.h | 3 +++ .../clang-tidy/bugprone/UseAfterMoveCheck.cpp | 3 --- .../clang-tidy/bugprone/UseAfterMoveCheck.h | 3 +++ .../bugprone/VirtualNearMissCheck.cpp | 3 --- .../bugprone/VirtualNearMissCheck.h | 3 +++ .../cert/DefaultOperatorNewAlignmentCheck.cpp | 4 ---- .../cert/DefaultOperatorNewAlignmentCheck.h | 3 +++ .../cert/DontModifyStdNamespaceCheck.cpp | 3 --- .../cert/DontModifyStdNamespaceCheck.h | 3 +++ .../clang-tidy/cert/MutatingCopyCheck.cpp | 3 --- .../clang-tidy/cert/MutatingCopyCheck.h | 3 +++ .../NonTrivialTypesLibcMemoryCallsCheck.cpp | 3 --- .../NonTrivialTypesLibcMemoryCallsCheck.h | 3 +++ .../clang-tidy/cert/PostfixOperatorCheck.cpp | 3 --- .../clang-tidy/cert/PostfixOperatorCheck.h | 3 +++ .../clang-tidy/cert/SetLongJmpCheck.cpp | 10 ---------- .../clang-tidy/cert/SetLongJmpCheck.h | 3 +++ .../cert/StaticObjectExceptionCheck.cpp | 3 --- .../cert/StaticObjectExceptionCheck.h | 3 +++ .../cert/ThrownExceptionTypeCheck.cpp | 3 --- .../cert/ThrownExceptionTypeCheck.h | 3 +++ .../cert/VariadicFunctionDefCheck.cpp | 3 --- .../cert/VariadicFunctionDefCheck.h | 3 +++ .../cppcoreguidelines/AvoidGotoCheck.cpp | 3 --- .../cppcoreguidelines/AvoidGotoCheck.h | 3 +++ .../cppcoreguidelines/MacroUsageCheck.cpp | 3 --- .../cppcoreguidelines/MacroUsageCheck.h | 3 +++ .../cppcoreguidelines/NoMallocCheck.cpp | 4 ---- .../cppcoreguidelines/NoMallocCheck.h | 4 ++++ .../cppcoreguidelines/OwningMemoryCheck.cpp | 3 --- .../cppcoreguidelines/OwningMemoryCheck.h | 3 +++ .../ProBoundsArrayToPointerDecayCheck.cpp | 3 --- .../ProBoundsArrayToPointerDecayCheck.h | 3 +++ .../ProBoundsConstantArrayIndexCheck.cpp | 6 ------ .../ProBoundsConstantArrayIndexCheck.h | 3 +++ .../ProTypeConstCastCheck.cpp | 3 --- .../cppcoreguidelines/ProTypeConstCastCheck.h | 3 +++ .../ProTypeCstyleCastCheck.cpp | 3 --- .../ProTypeCstyleCastCheck.h | 3 +++ .../ProTypeMemberInitCheck.cpp | 3 --- .../ProTypeMemberInitCheck.h | 3 +++ .../ProTypeReinterpretCastCheck.cpp | 3 --- .../ProTypeReinterpretCastCheck.h | 3 +++ .../ProTypeStaticCastDowncastCheck.cpp | 3 --- .../ProTypeStaticCastDowncastCheck.h | 3 +++ .../ProTypeUnionAccessCheck.cpp | 3 --- .../ProTypeUnionAccessCheck.h | 3 +++ .../cppcoreguidelines/ProTypeVarargCheck.cpp | 3 --- .../cppcoreguidelines/ProTypeVarargCheck.h | 3 +++ .../SpecialMemberFunctionsCheck.cpp | 2 -- .../SpecialMemberFunctionsCheck.h | 3 +++ .../fuchsia/MultipleInheritanceCheck.cpp | 4 ---- .../fuchsia/MultipleInheritanceCheck.h | 3 +++ .../StaticallyConstructedObjectsCheck.cpp | 5 ----- .../StaticallyConstructedObjectsCheck.h | 3 +++ .../fuchsia/TrailingReturnCheck.cpp | 5 ----- .../clang-tidy/fuchsia/TrailingReturnCheck.h | 3 +++ .../google/AvoidNSObjectNewCheck.cpp | 3 --- .../clang-tidy/google/AvoidNSObjectNewCheck.h | 3 +++ .../AvoidThrowingObjCExceptionCheck.cpp | 3 --- .../google/AvoidThrowingObjCExceptionCheck.h | 3 +++ .../google/ExplicitConstructorCheck.cpp | 4 ---- .../google/ExplicitConstructorCheck.h | 3 +++ .../google/ExplicitMakePairCheck.cpp | 5 ----- .../clang-tidy/google/ExplicitMakePairCheck.h | 3 +++ .../clang-tidy/google/FunctionNamingCheck.cpp | 4 ---- .../clang-tidy/google/FunctionNamingCheck.h | 3 +++ .../google/GlobalVariableDeclarationCheck.cpp | 4 ---- .../google/GlobalVariableDeclarationCheck.h | 3 +++ .../clang-tidy/google/IntegerTypesCheck.cpp | 5 ----- .../clang-tidy/google/IntegerTypesCheck.h | 3 +++ .../clang-tidy/google/NonConstReferences.cpp | 3 --- .../clang-tidy/google/NonConstReferences.h | 3 +++ .../google/OverloadedUnaryAndCheck.cpp | 5 ----- .../google/OverloadedUnaryAndCheck.h | 3 +++ .../google/UnnamedNamespaceInHeaderCheck.cpp | 3 --- .../google/UnnamedNamespaceInHeaderCheck.h | 3 +++ .../google/UpgradeGoogletestCaseCheck.cpp | 6 ------ .../google/UpgradeGoogletestCaseCheck.h | 3 +++ .../google/UsingNamespaceDirectiveCheck.cpp | 3 --- .../google/UsingNamespaceDirectiveCheck.h | 3 +++ .../hicpp/ExceptionBaseclassCheck.cpp | 3 --- .../hicpp/ExceptionBaseclassCheck.h | 3 +++ .../PreferIsaOrDynCastInConditionalsCheck.cpp | 3 --- .../PreferIsaOrDynCastInConditionalsCheck.h | 3 +++ .../misc/DefinitionsInHeadersCheck.cpp | 2 -- .../misc/DefinitionsInHeadersCheck.h | 3 +++ .../misc/NewDeleteOverloadsCheck.cpp | 3 --- .../clang-tidy/misc/NewDeleteOverloadsCheck.h | 3 +++ ...onPrivateMemberVariablesInClassesCheck.cpp | 3 --- .../NonPrivateMemberVariablesInClassesCheck.h | 3 +++ .../clang-tidy/misc/StaticAssertCheck.cpp | 5 ----- .../clang-tidy/misc/StaticAssertCheck.h | 3 +++ .../ThrowByValueCatchByReferenceCheck.cpp | 4 ---- .../misc/ThrowByValueCatchByReferenceCheck.h | 3 +++ .../UnconventionalAssignOperatorCheck.cpp | 5 ----- .../misc/UnconventionalAssignOperatorCheck.h | 3 +++ .../misc/UniqueptrResetReleaseCheck.cpp | 5 ----- .../misc/UniqueptrResetReleaseCheck.h | 6 ++++++ .../clang-tidy/misc/UnusedAliasDeclsCheck.cpp | 5 ----- .../clang-tidy/misc/UnusedAliasDeclsCheck.h | 3 +++ .../clang-tidy/modernize/AvoidBindCheck.cpp | 3 --- .../clang-tidy/modernize/AvoidBindCheck.h | 3 +++ .../modernize/AvoidCArraysCheck.cpp | 4 ---- .../clang-tidy/modernize/AvoidCArraysCheck.h | 3 +++ .../modernize/ConcatNestedNamespacesCheck.cpp | 3 --- .../modernize/ConcatNestedNamespacesCheck.h | 3 +++ .../modernize/DeprecatedHeadersCheck.cpp | 2 -- .../modernize/DeprecatedHeadersCheck.h | 3 +++ .../DeprecatedIosBaseAliasesCheck.cpp | 5 ----- .../modernize/DeprecatedIosBaseAliasesCheck.h | 3 +++ .../clang-tidy/modernize/LoopConvertCheck.cpp | 6 ------ .../clang-tidy/modernize/LoopConvertCheck.h | 3 +++ .../clang-tidy/modernize/PassByValueCheck.cpp | 10 ---------- .../clang-tidy/modernize/PassByValueCheck.h | 3 +++ .../modernize/RawStringLiteralCheck.cpp | 4 ---- .../modernize/RawStringLiteralCheck.h | 3 +++ .../modernize/RedundantVoidArgCheck.cpp | 3 --- .../modernize/RedundantVoidArgCheck.h | 4 ++++ .../modernize/ReplaceAutoPtrCheck.cpp | 10 ---------- .../modernize/ReplaceAutoPtrCheck.h | 3 +++ .../modernize/ReplaceRandomShuffleCheck.cpp | 3 --- .../modernize/ReplaceRandomShuffleCheck.h | 3 +++ .../modernize/ReturnBracedInitListCheck.cpp | 4 ---- .../modernize/ReturnBracedInitListCheck.h | 3 +++ .../clang-tidy/modernize/ShrinkToFitCheck.cpp | 3 --- .../clang-tidy/modernize/ShrinkToFitCheck.h | 3 +++ .../modernize/UnaryStaticAssertCheck.cpp | 3 --- .../modernize/UnaryStaticAssertCheck.h | 3 +++ .../clang-tidy/modernize/UseAutoCheck.cpp | 4 ---- .../clang-tidy/modernize/UseAutoCheck.h | 3 +++ .../modernize/UseBoolLiteralsCheck.cpp | 3 --- .../modernize/UseBoolLiteralsCheck.h | 3 +++ .../modernize/UseDefaultMemberInitCheck.cpp | 3 --- .../modernize/UseDefaultMemberInitCheck.h | 3 +++ .../clang-tidy/modernize/UseEmplaceCheck.cpp | 3 --- .../clang-tidy/modernize/UseEmplaceCheck.h | 3 +++ .../modernize/UseEqualsDefaultCheck.cpp | 3 --- .../modernize/UseEqualsDefaultCheck.h | 3 +++ .../modernize/UseEqualsDeleteCheck.cpp | 3 --- .../modernize/UseEqualsDeleteCheck.h | 3 +++ .../modernize/UseNodiscardCheck.cpp | 19 ++++++++++++------- .../clang-tidy/modernize/UseNodiscardCheck.h | 1 + .../clang-tidy/modernize/UseNoexceptCheck.cpp | 3 --- .../clang-tidy/modernize/UseNoexceptCheck.h | 3 +++ .../clang-tidy/modernize/UseNullptrCheck.cpp | 6 +----- .../clang-tidy/modernize/UseNullptrCheck.h | 5 +++++ .../clang-tidy/modernize/UseOverrideCheck.cpp | 4 ---- .../clang-tidy/modernize/UseOverrideCheck.h | 3 +++ .../modernize/UseTrailingReturnTypeCheck.cpp | 3 --- .../modernize/UseTrailingReturnTypeCheck.h | 3 +++ .../modernize/UseTransparentFunctorsCheck.cpp | 3 --- .../modernize/UseTransparentFunctorsCheck.h | 3 +++ .../modernize/UseUncaughtExceptionsCheck.cpp | 3 --- .../modernize/UseUncaughtExceptionsCheck.h | 3 +++ .../clang-tidy/modernize/UseUsingCheck.cpp | 2 -- .../clang-tidy/modernize/UseUsingCheck.h | 3 +++ .../clang-tidy/objc/AvoidNSErrorInitCheck.cpp | 4 ---- .../clang-tidy/objc/AvoidNSErrorInitCheck.h | 3 +++ .../objc/DeallocInCategoryCheck.cpp | 4 ---- .../clang-tidy/objc/DeallocInCategoryCheck.h | 3 +++ .../objc/ForbiddenSubclassingCheck.cpp | 4 ---- .../objc/ForbiddenSubclassingCheck.h | 3 +++ .../clang-tidy/objc/MissingHashCheck.cpp | 4 ---- .../clang-tidy/objc/MissingHashCheck.h | 3 +++ .../objc/PropertyDeclarationCheck.cpp | 3 --- .../objc/PropertyDeclarationCheck.h | 3 +++ .../clang-tidy/objc/SuperSelfCheck.cpp | 4 ---- .../clang-tidy/objc/SuperSelfCheck.h | 3 +++ .../openmp/ExceptionEscapeCheck.cpp | 8 -------- .../clang-tidy/openmp/ExceptionEscapeCheck.h | 3 +++ .../clang-tidy/openmp/UseDefaultNoneCheck.cpp | 5 ----- .../clang-tidy/openmp/UseDefaultNoneCheck.h | 3 +++ .../performance/InefficientAlgorithmCheck.cpp | 5 ----- .../performance/InefficientAlgorithmCheck.h | 3 +++ .../InefficientStringConcatenationCheck.cpp | 3 --- .../InefficientStringConcatenationCheck.h | 3 +++ .../performance/MoveConstArgCheck.cpp | 3 --- .../performance/MoveConstArgCheck.h | 3 +++ .../performance/MoveConstructorInitCheck.cpp | 5 ----- .../performance/MoveConstructorInitCheck.h | 3 +++ .../performance/NoAutomaticMoveCheck.cpp | 4 ---- .../performance/NoAutomaticMoveCheck.h | 3 +++ .../NoexceptMoveConstructorCheck.cpp | 5 ----- .../NoexceptMoveConstructorCheck.h | 3 +++ .../TriviallyDestructibleCheck.cpp | 3 --- .../performance/TriviallyDestructibleCheck.h | 3 +++ .../UnnecessaryValueParamCheck.cpp | 4 ---- .../performance/UnnecessaryValueParamCheck.h | 3 +++ .../portability/SIMDIntrinsicsCheck.cpp | 2 -- .../portability/SIMDIntrinsicsCheck.h | 3 +++ .../readability/ContainerSizeEmptyCheck.cpp | 5 ----- .../readability/ContainerSizeEmptyCheck.h | 3 +++ .../ImplicitBoolConversionCheck.cpp | 6 ------ .../readability/ImplicitBoolConversionCheck.h | 4 +++- .../MakeMemberFunctionConstCheck.cpp | 3 --- .../MakeMemberFunctionConstCheck.h | 3 +++ .../readability/NamespaceCommentCheck.cpp | 5 +---- .../readability/NamespaceCommentCheck.h | 3 +++ .../readability/QualifiedAutoCheck.cpp | 3 --- .../readability/QualifiedAutoCheck.h | 3 +++ .../RedundantAccessSpecifiersCheck.cpp | 3 --- .../RedundantAccessSpecifiersCheck.h | 3 +++ .../readability/RedundantMemberInitCheck.cpp | 3 --- .../readability/RedundantMemberInitCheck.h | 3 +++ .../readability/RedundantSmartptrGetCheck.cpp | 5 ----- .../readability/RedundantSmartptrGetCheck.h | 3 +++ .../readability/RedundantStringCStrCheck.cpp | 5 ----- .../readability/RedundantStringCStrCheck.h | 3 +++ .../readability/RedundantStringInitCheck.cpp | 2 -- .../readability/RedundantStringInitCheck.h | 3 +++ .../SimplifySubscriptExprCheck.cpp | 3 --- .../readability/SimplifySubscriptExprCheck.h | 3 +++ .../readability/StringCompareCheck.cpp | 3 --- .../readability/StringCompareCheck.h | 3 +++ 254 files changed, 400 insertions(+), 477 deletions(-) diff --git a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp index 82c405f9d0828c..7055ff57fdcb7d 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp @@ -17,9 +17,6 @@ namespace abseil { using namespace clang::ast_matchers; void DurationDivisionCheck::registerMatchers(MatchFinder *finder) { - if (!getLangOpts().CPlusPlus) - return; - const auto DurationExpr = expr(hasType(cxxRecordDecl(hasName("::absl::Duration")))); finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.h b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.h index ac81e059655cf2..42f6cd3701ba09 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.h @@ -23,6 +23,9 @@ namespace abseil { class DurationDivisionCheck : public ClangTidyCheck { public: using ClangTidyCheck::ClangTidyCheck; + 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; }; diff --git a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp index ef44b23331d791..bca606a7bc3a21 100644 --- a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp @@ -57,9 +57,6 @@ llvm::Optional makeCharacterLiteral(const StringLiteral *Literal, } // anonymous namespace void FasterStrsplitDelimiterCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // Binds to one character string literals. const auto SingleChar = expr(ignoringParenCasts(stringLiteral(lengthIsOne()).bind("Literal"))); diff --git a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h index 7dc77e7db5dc4f..4b7e18bc439871 100644 --- a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h @@ -24,6 +24,9 @@ class FasterStrsplitDelimiterCheck : public ClangTidyCheck { public: FasterStrsplitDelimiterCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.cpp b/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.cpp index 3ce937a756494b..ee0da4b50bf9c4 100644 --- a/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.cpp @@ -18,9 +18,6 @@ namespace tidy { namespace abseil { void NoInternalDependenciesCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // TODO: refactor matcher to be configurable or just match on any internal // access from outside the enclosing namespace. diff --git a/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.h b/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.h index 301c89d6860556..c71a81fe29361f 100644 --- a/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.h @@ -24,6 +24,9 @@ class NoInternalDependenciesCheck : public ClangTidyCheck { public: NoInternalDependenciesCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.cpp index 5db50de03d0835..3f93d4a2f570c6 100644 --- a/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.cpp @@ -18,9 +18,6 @@ namespace tidy { namespace abseil { void NoNamespaceCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( namespaceDecl(hasName("::absl"), unless(isInAbseilFile())) .bind("abslNamespace"), diff --git a/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.h b/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.h index 058d11011a1c70..e19f53b972bcfe 100644 --- a/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.h @@ -24,6 +24,9 @@ class NoNamespaceCheck : public ClangTidyCheck { public: NoNamespaceCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp index f8e6e7a59006aa..982d59e2cbe6f6 100644 --- a/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp @@ -25,8 +25,6 @@ namespace abseil { // argument. void RedundantStrcatCallsCheck::registerMatchers(MatchFinder* Finder) { - if (!getLangOpts().CPlusPlus) - return; const auto CallToStrcat = callExpr(callee(functionDecl(hasName("::absl::StrCat")))); const auto CallToStrappend = diff --git a/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.h b/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.h index 71f3ff64d898eb..850e354ef86722 100644 --- a/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.h @@ -27,6 +27,9 @@ class RedundantStrcatCallsCheck : public ClangTidyCheck { public: RedundantStrcatCallsCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp index 0780924f355755..0e8943f8545ec7 100644 --- a/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.cpp @@ -42,8 +42,6 @@ AST_MATCHER_P(Stmt, IgnoringTemporaries, ast_matchers::internal::Matcher, // str.append(StrCat(...)) void StrCatAppendCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; const auto StrCat = functionDecl(hasName("::absl::StrCat")); // The arguments of absl::StrCat are implicitly converted to AlphaNum. This // matches to the arguments because of that behavior. diff --git a/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.h b/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.h index 72203fddfbe72b..b5b36813d5f2d1 100644 --- a/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.h @@ -24,6 +24,9 @@ class StrCatAppendCheck : public ClangTidyCheck { public: StrCatAppendCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp index dc42e2633fdcd6..2d0ffce733038b 100644 --- a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp @@ -18,9 +18,6 @@ namespace tidy { namespace abseil { void UpgradeDurationConversionsCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // For the arithmetic calls, we match only the uses of the templated operators // where the template parameter is not a built-in type. This means the // instantiation makes use of an available user defined conversion to diff --git a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h index b1096a67826660..55978615faf913 100644 --- a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h @@ -25,6 +25,9 @@ class UpgradeDurationConversionsCheck : public ClangTidyCheck { public: UpgradeDurationConversionsCheck(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; diff --git a/clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp b/clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp index 29bedcf5ca8c29..4e4a0733aa7a96 100644 --- a/clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp +++ b/clang-tools-extra/clang-tidy/boost/UseToStringCheck.cpp @@ -22,9 +22,6 @@ AST_MATCHER(Type, isStrictlyInteger) { } // namespace void UseToStringCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( callExpr( hasDeclaration(functionDecl( diff --git a/clang-tools-extra/clang-tidy/boost/UseToStringCheck.h b/clang-tools-extra/clang-tidy/boost/UseToStringCheck.h index 058a34c7473bbe..013348cac02a47 100644 --- a/clang-tools-extra/clang-tidy/boost/UseToStringCheck.h +++ b/clang-tools-extra/clang-tidy/boost/UseToStringCheck.h @@ -25,6 +25,9 @@ class UseToStringCheck : public ClangTidyCheck { public: UseToStringCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.cpp index 5ae7999c3fac16..1a4d45404397dd 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.cpp @@ -18,9 +18,6 @@ namespace tidy { namespace bugprone { void CopyConstructorInitCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // In the future this might be extended to move constructors? Finder->addMatcher( cxxConstructorDecl( diff --git a/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.h b/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.h index 648aa42378baf4..f5ee77c8c7ba0a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.h @@ -24,6 +24,9 @@ class CopyConstructorInitCheck : public ClangTidyCheck { public: CopyConstructorInitCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp index 2c6f3b13fa7f77..1e2184e324fc13 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp @@ -44,8 +44,6 @@ void DynamicStaticInitializersCheck::storeOptions( } void DynamicStaticInitializersCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus || getLangOpts().ThreadsafeStatics) - return; Finder->addMatcher( varDecl(hasGlobalStorage(), unless(hasConstantDeclaration())).bind("var"), this); diff --git a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.h b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.h index 06db940bd4e340..1cf6e408aa422b 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.h @@ -27,6 +27,9 @@ namespace bugprone { class DynamicStaticInitializersCheck : public ClangTidyCheck { public: DynamicStaticInitializersCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus && !LangOpts.ThreadsafeStatics; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp index 951c6f1e391f6b..a78e93aff55078 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp @@ -52,9 +52,6 @@ void ExceptionEscapeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void ExceptionEscapeCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus || !getLangOpts().CXXExceptions) - return; - Finder->addMatcher( functionDecl(anyOf(isNoThrow(), cxxDestructorDecl(), cxxConstructorDecl(isMoveConstructor()), diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.h b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.h index 85bb713309484d..b3de78b54ed6e7 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.h @@ -27,6 +27,9 @@ namespace bugprone { class ExceptionEscapeCheck : public ClangTidyCheck { public: ExceptionEscapeCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus && LangOpts.CXXExceptions; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp index 2773d38420be35..20b6203d8c799d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp @@ -60,10 +60,6 @@ AST_MATCHER_P(TemplateTypeParmDecl, hasDefaultArgument, } // namespace void ForwardingReferenceOverloadCheck::registerMatchers(MatchFinder *Finder) { - // Forwarding references require C++11 or later. - if (!getLangOpts().CPlusPlus11) - return; - auto ForwardingRefParm = parmVarDecl( hasType(qualType(rValueReferenceType(), diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h index a27156c05930f6..6e00464cac7884 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h @@ -30,6 +30,9 @@ class ForwardingReferenceOverloadCheck : public ClangTidyCheck { public: ForwardingReferenceOverloadCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp index fffb8a5c12ac31..ef45f00d3e46ba 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp @@ -18,11 +18,6 @@ namespace tidy { namespace bugprone { void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - const auto EndCall = callExpr( callee(functionDecl(hasAnyName("remove", "remove_if", "unique"))), diff --git a/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.h b/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.h index 93ea239e6d516b..ef6006dca88887 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.h @@ -26,6 +26,9 @@ class InaccurateEraseCheck : public ClangTidyCheck { public: InaccurateEraseCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp index 8953f95159a988..90b35df09f3d82 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp @@ -67,9 +67,6 @@ static void replaceMoveWithForward(const UnresolvedLookupExpr *Callee, } void MoveForwardingReferenceCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; - // Matches a ParmVarDecl for a forwarding reference, i.e. a non-const rvalue // reference of a function template parameter type. auto ForwardingReferenceParmMatcher = diff --git a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.h b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.h index 2ed08cb74b206c..76284a0d47a24d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.h @@ -37,6 +37,9 @@ class MoveForwardingReferenceCheck : public ClangTidyCheck { public: MoveForwardingReferenceCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index e51839e686e6e2..598fb38c19b9c3 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -35,9 +35,6 @@ void StringConstructorCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - const auto ZeroExpr = expr(ignoringParenImpCasts(integerLiteral(equals(0)))); const auto CharExpr = expr(ignoringParenImpCasts(characterLiteral())); const auto NegativeExpr = expr(ignoringParenImpCasts( diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.h b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.h index e7b4c87404d46d..687f3b106fb4d0 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.h @@ -22,6 +22,9 @@ namespace bugprone { class StringConstructorCheck : public ClangTidyCheck { public: StringConstructorCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp index c64b5f3631cba6..e0410335b123ae 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp @@ -18,8 +18,6 @@ namespace tidy { namespace bugprone { void StringIntegerAssignmentCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; Finder->addMatcher( cxxOperatorCallExpr( anyOf(hasOverloadedOperatorName("="), diff --git a/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.h b/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.h index 733e7bed9ec55e..6e8526edc9fb04 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.h @@ -23,6 +23,9 @@ class StringIntegerAssignmentCheck : public ClangTidyCheck { public: StringIntegerAssignmentCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp index 767f9a4a07ec77..25e7bc9d91e04c 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp @@ -17,9 +17,6 @@ namespace tidy { namespace bugprone { void ThrowKeywordMissingCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - auto CtorInitializerList = cxxConstructorDecl(hasAnyConstructorInitializer(anything())); diff --git a/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.h b/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.h index d5e7d4ef9a1816..0ea1faab249c34 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.h @@ -24,6 +24,9 @@ class ThrowKeywordMissingCheck : public ClangTidyCheck { public: ThrowKeywordMissingCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp index 32a023fcc29b68..1dd9568734ab07 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp @@ -53,11 +53,6 @@ void UndelegatedConstructorCheck::registerMatchers(MatchFinder *Finder) { // depending on the type's destructor and the number of arguments on the // constructor call, this is handled by ignoringTemporaryExpr. Ignore template // instantiations to reduce the number of duplicated warnings. - // - // Only register the matchers for C++11; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus11) - return; Finder->addMatcher( compoundStmt( diff --git a/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.h b/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.h index 09060529bfb130..8b95f9c42e5cf7 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/UndelegatedConstructorCheck.h @@ -24,6 +24,9 @@ class UndelegatedConstructorCheck : public ClangTidyCheck { public: UndelegatedConstructorCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp index 14f5e1532474b9..6fab9ec60b1d19 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp @@ -29,9 +29,6 @@ void UnhandledSelfAssignmentCheck::storeOptions( } void UnhandledSelfAssignmentCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // We don't care about deleted, default or implicit operator implementations. const auto IsUserDefined = cxxMethodDecl( isDefinition(), unless(anyOf(isDeleted(), isImplicit(), isDefaulted()))); diff --git a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.h b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.h index d7a2b7c619ff84..7f75af4473a1a4 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.h @@ -25,6 +25,9 @@ class UnhandledSelfAssignmentCheck : public ClangTidyCheck { public: UnhandledSelfAssignmentCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp index e89cbe19d4a41f..40008797207e92 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp @@ -24,11 +24,6 @@ AST_MATCHER(CXXRecordDecl, hasNonTrivialDestructor) { } // namespace void UnusedRaiiCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - // Look for temporaries that are constructed in-place and immediately // destroyed. Look for temporaries created by a functional cast but not for // those returned from a call. diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.h b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.h index 1307a77b3e4764..3608365866997d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.h @@ -23,6 +23,9 @@ class UnusedRaiiCheck : public ClangTidyCheck { public: UnusedRaiiCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index 6c855440aa55ca..ba946ed6f03c8f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -396,9 +396,6 @@ static void emitDiagnostic(const Expr *MovingCall, const DeclRefExpr *MoveArg, } void UseAfterMoveCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; - auto CallMoveMatcher = callExpr(callee(functionDecl(hasName("::std::move"))), argumentCountIs(1), hasArgument(0, declRefExpr().bind("arg")), diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.h b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.h index 27cb32bb70f037..6e51641680360e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.h @@ -24,6 +24,9 @@ class UseAfterMoveCheck : public ClangTidyCheck { public: UseAfterMoveCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp index 32ca1b48394628..150b517811b66c 100644 --- a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp @@ -215,9 +215,6 @@ bool VirtualNearMissCheck::isOverriddenByDerivedClass( } void VirtualNearMissCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( cxxMethodDecl( unless(anyOf(isOverride(), isImplicit(), cxxConstructorDecl(), diff --git a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h index b628bf4f4a0f1f..69ae278f2e2c97 100644 --- a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h @@ -27,6 +27,9 @@ class VirtualNearMissCheck : public ClangTidyCheck { public: VirtualNearMissCheck(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; diff --git a/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp index 749b8f192aeba4..e9552bcb7b2036 100644 --- a/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp @@ -17,10 +17,6 @@ namespace tidy { namespace cert { void DefaultOperatorNewAlignmentCheck::registerMatchers(MatchFinder *Finder) { - // Check not applicable in C++17 (or newer). - if (getLangOpts().CPlusPlus17) - return; - Finder->addMatcher( cxxNewExpr(unless(hasAnyPlacementArg(anything()))).bind("new"), this); } diff --git a/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.h b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.h index 12729874411a95..02412b42ec67dd 100644 --- a/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.h +++ b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.h @@ -24,6 +24,9 @@ class DefaultOperatorNewAlignmentCheck : public ClangTidyCheck { public: DefaultOperatorNewAlignmentCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return !LangOpts.CPlusPlus17; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp index 7b2c7597508a34..2b30933385644d 100644 --- a/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp @@ -17,9 +17,6 @@ namespace tidy { namespace cert { void DontModifyStdNamespaceCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( namespaceDecl(unless(isExpansionInSystemHeader()), anyOf(hasName("std"), hasName("posix")), diff --git a/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.h b/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.h index 3e90111aa11d18..3cc03e875353ea 100644 --- a/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.h +++ b/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.h @@ -24,6 +24,9 @@ class DontModifyStdNamespaceCheck : public ClangTidyCheck { public: DontModifyStdNamespaceCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp b/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp index 6add0356870484..4de328f3249d65 100644 --- a/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp @@ -21,9 +21,6 @@ static constexpr llvm::StringLiteral MutatingOperatorName = "MutatingOp"; static constexpr llvm::StringLiteral MutatingCallName = "MutatingCall"; void MutatingCopyCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - const auto MemberExprOrSourceObject = anyOf( memberExpr(), declRefExpr(to(decl(equalsBoundNode(std::string(SourceDeclName)))))); diff --git a/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.h b/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.h index 0efba6aff3cb8c..f54371ea629598 100644 --- a/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.h +++ b/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.h @@ -24,6 +24,9 @@ class MutatingCopyCheck : public ClangTidyCheck { public: MutatingCopyCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.cpp b/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.cpp index a7bd38173eb0ff..cb03ad896b6e4b 100644 --- a/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.cpp @@ -85,9 +85,6 @@ void NonTrivialTypesLibcMemoryCallsCheck::storeOptions( void NonTrivialTypesLibcMemoryCallsCheck::registerMatchers( MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus || getLangOpts().ObjC) - return; - using namespace ast_matchers::internal; auto IsStructPointer = [](Matcher Constraint = anything(), bool Bind = false) { diff --git a/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.h b/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.h index 2675e27b11ac49..41737ddae465e2 100644 --- a/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.h +++ b/clang-tools-extra/clang-tidy/cert/NonTrivialTypesLibcMemoryCallsCheck.h @@ -24,6 +24,9 @@ class NonTrivialTypesLibcMemoryCallsCheck : public ClangTidyCheck { public: NonTrivialTypesLibcMemoryCallsCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus && !LangOpts.ObjC; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/cert/PostfixOperatorCheck.cpp b/clang-tools-extra/clang-tidy/cert/PostfixOperatorCheck.cpp index 45c748147bd691..dd9efcfe795769 100644 --- a/clang-tools-extra/clang-tidy/cert/PostfixOperatorCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/PostfixOperatorCheck.cpp @@ -18,9 +18,6 @@ namespace tidy { namespace cert { void PostfixOperatorCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher(functionDecl(anyOf(hasOverloadedOperatorName("++"), hasOverloadedOperatorName("--")), unless(isInstantiated())) diff --git a/clang-tools-extra/clang-tidy/cert/PostfixOperatorCheck.h b/clang-tools-extra/clang-tidy/cert/PostfixOperatorCheck.h index 4a6133bb2acef9..08d892d8165b71 100644 --- a/clang-tools-extra/clang-tidy/cert/PostfixOperatorCheck.h +++ b/clang-tools-extra/clang-tidy/cert/PostfixOperatorCheck.h @@ -24,6 +24,9 @@ class PostfixOperatorCheck : public ClangTidyCheck { public: PostfixOperatorCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cert/SetLongJmpCheck.cpp b/clang-tools-extra/clang-tidy/cert/SetLongJmpCheck.cpp index a7a78ec5baa17f..99f138087abee5 100644 --- a/clang-tools-extra/clang-tidy/cert/SetLongJmpCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/SetLongJmpCheck.cpp @@ -44,22 +44,12 @@ class SetJmpMacroCallbacks : public PPCallbacks { void SetLongJmpCheck::registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { - // This checker only applies to C++, where exception handling is a superior - // solution to setjmp/longjmp calls. - if (!getLangOpts().CPlusPlus) - return; - // Per [headers]p5, setjmp must be exposed as a macro instead of a function, // despite the allowance in C for setjmp to also be an extern function. PP->addPPCallbacks(std::make_unique(*this)); } void SetLongJmpCheck::registerMatchers(MatchFinder *Finder) { - // This checker only applies to C++, where exception handling is a superior - // solution to setjmp/longjmp calls. - if (!getLangOpts().CPlusPlus) - return; - // In case there is an implementation that happens to define setjmp as a // function instead of a macro, this will also catch use of it. However, we // are primarily searching for uses of longjmp. diff --git a/clang-tools-extra/clang-tidy/cert/SetLongJmpCheck.h b/clang-tools-extra/clang-tidy/cert/SetLongJmpCheck.h index d9cef1b6784a24..95b440d8d49e35 100644 --- a/clang-tools-extra/clang-tidy/cert/SetLongJmpCheck.h +++ b/clang-tools-extra/clang-tidy/cert/SetLongJmpCheck.h @@ -23,6 +23,9 @@ class SetLongJmpCheck : public ClangTidyCheck { public: SetLongJmpCheck(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; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, diff --git a/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.cpp b/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.cpp index 363c96a2ae93f8..233bd29cc8644c 100644 --- a/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.cpp @@ -18,9 +18,6 @@ namespace tidy { namespace cert { void StaticObjectExceptionCheck::registerMatchers(MatchFinder *Finder) { - if ((!getLangOpts().CPlusPlus) || (!getLangOpts().CXXExceptions)) - return; - // Match any static or thread_local variable declaration that has an // initializer that can throw. Finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.h b/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.h index 64a1eb563df2d6..768ae767fec13b 100644 --- a/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.h +++ b/clang-tools-extra/clang-tidy/cert/StaticObjectExceptionCheck.h @@ -24,6 +24,9 @@ class StaticObjectExceptionCheck : public ClangTidyCheck { public: StaticObjectExceptionCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return getLangOpts().CPlusPlus && getLangOpts().CXXExceptions; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp b/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp index 9478405515fdae..ca44c002239f0e 100644 --- a/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp @@ -18,9 +18,6 @@ namespace tidy { namespace cert { void ThrownExceptionTypeCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( cxxThrowExpr(has(ignoringParenImpCasts( cxxConstructExpr(hasDeclaration(cxxConstructorDecl( diff --git a/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.h b/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.h index dc37b6a083eb90..80c51edb5ffa18 100644 --- a/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.h +++ b/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.h @@ -23,6 +23,9 @@ class ThrownExceptionTypeCheck : public ClangTidyCheck { public: ThrownExceptionTypeCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cert/VariadicFunctionDefCheck.cpp b/clang-tools-extra/clang-tidy/cert/VariadicFunctionDefCheck.cpp index 8ee67f91242270..25b255f7d79243 100644 --- a/clang-tools-extra/clang-tidy/cert/VariadicFunctionDefCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/VariadicFunctionDefCheck.cpp @@ -17,9 +17,6 @@ namespace tidy { namespace cert { void VariadicFunctionDefCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // We only care about function *definitions* that are variadic, and do not // have extern "C" language linkage. Finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/cert/VariadicFunctionDefCheck.h b/clang-tools-extra/clang-tidy/cert/VariadicFunctionDefCheck.h index 24408ace9f4782..43cbf2eae58b20 100644 --- a/clang-tools-extra/clang-tidy/cert/VariadicFunctionDefCheck.h +++ b/clang-tools-extra/clang-tidy/cert/VariadicFunctionDefCheck.h @@ -23,6 +23,9 @@ class VariadicFunctionDefCheck : public ClangTidyCheck { public: VariadicFunctionDefCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp index 9e7bf6362f7548..cf3a16a4dd7dd2 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp @@ -23,9 +23,6 @@ AST_MATCHER(GotoStmt, isForwardJumping) { } // namespace void AvoidGotoCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // TODO: This check does not recognize `IndirectGotoStmt` which is a // GNU extension. These must be matched separately and an AST matcher // is currently missing for them. diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h index f27e22c7656ad2..a00fe9cb4887a0 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h @@ -24,6 +24,9 @@ class AvoidGotoCheck : public ClangTidyCheck { public: AvoidGotoCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp index 21aead58d9b215..9c8652770963d4 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp @@ -71,9 +71,6 @@ void MacroUsageCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { void MacroUsageCheck::registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { - if (!getLangOpts().CPlusPlus11) - return; - PP->addPPCallbacks(std::make_unique( this, SM, AllowedRegexp, CheckCapsOnly, IgnoreCommandLineMacros)); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.h index 978edd8e67cb21..6875abeb3cf403 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.h @@ -29,6 +29,9 @@ class MacroUsageCheck : public ClangTidyCheck { AllowedRegexp(Options.get("AllowedRegexp", "^DEBUG_*")), CheckCapsOnly(Options.get("CheckCapsOnly", 0)), IgnoreCommandLineMacros(Options.get("IgnoreCommandLineMacros", 1)) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp index b78e7d170396fa..d502ddf50e84fc 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp @@ -37,10 +37,6 @@ void NoMallocCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void NoMallocCheck::registerMatchers(MatchFinder *Finder) { - // C-style memory management is only problematic in C++. - if (!getLangOpts().CPlusPlus) - return; - // Registering malloc, will suggest RAII. Finder->addMatcher(callExpr(callee(functionDecl(hasAnyListedName(AllocList)))) .bind("allocation"), diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.h index 023202ae83f6ee..cf676421bc53e6 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.h @@ -33,6 +33,10 @@ class NoMallocCheck : public ClangTidyCheck { ReallocList(Options.get("Reallocations", "::realloc")), DeallocList(Options.get("Deallocations", "::free")) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } + /// Make configuration of checker discoverable. void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp index 11d1e3ebda1b67..2b7726292dc25e 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp @@ -39,9 +39,6 @@ void OwningMemoryCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { /// Match common cases, where the owner semantic is relevant, like function /// calls, delete expressions and others. void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; - const auto OwnerDecl = typeAliasTemplateDecl(hasName("::gsl::owner")); const auto IsOwnerType = hasType(OwnerDecl); diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h index 0498eea9185b23..aaa3511d2f2e88 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h @@ -30,6 +30,9 @@ class OwningMemoryCheck : public ClangTidyCheck { LegacyResourceConsumers(Options.get( "LegacyResourceConsumers", "::free;::realloc;::freopen;::fclose")) { } + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } /// Make configuration of checker discoverable. void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp index 760073fcaac27f..cdea1375aba733 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp @@ -49,9 +49,6 @@ AST_MATCHER_P(Expr, hasParentIgnoringImpCasts, } // namespace void ProBoundsArrayToPointerDecayCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // The only allowed array to pointer decay // 1) just before array subscription // 2) inside a range-for over an array diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h index 2809965492ff1c..a219d03b1c12d3 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h @@ -23,6 +23,9 @@ class ProBoundsArrayToPointerDecayCheck : public ClangTidyCheck { public: ProBoundsArrayToPointerDecayCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp index 7cd6603790bdd5..d8997f8a72105c 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp @@ -32,18 +32,12 @@ void ProBoundsConstantArrayIndexCheck::storeOptions( void ProBoundsConstantArrayIndexCheck::registerPPCallbacks( const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { - if (!getLangOpts().CPlusPlus) - return; - Inserter = std::make_unique(SM, getLangOpts(), IncludeStyle); PP->addPPCallbacks(Inserter->CreatePPCallbacks()); } void ProBoundsConstantArrayIndexCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // Note: if a struct contains an array member, the compiler-generated // constructor has an arraySubscriptExpr. Finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h index c75795ac7445f1..1b5d7f1428db21 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h @@ -28,6 +28,9 @@ class ProBoundsConstantArrayIndexCheck : public ClangTidyCheck { public: ProBoundsConstantArrayIndexCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp index 419c6765a6449b..7d67301eca2aa9 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp @@ -17,9 +17,6 @@ namespace tidy { namespace cppcoreguidelines { void ProTypeConstCastCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher(cxxConstCastExpr().bind("cast"), this); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h index 2fbfdd3b5f55e1..969e8092e21387 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h @@ -23,6 +23,9 @@ class ProTypeConstCastCheck : public ClangTidyCheck { public: ProTypeConstCastCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp index 18fad57929fc8e..6873e23e7dd13b 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp @@ -30,9 +30,6 @@ static bool needsConstCast(QualType SourceType, QualType DestType) { } void ProTypeCstyleCastCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( cStyleCastExpr(unless(isInTemplateInstantiation())).bind("cast"), this); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h index aebc57ec0eb455..144b4c7b6da96f 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h @@ -24,6 +24,9 @@ class ProTypeCstyleCastCheck : public ClangTidyCheck { public: ProTypeCstyleCastCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp index 96e9d3edc01694..485a07c5e37589 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -254,9 +254,6 @@ ProTypeMemberInitCheck::ProTypeMemberInitCheck(StringRef Name, UseAssignment(Options.getLocalOrGlobal("UseAssignment", false)) {} void ProTypeMemberInitCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - auto IsUserProvidedNonDelegatingConstructor = allOf(isUserProvided(), unless(anyOf(isInstantiated(), isDelegatingConstructor()))); diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h index 070734bc029a0c..9e5491cd507119 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h @@ -33,6 +33,9 @@ namespace cppcoreguidelines { class ProTypeMemberInitCheck : public ClangTidyCheck { public: ProTypeMemberInitCheck(StringRef Name, ClangTidyContext *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; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp index 4c4c6ce1a488dc..66f03783773bc1 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp @@ -17,9 +17,6 @@ namespace tidy { namespace cppcoreguidelines { void ProTypeReinterpretCastCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher(cxxReinterpretCastExpr().bind("cast"), this); } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h index 5afd461f2bac0e..c33bbd66fae123 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h @@ -23,6 +23,9 @@ class ProTypeReinterpretCastCheck : public ClangTidyCheck { public: ProTypeReinterpretCastCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp index 59503ba6c09a8c..0298685102cda0 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp @@ -17,9 +17,6 @@ namespace tidy { namespace cppcoreguidelines { void ProTypeStaticCastDowncastCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( cxxStaticCastExpr(unless(isInTemplateInstantiation())).bind("cast"), this); diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h index e7c45aec412084..5eacb42a613da3 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h @@ -24,6 +24,9 @@ class ProTypeStaticCastDowncastCheck : public ClangTidyCheck { public: ProTypeStaticCastDowncastCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp index e50dd4e69b4bd7..635041b41a2dde 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp @@ -17,9 +17,6 @@ namespace tidy { namespace cppcoreguidelines { void ProTypeUnionAccessCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( memberExpr(hasObjectExpression(hasType(recordDecl(isUnion())))) .bind("expr"), diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h index 70080f43bb6c80..5d36e05225d1ca 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h @@ -24,6 +24,9 @@ class ProTypeUnionAccessCheck : public ClangTidyCheck { public: ProTypeUnionAccessCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp index 650e668d200ea2..4509c934ddc5d5 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp @@ -19,9 +19,6 @@ namespace cppcoreguidelines { const internal::VariadicDynCastAllOfMatcher vAArgExpr; void ProTypeVarargCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher(vAArgExpr().bind("va_use"), this); Finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h index 98acc5ad4ebcf2..11348d768e8712 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h @@ -24,6 +24,9 @@ class ProTypeVarargCheck : public ClangTidyCheck { public: ProTypeVarargCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp index a6df54701b0e89..6ff60495a72be6 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp @@ -34,8 +34,6 @@ void SpecialMemberFunctionsCheck::storeOptions( } void SpecialMemberFunctionsCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; Finder->addMatcher( cxxRecordDecl( eachOf( diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h index 71caa4da9fdf67..29982ba4796aec 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h @@ -25,6 +25,9 @@ namespace cppcoreguidelines { class SpecialMemberFunctionsCheck : public ClangTidyCheck { public: SpecialMemberFunctionsCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp index 404b4beddd247b..357ecb016173da 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp +++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp @@ -88,10 +88,6 @@ bool MultipleInheritanceCheck::isInterface(const CXXRecordDecl *Node) { } void MultipleInheritanceCheck::registerMatchers(MatchFinder *Finder) { - // Requires C++. - if (!getLangOpts().CPlusPlus) - return; - // Match declarations which have bases. Finder->addMatcher( cxxRecordDecl(allOf(hasBases(), isDefinition())).bind("decl"), this); diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h index c79050a040e2ad..7ac70dabf9baa2 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h +++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h @@ -23,6 +23,9 @@ class MultipleInheritanceCheck : public ClangTidyCheck { public: MultipleInheritanceCheck(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; diff --git a/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp index cd6de922b02049..ca2f85fc106cc1 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp +++ b/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp @@ -28,11 +28,6 @@ void StaticallyConstructedObjectsCheck::registerMatchers(MatchFinder *Finder) { // Constructing global, non-trivial objects with static storage is // disallowed, unless the object is statically initialized with a constexpr // constructor or has no explicit constructor. - - // Constexpr requires C++11 or later. - if (!getLangOpts().CPlusPlus11) - return; - Finder->addMatcher(varDecl( // Match global, statically stored objects... isGlobalStatic(), diff --git a/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h b/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h index adf48aaa94afac..96f1a873e148cb 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h +++ b/clang-tools-extra/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h @@ -25,6 +25,9 @@ class StaticallyConstructedObjectsCheck : public ClangTidyCheck { public: StaticallyConstructedObjectsCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/fuchsia/TrailingReturnCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/TrailingReturnCheck.cpp index a1da0db6e8c82b..4ade4767190ef8 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/TrailingReturnCheck.cpp +++ b/clang-tools-extra/clang-tidy/fuchsia/TrailingReturnCheck.cpp @@ -24,11 +24,6 @@ AST_MATCHER(FunctionDecl, hasTrailingReturn) { } // namespace void TrailingReturnCheck::registerMatchers(MatchFinder *Finder) { - - // Requires C++11 or later. - if (!getLangOpts().CPlusPlus11) - return; - // Functions that have trailing returns are disallowed, except for those // using decltype specifiers and lambda with otherwise unutterable // return types. diff --git a/clang-tools-extra/clang-tidy/fuchsia/TrailingReturnCheck.h b/clang-tools-extra/clang-tidy/fuchsia/TrailingReturnCheck.h index e0aab1f4dc1b02..398cabd3fea8f1 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/TrailingReturnCheck.h +++ b/clang-tools-extra/clang-tidy/fuchsia/TrailingReturnCheck.h @@ -25,6 +25,9 @@ class TrailingReturnCheck : public ClangTidyCheck { public: TrailingReturnCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.cpp b/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.cpp index 0186ed8fbe0d4f..b7388fd31bfc23 100644 --- a/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.cpp @@ -94,9 +94,6 @@ static FixItHint getCallFixItHint(const ObjCMessageExpr *Expr, } void AvoidNSObjectNewCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().ObjC) - return; - // Add two matchers, to catch calls to +new and implementations of +new. Finder->addMatcher( objcMessageExpr(isClassMessage(), hasSelector("new")).bind("new_call"), diff --git a/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.h b/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.h index 97988c903e8e5a..dccbf83872dc7f 100644 --- a/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.h +++ b/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.h @@ -26,6 +26,9 @@ class AvoidNSObjectNewCheck : public ClangTidyCheck { public: AvoidNSObjectNewCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.ObjC; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp b/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp index bfc34672bfd009..2263806fb6a7f8 100644 --- a/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp @@ -18,9 +18,6 @@ namespace google { namespace objc { void AvoidThrowingObjCExceptionCheck::registerMatchers(MatchFinder *Finder) { - // this check should only be applied to ObjC sources. - if (!getLangOpts().ObjC) - return; Finder->addMatcher(objcThrowStmt().bind("throwStmt"), this); Finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h b/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h index 692a37f1febc6c..4f5ec40930a7d7 100644 --- a/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h +++ b/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h @@ -26,6 +26,9 @@ class AvoidThrowingObjCExceptionCheck : public ClangTidyCheck { public: AvoidThrowingObjCExceptionCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.ObjC; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp index 69731c262fafc7..80fc139e4b9c10 100644 --- a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp @@ -19,10 +19,6 @@ namespace tidy { namespace google { void ExplicitConstructorCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; Finder->addMatcher( cxxConstructorDecl(unless(anyOf(isImplicit(), // Compiler-generated. isDeleted(), isInstantiated()))) diff --git a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.h b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.h index b6a76f63bd919e..721ad4efc9797c 100644 --- a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.h +++ b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.h @@ -22,6 +22,9 @@ class ExplicitConstructorCheck : public ClangTidyCheck { public: ExplicitConstructorCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/google/ExplicitMakePairCheck.cpp b/clang-tools-extra/clang-tidy/google/ExplicitMakePairCheck.cpp index 51df3a8fd42761..e719a426e56f12 100644 --- a/clang-tools-extra/clang-tidy/google/ExplicitMakePairCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/ExplicitMakePairCheck.cpp @@ -26,11 +26,6 @@ namespace build { void ExplicitMakePairCheck::registerMatchers( ast_matchers::MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - // Look for std::make_pair with explicit template args. Ignore calls in // templates. Finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/google/ExplicitMakePairCheck.h b/clang-tools-extra/clang-tidy/google/ExplicitMakePairCheck.h index 8029384f7cf8ce..dae66c8afa8b9c 100644 --- a/clang-tools-extra/clang-tidy/google/ExplicitMakePairCheck.h +++ b/clang-tools-extra/clang-tidy/google/ExplicitMakePairCheck.h @@ -26,6 +26,9 @@ class ExplicitMakePairCheck : public ClangTidyCheck { public: ExplicitMakePairCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/google/FunctionNamingCheck.cpp b/clang-tools-extra/clang-tidy/google/FunctionNamingCheck.cpp index 8096d65d7f1646..f29d650bf5fcfe 100644 --- a/clang-tools-extra/clang-tidy/google/FunctionNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/FunctionNamingCheck.cpp @@ -89,10 +89,6 @@ FixItHint generateFixItHint(const FunctionDecl *Decl) { } // namespace void FunctionNamingCheck::registerMatchers(MatchFinder *Finder) { - // This check should only be applied to Objective-C sources. - if (!getLangOpts().ObjC) - return; - // Enforce Objective-C function naming conventions on all functions except: // • Functions defined in system headers. // • C++ member functions. diff --git a/clang-tools-extra/clang-tidy/google/FunctionNamingCheck.h b/clang-tools-extra/clang-tidy/google/FunctionNamingCheck.h index c45f87d5f12876..e646ec9711c1c3 100644 --- a/clang-tools-extra/clang-tidy/google/FunctionNamingCheck.h +++ b/clang-tools-extra/clang-tidy/google/FunctionNamingCheck.h @@ -30,6 +30,9 @@ class FunctionNamingCheck : public ClangTidyCheck { public: FunctionNamingCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.ObjC; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.cpp b/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.cpp index 30ab04c08c0089..8b718ad97d9034 100644 --- a/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.cpp @@ -59,10 +59,6 @@ FixItHint generateFixItHint(const VarDecl *Decl, bool IsConst) { } // namespace void GlobalVariableDeclarationCheck::registerMatchers(MatchFinder *Finder) { - // The relevant Style Guide rule only applies to Objective-C. - if (!getLangOpts().ObjC) - return; - // need to add two matchers since we need to bind different ids to distinguish // constants and variables. Since bind() can only be called on node matchers, // we cannot make it in one matcher. diff --git a/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.h b/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.h index 9ea0136d3d1534..1c707835a033da 100644 --- a/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.h +++ b/clang-tools-extra/clang-tidy/google/GlobalVariableDeclarationCheck.h @@ -26,6 +26,9 @@ class GlobalVariableDeclarationCheck : public ClangTidyCheck { public: GlobalVariableDeclarationCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.ObjC; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.cpp b/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.cpp index f41eba2c62933d..b5600c19a6d53b 100644 --- a/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.cpp @@ -53,11 +53,6 @@ void IntegerTypesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void IntegerTypesCheck::registerMatchers(MatchFinder *Finder) { - // Find all TypeLocs. The relevant Style Guide rule only applies to C++. - // This check is also not applied in Objective-C++ sources as Objective-C - // often uses built-in integer types other than `int`. - if (!getLangOpts().CPlusPlus || getLangOpts().ObjC) - return; // Match any integer types, unless they are passed to a printf-based API: // // http://google.github.io/styleguide/cppguide.html#64-bit_Portability diff --git a/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.h b/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.h index b161b824f220e5..0b528dab2476d5 100644 --- a/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.h +++ b/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.h @@ -28,6 +28,9 @@ namespace runtime { class IntegerTypesCheck : public ClangTidyCheck { public: IntegerTypesCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus && !LangOpts.ObjC; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Options) override; diff --git a/clang-tools-extra/clang-tidy/google/NonConstReferences.cpp b/clang-tools-extra/clang-tidy/google/NonConstReferences.cpp index 95dc708456a2fd..b7da1c5940c567 100644 --- a/clang-tools-extra/clang-tidy/google/NonConstReferences.cpp +++ b/clang-tools-extra/clang-tidy/google/NonConstReferences.cpp @@ -31,9 +31,6 @@ void NonConstReferences::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void NonConstReferences::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( parmVarDecl( unless(isInstantiated()), diff --git a/clang-tools-extra/clang-tidy/google/NonConstReferences.h b/clang-tools-extra/clang-tidy/google/NonConstReferences.h index 7e8934ec79a700..a8499a1982b18e 100644 --- a/clang-tools-extra/clang-tidy/google/NonConstReferences.h +++ b/clang-tools-extra/clang-tidy/google/NonConstReferences.h @@ -22,6 +22,9 @@ namespace runtime { class NonConstReferences : public ClangTidyCheck { public: NonConstReferences(StringRef Name, ClangTidyContext *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; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/google/OverloadedUnaryAndCheck.cpp b/clang-tools-extra/clang-tidy/google/OverloadedUnaryAndCheck.cpp index 1d4d10490005bc..28aa5fafde938d 100644 --- a/clang-tools-extra/clang-tidy/google/OverloadedUnaryAndCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/OverloadedUnaryAndCheck.cpp @@ -20,11 +20,6 @@ namespace runtime { void OverloadedUnaryAndCheck::registerMatchers( ast_matchers::MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - // Match unary methods that overload operator&. Finder->addMatcher( cxxMethodDecl(parameterCountIs(0), hasOverloadedOperatorName("&")) diff --git a/clang-tools-extra/clang-tidy/google/OverloadedUnaryAndCheck.h b/clang-tools-extra/clang-tidy/google/OverloadedUnaryAndCheck.h index bafbd29abb6b8b..33cf4d62a45a6f 100644 --- a/clang-tools-extra/clang-tidy/google/OverloadedUnaryAndCheck.h +++ b/clang-tools-extra/clang-tidy/google/OverloadedUnaryAndCheck.h @@ -25,6 +25,9 @@ class OverloadedUnaryAndCheck : public ClangTidyCheck { public: OverloadedUnaryAndCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp b/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp index cdb6149c441896..c14427a2b139f7 100644 --- a/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp @@ -37,9 +37,6 @@ void UnnamedNamespaceInHeaderCheck::storeOptions( void UnnamedNamespaceInHeaderCheck::registerMatchers( ast_matchers::MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (getLangOpts().CPlusPlus) Finder->addMatcher(namespaceDecl(isAnonymous()).bind("anonymousNamespace"), this); } diff --git a/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h b/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h index 517ff8bc8e7e56..fe011119f0ebd7 100644 --- a/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h +++ b/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h @@ -32,6 +32,9 @@ namespace build { class UnnamedNamespaceInHeaderCheck : public ClangTidyCheck { public: UnnamedNamespaceInHeaderCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp index 27307c000f78d6..16fed8156e81a4 100644 --- a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp @@ -121,17 +121,11 @@ class UpgradeGoogletestCasePPCallback : public PPCallbacks { void UpgradeGoogletestCaseCheck::registerPPCallbacks(const SourceManager &, Preprocessor *PP, Preprocessor *) { - if (!getLangOpts().CPlusPlus) - return; - PP->addPPCallbacks( std::make_unique(this, PP)); } void UpgradeGoogletestCaseCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - auto LocationFilter = unless(isExpansionInFileMatching("gtest/gtest(-typed-test)?\\.h$")); diff --git a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.h b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.h index 0fbd9fdf26db9d..367498b16a974f 100644 --- a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.h +++ b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.h @@ -24,6 +24,9 @@ class UpgradeGoogletestCaseCheck : public ClangTidyCheck { public: UpgradeGoogletestCaseCheck(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 registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; diff --git a/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp b/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp index f11a7d1c6117a5..20011fe70a0479 100644 --- a/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp @@ -20,9 +20,6 @@ namespace build { void UsingNamespaceDirectiveCheck::registerMatchers( ast_matchers::MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (getLangOpts().CPlusPlus) Finder->addMatcher(usingDirectiveDecl().bind("usingNamespace"), this); } diff --git a/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.h b/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.h index c9bcf48cfce3df..97a1afbf160fe1 100644 --- a/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.h +++ b/clang-tools-extra/clang-tidy/google/UsingNamespaceDirectiveCheck.h @@ -35,6 +35,9 @@ class UsingNamespaceDirectiveCheck : public ClangTidyCheck { public: UsingNamespaceDirectiveCheck(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; diff --git a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp index a58842869204d0..7416eb5f1031ed 100644 --- a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp +++ b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp @@ -17,9 +17,6 @@ namespace tidy { namespace hicpp { void ExceptionBaseclassCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( cxxThrowExpr( unless(has(expr(anyOf(isTypeDependent(), isValueDependent())))), diff --git a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.h b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.h index 1022013929c765..ed9fcb6f7eadf4 100644 --- a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.h +++ b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.h @@ -23,6 +23,9 @@ class ExceptionBaseclassCheck : public ClangTidyCheck { public: ExceptionBaseclassCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp index 560d24f010694e..b9743e94fe3440 100644 --- a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp @@ -23,9 +23,6 @@ namespace llvm_check { void PreferIsaOrDynCastInConditionalsCheck::registerMatchers( MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - auto Condition = hasCondition(implicitCastExpr(has( callExpr( allOf(unless(isMacroID()), unless(cxxMemberCallExpr()), diff --git a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.h b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.h index 2bed228e2e6ec0..723475bfe8817f 100644 --- a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.h +++ b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.h @@ -53,6 +53,9 @@ class PreferIsaOrDynCastInConditionalsCheck : public ClangTidyCheck { PreferIsaOrDynCastInConditionalsCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp b/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp index 7ff6c0d20f6300..32b75c3654536d 100644 --- a/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp @@ -49,8 +49,6 @@ void DefinitionsInHeadersCheck::storeOptions( } void DefinitionsInHeadersCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; auto DefinitionMatcher = anyOf(functionDecl(isDefinition(), unless(isDeleted())), varDecl(isDefinition())); diff --git a/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h b/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h index dda6d69ea644cb..7ba8a128f8bc06 100644 --- a/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h +++ b/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h @@ -33,6 +33,9 @@ namespace misc { class DefinitionsInHeadersCheck : public ClangTidyCheck { public: DefinitionsInHeadersCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.cpp b/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.cpp index a96d1904392c5d..3f5d59718be5cf 100644 --- a/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.cpp @@ -129,9 +129,6 @@ bool hasCorrespondingOverloadInBaseClass(const CXXMethodDecl *MD, } // anonymous namespace void NewDeleteOverloadsCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // Match all operator new and operator delete overloads (including the array // forms). Do not match implicit operators, placement operators, or // deleted/private operators. diff --git a/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.h b/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.h index cd23a746370fb4..a636d1f5514ac0 100644 --- a/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.h +++ b/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.h @@ -25,6 +25,9 @@ class NewDeleteOverloadsCheck : public ClangTidyCheck { public: NewDeleteOverloadsCheck(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; void onEndOfTranslationUnit() override; diff --git a/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp b/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp index 7f57fecde7980d..12fb7d8a7ae8ce 100644 --- a/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp @@ -50,9 +50,6 @@ NonPrivateMemberVariablesInClassesCheck:: void NonPrivateMemberVariablesInClassesCheck::registerMatchers( MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // We can ignore structs/classes with all member variables being public. auto ShouldIgnoreRecord = allOf(boolean(IgnoreClassesWithAllMemberVariablesBeingPublic), diff --git a/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h b/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h index 7bc44250128fcd..70658e1355fb2c 100644 --- a/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h +++ b/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h @@ -30,6 +30,9 @@ class NonPrivateMemberVariablesInClassesCheck : public ClangTidyCheck { public: NonPrivateMemberVariablesInClassesCheck(StringRef Name, ClangTidyContext *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; diff --git a/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.cpp b/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.cpp index a2f31797c4a364..efb3f20fbd7f93 100644 --- a/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.cpp @@ -27,11 +27,6 @@ StaticAssertCheck::StaticAssertCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} void StaticAssertCheck::registerMatchers(MatchFinder *Finder) { - // This checker only makes sense for languages that have static assertion - // capabilities: C++11 and C11. - if (!(getLangOpts().CPlusPlus11 || getLangOpts().C11)) - return; - auto NegatedString = unaryOperator( hasOperatorName("!"), hasUnaryOperand(ignoringImpCasts(stringLiteral()))); auto IsAlwaysFalse = diff --git a/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.h b/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.h index b6d7211bbb81a5..0168d1fcd107fb 100644 --- a/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.h +++ b/clang-tools-extra/clang-tidy/misc/StaticAssertCheck.h @@ -25,6 +25,9 @@ namespace misc { class StaticAssertCheck : public ClangTidyCheck { public: StaticAssertCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11 || LangOpts.C11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp b/clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp index 7b1f7eafe1ebf5..02cbf273b73a08 100644 --- a/clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp @@ -26,10 +26,6 @@ ThrowByValueCatchByReferenceCheck::ThrowByValueCatchByReferenceCheck( MaxSize(Options.get("MaxSize", std::numeric_limits::max())) {} void ThrowByValueCatchByReferenceCheck::registerMatchers(MatchFinder *Finder) { - // This is a C++ only check thus we register the matchers only for C++ - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher(cxxThrowExpr().bind("throw"), this); Finder->addMatcher(cxxCatchStmt().bind("catch"), this); } diff --git a/clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h b/clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h index ecf27e82cdd13d..fdee9a01c9c5dc 100644 --- a/clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h +++ b/clang-tools-extra/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h @@ -29,6 +29,9 @@ namespace misc { class ThrowByValueCatchByReferenceCheck : public ClangTidyCheck { public: ThrowByValueCatchByReferenceCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp index 811b55bd12bec0..93ccd5492af764 100644 --- a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp @@ -18,11 +18,6 @@ namespace misc { void UnconventionalAssignOperatorCheck::registerMatchers( ast_matchers::MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - const auto HasGoodReturnType = cxxMethodDecl(returns(lValueReferenceType( pointee(unless(isConstQualified()), anyOf(autoType(), hasDeclaration(equalsBoundNode("class"))))))); diff --git a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.h b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.h index 86e09388cd8065..829c91dbfb48fb 100644 --- a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.h +++ b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.h @@ -30,6 +30,9 @@ class UnconventionalAssignOperatorCheck : public ClangTidyCheck { public: UnconventionalAssignOperatorCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp b/clang-tools-extra/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp index 8c24cb43c4ab9b..98b53e33bdaf28 100644 --- a/clang-tools-extra/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp @@ -17,11 +17,6 @@ namespace tidy { namespace misc { void UniqueptrResetReleaseCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++11; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus11) - return; - Finder->addMatcher( cxxMemberCallExpr( on(expr().bind("left")), callee(memberExpr().bind("reset_member")), diff --git a/clang-tools-extra/clang-tidy/misc/UniqueptrResetReleaseCheck.h b/clang-tools-extra/clang-tidy/misc/UniqueptrResetReleaseCheck.h index b302f156e0dbaf..8a085322e209f4 100644 --- a/clang-tools-extra/clang-tidy/misc/UniqueptrResetReleaseCheck.h +++ b/clang-tools-extra/clang-tidy/misc/UniqueptrResetReleaseCheck.h @@ -31,6 +31,12 @@ class UniqueptrResetReleaseCheck : public ClangTidyCheck { UniqueptrResetReleaseCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + // Only register the matchers for C++11; the functionality currently does + // not + // provide any benefit to other languages, despite being benign. + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp index c301aeabd11c7e..bebf83102881b6 100644 --- a/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp @@ -18,11 +18,6 @@ namespace tidy { namespace misc { void UnusedAliasDeclsCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++11; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus11) - return; - // We cannot do anything about headers (yet), as the alias declarations // used in one header could be used by some other translation unit. Finder->addMatcher(namespaceAliasDecl(isExpansionInMainFile()).bind("alias"), diff --git a/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.h b/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.h index f25e8d8db05092..32e5e156812ea0 100644 --- a/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.h +++ b/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.h @@ -21,6 +21,9 @@ class UnusedAliasDeclsCheck : public ClangTidyCheck { public: UnusedAliasDeclsCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void onEndOfTranslationUnit() override; diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp index a80bad7ea97b7a..710d90edebbd73 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp @@ -579,9 +579,6 @@ AvoidBindCheck::AvoidBindCheck(StringRef Name, ClangTidyContext *Context) PermissiveParameterList(Options.get("PermissiveParameterList", 0) != 0) {} void AvoidBindCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus14) // Need C++14 for generic lambdas. - return; - Finder->addMatcher( callExpr( callee(namedDecl( diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.h b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.h index 5576fe6c3bd5db..8a8a1d15d120da 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.h @@ -24,6 +24,9 @@ namespace modernize { class AvoidBindCheck : public ClangTidyCheck { public: AvoidBindCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus14; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp index 1874d8ef35cfc4..bc586d30b378cb 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp @@ -43,10 +43,6 @@ namespace tidy { namespace modernize { void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) { - // std::array<> is available since C++11. - if (!getLangOpts().CPlusPlus11) - return; - Finder->addMatcher( typeLoc(hasValidBeginLoc(), hasType(arrayType()), unless(anyOf(hasParent(parmVarDecl(isArgvOfMain())), diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.h b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.h index 48e38bfbb4b0e2..2b2a64560fbd64 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.h @@ -23,6 +23,9 @@ class AvoidCArraysCheck : public ClangTidyCheck { public: AvoidCArraysCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp index c1539bfd1d28a5..48afcdc5c14bef 100644 --- a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp @@ -63,9 +63,6 @@ ConcatNestedNamespacesCheck::concatNamespaces() { void ConcatNestedNamespacesCheck::registerMatchers( ast_matchers::MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus17) - return; - Finder->addMatcher(ast_matchers::namespaceDecl().bind("namespace"), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.h b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.h index 2c589fca50797a..9dfaee2a4fa1b0 100644 --- a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.h @@ -21,6 +21,9 @@ class ConcatNestedNamespacesCheck : public ClangTidyCheck { public: ConcatNestedNamespacesCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus17; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp index 264a6f04786553..af12fec75ddc31 100644 --- a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp @@ -42,10 +42,8 @@ class IncludeModernizePPCallbacks : public PPCallbacks { void DeprecatedHeadersCheck::registerPPCallbacks( const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { - if (getLangOpts().CPlusPlus) { PP->addPPCallbacks( ::std::make_unique(*this, getLangOpts())); - } } IncludeModernizePPCallbacks::IncludeModernizePPCallbacks(ClangTidyCheck &Check, diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h index dfe6b85019f9d9..113b0ca182e0fe 100644 --- a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.h @@ -36,6 +36,9 @@ class DeprecatedHeadersCheck : public ClangTidyCheck { public: DeprecatedHeadersCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; }; diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp index e00043841b9934..15eb2e88285c4a 100644 --- a/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp @@ -27,11 +27,6 @@ static const llvm::StringMap ReplacementTypes = { {"seek_dir", "seekdir"}}; void DeprecatedIosBaseAliasesCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - auto IoStateDecl = typedefDecl(hasAnyName(DeprecatedTypes)).bind("TypeDecl"); auto IoStateType = qualType(hasDeclaration(IoStateDecl), unless(elaboratedType())); diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h b/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h index 55c1d42cb6d44f..df7d3f07b6db5e 100644 --- a/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h @@ -24,6 +24,9 @@ class DeprecatedIosBaseAliasesCheck : public ClangTidyCheck { public: DeprecatedIosBaseAliasesCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp index 7c0ae0281a9a3b..cbec56fbf7a59b 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp @@ -480,12 +480,6 @@ void LoopConvertCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void LoopConvertCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++. Because this checker is used for - // modernization, it is reasonable to run it on any C++ standard with the - // assumption the user is trying to modernize their codebase. - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher(makeArrayLoopMatcher(), this); Finder->addMatcher(makeIteratorLoopMatcher(), this); Finder->addMatcher(makePseudoArrayLoopMatcher(), this); diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.h b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.h index 1806572b9160eb..d26d87ee6ee54c 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.h @@ -19,6 +19,9 @@ namespace modernize { class LoopConvertCheck : public ClangTidyCheck { public: LoopConvertCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp index a6efdc4ab0e054..c29f8c949b338a 100644 --- a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp @@ -131,11 +131,6 @@ void PassByValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void PassByValueCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( cxxConstructorDecl( forEachConstructorInitializer( @@ -170,14 +165,9 @@ void PassByValueCheck::registerMatchers(MatchFinder *Finder) { void PassByValueCheck::registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { - // Only register the preprocessor callbacks for C++; the functionality - // currently does not provide any benefit to other languages, despite being - // benign. - if (getLangOpts().CPlusPlus) { Inserter = std::make_unique(SM, getLangOpts(), IncludeStyle); PP->addPPCallbacks(Inserter->CreatePPCallbacks()); - } } void PassByValueCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.h b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.h index 7c741956b5103b..7abda91ac56327 100644 --- a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.h @@ -21,6 +21,9 @@ namespace modernize { class PassByValueCheck : public ClangTidyCheck { public: PassByValueCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; diff --git a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp index 415010bc2b524d..fa0313f1ef0a0f 100644 --- a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp @@ -118,10 +118,6 @@ void RawStringLiteralCheck::storeOptions(ClangTidyOptions::OptionMap &Options) { } void RawStringLiteralCheck::registerMatchers(MatchFinder *Finder) { - // Raw string literals require C++11 or later. - if (!getLangOpts().CPlusPlus11) - return; - Finder->addMatcher( stringLiteral(unless(hasParent(predefinedExpr()))).bind("lit"), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.h b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.h index fd38dc27f70eb3..1733f7e1d126d3 100644 --- a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.h @@ -27,6 +27,9 @@ class RawStringLiteralCheck : public ClangTidyCheck { public: RawStringLiteralCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void storeOptions(ClangTidyOptions::OptionMap &Options) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp b/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp index 46de805ed50857..7e44738850983f 100644 --- a/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp @@ -44,9 +44,6 @@ const char LambdaId[] = "lambda"; } // namespace void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher(functionDecl(parameterCountIs(0), unless(isImplicit()), unless(isInstantiated()), unless(isExternC())) .bind(FunctionId), diff --git a/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.h b/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.h index 8b61511196b8cd..ceb123082ba43e 100644 --- a/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.h @@ -33,6 +33,10 @@ class RedundantVoidArgCheck : public ClangTidyCheck { RedundantVoidArgCheck(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; diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp index 9ed13775dd72e0..c9fcefdc7b105f 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp @@ -83,11 +83,6 @@ void ReplaceAutoPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - auto AutoPtrDecl = recordDecl(hasName("auto_ptr"), isFromStdNamespace()); auto AutoPtrType = qualType(hasDeclaration(AutoPtrDecl)); @@ -135,11 +130,6 @@ void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) { void ReplaceAutoPtrCheck::registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { - // Only register the preprocessor callbacks for C++; the functionality - // currently does not provide any benefit to other languages, despite being - // benign. - if (!getLangOpts().CPlusPlus) - return; Inserter = std::make_unique(SM, getLangOpts(), IncludeStyle); PP->addPPCallbacks(Inserter->CreatePPCallbacks()); diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.h b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.h index d1c66fca289c69..e2b04073a65f40 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.h @@ -43,6 +43,9 @@ namespace modernize { class ReplaceAutoPtrCheck : public ClangTidyCheck { public: ReplaceAutoPtrCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp index dbaceca1cdc4c5..115615417335c4 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp @@ -27,9 +27,6 @@ ReplaceRandomShuffleCheck::ReplaceRandomShuffleCheck(StringRef Name, Options.getLocalOrGlobal("IncludeStyle", "llvm"))) {} void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; - const auto Begin = hasArgument(0, expr()); const auto End = hasArgument(1, expr()); const auto RandomFunc = hasArgument(2, expr().bind("randomFunc")); diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.h b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.h index 3c5f66240769e3..c4ac74d6e662a2 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.h @@ -26,6 +26,9 @@ class ReplaceRandomShuffleCheck : public ClangTidyCheck { ReplaceRandomShuffleCheck(StringRef Name, ClangTidyContext *Context); void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp index f7e2717211fd9c..d37b276d93cf25 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp @@ -19,10 +19,6 @@ namespace tidy { namespace modernize { void ReturnBracedInitListCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++. - if (!getLangOpts().CPlusPlus11) - return; - // Skip list initialization and constructors with an initializer list. auto ConstructExpr = cxxConstructExpr( diff --git a/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.h b/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.h index 553a042ced30d2..12bd694cd3aee2 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.h @@ -24,6 +24,9 @@ class ReturnBracedInitListCheck : public ClangTidyCheck { public: ReturnBracedInitListCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp index 4b98f122c6bcbb..8f6f80cbc9571c 100644 --- a/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.cpp @@ -19,9 +19,6 @@ namespace tidy { namespace modernize { void ShrinkToFitCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; - // Swap as a function need not to be considered, because rvalue can not // be bound to a non-const reference. const auto ShrinkableAsMember = diff --git a/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.h b/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.h index 7d589b2c3f2fe2..336485572bb89f 100644 --- a/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/ShrinkToFitCheck.h @@ -25,6 +25,9 @@ class ShrinkToFitCheck : public ClangTidyCheck { public: ShrinkToFitCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.cpp index d93a02485529f5..c074b931e845d9 100644 --- a/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.cpp @@ -17,9 +17,6 @@ namespace tidy { namespace modernize { void UnaryStaticAssertCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus17) - return; - Finder->addMatcher(staticAssertDecl().bind("static_assert"), this); } diff --git a/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.h b/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.h index f43dd5ac74c591..afde7da5bb5c43 100644 --- a/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.h @@ -24,6 +24,9 @@ class UnaryStaticAssertCheck : public ClangTidyCheck { public: UnaryStaticAssertCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus17; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp index 86545d3714acb1..d0f1370a244e1b 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp @@ -325,11 +325,7 @@ void UseAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void UseAutoCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (getLangOpts().CPlusPlus) { Finder->addMatcher(makeCombinedMatcher(), this); - } } void UseAutoCheck::replaceIterators(const DeclStmt *D, ASTContext *Context) { diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.h b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.h index 600de1ef4d8a09..4ded73220b2d78 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.h @@ -18,6 +18,9 @@ namespace modernize { class UseAutoCheck : public ClangTidyCheck { public: UseAutoCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp index 011837e02bbabd..65646d6bdad114 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp @@ -23,9 +23,6 @@ UseBoolLiteralsCheck::UseBoolLiteralsCheck(StringRef Name, IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {} void UseBoolLiteralsCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( implicitCastExpr( has(ignoringParenImpCasts(integerLiteral().bind("literal"))), diff --git a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.h b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.h index 7368588e0f40b4..8bbd739e4fa17d 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.h @@ -22,6 +22,9 @@ namespace modernize { class UseBoolLiteralsCheck : public ClangTidyCheck { public: UseBoolLiteralsCheck(StringRef Name, ClangTidyContext *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; diff --git a/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp index 5d62e5446f6afe..78ccffdf1314d8 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp @@ -190,9 +190,6 @@ void UseDefaultMemberInitCheck::storeOptions( } void UseDefaultMemberInitCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; - auto Init = anyOf(stringLiteral(), characterLiteral(), integerLiteral(), unaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("-")), diff --git a/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.h b/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.h index f1e62228e98921..fc26eb55c83aee 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.h @@ -24,6 +24,9 @@ namespace modernize { class UseDefaultMemberInitCheck : public ClangTidyCheck { public: UseDefaultMemberInitCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp index 786bb5a96fb3f5..a8ae8f0d6003e1 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -40,9 +40,6 @@ UseEmplaceCheck::UseEmplaceCheck(StringRef Name, ClangTidyContext *Context) Options.get("TupleMakeFunctions", DefaultTupleMakeFunctions))) {} void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; - // FIXME: Bunch of functionality that could be easily added: // + add handling of `push_front` for std::forward_list, std::list // and std::deque. diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.h b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.h index 5382eb699ae7c5..6f34bc5b6d77f3 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.h @@ -27,6 +27,9 @@ namespace modernize { class UseEmplaceCheck : public ClangTidyCheck { public: UseEmplaceCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp index 0309fa8d0a379b..bb7c8f5d96f76e 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp @@ -208,9 +208,6 @@ void UseEqualsDefaultCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - // Destructor. Finder->addMatcher(cxxDestructorDecl(isDefinition()).bind(SpecialFunction), this); diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h index 4e2f1f81b9a725..6bc3fe08ac2b8a 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h @@ -37,6 +37,9 @@ namespace modernize { class UseEqualsDefaultCheck : public ClangTidyCheck { public: UseEqualsDefaultCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp index 4c366b4c73bede..ea4bf91b0d438e 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp @@ -25,9 +25,6 @@ void UseEqualsDeleteCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - auto PrivateSpecialFn = cxxMethodDecl( isPrivate(), anyOf(cxxConstructorDecl(anyOf(isDefaultConstructor(), diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.h b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.h index f474196d060455..10c4e43959820a 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.h @@ -39,6 +39,9 @@ class UseEqualsDeleteCheck : public ClangTidyCheck { UseEqualsDeleteCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", 1) != 0) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp index f9d72f5d62c2f6..a2e6a7a2807610 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp @@ -84,13 +84,6 @@ void UseNodiscardCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void UseNodiscardCheck::registerMatchers(MatchFinder *Finder) { - // If we use ``[[nodiscard]]`` attribute, we require at least C++17. Use a - // macro or ``__attribute__`` with pre c++17 compilers by using - // ReplacementString option. - if ((NoDiscardMacro == "[[nodiscard]]" && !getLangOpts().CPlusPlus17) || - !getLangOpts().CPlusPlus) - return; - auto FunctionObj = cxxRecordDecl(hasAnyName("::std::function", "::boost::function")); @@ -141,6 +134,18 @@ void UseNodiscardCheck::check(const MatchFinder::MatchResult &Result) { Diag << FixItHint::CreateInsertion(RetLoc, NoDiscardMacro + " "); } +bool UseNodiscardCheck::isLanguageVersionSupported( + const LangOptions &LangOpts) const { + // If we use ``[[nodiscard]]`` attribute, we require at least C++17. Use a + // macro or ``__attribute__`` with pre c++17 compilers by using + // ReplacementString option. + + if (NoDiscardMacro == "[[nodiscard]]") + return LangOpts.CPlusPlus17; + + return LangOpts.CPlusPlus; +} + } // namespace modernize } // namespace tidy } // namespace clang diff --git a/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.h b/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.h index 2a8391c2431af0..8c2872e7f51549 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.h @@ -34,6 +34,7 @@ namespace modernize { class UseNodiscardCheck : public ClangTidyCheck { public: UseNodiscardCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp index 4b9c4984558bd9..bbda8d58f10328 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp @@ -27,9 +27,6 @@ void UseNoexceptCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void UseNoexceptCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; - Finder->addMatcher( functionDecl( cxxMethodDecl( diff --git a/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.h b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.h index 854af0ac1dc293..4f3ba321483ee1 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.h @@ -32,6 +32,9 @@ namespace modernize { class UseNoexceptCheck : public ClangTidyCheck { public: UseNoexceptCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp index 6efa9822c6c46f..307297f249c6b1 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp @@ -473,11 +473,7 @@ void UseNullptrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void UseNullptrCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matcher for C++. Because this checker is used for - // modernization, it is reasonable to run it on any C++ standard with the - // assumption the user is trying to modernize their codebase. - if (getLangOpts().CPlusPlus) - Finder->addMatcher(makeCastSequenceMatcher(), this); + Finder->addMatcher(makeCastSequenceMatcher(), this); } void UseNullptrCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h index dab6ca95601051..143cba4da7d62b 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h @@ -18,6 +18,11 @@ namespace modernize { class UseNullptrCheck : public ClangTidyCheck { public: UseNullptrCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + // FIXME this should be CPlusCplus11 but that causes test cases to + // erroneously fail. + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp index 8ee77ccd16ff49..bfce7a61470f81 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp @@ -32,10 +32,6 @@ void UseOverrideCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void UseOverrideCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matcher for C++11. - if (!getLangOpts().CPlusPlus11) - return; - if (IgnoreDestructors) Finder->addMatcher( cxxMethodDecl(isOverride(), unless(cxxDestructorDecl())).bind("method"), diff --git a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.h b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.h index 082778f2957c76..abb4815967bfc2 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.h @@ -20,6 +20,9 @@ class UseOverrideCheck : public ClangTidyCheck { public: UseOverrideCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp index 41b7e1739ee0cc..f9205920ecd572 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp @@ -370,9 +370,6 @@ bool UseTrailingReturnTypeCheck::keepSpecifiers( } void UseTrailingReturnTypeCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; - auto F = functionDecl(unless(anyOf(hasTrailingReturn(), returns(voidType()), returns(autoType()), cxxConversionDecl(), cxxMethodDecl(isImplicit())))) diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h index 565000d41a7fc4..4da9b7a9aa92f5 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h @@ -30,6 +30,9 @@ class UseTrailingReturnTypeCheck : public ClangTidyCheck { public: UseTrailingReturnTypeCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp index 6490f02772fd54..e55e2fa1f84945 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp @@ -26,9 +26,6 @@ void UseTransparentFunctorsCheck::storeOptions( } void UseTransparentFunctorsCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus14) - return; - const auto TransparentFunctors = classTemplateSpecializationDecl( unless(hasAnyTemplateArgument(refersToType(voidType()))), diff --git a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.h b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.h index dce4e99abab60a..8da0ca53a9b53a 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.h @@ -22,6 +22,9 @@ namespace modernize { class UseTransparentFunctorsCheck : public ClangTidyCheck { public: UseTransparentFunctorsCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus14; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp index a7a07465bc53a9..82308f75c13307 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp @@ -17,9 +17,6 @@ namespace tidy { namespace modernize { void UseUncaughtExceptionsCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus17) - return; - std::string MatchText = "::std::uncaught_exception"; // Using declaration: warning and fix-it. diff --git a/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.h b/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.h index 2c4386e6cc638c..71ad39464658e8 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.h @@ -25,6 +25,9 @@ class UseUncaughtExceptionsCheck : public ClangTidyCheck { public: UseUncaughtExceptionsCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus17; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp index 918b4846bf3afe..f352374d4b9100 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp @@ -21,8 +21,6 @@ UseUsingCheck::UseUsingCheck(StringRef Name, ClangTidyContext *Context) IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {} void UseUsingCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; Finder->addMatcher(typedefDecl(unless(isInstantiated())).bind("typedef"), this); // This matcher used to find tag declarations in source code within typedefs. diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h index 616bc27947cfb9..b7fbf74997ae92 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h @@ -29,6 +29,9 @@ class UseUsingCheck : public ClangTidyCheck { public: UseUsingCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override { Options.store(Opts, "IgnoreMacros", IgnoreMacros); } diff --git a/clang-tools-extra/clang-tidy/objc/AvoidNSErrorInitCheck.cpp b/clang-tools-extra/clang-tidy/objc/AvoidNSErrorInitCheck.cpp index eb18dcd29eb802..de3fdd64601389 100644 --- a/clang-tools-extra/clang-tidy/objc/AvoidNSErrorInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/AvoidNSErrorInitCheck.cpp @@ -17,10 +17,6 @@ namespace tidy { namespace objc { void AvoidNSErrorInitCheck::registerMatchers(MatchFinder *Finder) { - // this check should only be applied to ObjC sources. - if (!getLangOpts().ObjC) - return; - Finder->addMatcher(objcMessageExpr(hasSelector("init"), hasReceiverType(asString("NSError *"))) .bind("nserrorInit"), diff --git a/clang-tools-extra/clang-tidy/objc/AvoidNSErrorInitCheck.h b/clang-tools-extra/clang-tidy/objc/AvoidNSErrorInitCheck.h index 030a532eebf546..ea12516a8149c6 100644 --- a/clang-tools-extra/clang-tidy/objc/AvoidNSErrorInitCheck.h +++ b/clang-tools-extra/clang-tidy/objc/AvoidNSErrorInitCheck.h @@ -24,6 +24,9 @@ class AvoidNSErrorInitCheck : public ClangTidyCheck { public: AvoidNSErrorInitCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.ObjC; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/objc/DeallocInCategoryCheck.cpp b/clang-tools-extra/clang-tidy/objc/DeallocInCategoryCheck.cpp index 4680657426701a..8c5ecb778397d3 100644 --- a/clang-tools-extra/clang-tidy/objc/DeallocInCategoryCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/DeallocInCategoryCheck.cpp @@ -18,10 +18,6 @@ namespace tidy { namespace objc { void DeallocInCategoryCheck::registerMatchers(MatchFinder *Finder) { - // This check should only be applied to Objective-C sources. - if (!getLangOpts().ObjC) - return; - // Non-NSObject/NSProxy-derived objects may not have -dealloc as a special // method. However, it seems highly unrealistic to expect many false-positives // by warning on -dealloc in categories on classes without one of those diff --git a/clang-tools-extra/clang-tidy/objc/DeallocInCategoryCheck.h b/clang-tools-extra/clang-tidy/objc/DeallocInCategoryCheck.h index f8e1f70e216b22..a655eae31e859b 100644 --- a/clang-tools-extra/clang-tidy/objc/DeallocInCategoryCheck.h +++ b/clang-tools-extra/clang-tidy/objc/DeallocInCategoryCheck.h @@ -25,6 +25,9 @@ class DeallocInCategoryCheck final : public ClangTidyCheck { public: DeallocInCategoryCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.ObjC; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/objc/ForbiddenSubclassingCheck.cpp b/clang-tools-extra/clang-tidy/objc/ForbiddenSubclassingCheck.cpp index 0703bca7356ba4..956cb79ed517eb 100644 --- a/clang-tools-extra/clang-tidy/objc/ForbiddenSubclassingCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/ForbiddenSubclassingCheck.cpp @@ -49,10 +49,6 @@ ForbiddenSubclassingCheck::ForbiddenSubclassingCheck( } void ForbiddenSubclassingCheck::registerMatchers(MatchFinder *Finder) { - // this check should only be applied to ObjC sources. - if (!getLangOpts().ObjC) - return; - Finder->addMatcher( objcInterfaceDecl( isDerivedFrom( diff --git a/clang-tools-extra/clang-tidy/objc/ForbiddenSubclassingCheck.h b/clang-tools-extra/clang-tidy/objc/ForbiddenSubclassingCheck.h index c05ba084e89e81..27be9c9463bcad 100644 --- a/clang-tools-extra/clang-tidy/objc/ForbiddenSubclassingCheck.h +++ b/clang-tools-extra/clang-tidy/objc/ForbiddenSubclassingCheck.h @@ -26,6 +26,9 @@ namespace objc { class ForbiddenSubclassingCheck : public ClangTidyCheck { public: ForbiddenSubclassingCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.ObjC; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Options) override; diff --git a/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp b/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp index 0da5571b2f26ca..26104ed8f19695 100644 --- a/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp @@ -37,10 +37,6 @@ AST_MATCHER_P(ObjCContainerDecl, hasInstanceMethod, } // namespace void MissingHashCheck::registerMatchers(MatchFinder *Finder) { - // This check should only be applied to Objective-C sources. - if (!getLangOpts().ObjC) - return; - Finder->addMatcher( objcMethodDecl( hasName("isEqual:"), isInstanceMethod(), diff --git a/clang-tools-extra/clang-tidy/objc/MissingHashCheck.h b/clang-tools-extra/clang-tidy/objc/MissingHashCheck.h index 4ac74d58652182..5e4b96a71983a2 100644 --- a/clang-tools-extra/clang-tidy/objc/MissingHashCheck.h +++ b/clang-tools-extra/clang-tidy/objc/MissingHashCheck.h @@ -24,6 +24,9 @@ class MissingHashCheck : public ClangTidyCheck { public: MissingHashCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.ObjC; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/objc/PropertyDeclarationCheck.cpp b/clang-tools-extra/clang-tidy/objc/PropertyDeclarationCheck.cpp index 094c193c15ccc3..b4e6d0e3d20205 100644 --- a/clang-tools-extra/clang-tidy/objc/PropertyDeclarationCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/PropertyDeclarationCheck.cpp @@ -98,9 +98,6 @@ bool prefixedPropertyNameValid(llvm::StringRef PropertyName) { } // namespace void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) { - // this check should only be applied to ObjC sources. - if (!getLangOpts().ObjC) return; - Finder->addMatcher(objcPropertyDecl( // the property name should be in Lower Camel Case like // 'lowerCamelCase' diff --git a/clang-tools-extra/clang-tidy/objc/PropertyDeclarationCheck.h b/clang-tools-extra/clang-tidy/objc/PropertyDeclarationCheck.h index 769f0c4cac57d0..4b4ac469dca4cf 100644 --- a/clang-tools-extra/clang-tidy/objc/PropertyDeclarationCheck.h +++ b/clang-tools-extra/clang-tidy/objc/PropertyDeclarationCheck.h @@ -27,6 +27,9 @@ class PropertyDeclarationCheck : public ClangTidyCheck { public: PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.ObjC; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp b/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp index 6ef1f0c564d082..6a382fef044576 100644 --- a/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp @@ -75,10 +75,6 @@ AST_MATCHER(ObjCMessageExpr, isMessagingSuperInstance) { } // namespace void SuperSelfCheck::registerMatchers(MatchFinder *Finder) { - // This check should only be applied to Objective-C sources. - if (!getLangOpts().ObjC) - return; - Finder->addMatcher( objcMessageExpr(hasSelector("self"), isMessagingSuperInstance(), hasAncestor(objcMethodDecl( diff --git a/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.h b/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.h index ed5d1cd09998a7..03f0fc1bb1f9b4 100644 --- a/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.h +++ b/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.h @@ -25,6 +25,9 @@ class SuperSelfCheck : public ClangTidyCheck { public: SuperSelfCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.ObjC; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.cpp b/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.cpp index c3894a6c81ac73..aa06941d93457a 100644 --- a/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.cpp +++ b/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.cpp @@ -43,14 +43,6 @@ void ExceptionEscapeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void ExceptionEscapeCheck::registerMatchers(MatchFinder *Finder) { - // Don't register the check if OpenMP is not enabled; the OpenMP pragmas are - // completely ignored then, so no OpenMP entires will be present in the AST. - if (!getLangOpts().OpenMP) - return; - // Similarly, if C++ Exceptions are not enabled, nothing to do. - if (!getLangOpts().CPlusPlus || !getLangOpts().CXXExceptions) - return; - Finder->addMatcher(ompExecutableDirective( unless(isStandaloneDirective()), hasStructuredBlock(stmt().bind("structured-block"))) diff --git a/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.h b/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.h index bcbeccd58540a4..d7a80feaec0994 100644 --- a/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.h +++ b/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.h @@ -24,6 +24,9 @@ namespace openmp { class ExceptionEscapeCheck : public ClangTidyCheck { public: ExceptionEscapeCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.OpenMP && LangOpts.CPlusPlus && LangOpts.CXXExceptions; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp b/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp index c8a88c64c503b3..efd70e778c6f1b 100644 --- a/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp +++ b/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp @@ -22,11 +22,6 @@ namespace tidy { namespace openmp { void UseDefaultNoneCheck::registerMatchers(MatchFinder *Finder) { - // Don't register the check if OpenMP is not enabled; the OpenMP pragmas are - // completely ignored then, so no OpenMP entires will be present in the AST. - if (!getLangOpts().OpenMP) - return; - Finder->addMatcher( ompExecutableDirective( allOf(isAllowedToContainClauseKind(OMPC_default), diff --git a/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.h b/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.h index c5ff8829cd300a..09744c01a7cc47 100644 --- a/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.h +++ b/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.h @@ -25,6 +25,9 @@ class UseDefaultNoneCheck : public ClangTidyCheck { public: UseDefaultNoneCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.OpenMP; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp index 5ce5ffa067aeed..8dda7a8022147e 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.cpp @@ -27,11 +27,6 @@ static bool areTypesCompatible(QualType Left, QualType Right) { } void InefficientAlgorithmCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - const auto Algorithms = hasAnyName("::std::find", "::std::count", "::std::equal_range", "::std::lower_bound", "::std::upper_bound"); diff --git a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.h b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.h index eba6207ed740e8..14f8fbbab2aef0 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.h +++ b/clang-tools-extra/clang-tidy/performance/InefficientAlgorithmCheck.h @@ -24,6 +24,9 @@ class InefficientAlgorithmCheck : public ClangTidyCheck { public: InefficientAlgorithmCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.cpp index fe4b5a9e8ae849..8b48093acfae30 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.cpp @@ -28,9 +28,6 @@ InefficientStringConcatenationCheck::InefficientStringConcatenationCheck( void InefficientStringConcatenationCheck::registerMatchers( MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - const auto BasicStringType = hasType(qualType(hasUnqualifiedDesugaredType(recordType( hasDeclaration(cxxRecordDecl(hasName("::std::basic_string"))))))); diff --git a/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.h b/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.h index 83f27bb268660b..512f5c19532615 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.h +++ b/clang-tools-extra/clang-tidy/performance/InefficientStringConcatenationCheck.h @@ -25,6 +25,9 @@ class InefficientStringConcatenationCheck : public ClangTidyCheck { public: InefficientStringConcatenationCheck(StringRef Name, ClangTidyContext *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; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp index 8b5838f9f065a7..17eb62a41a1d0e 100644 --- a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp @@ -40,9 +40,6 @@ void MoveConstArgCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void MoveConstArgCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - auto MoveCallMatcher = callExpr(callee(functionDecl(hasName("::std::move"))), argumentCountIs(1), unless(isInTemplateInstantiation())) diff --git a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.h b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.h index 7fc10adb1377b2..28fe8d523d9431 100644 --- a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.h +++ b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.h @@ -27,6 +27,9 @@ class MoveConstArgCheck : public ClangTidyCheck { : ClangTidyCheck(Name, Context), CheckTriviallyCopyableMove( Options.get("CheckTriviallyCopyableMove", true)) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp b/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp index f64d91b0a940d0..b852734b8caf22 100644 --- a/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp @@ -27,11 +27,6 @@ MoveConstructorInitCheck::MoveConstructorInitCheck(StringRef Name, Options.getLocalOrGlobal("IncludeStyle", "llvm"))) {} void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++11; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus11) - return; - Finder->addMatcher( cxxConstructorDecl( unless(isImplicit()), isMoveConstructor(), diff --git a/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.h b/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.h index a84d05268072a0..0473978f29db44 100644 --- a/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.h +++ b/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.h @@ -26,6 +26,9 @@ namespace performance { class MoveConstructorInitCheck : public ClangTidyCheck { public: MoveConstructorInitCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, diff --git a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp index d806c98d5c41b7..8ce8bb479ee5c7 100644 --- a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp @@ -25,10 +25,6 @@ NoAutomaticMoveCheck::NoAutomaticMoveCheck(StringRef Name, utils::options::parseStringList(Options.get("AllowedTypes", ""))) {} void NoAutomaticMoveCheck::registerMatchers(MatchFinder *Finder) { - // Automatic move exists only for c++11 onwards. - if (!getLangOpts().CPlusPlus11) - return; - const auto ConstLocalVariable = varDecl(hasLocalStorage(), unless(hasType(lValueReferenceType())), hasType(qualType( diff --git a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.h b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.h index ed521f1352e8b2..037a34eeb94687 100644 --- a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.h +++ b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.h @@ -21,6 +21,9 @@ namespace performance { class NoAutomaticMoveCheck : public ClangTidyCheck { public: NoAutomaticMoveCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp b/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp index e55ce36ceb3c38..a54b295b2e0c71 100644 --- a/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp @@ -18,11 +18,6 @@ namespace tidy { namespace performance { void NoexceptMoveConstructorCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++11; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus11) - return; - Finder->addMatcher( cxxMethodDecl(anyOf(cxxConstructorDecl(), hasOverloadedOperatorName("=")), unless(isImplicit()), unless(isDeleted())) diff --git a/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.h b/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.h index bf000bd458b066..473b5185895487 100644 --- a/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.h +++ b/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.h @@ -26,6 +26,9 @@ class NoexceptMoveConstructorCheck : public ClangTidyCheck { public: NoexceptMoveConstructorCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp b/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp index 5ed705b0cd791f..1c20e581310382 100644 --- a/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp @@ -36,9 +36,6 @@ AST_MATCHER_P(CXXRecordDecl, hasBase, Matcher, InnerMatcher) { } // namespace void TriviallyDestructibleCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; - Finder->addMatcher( cxxDestructorDecl( isDefaulted(), diff --git a/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.h b/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.h index ee3fb40c2a91dd..e644fd8140efbe 100644 --- a/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.h +++ b/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.h @@ -29,6 +29,9 @@ class TriviallyDestructibleCheck : public ClangTidyCheck { public: TriviallyDestructibleCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp index c840bd61891d44..6182be47c78361 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp @@ -73,10 +73,6 @@ UnnecessaryValueParamCheck::UnnecessaryValueParamCheck( utils::options::parseStringList(Options.get("AllowedTypes", ""))) {} void UnnecessaryValueParamCheck::registerMatchers(MatchFinder *Finder) { - // This check is specific to C++ and doesn't apply to languages like - // Objective-C. - if (!getLangOpts().CPlusPlus) - return; const auto ExpensiveValueParamDecl = parmVarDecl( hasType(qualType( hasCanonicalType(matchers::isExpensiveToCopy()), diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h index e945a148e454ca..1d2367148ef82d 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h @@ -25,6 +25,9 @@ namespace performance { class UnnecessaryValueParamCheck : public ClangTidyCheck { public: UnnecessaryValueParamCheck(StringRef Name, ClangTidyContext *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; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, diff --git a/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.cpp b/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.cpp index d9e3d263634760..ac0b61c96a93c1 100644 --- a/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.cpp +++ b/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.cpp @@ -92,8 +92,6 @@ void SIMDIntrinsicsCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void SIMDIntrinsicsCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; // If Std is not specified, infer it from the language options. // libcxx implementation backports it to C++11 std::experimental::simd. if (Std.empty()) diff --git a/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.h b/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.h index 8f3a9902c42f9c..17ed4bb3c11d84 100644 --- a/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.h +++ b/clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.h @@ -25,6 +25,9 @@ class SIMDIntrinsicsCheck : public ClangTidyCheck { public: SIMDIntrinsicsCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp index 1086340a30a644..6f5cc186166622 100644 --- a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp @@ -26,11 +26,6 @@ ContainerSizeEmptyCheck::ContainerSizeEmptyCheck(StringRef Name, : ClangTidyCheck(Name, Context) {} void ContainerSizeEmptyCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - const auto ValidContainer = qualType(hasUnqualifiedDesugaredType( recordType(hasDeclaration(cxxRecordDecl(isSameOrDerivedFrom( namedDecl( diff --git a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.h b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.h index 26a6b9eea2a7ef..8afff2265b1ca3 100644 --- a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.h +++ b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.h @@ -28,6 +28,9 @@ namespace readability { class ContainerSizeEmptyCheck : public ClangTidyCheck { public: ContainerSizeEmptyCheck(StringRef Name, ClangTidyContext *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; }; diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp index aae5bcff7bbed9..2d5e2487951514 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp @@ -257,12 +257,6 @@ void ImplicitBoolConversionCheck::storeOptions( } void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) { - // This check doesn't make much sense if we run it on language without - // built-in bool support. - if (!getLangOpts().Bool) { - return; - } - auto exceptionCases = expr(anyOf(allOf(isMacroExpansion(), unless(isNULLMacroExpansion())), has(ignoringImplicit(memberExpr(hasDeclaration(fieldDecl(hasBitWidth(1)))))), diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h index 5af0274c9b7d3f..03abeaffe4aa03 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h @@ -22,8 +22,10 @@ namespace readability { class ImplicitBoolConversionCheck : public ClangTidyCheck { public: ImplicitBoolConversionCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.Bool; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; - void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp index 3f1dcfe803e2d6..3f096c22ac00af 100644 --- a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp @@ -209,9 +209,6 @@ AST_MATCHER(CXXMethodDecl, usesThisAsConst) { } void MakeMemberFunctionConstCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( cxxMethodDecl( isDefinition(), isUserProvided(), diff --git a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.h b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.h index 28d7bda5214169..f07f66b123354e 100644 --- a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.h +++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.h @@ -23,6 +23,9 @@ class MakeMemberFunctionConstCheck : public ClangTidyCheck { public: MakeMemberFunctionConstCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp index 9580373d4a4f2a..6b5569085f7144 100644 --- a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp @@ -36,10 +36,7 @@ void NamespaceCommentCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void NamespaceCommentCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (getLangOpts().CPlusPlus) - Finder->addMatcher(namespaceDecl().bind("namespace"), this); + Finder->addMatcher(namespaceDecl().bind("namespace"), this); } static bool locationsInSameFile(const SourceManager &Sources, diff --git a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.h b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.h index 712cd4662965ef..84ece6437fb03a 100644 --- a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.h +++ b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.h @@ -24,6 +24,9 @@ namespace readability { class NamespaceCommentCheck : public ClangTidyCheck { public: NamespaceCommentCheck(StringRef Name, ClangTidyContext *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; diff --git a/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp b/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp index 79885dbe4b43cd..9ca4d2e1ad4deb 100644 --- a/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp @@ -107,9 +107,6 @@ void QualifiedAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus11) - return; // Auto deduction not used in 'C or C++03 and earlier', so don't - // register Matchers. auto ExplicitSingleVarDecl = [](const ast_matchers::internal::Matcher &InnerMatcher, llvm::StringRef ID) { diff --git a/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.h b/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.h index 448b8e9353e453..d327bf64968fb2 100644 --- a/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.h +++ b/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.h @@ -26,6 +26,9 @@ class QualifiedAutoCheck : public ClangTidyCheck { QualifiedAutoCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), AddConstToQualified(Options.get("AddConstToQualified", true)) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.cpp index 22625c91258014..cf7fc03bc58e4c 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.cpp @@ -17,9 +17,6 @@ namespace tidy { namespace readability { void RedundantAccessSpecifiersCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - Finder->addMatcher( cxxRecordDecl(has(accessSpecDecl())).bind("redundant-access-specifiers"), this); diff --git a/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.h index 2aee22f1077c5a..507687f6846fa7 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.h @@ -25,6 +25,9 @@ class RedundantAccessSpecifiersCheck : public ClangTidyCheck { : ClangTidyCheck(Name, Context), CheckFirstDeclaration( Options.getLocalOrGlobal("CheckFirstDeclaration", false)) {} + 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; diff --git a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp index cf48bbdc621049..09be12a71926c7 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp @@ -26,9 +26,6 @@ void RedundantMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - auto Construct = cxxConstructExpr( hasDeclaration(cxxConstructorDecl(hasParent( diff --git a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.h index b8e11a6ceee9ae..438db4c722ffbf 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.h @@ -26,6 +26,9 @@ class RedundantMemberInitCheck : public ClangTidyCheck { : ClangTidyCheck(Name, Context), IgnoreBaseInCopyConstructors( Options.get("IgnoreBaseInCopyConstructors", 0)) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp index 834c0cbadb0c41..688efc6a988b2e 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp @@ -99,11 +99,6 @@ void RedundantSmartptrGetCheck::storeOptions( } void RedundantSmartptrGetCheck::registerMatchers(MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - registerMatchersForGetArrowStart(Finder, this); registerMatchersForGetEquals(Finder, this); } diff --git a/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.h index 66c13542ed73b9..4d2d9bf5f47c76 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.h @@ -29,6 +29,9 @@ class RedundantSmartptrGetCheck : public ClangTidyCheck { RedundantSmartptrGetCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", 1) != 0) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp index 2938e2b9c7cd06..aa5e0ba767f792 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp @@ -114,11 +114,6 @@ AST_MATCHER(CXXConstructExpr, void RedundantStringCStrCheck::registerMatchers( ast_matchers::MatchFinder *Finder) { - // Only register the matchers for C++; the functionality currently does not - // provide any benefit to other languages, despite being benign. - if (!getLangOpts().CPlusPlus) - return; - // Match expressions of type 'string' or 'string*'. const auto StringDecl = type(hasUnqualifiedDesugaredType(recordType( hasDeclaration(cxxRecordDecl(hasName("::std::basic_string")))))); diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.h index 0448865f4a2a0c..c808f2a3427714 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.h @@ -20,6 +20,9 @@ class RedundantStringCStrCheck : public ClangTidyCheck { public: RedundantStringCStrCheck(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; }; diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp index 866bb79829d85c..6c54ca874401c1 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp @@ -71,8 +71,6 @@ void RedundantStringInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; const auto hasStringTypeName = hasAnyNameStdString(StringNames); const auto hasStringCtorName = hasAnyNameStdString(removeNamespaces(StringNames)); diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.h index 9ab009aea84dd7..bf694fdc0ba191 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.h @@ -21,6 +21,9 @@ namespace readability { class RedundantStringInitCheck : public ClangTidyCheck { public: RedundantStringInitCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp b/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp index ec060f86378385..3dd646b2edd442 100644 --- a/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.cpp @@ -27,9 +27,6 @@ SimplifySubscriptExprCheck::SimplifySubscriptExprCheck( } void SimplifySubscriptExprCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - const auto TypesMatcher = hasUnqualifiedDesugaredType( recordType(hasDeclaration(cxxRecordDecl(hasAnyName( llvm::SmallVector(Types.begin(), Types.end())))))); diff --git a/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.h b/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.h index 01d4e4bf3d8239..4f43cdb726df5d 100644 --- a/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.h +++ b/clang-tools-extra/clang-tidy/readability/SimplifySubscriptExprCheck.h @@ -22,6 +22,9 @@ namespace readability { class SimplifySubscriptExprCheck : public ClangTidyCheck { public: SimplifySubscriptExprCheck(StringRef Name, ClangTidyContext *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; void storeOptions(ClangTidyOptions::OptionMap& Opts) override; diff --git a/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp b/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp index 1064c3a8ea4a35..2c0df515893d0f 100644 --- a/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/StringCompareCheck.cpp @@ -23,9 +23,6 @@ static const StringRef CompareMessage = "do not use 'compare' to test equality " "operator instead"; void StringCompareCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - const auto StrCompare = cxxMemberCallExpr( callee(cxxMethodDecl(hasName("compare"), ofClass(classTemplateSpecializationDecl( diff --git a/clang-tools-extra/clang-tidy/readability/StringCompareCheck.h b/clang-tools-extra/clang-tidy/readability/StringCompareCheck.h index d58cce6a512381..3d2a3abbe4467d 100644 --- a/clang-tools-extra/clang-tidy/readability/StringCompareCheck.h +++ b/clang-tools-extra/clang-tidy/readability/StringCompareCheck.h @@ -24,6 +24,9 @@ class StringCompareCheck : public ClangTidyCheck { public: StringCompareCheck(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; }; From 388bccb0135977a9d51e18e59cdebb26071cb842 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Tue, 3 Mar 2020 16:13:52 +0100 Subject: [PATCH 25/29] Add module for llvm/Bitstream --- llvm/include/llvm/module.modulemap | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/llvm/include/llvm/module.modulemap b/llvm/include/llvm/module.modulemap index f3623a6ff5da6d..39f489d10d4404 100644 --- a/llvm/include/llvm/module.modulemap +++ b/llvm/include/llvm/module.modulemap @@ -47,6 +47,11 @@ module LLVM_Bitcode { module * { export * } } +module LLVM_Bitstream { + requires cplusplus + umbrella "Bitstream" + module * { export * } +} module LLVM_BinaryFormat { requires cplusplus From c5ec8890c95bf9f56beff285efbcc7b797ffb15a Mon Sep 17 00:00:00 2001 From: Tyker Date: Tue, 3 Mar 2020 17:42:57 +0100 Subject: [PATCH 26/29] [NFC] Try fix ubsan buildbot after 876d13378931bee3dcefafff8729c40d5457ff31 --- llvm/include/llvm/IR/Attributes.h | 4 +++- llvm/include/llvm/Transforms/Utils/KnowledgeRetention.h | 6 ++---- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 2 ++ llvm/lib/Transforms/Utils/CodeExtractor.cpp | 2 ++ 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h index 3871db9a200ed6..c8d6db66c36a25 100644 --- a/llvm/include/llvm/IR/Attributes.h +++ b/llvm/include/llvm/IR/Attributes.h @@ -73,7 +73,9 @@ class Attribute { #define GET_ATTR_NAMES #define ATTRIBUTE_ENUM(ENUM_NAME, OTHER) ENUM_NAME, #include "llvm/IR/Attributes.inc" - EndAttrKinds ///< Sentinal value useful for loops + EndAttrKinds, ///< Sentinal value useful for loops + EmptyKey, ///< Use as Empty key for DenseMap of AttrKind + TombstoneKey, ///< Use as Tombstone key for DenseMap of AttrKind }; private: diff --git a/llvm/include/llvm/Transforms/Utils/KnowledgeRetention.h b/llvm/include/llvm/Transforms/Utils/KnowledgeRetention.h index c3baf8a43c0d80..fcc0dae76fe1e5 100644 --- a/llvm/include/llvm/Transforms/Utils/KnowledgeRetention.h +++ b/llvm/include/llvm/Transforms/Utils/KnowledgeRetention.h @@ -60,13 +60,11 @@ inline bool hasAttributeInAssume(CallInst &AssumeCI, Value *IsOn, } template<> struct DenseMapInfo { - static constexpr auto MaxValue = std::numeric_limits< - std::underlying_type::type>::max(); static Attribute::AttrKind getEmptyKey() { - return static_cast(MaxValue); + return Attribute::EmptyKey; } static Attribute::AttrKind getTombstoneKey() { - return static_cast(MaxValue - 1); + return Attribute::TombstoneKey; } static unsigned getHashValue(Attribute::AttrKind AK) { return hash_combine(AK); diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 0d243593288882..de2a6b47e6e294 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1218,6 +1218,8 @@ StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context) { static uint64_t getRawAttributeMask(Attribute::AttrKind Val) { switch (Val) { case Attribute::EndAttrKinds: + case Attribute::EmptyKey: + case Attribute::TombstoneKey: llvm_unreachable("Synthetic enumerators which should never get here"); case Attribute::None: return 0; diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index e72e17f495afed..d026e4793b1563 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -887,6 +887,8 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs, case Attribute::ZExt: case Attribute::ImmArg: case Attribute::EndAttrKinds: + case Attribute::EmptyKey: + case Attribute::TombstoneKey: continue; // Those attributes should be safe to propagate to the extracted function. case Attribute::AlwaysInline: From 55a56041d1da59dacb8f9abb1f3bfa841798e6cc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 27 Feb 2020 21:57:40 -0800 Subject: [PATCH 27/29] [MCDwarf] Generate DWARF v5 .debug_rnglists for assembly files ``` // clang -c -gdwarf-5 a.s -o a.o .section .init; ret .text; ret ``` .debug_info contains DW_AT_ranges and llvm-dwarfdump will report a verification error because .debug_rnglists does not exist (not implemented). This patch generates .debug_rnglists for assembly files. emitListsTableHeaderStart() in DwarfDebug.cpp can be shared with MCDwarf.cpp. Because CodeGen depends on MC, I move the function to MCDwarf.cpp Reviewed By: probinson Differential Revision: https://reviews.llvm.org/D75375 --- llvm/include/llvm/MC/MCDwarf.h | 6 + llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 25 +--- llvm/lib/MC/MCDwarf.cpp | 119 +++++++++++------- .../test/MC/ARM/dwarf-asm-multiple-sections.s | 54 +++++--- 4 files changed, 119 insertions(+), 85 deletions(-) diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h index 9dead61eb737ac..2938245d566995 100644 --- a/llvm/include/llvm/MC/MCDwarf.h +++ b/llvm/include/llvm/MC/MCDwarf.h @@ -41,6 +41,12 @@ class raw_ostream; class SMLoc; class SourceMgr; +namespace mcdwarf { +// Emit the common part of the DWARF 5 range/locations list tables header. +void emitListsTableHeaderStart(MCStreamer *S, MCSymbol *TableStart, + MCSymbol *TableEnd); +} // namespace mcdwarf + /// Instances of this class represent the name of the dwarf .file directive and /// its associated dwarf file number in the MC file. MCDwarfFile's are created /// and uniqued by the MCContext class. In Dwarf 4 file numbers start from 1; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 40ab350a110e85..dfa09d7a8c0d21 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2400,25 +2400,6 @@ void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, emitDebugLocEntry(Streamer, Entry, CU); } -// Emit the common part of the DWARF 5 range/locations list tables header. -static void emitListsTableHeaderStart(AsmPrinter *Asm, - MCSymbol *TableStart, - MCSymbol *TableEnd) { - // Build the table header, which starts with the length field. - Asm->OutStreamer->AddComment("Length"); - Asm->emitLabelDifference(TableEnd, TableStart, 4); - Asm->OutStreamer->emitLabel(TableStart); - // Version number (DWARF v5 and later). - Asm->OutStreamer->AddComment("Version"); - Asm->emitInt16(Asm->OutStreamer->getContext().getDwarfVersion()); - // Address size. - Asm->OutStreamer->AddComment("Address size"); - Asm->emitInt8(Asm->MAI->getCodePointerSize()); - // Segment selector size. - Asm->OutStreamer->AddComment("Segment selector size"); - Asm->emitInt8(0); -} - // Emit the header of a DWARF 5 range list table list table. Returns the symbol // that designates the end of the table for the caller to emit when the table is // complete. @@ -2426,7 +2407,8 @@ static MCSymbol *emitRnglistsTableHeader(AsmPrinter *Asm, const DwarfFile &Holder) { MCSymbol *TableStart = Asm->createTempSymbol("debug_rnglist_table_start"); MCSymbol *TableEnd = Asm->createTempSymbol("debug_rnglist_table_end"); - emitListsTableHeaderStart(Asm, TableStart, TableEnd); + mcdwarf::emitListsTableHeaderStart(Asm->OutStreamer.get(), TableStart, + TableEnd); Asm->OutStreamer->AddComment("Offset entry count"); Asm->emitInt32(Holder.getRangeLists().size()); @@ -2445,7 +2427,8 @@ static MCSymbol *emitLoclistsTableHeader(AsmPrinter *Asm, const DwarfDebug &DD) { MCSymbol *TableStart = Asm->createTempSymbol("debug_loclist_table_start"); MCSymbol *TableEnd = Asm->createTempSymbol("debug_loclist_table_end"); - emitListsTableHeaderStart(Asm, TableStart, TableEnd); + mcdwarf::emitListsTableHeaderStart(Asm->OutStreamer.get(), TableStart, + TableEnd); const auto &DebugLocs = DD.getDebugLocs(); diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index ecf7581b3ef34f..a0d47569e01c09 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -45,6 +45,19 @@ using namespace llvm; +void mcdwarf::emitListsTableHeaderStart(MCStreamer *S, MCSymbol *TableStart, + MCSymbol *TableEnd) { + S->AddComment("Length"); + S->emitAbsoluteSymbolDiff(TableEnd, TableStart, 4); + S->emitLabel(TableStart); + S->AddComment("Version"); + S->emitInt16(S->getContext().getDwarfVersion()); + S->AddComment("Address size"); + S->emitInt8(S->getContext().getAsmInfo()->getCodePointerSize()); + S->AddComment("Segment selector size"); + S->emitInt8(0); +} + /// Manage the .debug_line_str section contents, if we use it. class llvm::MCDwarfLineStr { MCSymbol *LineStrLabel = nullptr; @@ -925,7 +938,7 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS, static void EmitGenDwarfInfo(MCStreamer *MCOS, const MCSymbol *AbbrevSectionSymbol, const MCSymbol *LineSectionSymbol, - const MCSymbol *RangesSectionSymbol) { + const MCSymbol *RangesSymbol) { MCContext &context = MCOS->getContext(); MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection()); @@ -977,13 +990,11 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, else MCOS->emitInt32(0); - if (RangesSectionSymbol) { - // There are multiple sections containing code, so we must use the - // .debug_ranges sections. - - // AT_ranges, the 4 byte offset from the start of the .debug_ranges section - // to the address range list for this compilation unit. - MCOS->emitSymbolValue(RangesSectionSymbol, 4); + if (RangesSymbol) { + // There are multiple sections containing code, so we must use + // .debug_ranges/.debug_rnglists. AT_ranges, the 4 byte offset from the + // start of the .debug_ranges/.debug_rnglists. + MCOS->emitSymbolValue(RangesSymbol, 4); } else { // If we only have one non-empty code section, we can use the simpler // AT_low_pc and AT_high_pc attributes. @@ -1096,37 +1107,65 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, // When generating dwarf for assembly source files this emits the data for // .debug_ranges section. We only emit one range list, which spans all of the // executable sections of this file. -static void EmitGenDwarfRanges(MCStreamer *MCOS) { +static MCSymbol *emitGenDwarfRanges(MCStreamer *MCOS) { MCContext &context = MCOS->getContext(); auto &Sections = context.getGenDwarfSectionSyms(); const MCAsmInfo *AsmInfo = context.getAsmInfo(); int AddrSize = AsmInfo->getCodePointerSize(); + MCSymbol *RangesSymbol; + + if (MCOS->getContext().getDwarfVersion() >= 5) { + MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRnglistsSection()); + MCSymbol *StartSymbol = + context.createTempSymbol("debug_rnglists_start", true, true); + MCSymbol *EndSymbol = + context.createTempSymbol("debug_rnglists_end", true, true); + mcdwarf::emitListsTableHeaderStart(MCOS, StartSymbol, EndSymbol); + MCOS->AddComment("Offset entry count"); + MCOS->emitInt32(0); + RangesSymbol = context.createTempSymbol("debug_rnglist0_start", true, true); + MCOS->emitLabel(RangesSymbol); + for (MCSection *Sec : Sections) { + const MCSymbol *StartSymbol = Sec->getBeginSymbol(); + const MCSymbol *EndSymbol = Sec->getEndSymbol(context); + const MCExpr *SectionStartAddr = MCSymbolRefExpr::create( + StartSymbol, MCSymbolRefExpr::VK_None, context); + const MCExpr *SectionSize = + MakeStartMinusEndExpr(*MCOS, *StartSymbol, *EndSymbol, 0); + MCOS->emitInt8(dwarf::DW_RLE_start_length); + MCOS->emitValue(SectionStartAddr, AddrSize); + MCOS->emitULEB128Value(SectionSize); + } + MCOS->emitInt8(dwarf::DW_RLE_end_of_list); + MCOS->emitLabel(EndSymbol); + } else { + MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection()); + RangesSymbol = context.createTempSymbol("debug_ranges_start", true, true); + MCOS->emitLabel(RangesSymbol); + for (MCSection *Sec : Sections) { + const MCSymbol *StartSymbol = Sec->getBeginSymbol(); + const MCSymbol *EndSymbol = Sec->getEndSymbol(context); + + // Emit a base address selection entry for the section start. + const MCExpr *SectionStartAddr = MCSymbolRefExpr::create( + StartSymbol, MCSymbolRefExpr::VK_None, context); + MCOS->emitFill(AddrSize, 0xFF); + MCOS->emitValue(SectionStartAddr, AddrSize); + + // Emit a range list entry spanning this section. + const MCExpr *SectionSize = + MakeStartMinusEndExpr(*MCOS, *StartSymbol, *EndSymbol, 0); + MCOS->emitIntValue(0, AddrSize); + emitAbsValue(*MCOS, SectionSize, AddrSize); + } - MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection()); - - for (MCSection *Sec : Sections) { - const MCSymbol *StartSymbol = Sec->getBeginSymbol(); - MCSymbol *EndSymbol = Sec->getEndSymbol(context); - assert(StartSymbol && "StartSymbol must not be NULL"); - assert(EndSymbol && "EndSymbol must not be NULL"); - - // Emit a base address selection entry for the start of this section - const MCExpr *SectionStartAddr = MCSymbolRefExpr::create( - StartSymbol, MCSymbolRefExpr::VK_None, context); - MCOS->emitFill(AddrSize, 0xFF); - MCOS->emitValue(SectionStartAddr, AddrSize); - - // Emit a range list entry spanning this section - const MCExpr *SectionSize = MakeStartMinusEndExpr(*MCOS, - *StartSymbol, *EndSymbol, 0); + // Emit end of list entry + MCOS->emitIntValue(0, AddrSize); MCOS->emitIntValue(0, AddrSize); - emitAbsValue(*MCOS, SectionSize, AddrSize); } - // Emit end of list entry - MCOS->emitIntValue(0, AddrSize); - MCOS->emitIntValue(0, AddrSize); + return RangesSymbol; } // @@ -1145,7 +1184,7 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) { LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0); MCSymbol *AbbrevSectionSymbol = nullptr; MCSymbol *InfoSectionSymbol = nullptr; - MCSymbol *RangesSectionSymbol = nullptr; + MCSymbol *RangesSymbol = nullptr; // Create end symbols for each section, and remove empty sections MCOS->getContext().finalizeDwarfSections(*MCOS); @@ -1172,30 +1211,22 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) { AbbrevSectionSymbol = context.createTempSymbol(); MCOS->emitLabel(AbbrevSectionSymbol); } - if (UseRangesSection) { - MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection()); - if (CreateDwarfSectionSymbols) { - RangesSectionSymbol = context.createTempSymbol(); - MCOS->emitLabel(RangesSectionSymbol); - } - } - - assert((RangesSectionSymbol != nullptr) || !UseRangesSection); MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection()); // Output the data for .debug_aranges section. EmitGenDwarfAranges(MCOS, InfoSectionSymbol); - if (UseRangesSection) - EmitGenDwarfRanges(MCOS); + if (UseRangesSection) { + RangesSymbol = emitGenDwarfRanges(MCOS); + assert(RangesSymbol); + } // Output the data for .debug_abbrev section. EmitGenDwarfAbbrev(MCOS); // Output the data for .debug_info section. - EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, - RangesSectionSymbol); + EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol); } // diff --git a/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s b/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s index 69a45ed3495057..ffcdfda3975246 100644 --- a/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s +++ b/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s @@ -1,13 +1,13 @@ // RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -dwarf-version 5 -fdebug-compilation-dir=/tmp -// RUN: llvm-dwarfdump -v %t | FileCheck -check-prefix DWARF -check-prefix DWARF45 %s +// RUN: llvm-dwarfdump -v %t | FileCheck --check-prefixes=DWARF,DWARF5 %s // RUN: llvm-dwarfdump --debug-line %t | FileCheck -check-prefix DWARF-DL -check-prefix DWARF-DL-5 -DDWVER=5 -DDWFILE=0 %s -// RUN: llvm-objdump -r %t | FileCheck -check-prefix RELOC -check-prefix RELOC5 %s +// RUN: llvm-objdump -r %t | FileCheck --check-prefixes=RELOC,RELOC5 %s // RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -dwarf-version 4 -fdebug-compilation-dir=/tmp -// RUN: llvm-dwarfdump -v %t | FileCheck -check-prefix DWARF -check-prefix DWARF45 %s +// RUN: llvm-dwarfdump -v %t | FileCheck -check-prefixes=DWARF,DWARF34,DWARF4 %s // RUN: llvm-dwarfdump --debug-line %t | FileCheck -check-prefix DWARF-DL -check-prefix DWARF-DL-4 -DDWVER=4 -DDWFILE=1 %s -// RUN: llvm-objdump -r %t | FileCheck -check-prefix RELOC -check-prefix RELOC4 %s +// RUN: llvm-objdump -r %t | FileCheck --check-prefixes=RELOC,RELOC34,RELOC4 %s // RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -dwarf-version 3 -fdebug-compilation-dir=/tmp -// RUN: llvm-dwarfdump -v %t | FileCheck -check-prefix DWARF -check-prefix DWARF3 %s +// RUN: llvm-dwarfdump -v %t | FileCheck --check-prefixes=DWARF,DWARF34,DWARF3 %s // RUN: llvm-dwarfdump --debug-line %t | FileCheck -check-prefix DWARF-DL -DDWVER=3 -DDWFILE=1 %s // RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -dwarf-version 2 2>&1 | FileCheck -check-prefix VERSION %s // RUN: not llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -dwarf-version 1 2>&1 | FileCheck -check-prefix DWARF1 %s @@ -24,9 +24,11 @@ b: // DWARF: Abbrev table for offset: 0x00000000 // DWARF: [1] DW_TAG_compile_unit DW_CHILDREN_yes // DWARF3: DW_AT_stmt_list DW_FORM_data4 -// DWARF45: DW_AT_stmt_list DW_FORM_sec_offset +// DWARF4: DW_AT_stmt_list DW_FORM_sec_offset +// DWARF5: DW_AT_stmt_list DW_FORM_sec_offset // DWARF3: DW_AT_ranges DW_FORM_data4 -// DWARF45: DW_AT_ranges DW_FORM_sec_offset +// DWARF4: DW_AT_ranges DW_FORM_sec_offset +// DWARF5: DW_AT_ranges DW_FORM_sec_offset // DWARF: DW_AT_name DW_FORM_string // DWARF: DW_AT_comp_dir DW_FORM_string // DWARF: DW_AT_producer DW_FORM_string @@ -36,7 +38,8 @@ b: // DWARF: 0x{{[0-9a-f]+}}: DW_TAG_compile_unit [1] // DWARF-NOT: DW_TAG_ // DWARF3: DW_AT_ranges [DW_FORM_data4] (0x00000000 -// DWARF45: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000 +// DWARF4: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000 +// DWARF5: DW_AT_ranges [DW_FORM_sec_offset] (0x0000000c // DWARF: 0x{{[0-9a-f]+}}: DW_TAG_label [2] * // DWARF-NEXT: DW_AT_name [DW_FORM_string] ("a") @@ -67,13 +70,19 @@ b: // DWARF-DL-4-NEXT: 0x0000000000000004 21 0 1 0 0 is_stmt end_sequence -// DWARF: .debug_ranges contents: -// DWARF: 00000000 ffffffff 00000000 -// DWARF: 00000000 00000000 00000004 -// DWARF: 00000000 ffffffff 00000000 -// DWARF: 00000000 00000000 00000004 -// DWARF: 00000000 +// DWARF34: .debug_ranges contents: +// DWARF34-NEXT: 00000000 ffffffff 00000000 +// DWARF34-NEXT: 00000000 00000000 00000004 +// DWARF34-NEXT: 00000000 ffffffff 00000000 +// DWARF34-NEXT: 00000000 00000000 00000004 +// DWARF34-NEXT: 00000000 +// DWARF5: .debug_rnglists contents: +// DWARF5-NEXT: 0x00000000: range list header: length = 0x00000015, version = 0x0005, addr_size = 0x04, seg_size = 0x00, offset_entry_count = 0x00000000 +// DWARF5-NEXT: ranges: +// DWARF5-NEXT: 0x0000000c: [DW_RLE_start_length]: 0x00000000, 0x00000004 => [0x00000000, 0x00000004) +// DWARF5-NEXT: 0x00000012: [DW_RLE_start_length]: 0x00000000, 0x00000004 => [0x00000000, 0x00000004) +// DWARF5-NEXT: 0x00000018: [DW_RLE_end_of_list ] // Offsets are different in DWARF v5 due to different header layout. @@ -85,21 +94,26 @@ b: // RELOC5-NEXT: OFFSET TYPE VALUE // RELOC5-NEXT: 00000008 R_ARM_ABS32 .debug_abbrev // RELOC5-NEXT: 0000000d R_ARM_ABS32 .debug_line -// RELOC5-NEXT: 00000011 R_ARM_ABS32 .debug_ranges +// RELOC5-NEXT: 00000011 R_ARM_ABS32 .debug_rnglists // RELOC-NEXT: R_ARM_ABS32 .text // RELOC-NEXT: R_ARM_ABS32 foo -// RELOC: RELOCATION RECORDS FOR [.debug_ranges]: -// RELOC-NEXT: OFFSET TYPE VALUE -// RELOC-NEXT: 00000004 R_ARM_ABS32 .text -// RELOC-NEXT: 00000014 R_ARM_ABS32 foo - // RELOC: RELOCATION RECORDS FOR [.debug_aranges]: // RELOC-NEXT: OFFSET TYPE VALUE // RELOC-NEXT: 00000006 R_ARM_ABS32 .debug_info // RELOC-NEXT: 00000010 R_ARM_ABS32 .text // RELOC-NEXT: 00000018 R_ARM_ABS32 foo +// RELOC34: RELOCATION RECORDS FOR [.debug_ranges]: +// RELOC34-NEXT: OFFSET TYPE VALUE +// RELOC34-NEXT: 00000004 R_ARM_ABS32 .text +// RELOC34-NEXT: 00000014 R_ARM_ABS32 foo + +// RELOC5: RELOCATION RECORDS FOR [.debug_rnglists]: +// RELOC5-NEXT: OFFSET TYPE VALUE +// RELOC5-NEXT: 0000000d R_ARM_ABS32 .text +// RELOC5-NEXT: 00000013 R_ARM_ABS32 foo + // VERSION: {{.*}} warning: DWARF2 only supports one section per compilation unit From d93371238e7f5d5f9c506a88cf4f05f8dea9d008 Mon Sep 17 00:00:00 2001 From: Sterling Augustine Date: Mon, 2 Mar 2020 14:09:33 -0800 Subject: [PATCH 28/29] Promote nameless lambda used by dl_iterate_phdr to named function to clean up control flow inside findUnwindSections. Also, expose the data structure to allow use by a future replacment function. Summary: [Refactor] Promote nameless lambda to fully named function, allowing easy replacement in following patch. Subscribers: krytarowski, libcxx-commits Tags: #libc Differential Revision: https://reviews.llvm.org/D75480 --- libunwind/src/AddressSpace.hpp | 209 +++++++++++++++++---------------- 1 file changed, 106 insertions(+), 103 deletions(-) diff --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp index 7433476f911722..63c20412ef54b3 100644 --- a/libunwind/src/AddressSpace.hpp +++ b/libunwind/src/AddressSpace.hpp @@ -392,6 +392,111 @@ LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, return result; } +#if defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) +struct _LIBUNWIND_HIDDEN dl_iterate_cb_data { + LocalAddressSpace *addressSpace; + UnwindInfoSections *sects; + uintptr_t targetAddr; +}; + +static int findUnwindSectionByPhdr(struct dl_phdr_info *pinfo, size_t, void *data) { + auto cbdata = static_cast(data); + bool found_obj = false; + bool found_hdr = false; + + assert(cbdata); + assert(cbdata->sects); + + if (cbdata->targetAddr < pinfo->dlpi_addr) { + return false; + } + +#if !defined(Elf_Half) + typedef ElfW(Half) Elf_Half; +#endif +#if !defined(Elf_Phdr) + typedef ElfW(Phdr) Elf_Phdr; +#endif +#if !defined(Elf_Addr) + typedef ElfW(Addr) Elf_Addr; +#endif + + Elf_Addr image_base = pinfo->dlpi_addr; + +#if defined(__ANDROID__) && __ANDROID_API__ < 18 + if (image_base == 0) { + // Normally, an image base of 0 indicates a non-PIE executable. On + // versions of Android prior to API 18, the dynamic linker reported a + // dlpi_addr of 0 for PIE executables. Compute the true image base + // using the PT_PHDR segment. + // See https://github.com/android/ndk/issues/505. + for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { + const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; + if (phdr->p_type == PT_PHDR) { + image_base = reinterpret_cast(pinfo->dlpi_phdr) - + phdr->p_vaddr; + break; + } + } + } +#endif + + #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) + #if !defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) + #error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform." + #endif + size_t object_length; + + for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { + const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; + if (phdr->p_type == PT_LOAD) { + uintptr_t begin = image_base + phdr->p_vaddr; + uintptr_t end = begin + phdr->p_memsz; + if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) { + cbdata->sects->dso_base = begin; + object_length = phdr->p_memsz; + found_obj = true; + } + } else if (phdr->p_type == PT_GNU_EH_FRAME) { + EHHeaderParser::EHHeaderInfo hdrInfo; + uintptr_t eh_frame_hdr_start = image_base + phdr->p_vaddr; + cbdata->sects->dwarf_index_section = eh_frame_hdr_start; + cbdata->sects->dwarf_index_section_length = phdr->p_memsz; + found_hdr = EHHeaderParser::decodeEHHdr( + *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz, + hdrInfo); + if (found_hdr) + cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; + } + } + + if (found_obj && found_hdr) { + cbdata->sects->dwarf_section_length = object_length; + return true; + } else { + return false; + } + #else // defined(_LIBUNWIND_ARM_EHABI) + for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { + const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; + if (phdr->p_type == PT_LOAD) { + uintptr_t begin = image_base + phdr->p_vaddr; + uintptr_t end = begin + phdr->p_memsz; + if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) + found_obj = true; + } else if (phdr->p_type == PT_ARM_EXIDX) { + uintptr_t exidx_start = image_base + phdr->p_vaddr; + cbdata->sects->arm_section = exidx_start; + cbdata->sects->arm_section_length = phdr->p_memsz; + found_hdr = true; + } + } + return found_obj && found_hdr; + #endif +} + +#endif // defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) + inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, UnwindInfoSections &info) { #ifdef __APPLE__ @@ -483,110 +588,8 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, if (info.arm_section && info.arm_section_length) return true; #elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - struct dl_iterate_cb_data { - LocalAddressSpace *addressSpace; - UnwindInfoSections *sects; - uintptr_t targetAddr; - }; - dl_iterate_cb_data cb_data = {this, &info, targetAddr}; - int found = dl_iterate_phdr( - [](struct dl_phdr_info *pinfo, size_t, void *data) -> int { - auto cbdata = static_cast(data); - bool found_obj = false; - bool found_hdr = false; - - assert(cbdata); - assert(cbdata->sects); - - if (cbdata->targetAddr < pinfo->dlpi_addr) { - return false; - } - -#if !defined(Elf_Half) - typedef ElfW(Half) Elf_Half; -#endif -#if !defined(Elf_Phdr) - typedef ElfW(Phdr) Elf_Phdr; -#endif -#if !defined(Elf_Addr) - typedef ElfW(Addr) Elf_Addr; -#endif - - Elf_Addr image_base = pinfo->dlpi_addr; - -#if defined(__ANDROID__) && __ANDROID_API__ < 18 - if (image_base == 0) { - // Normally, an image base of 0 indicates a non-PIE executable. On - // versions of Android prior to API 18, the dynamic linker reported a - // dlpi_addr of 0 for PIE executables. Compute the true image base - // using the PT_PHDR segment. - // See https://github.com/android/ndk/issues/505. - for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { - const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; - if (phdr->p_type == PT_PHDR) { - image_base = reinterpret_cast(pinfo->dlpi_phdr) - - phdr->p_vaddr; - break; - } - } - } -#endif - - #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - #if !defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) - #error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform." - #endif - size_t object_length; - - for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { - const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; - if (phdr->p_type == PT_LOAD) { - uintptr_t begin = image_base + phdr->p_vaddr; - uintptr_t end = begin + phdr->p_memsz; - if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) { - cbdata->sects->dso_base = begin; - object_length = phdr->p_memsz; - found_obj = true; - } - } else if (phdr->p_type == PT_GNU_EH_FRAME) { - EHHeaderParser::EHHeaderInfo hdrInfo; - uintptr_t eh_frame_hdr_start = image_base + phdr->p_vaddr; - cbdata->sects->dwarf_index_section = eh_frame_hdr_start; - cbdata->sects->dwarf_index_section_length = phdr->p_memsz; - found_hdr = EHHeaderParser::decodeEHHdr( - *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz, - hdrInfo); - if (found_hdr) - cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; - } - } - - if (found_obj && found_hdr) { - cbdata->sects->dwarf_section_length = object_length; - return true; - } else { - return false; - } - #else // defined(_LIBUNWIND_ARM_EHABI) - for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { - const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; - if (phdr->p_type == PT_LOAD) { - uintptr_t begin = image_base + phdr->p_vaddr; - uintptr_t end = begin + phdr->p_memsz; - if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) - found_obj = true; - } else if (phdr->p_type == PT_ARM_EXIDX) { - uintptr_t exidx_start = image_base + phdr->p_vaddr; - cbdata->sects->arm_section = exidx_start; - cbdata->sects->arm_section_length = phdr->p_memsz; - found_hdr = true; - } - } - return found_obj && found_hdr; - #endif - }, - &cb_data); + int found = dl_iterate_phdr(findUnwindSectionByPhdr, &cb_data); return static_cast(found); #endif From 8ba8ab8c95fb185d722842bf78053a8dad6181cd Mon Sep 17 00:00:00 2001 From: Alex Zinenko Date: Tue, 3 Mar 2020 13:21:51 +0100 Subject: [PATCH 29/29] [mlir] support reductions in loop to std conversion Summary: Introduce support for converting loop.for operations with loop-carried values to a CFG in the standard dialect. This is achieved by passing loop-carried values as block arguments to the loop condition block. This block dominates both the loop body and the block immediately following the loop, so the arguments of this block are remain visible there. Differential Revision: https://reviews.llvm.org/D75513 --- .../LoopToStandard/ConvertLoopToStandard.cpp | 59 +++++++++++++------ mlir/test/Conversion/convert-to-cfg.mlir | 56 ++++++++++++++++++ 2 files changed, 96 insertions(+), 19 deletions(-) diff --git a/mlir/lib/Conversion/LoopToStandard/ConvertLoopToStandard.cpp b/mlir/lib/Conversion/LoopToStandard/ConvertLoopToStandard.cpp index c57ec80c7a994a..b4d25e04e3896f 100644 --- a/mlir/lib/Conversion/LoopToStandard/ConvertLoopToStandard.cpp +++ b/mlir/lib/Conversion/LoopToStandard/ConvertLoopToStandard.cpp @@ -45,21 +45,26 @@ struct LoopToStandardPass : public OperationPass { // are split out into a separate continuation (exit) block. A condition block is // created before the continuation block. It checks the exit condition of the // loop and branches either to the continuation block, or to the first block of -// the body. Induction variable modification is appended to the last block of -// the body (which is the exit block from the body subgraph thanks to the +// the body. The condition block takes as arguments the values of the induction +// variable followed by loop-carried values. Since it dominates both the body +// blocks and the continuation block, loop-carried values are visible in all of +// those blocks. Induction variable modification is appended to the last block +// of the body (which is the exit block from the body subgraph thanks to the // invariant we maintain) along with a branch that loops back to the condition -// block. +// block. Loop-carried values are the loop terminator operands, which are +// forwarded to the branch. // // +---------------------------------+ // | | +// | | // | | -// | br cond(%iv) | +// | br cond(%iv, %init...) | // +---------------------------------+ // | // -------| | // | v v // | +--------------------------------+ -// | | cond(%iv): | +// | | cond(%iv, %init...): | // | | | // | | cond_br %r, body, end | // | +--------------------------------+ @@ -68,6 +73,7 @@ struct LoopToStandardPass : public OperationPass { // | v | // | +--------------------------------+ | // | | body-first: | | +// | | <%init visible by dominance> | | // | | | | // | +--------------------------------+ | // | | | @@ -76,15 +82,17 @@ struct LoopToStandardPass : public OperationPass { // | +--------------------------------+ | // | | body-last: | | // | | | | +// | | | | // | | %new_iv = | | -// | | br cond(%new_iv) | | +// | | br cond(%new_iv, %yields) | | // | +--------------------------------+ | // | | | // |----------- |-------------------- // v // +--------------------------------+ // | end: | -// | | +// | | +// | <%init visible by dominance> | // +--------------------------------+ // struct ForLowering : public OpRewritePattern { @@ -133,7 +141,7 @@ struct ForLowering : public OpRewritePattern { // v v // +--------------------------------+ // | continue: | -// | | +// | | // +--------------------------------+ // struct IfLowering : public OpRewritePattern { @@ -162,10 +170,10 @@ ForLowering::matchAndRewrite(ForOp forOp, PatternRewriter &rewriter) const { auto initPosition = rewriter.getInsertionPoint(); auto *endBlock = rewriter.splitBlock(initBlock, initPosition); - // Use the first block of the loop body as the condition block since it is - // the block that has the induction variable as its argument. Split out - // all operations from the first block into a new block. Move all body - // blocks from the loop body region to the region containing the loop. + // Use the first block of the loop body as the condition block since it is the + // block that has the induction variable and loop-carried values as arguments. + // Split out all operations from the first block into a new block. Move all + // body blocks from the loop body region to the region containing the loop. auto *conditionBlock = &forOp.region().front(); auto *firstBodyBlock = rewriter.splitBlock(conditionBlock, conditionBlock->begin()); @@ -174,15 +182,20 @@ ForLowering::matchAndRewrite(ForOp forOp, PatternRewriter &rewriter) const { auto iv = conditionBlock->getArgument(0); // Append the induction variable stepping logic to the last body block and - // branch back to the condition block. Construct an expression f : - // (x -> x+step) and apply this expression to the induction variable. - rewriter.eraseOp(lastBodyBlock->getTerminator()); + // branch back to the condition block. Loop-carried values are taken from + // operands of the loop terminator. + Operation *terminator = lastBodyBlock->getTerminator(); rewriter.setInsertionPointToEnd(lastBodyBlock); auto step = forOp.step(); auto stepped = rewriter.create(loc, iv, step).getResult(); if (!stepped) return matchFailure(); - rewriter.create(loc, conditionBlock, stepped); + + SmallVector loopCarried; + loopCarried.push_back(stepped); + loopCarried.append(terminator->operand_begin(), terminator->operand_end()); + rewriter.create(loc, conditionBlock, loopCarried); + rewriter.eraseOp(terminator); // Compute loop bounds before branching to the condition. rewriter.setInsertionPointToEnd(initBlock); @@ -190,7 +203,14 @@ ForLowering::matchAndRewrite(ForOp forOp, PatternRewriter &rewriter) const { Value upperBound = forOp.upperBound(); if (!lowerBound || !upperBound) return matchFailure(); - rewriter.create(loc, conditionBlock, lowerBound); + + // The initial values of loop-carried values is obtained from the operands + // of the loop operation. + SmallVector destOperands; + destOperands.push_back(lowerBound); + auto iterOperands = forOp.getIterOperands(); + destOperands.append(iterOperands.begin(), iterOperands.end()); + rewriter.create(loc, conditionBlock, destOperands); // With the body block done, we can fill in the condition block. rewriter.setInsertionPointToEnd(conditionBlock); @@ -199,8 +219,9 @@ ForLowering::matchAndRewrite(ForOp forOp, PatternRewriter &rewriter) const { rewriter.create(loc, comparison, firstBodyBlock, ArrayRef(), endBlock, ArrayRef()); - // Ok, we're done! - rewriter.eraseOp(forOp); + // The result of the loop operation is the values of the condition block + // arguments except the induction variable on the last iteration. + rewriter.replaceOp(forOp, conditionBlock->getArguments().drop_front()); return matchSuccess(); } diff --git a/mlir/test/Conversion/convert-to-cfg.mlir b/mlir/test/Conversion/convert-to-cfg.mlir index b53dc23c7a78c1..c6be3fdb895357 100644 --- a/mlir/test/Conversion/convert-to-cfg.mlir +++ b/mlir/test/Conversion/convert-to-cfg.mlir @@ -180,3 +180,59 @@ func @parallel_loop(%arg0 : index, %arg1 : index, %arg2 : index, } return } + +// CHECK-LABEL: @for_yield +// CHECK-SAME: (%[[LB:.*]]: index, %[[UB:.*]]: index, %[[STEP:.*]]: index) +// CHECK: %[[INIT0:.*]] = constant 0 +// CHECK: %[[INIT1:.*]] = constant 1 +// CHECK: br ^[[COND:.*]](%[[LB]], %[[INIT0]], %[[INIT1]] : index, f32, f32) +// +// CHECK: ^[[COND]](%[[ITER:.*]]: index, %[[ITER_ARG0:.*]]: f32, %[[ITER_ARG1:.*]]: f32): +// CHECK: %[[CMP:.*]] = cmpi "slt", %[[ITER]], %[[UB]] : index +// CHECK: cond_br %[[CMP]], ^[[BODY:.*]], ^[[CONTINUE:.*]] +// +// CHECK: ^[[BODY]]: +// CHECK: %[[SUM:.*]] = addf %[[ITER_ARG0]], %[[ITER_ARG1]] : f32 +// CHECK: %[[STEPPED:.*]] = addi %[[ITER]], %[[STEP]] : index +// CHECK: br ^[[COND]](%[[STEPPED]], %[[SUM]], %[[SUM]] : index, f32, f32) +// +// CHECK: ^[[CONTINUE]]: +// CHECK: return %[[ITER_ARG0]], %[[ITER_ARG1]] : f32, f32 +func @for_yield(%arg0 : index, %arg1 : index, %arg2 : index) -> (f32, f32) { + %s0 = constant 0.0 : f32 + %s1 = constant 1.0 : f32 + %result:2 = loop.for %i0 = %arg0 to %arg1 step %arg2 iter_args(%si = %s0, %sj = %s1) -> (f32, f32) { + %sn = addf %si, %sj : f32 + loop.yield %sn, %sn : f32, f32 + } + return %result#0, %result#1 : f32, f32 +} + +// CHECK-LABEL: @nested_for_yield +// CHECK-SAME: (%[[LB:.*]]: index, %[[UB:.*]]: index, %[[STEP:.*]]: index) +// CHECK: %[[INIT:.*]] = constant +// CHECK: br ^[[COND_OUT:.*]](%[[LB]], %[[INIT]] : index, f32) +// CHECK: ^[[COND_OUT]](%[[ITER_OUT:.*]]: index, %[[ARG_OUT:.*]]: f32): +// CHECK: cond_br %{{.*}}, ^[[BODY_OUT:.*]], ^[[CONT_OUT:.*]] +// CHECK: ^[[BODY_OUT]]: +// CHECK: br ^[[COND_IN:.*]](%[[LB]], %[[ARG_OUT]] : index, f32) +// CHECK: ^[[COND_IN]](%[[ITER_IN:.*]]: index, %[[ARG_IN:.*]]: f32): +// CHECK: cond_br %{{.*}}, ^[[BODY_IN:.*]], ^[[CONT_IN:.*]] +// CHECK: ^[[BODY_IN]] +// CHECK: %[[RES:.*]] = addf +// CHECK: br ^[[COND_IN]](%{{.*}}, %[[RES]] : index, f32) +// CHECK: ^[[CONT_IN]]: +// CHECK: br ^[[COND_OUT]](%{{.*}}, %[[ARG_IN]] : index, f32) +// CHECK: ^[[CONT_OUT]]: +// CHECK: return %[[ARG_OUT]] : f32 +func @nested_for_yield(%arg0 : index, %arg1 : index, %arg2 : index) -> f32 { + %s0 = constant 1.0 : f32 + %r = loop.for %i0 = %arg0 to %arg1 step %arg2 iter_args(%iter = %s0) -> (f32) { + %result = loop.for %i1 = %arg0 to %arg1 step %arg2 iter_args(%si = %iter) -> (f32) { + %sn = addf %si, %si : f32 + loop.yield %sn : f32 + } + loop.yield %result : f32 + } + return %r : f32 +}