From: Benjamin Kramer Date: Sat, 1 Mar 2014 14:48:57 +0000 (+0000) Subject: [C++11] Replace verbose functors with succinct lambdas X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=802ac72495558ab109f0ce407383ef3547d4ca59;p=clang [C++11] Replace verbose functors with succinct lambdas No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202590 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index cc0d7fded9..1e081d212d 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -3070,16 +3070,6 @@ static void PrintIndentNoOffset(raw_ostream &OS, unsigned IndentLevel) { OS.indent(IndentLevel * 2); } -namespace { -struct BaseOffsetComparator { - const ASTRecordLayout &RL; - BaseOffsetComparator(const ASTRecordLayout &RL) : RL(RL) {} - bool operator()(const CXXRecordDecl *L, const CXXRecordDecl *R) const { - return RL.getBaseClassOffset(L) < RL.getBaseClassOffset(R); - } -}; -} - static void DumpCXXRecordLayout(raw_ostream &OS, const CXXRecordDecl *RD, const ASTContext &C, CharUnits Offset, @@ -3124,8 +3114,10 @@ static void DumpCXXRecordLayout(raw_ostream &OS, } // Sort nvbases by offset. - BaseOffsetComparator Cmp(Layout); - std::stable_sort(Bases.begin(), Bases.end(), Cmp); + std::stable_sort(Bases.begin(), Bases.end(), + [&](const CXXRecordDecl *L, const CXXRecordDecl *R) { + return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R); + }); // Dump (non-virtual) bases for (SmallVectorImpl::iterator I = Bases.begin(), diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index 660c0d15eb..99395b9189 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -1907,21 +1907,6 @@ void ItaniumVTableBuilder::LayoutVTablesForVirtualBases( } } -struct ItaniumThunkInfoComparator { - bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) { - assert(LHS.Method == 0); - assert(RHS.Method == 0); - - if (LHS.This != RHS.This) - return LHS.This < RHS.This; - - if (LHS.Return != RHS.Return) - return LHS.Return < RHS.Return; - - return false; - } -}; - /// dumpLayout - Dump the vtable layout. void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { // FIXME: write more tests that actually use the dumpLayout output to prevent @@ -2169,7 +2154,13 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { ThunkInfoVectorTy ThunksVector = Thunks[MD]; std::sort(ThunksVector.begin(), ThunksVector.end(), - ItaniumThunkInfoComparator()); + [](const ThunkInfo &LHS, const ThunkInfo &RHS) { + assert(LHS.Method == 0 && RHS.Method == 0); + + if (LHS.This != RHS.This) + return LHS.This < RHS.This; + return LHS.Return < RHS.Return; + }); Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size(); Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n"; @@ -2256,17 +2247,6 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { Out << '\n'; } - -struct VTableThunksComparator { - bool operator()(const VTableLayout::VTableThunkTy &LHS, - const VTableLayout::VTableThunkTy &RHS) { - if (LHS.first == RHS.first) { - assert(LHS.second == RHS.second && - "Different thunks should have unique indices!"); - } - return LHS.first < RHS.first; - } -}; } VTableLayout::VTableLayout(uint64_t NumVTableComponents, @@ -2287,7 +2267,12 @@ VTableLayout::VTableLayout(uint64_t NumVTableComponents, this->VTableThunks.get()); std::sort(this->VTableThunks.get(), this->VTableThunks.get() + NumVTableThunks, - VTableThunksComparator()); + [](const VTableLayout::VTableThunkTy &LHS, + const VTableLayout::VTableThunkTy &RHS) { + assert((LHS.first != RHS.first || LHS.second == RHS.second) && + "Different thunks should have unique indices!"); + return LHS.first < RHS.first; + }); } VTableLayout::~VTableLayout() { } @@ -3047,22 +3032,6 @@ static void PrintBasePath(const VPtrInfo::BasePath &Path, raw_ostream &Out) { } } -namespace { -struct MicrosoftThunkInfoStableSortComparator { - bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) { - if (LHS.This != RHS.This) - return LHS.This < RHS.This; - - if (LHS.Return != RHS.Return) - return LHS.Return < RHS.Return; - - // Keep different thunks with the same adjustments in the order they - // were put into the vector. - return false; - } -}; -} - static void dumpMicrosoftThunkAdjustment(const ThunkInfo &TI, raw_ostream &Out, bool ContinueFirstLine) { const ReturnAdjustment &R = TI.Return; @@ -3197,7 +3166,13 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) { ThunkInfoVectorTy ThunksVector = Thunks[MD]; std::stable_sort(ThunksVector.begin(), ThunksVector.end(), - MicrosoftThunkInfoStableSortComparator()); + [](const ThunkInfo &LHS, const ThunkInfo &RHS) { + // Keep different thunks with the same adjustments in the order they + // were put into the vector. + if (LHS.This != RHS.This) + return LHS.This < RHS.This; + return LHS.Return < RHS.Return; + }); Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size(); Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n"; diff --git a/lib/Driver/Multilib.cpp b/lib/Driver/Multilib.cpp index 6681e7f364..3d30bf8be5 100644 --- a/lib/Driver/Multilib.cpp +++ b/lib/Driver/Multilib.cpp @@ -338,20 +338,11 @@ MultilibSet::filterCopy(const MultilibSet::FilterCallback &F, return Copy; } -namespace { -// Wrapper for FilterCallback to make operator() nonvirtual so it -// can be passed by value to std::remove_if -class FilterWrapper { - const MultilibSet::FilterCallback &F; -public: - FilterWrapper(const MultilibSet::FilterCallback &F) : F(F) {} - bool operator()(const Multilib &M) const { return F(M); } -}; -} // end anonymous namespace - void MultilibSet::filterInPlace(const MultilibSet::FilterCallback &F, multilib_list &Ms) { - Ms.erase(std::remove_if(Ms.begin(), Ms.end(), FilterWrapper(F)), Ms.end()); + Ms.erase(std::remove_if(Ms.begin(), Ms.end(), + [&F](const Multilib &M) { return F(M); }), + Ms.end()); } raw_ostream &clang::driver::operator<<(raw_ostream &OS, const MultilibSet &MS) { diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index a2b321ff6c..4ab7f00e5a 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -778,23 +778,6 @@ static void doCompileMapModule(void *UserData) { Data.Instance.ExecuteAction(Data.CreateModuleAction); } -namespace { - /// \brief Function object that checks with the given macro definition should - /// be removed, because it is one of the ignored macros. - class RemoveIgnoredMacro { - const HeaderSearchOptions &HSOpts; - - public: - explicit RemoveIgnoredMacro(const HeaderSearchOptions &HSOpts) - : HSOpts(HSOpts) { } - - bool operator()(const std::pair &def) const { - StringRef MacroDef = def.first; - return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0; - } - }; -} - /// \brief Compile a module file for the given module, using the options /// provided by the importing compiler instance. static void compileModule(CompilerInstance &ImportingInstance, @@ -839,10 +822,13 @@ static void compileModule(CompilerInstance &ImportingInstance, // Remove any macro definitions that are explicitly ignored by the module. // They aren't supposed to affect how the module is built anyway. const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); - PPOpts.Macros.erase(std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), - RemoveIgnoredMacro(HSOpts)), - PPOpts.Macros.end()); - + PPOpts.Macros.erase( + std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), + [&HSOpts](const std::pair &def) { + StringRef MacroDef = def.first; + return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0; + }), + PPOpts.Macros.end()); // Note the name of the module we're building. Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName(); diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp index d95b925355..ad13a92dcd 100644 --- a/lib/Frontend/TextDiagnostic.cpp +++ b/lib/Frontend/TextDiagnostic.cpp @@ -314,14 +314,6 @@ private: SmallVector m_byteToColumn; SmallVector m_columnToByte; }; - -// used in assert in selectInterestingSourceRegion() -struct char_out_of_range { - const char lower,upper; - char_out_of_range(char lower, char upper) : - lower(lower), upper(upper) {} - bool operator()(char c) { return c < lower || upper < c; } -}; } // end anonymous namespace /// \brief When the source code line we want to print is too long for @@ -341,7 +333,7 @@ static void selectInterestingSourceRegion(std::string &SourceLine, // No special characters are allowed in CaretLine. assert(CaretLine.end() == std::find_if(CaretLine.begin(), CaretLine.end(), - char_out_of_range(' ','~'))); + [](char c) { return c < ' ' || '~' < c; })); // Find the slice that we need to display the full caret line // correctly. diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index e6f2f82dd2..967f521b20 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -1089,24 +1089,6 @@ static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC, } -namespace { -typedef std::pair - StmtUsesPair; - -class StmtUseSorter { - const SourceManager &SM; - -public: - explicit StmtUseSorter(const SourceManager &SM) : SM(SM) { } - - bool operator()(const StmtUsesPair &LHS, const StmtUsesPair &RHS) { - return SM.isBeforeInTranslationUnit(LHS.first->getLocStart(), - RHS.first->getLocStart()); - } -}; -} - static bool isInLoop(const ASTContext &Ctx, const ParentMap &PM, const Stmt *S) { assert(S); @@ -1141,6 +1123,8 @@ static void diagnoseRepeatedUseOfWeak(Sema &S, typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy; typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap; typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector; + typedef std::pair + StmtUsesPair; ASTContext &Ctx = S.getASTContext(); @@ -1199,8 +1183,12 @@ static void diagnoseRepeatedUseOfWeak(Sema &S, return; // Sort by first use so that we emit the warnings in a deterministic order. + SourceManager &SM = S.getSourceManager(); std::sort(UsesByStmt.begin(), UsesByStmt.end(), - StmtUseSorter(S.getSourceManager())); + [&SM](const StmtUsesPair &LHS, const StmtUsesPair &RHS) { + return SM.isBeforeInTranslationUnit(LHS.first->getLocStart(), + RHS.first->getLocStart()); + }); // Classify the current code body for better warning text. // This enum should stay in sync with the cases in @@ -1281,19 +1269,7 @@ static void diagnoseRepeatedUseOfWeak(Sema &S, } } - namespace { -struct SLocSort { - bool operator()(const UninitUse &a, const UninitUse &b) { - // Prefer a more confident report over a less confident one. - if (a.getKind() != b.getKind()) - return a.getKind() > b.getKind(); - SourceLocation aLoc = a.getUser()->getLocStart(); - SourceLocation bLoc = b.getUser()->getLocStart(); - return aLoc.getRawEncoding() < bLoc.getRawEncoding(); - } -}; - class UninitValsDiagReporter : public UninitVariablesHandler { Sema &S; typedef SmallVector UsesVec; @@ -1352,8 +1328,14 @@ public: // Sort the uses by their SourceLocations. While not strictly // guaranteed to produce them in line/column order, this will provide // a stable ordering. - std::sort(vec->begin(), vec->end(), SLocSort()); - + std::sort(vec->begin(), vec->end(), + [](const UninitUse &a, const UninitUse &b) { + // Prefer a more confident report over a less confident one. + if (a.getKind() != b.getKind()) + return a.getKind() > b.getKind(); + return a.getUser()->getLocStart() < b.getUser()->getLocStart(); + }); + for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi) { // If we have self-init, downgrade all uses to 'may be uninitialized'. diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 037327a22d..aa223bacab 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -409,25 +409,6 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) { return false; } -namespace { - struct SortUndefinedButUsed { - const SourceManager &SM; - explicit SortUndefinedButUsed(SourceManager &SM) : SM(SM) {} - - bool operator()(const std::pair &l, - const std::pair &r) const { - if (l.second.isValid() && !r.second.isValid()) - return true; - if (!l.second.isValid() && r.second.isValid()) - return false; - if (l.second != r.second) - return SM.isBeforeInTranslationUnit(l.second, r.second); - return SM.isBeforeInTranslationUnit(l.first->getLocation(), - r.first->getLocation()); - } - }; -} - /// Obtains a sorted list of functions that are undefined but ODR-used. void Sema::getUndefinedButUsed( SmallVectorImpl > &Undefined) { @@ -460,8 +441,19 @@ void Sema::getUndefinedButUsed( // Sort (in order of use site) so that we're not dependent on the iteration // order through an llvm::DenseMap. + SourceManager &SM = Context.getSourceManager(); std::sort(Undefined.begin(), Undefined.end(), - SortUndefinedButUsed(Context.getSourceManager())); + [&SM](const std::pair &l, + const std::pair &r) { + if (l.second.isValid() && !r.second.isValid()) + return true; + if (!l.second.isValid() && r.second.isValid()) + return false; + if (l.second != r.second) + return SM.isBeforeInTranslationUnit(l.second, r.second); + return SM.isBeforeInTranslationUnit(l.first->getLocation(), + r.first->getLocation()); + }); } /// checkUndefinedButUsed - Check for undefined objects with internal linkage diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 5369a4beb2..28f85d7a9f 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -3825,22 +3825,6 @@ void Sema::CodeCompleteCase(Scope *S) { Results.data(),Results.size()); } -namespace { - struct IsBetterOverloadCandidate { - Sema &S; - SourceLocation Loc; - - public: - explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc) - : S(S), Loc(Loc) { } - - bool - operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const { - return isBetterOverloadCandidate(S, X, Y, Loc); - } - }; -} - static bool anyNullArguments(ArrayRef Args) { if (Args.size() && !Args.data()) return true; @@ -3902,9 +3886,12 @@ void Sema::CodeCompleteCall(Scope *S, Expr *FnIn, ArrayRef Args) { if (!CandidateSet.empty()) { // Sort the overload candidate set by placing the best overloads first. - std::stable_sort(CandidateSet.begin(), CandidateSet.end(), - IsBetterOverloadCandidate(*this, Loc)); - + std::stable_sort( + CandidateSet.begin(), CandidateSet.end(), + [&](const OverloadCandidate &X, const OverloadCandidate &Y) { + return isBetterOverloadCandidate(*this, X, Y, Loc); + }); + // Add the remaining viable overload candidates as code-completion reslults. for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(), CandEnd = CandidateSet.end(); diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp index ce7e7af3d1..201f8fadea 100644 --- a/lib/Serialization/ModuleManager.cpp +++ b/lib/Serialization/ModuleManager.cpp @@ -134,22 +134,6 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, return NewModule? NewlyLoaded : AlreadyLoaded; } -namespace { - /// \brief Predicate that checks whether a module file occurs within - /// the given set. - class IsInModuleFileSet : public std::unary_function { - llvm::SmallPtrSet &Removed; - - public: - IsInModuleFileSet(llvm::SmallPtrSet &Removed) - : Removed(Removed) { } - - bool operator()(ModuleFile *MF) const { - return Removed.count(MF); - } - }; -} - void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last, ModuleMap *modMap) { if (first == last) @@ -159,7 +143,9 @@ void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last, llvm::SmallPtrSet victimSet(first, last); // Remove any references to the now-destroyed modules. - IsInModuleFileSet checkInSet(victimSet); + std::function checkInSet = [&](ModuleFile *MF) { + return victimSet.count(MF); + }; for (unsigned i = 0, n = Chain.size(); i != n; ++i) { Chain[i]->ImportedBy.remove_if(checkInSet); } diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index fec39bdc0b..e0fafef05e 100644 --- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -416,17 +416,6 @@ static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y) { return b.getValue(); } -namespace { -struct CompareDiagnostics { - // Compare if 'X' is "<" than 'Y'. - bool operator()(const PathDiagnostic *X, const PathDiagnostic *Y) const { - if (X == Y) - return false; - return compare(*X, *Y); - } -}; -} - void PathDiagnosticConsumer::FlushDiagnostics( PathDiagnosticConsumer::FilesMade *Files) { if (flushed) @@ -444,8 +433,11 @@ void PathDiagnosticConsumer::FlushDiagnostics( // Sort the diagnostics so that they are always emitted in a deterministic // order. if (!BatchDiags.empty()) - std::sort(BatchDiags.begin(), BatchDiags.end(), CompareDiagnostics()); - + std::sort(BatchDiags.begin(), BatchDiags.end(), + [](const PathDiagnostic *X, const PathDiagnostic *Y) { + return X != Y && compare(*X, *Y); + }); + FlushDiagnosticsImpl(BatchDiags, Files); // Delete the flushed diagnostics. diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index fa106e990d..626910b280 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -951,19 +951,6 @@ static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current, } } -namespace { - struct ContainerDeclsSort { - SourceManager &SM; - ContainerDeclsSort(SourceManager &sm) : SM(sm) {} - bool operator()(Decl *A, Decl *B) { - SourceLocation L_A = A->getLocStart(); - SourceLocation L_B = B->getLocStart(); - assert(L_A.isValid() && L_B.isValid()); - return SM.isBeforeInTranslationUnit(L_A, L_B); - } - }; -} - bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) { // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially // an @implementation can lexically contain Decls that are not properly @@ -1006,7 +993,12 @@ bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) { // Now sort the Decls so that they appear in lexical order. std::sort(DeclsInContainer.begin(), DeclsInContainer.end(), - ContainerDeclsSort(SM)); + [&SM](Decl *A, Decl *B) { + SourceLocation L_A = A->getLocStart(); + SourceLocation L_B = B->getLocStart(); + assert(L_A.isValid() && L_B.isValid()); + return SM.isBeforeInTranslationUnit(L_A, L_B); + }); // Now visit the decls. for (SmallVectorImpl::iterator I = DeclsInContainer.begin(), diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp index 2c265aff62..40af9f6000 100644 --- a/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -761,17 +761,6 @@ struct RecordIndexElement std::string Name; }; - -struct RecordIndexElementSorter : - public std::binary_function { - - bool operator()(RecordIndexElement const &Lhs, - RecordIndexElement const &Rhs) const { - return Lhs.Name < Rhs.Name; - } - -}; - } // end anonymous namespace. namespace clang { @@ -786,7 +775,9 @@ void EmitClangDiagsIndexName(RecordKeeper &Records, raw_ostream &OS) { Index.push_back(RecordIndexElement(R)); } - std::sort(Index.begin(), Index.end(), RecordIndexElementSorter()); + std::sort(Index.begin(), Index.end(), + [](const RecordIndexElement &Lhs, + const RecordIndexElement &Rhs) { return Lhs.Name < Rhs.Name; }); for (unsigned i = 0, e = Index.size(); i != e; ++i) { const RecordIndexElement &R = Index[i];