박우진

change code

Showing 1000 changed files with 611 additions and 1737 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

1 +{
2 + "files.associations": {
3 + "algorithm": "cpp",
4 + "typeinfo": "cpp",
5 + "cmath": "cpp",
6 + "cstdlib": "cpp",
7 + "limits": "cpp",
8 + "vector": "cpp",
9 + "__bit_reference": "cpp",
10 + "__config": "cpp",
11 + "__debug": "cpp",
12 + "__functional_base": "cpp",
13 + "__hash_table": "cpp",
14 + "__locale": "cpp",
15 + "__node_handle": "cpp",
16 + "__nullptr": "cpp",
17 + "__split_buffer": "cpp",
18 + "__threading_support": "cpp",
19 + "__tuple": "cpp",
20 + "array": "cpp",
21 + "atomic": "cpp",
22 + "bit": "cpp",
23 + "bitset": "cpp",
24 + "cctype": "cpp",
25 + "chrono": "cpp",
26 + "cstdarg": "cpp",
27 + "cstddef": "cpp",
28 + "cstdint": "cpp",
29 + "cstdio": "cpp",
30 + "cstring": "cpp",
31 + "ctime": "cpp",
32 + "cwchar": "cpp",
33 + "exception": "cpp",
34 + "functional": "cpp",
35 + "initializer_list": "cpp",
36 + "ios": "cpp",
37 + "iosfwd": "cpp",
38 + "iostream": "cpp",
39 + "istream": "cpp",
40 + "iterator": "cpp",
41 + "locale": "cpp",
42 + "memory": "cpp",
43 + "mutex": "cpp",
44 + "new": "cpp",
45 + "numeric": "cpp",
46 + "optional": "cpp",
47 + "ostream": "cpp",
48 + "random": "cpp",
49 + "ratio": "cpp",
50 + "set": "cpp",
51 + "sstream": "cpp",
52 + "stdexcept": "cpp",
53 + "streambuf": "cpp",
54 + "string": "cpp",
55 + "string_view": "cpp",
56 + "system_error": "cpp",
57 + "tuple": "cpp",
58 + "type_traits": "cpp",
59 + "unordered_map": "cpp",
60 + "utility": "cpp",
61 + "*.tcc": "cpp",
62 + "memory_resource": "cpp",
63 + "clocale": "cpp",
64 + "condition_variable": "cpp",
65 + "cwctype": "cpp",
66 + "deque": "cpp",
67 + "list": "cpp",
68 + "fstream": "cpp",
69 + "shared_mutex": "cpp",
70 + "thread": "cpp",
71 + "mock_vector": "cpp",
72 + "*.inc": "cpp",
73 + "filesystem": "cpp",
74 + "*.def": "cpp",
75 + "queue": "cpp",
76 + "stack": "cpp"
77 + }
78 +}
...\ No newline at end of file ...\ No newline at end of file
1 include(CMakeDependentOption) 1 include(CMakeDependentOption)
2 2
3 -option(CLANG_TIDY_ENABLE_STATIC_ANALYZER
4 - "Include static analyzer checks in clang-tidy" ON)
5 -
6 add_subdirectory(clang-apply-replacements) 3 add_subdirectory(clang-apply-replacements)
7 add_subdirectory(clang-reorder-fields) 4 add_subdirectory(clang-reorder-fields)
8 add_subdirectory(modularize) 5 add_subdirectory(modularize)
......
...@@ -99,7 +99,7 @@ CreateSymbolInfo(const NamedDecl *ND, const SourceManager &SM, ...@@ -99,7 +99,7 @@ CreateSymbolInfo(const NamedDecl *ND, const SourceManager &SM,
99 99
100 SourceLocation Loc = SM.getExpansionLoc(ND->getLocation()); 100 SourceLocation Loc = SM.getExpansionLoc(ND->getLocation());
101 if (!Loc.isValid()) { 101 if (!Loc.isValid()) {
102 - llvm::errs() << "Declaration " << ND->getDeclName() << "(" 102 + llvm::errs() << "Declaration " << ND->getNameAsString() << "("
103 << ND->getDeclKindName() 103 << ND->getDeclKindName()
104 << ") has invalid declaration location."; 104 << ") has invalid declaration location.";
105 return llvm::None; 105 return llvm::None;
......
...@@ -116,7 +116,7 @@ void HelperDeclRGBuilder::run( ...@@ -116,7 +116,7 @@ void HelperDeclRGBuilder::run(
116 const auto *DC = Result.Nodes.getNodeAs<Decl>("dc"); 116 const auto *DC = Result.Nodes.getNodeAs<Decl>("dc");
117 assert(DC); 117 assert(DC);
118 LLVM_DEBUG(llvm::dbgs() << "Find helper function usage: " 118 LLVM_DEBUG(llvm::dbgs() << "Find helper function usage: "
119 - << FuncRef->getDecl()->getDeclName() << " (" 119 + << FuncRef->getDecl()->getNameAsString() << " ("
120 << FuncRef->getDecl() << ")\n"); 120 << FuncRef->getDecl() << ")\n");
121 RG->addEdge( 121 RG->addEdge(
122 getOutmostClassOrFunDecl(DC->getCanonicalDecl()), 122 getOutmostClassOrFunDecl(DC->getCanonicalDecl()),
...@@ -126,7 +126,7 @@ void HelperDeclRGBuilder::run( ...@@ -126,7 +126,7 @@ void HelperDeclRGBuilder::run(
126 const auto *DC = Result.Nodes.getNodeAs<Decl>("dc"); 126 const auto *DC = Result.Nodes.getNodeAs<Decl>("dc");
127 assert(DC); 127 assert(DC);
128 LLVM_DEBUG(llvm::dbgs() 128 LLVM_DEBUG(llvm::dbgs()
129 - << "Find helper class usage: " << UsedClass->getDeclName() 129 + << "Find helper class usage: " << UsedClass->getNameAsString()
130 << " (" << UsedClass << ")\n"); 130 << " (" << UsedClass << ")\n");
131 RG->addEdge(getOutmostClassOrFunDecl(DC->getCanonicalDecl()), UsedClass); 131 RG->addEdge(getOutmostClassOrFunDecl(DC->getCanonicalDecl()), UsedClass);
132 } 132 }
......
...@@ -675,8 +675,8 @@ void ClangMoveTool::run(const ast_matchers::MatchFinder::MatchResult &Result) { ...@@ -675,8 +675,8 @@ void ClangMoveTool::run(const ast_matchers::MatchFinder::MatchResult &Result) {
675 Result.Nodes.getNodeAs<NamedDecl>("helper_decls")) { 675 Result.Nodes.getNodeAs<NamedDecl>("helper_decls")) {
676 MovedDecls.push_back(ND); 676 MovedDecls.push_back(ND);
677 HelperDeclarations.push_back(ND); 677 HelperDeclarations.push_back(ND);
678 - LLVM_DEBUG(llvm::dbgs() 678 + LLVM_DEBUG(llvm::dbgs() << "Add helper : " << ND->getNameAsString() << " ("
679 - << "Add helper : " << ND->getDeclName() << " (" << ND << ")\n"); 679 + << ND << ")\n");
680 } else if (const auto *UD = Result.Nodes.getNodeAs<NamedDecl>("using_decl")) { 680 } else if (const auto *UD = Result.Nodes.getNodeAs<NamedDecl>("using_decl")) {
681 MovedDecls.push_back(UD); 681 MovedDecls.push_back(UD);
682 } 682 }
...@@ -735,12 +735,12 @@ void ClangMoveTool::removeDeclsInOldFiles() { ...@@ -735,12 +735,12 @@ void ClangMoveTool::removeDeclsInOldFiles() {
735 // We remove the helper declarations which are not used in the old.cc after 735 // We remove the helper declarations which are not used in the old.cc after
736 // moving the given declarations. 736 // moving the given declarations.
737 for (const auto *D : HelperDeclarations) { 737 for (const auto *D : HelperDeclarations) {
738 - LLVM_DEBUG(llvm::dbgs() << "Check helper is used: " << D->getDeclName() 738 + LLVM_DEBUG(llvm::dbgs() << "Check helper is used: "
739 - << " (" << D << ")\n"); 739 + << D->getNameAsString() << " (" << D << ")\n");
740 if (!UsedDecls.count(HelperDeclRGBuilder::getOutmostClassOrFunDecl( 740 if (!UsedDecls.count(HelperDeclRGBuilder::getOutmostClassOrFunDecl(
741 D->getCanonicalDecl()))) { 741 D->getCanonicalDecl()))) {
742 LLVM_DEBUG(llvm::dbgs() << "Helper removed in old.cc: " 742 LLVM_DEBUG(llvm::dbgs() << "Helper removed in old.cc: "
743 - << D->getDeclName() << " (" << D << ")\n"); 743 + << D->getNameAsString() << " (" << D << ")\n");
744 RemovedDecls.push_back(D); 744 RemovedDecls.push_back(D);
745 } 745 }
746 } 746 }
...@@ -820,7 +820,7 @@ void ClangMoveTool::moveDeclsToNewFiles() { ...@@ -820,7 +820,7 @@ void ClangMoveTool::moveDeclsToNewFiles() {
820 D->getCanonicalDecl()))) 820 D->getCanonicalDecl())))
821 continue; 821 continue;
822 822
823 - LLVM_DEBUG(llvm::dbgs() << "Helper used in new.cc: " << D->getDeclName() 823 + LLVM_DEBUG(llvm::dbgs() << "Helper used in new.cc: " << D->getNameAsString()
824 << " " << D << "\n"); 824 << " " << D << "\n");
825 ActualNewCCDecls.push_back(D); 825 ActualNewCCDecls.push_back(D);
826 } 826 }
......
...@@ -110,33 +110,31 @@ int main(int argc, const char **argv) { ...@@ -110,33 +110,31 @@ int main(int argc, const char **argv) {
110 ClangTool Tool(OptionsParser->getCompilations(), 110 ClangTool Tool(OptionsParser->getCompilations(),
111 OptionsParser->getSourcePathList()); 111 OptionsParser->getSourcePathList());
112 std::vector<std::unique_ptr<ASTUnit>> ASTs; 112 std::vector<std::unique_ptr<ASTUnit>> ASTs;
113 + int Status = Tool.buildASTs(ASTs);
113 int ASTStatus = 0; 114 int ASTStatus = 0;
114 - switch (Tool.buildASTs(ASTs)) { 115 + if (Status == 1) {
115 - case 0: 116 + // Building ASTs failed.
116 - break;
117 - case 1: // Building ASTs failed.
118 return 1; 117 return 1;
119 - case 2: 118 + } else if (Status == 2) {
120 ASTStatus |= 1; 119 ASTStatus |= 1;
121 llvm::errs() << "Failed to build AST for some of the files, " 120 llvm::errs() << "Failed to build AST for some of the files, "
122 << "results may be incomplete." 121 << "results may be incomplete."
123 << "\n"; 122 << "\n";
124 - break; 123 + } else {
125 - default: 124 + assert(Status == 0 && "Unexpected status returned");
126 - llvm_unreachable("Unexpected status returned");
127 } 125 }
128 126
129 QuerySession QS(ASTs); 127 QuerySession QS(ASTs);
130 128
131 if (!Commands.empty()) { 129 if (!Commands.empty()) {
132 - for (auto &Command : Commands) { 130 + for (auto I = Commands.begin(), E = Commands.end(); I != E; ++I) {
133 - QueryRef Q = QueryParser::parse(Command, QS); 131 + QueryRef Q = QueryParser::parse(*I, QS);
134 if (!Q->run(llvm::outs(), QS)) 132 if (!Q->run(llvm::outs(), QS))
135 return 1; 133 return 1;
136 } 134 }
137 } else if (!CommandFiles.empty()) { 135 } else if (!CommandFiles.empty()) {
138 - for (auto &CommandFile : CommandFiles) { 136 + for (auto I = CommandFiles.begin(), E = CommandFiles.end(); I != E; ++I) {
139 - if (runCommandsInFile(argv[0], CommandFile, QS)) 137 + if (runCommandsInFile(argv[0], *I, QS))
140 return 1; 138 return 1;
141 } 139 }
142 } else { 140 } else {
......
...@@ -3,11 +3,6 @@ set(LLVM_LINK_COMPONENTS ...@@ -3,11 +3,6 @@ set(LLVM_LINK_COMPONENTS
3 Support 3 Support
4 ) 4 )
5 5
6 -configure_file(
7 - ${CMAKE_CURRENT_SOURCE_DIR}/clang-tidy-config.h.cmake
8 - ${CMAKE_CURRENT_BINARY_DIR}/clang-tidy-config.h)
9 -include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
10 -
11 add_clang_library(clangTidy 6 add_clang_library(clangTidy
12 ClangTidy.cpp 7 ClangTidy.cpp
13 ClangTidyCheck.cpp 8 ClangTidyCheck.cpp
...@@ -39,7 +34,7 @@ clang_target_link_libraries(clangTidy ...@@ -39,7 +34,7 @@ clang_target_link_libraries(clangTidy
39 clangToolingCore 34 clangToolingCore
40 ) 35 )
41 36
42 -if(CLANG_TIDY_ENABLE_STATIC_ANALYZER) 37 +if(CLANG_ENABLE_STATIC_ANALYZER)
43 clang_target_link_libraries(clangTidy 38 clang_target_link_libraries(clangTidy
44 PRIVATE 39 PRIVATE
45 clangStaticAnalyzerCore 40 clangStaticAnalyzerCore
...@@ -51,7 +46,6 @@ endif() ...@@ -51,7 +46,6 @@ endif()
51 # If you add a check, also add it to ClangTidyForceLinker.h in this directory. 46 # If you add a check, also add it to ClangTidyForceLinker.h in this directory.
52 add_subdirectory(android) 47 add_subdirectory(android)
53 add_subdirectory(abseil) 48 add_subdirectory(abseil)
54 -add_subdirectory(altera)
55 add_subdirectory(boost) 49 add_subdirectory(boost)
56 add_subdirectory(bugprone) 50 add_subdirectory(bugprone)
57 add_subdirectory(cert) 51 add_subdirectory(cert)
...@@ -65,7 +59,7 @@ add_subdirectory(llvm) ...@@ -65,7 +59,7 @@ add_subdirectory(llvm)
65 add_subdirectory(llvmlibc) 59 add_subdirectory(llvmlibc)
66 add_subdirectory(misc) 60 add_subdirectory(misc)
67 add_subdirectory(modernize) 61 add_subdirectory(modernize)
68 -if(CLANG_TIDY_ENABLE_STATIC_ANALYZER) 62 +if(CLANG_ENABLE_STATIC_ANALYZER)
69 add_subdirectory(mpi) 63 add_subdirectory(mpi)
70 endif() 64 endif()
71 add_subdirectory(objc) 65 add_subdirectory(objc)
...@@ -77,7 +71,6 @@ add_subdirectory(zircon) ...@@ -77,7 +71,6 @@ add_subdirectory(zircon)
77 set(ALL_CLANG_TIDY_CHECKS 71 set(ALL_CLANG_TIDY_CHECKS
78 clangTidyAndroidModule 72 clangTidyAndroidModule
79 clangTidyAbseilModule 73 clangTidyAbseilModule
80 - clangTidyAlteraModule
81 clangTidyBoostModule 74 clangTidyBoostModule
82 clangTidyBugproneModule 75 clangTidyBugproneModule
83 clangTidyCERTModule 76 clangTidyCERTModule
...@@ -98,7 +91,7 @@ set(ALL_CLANG_TIDY_CHECKS ...@@ -98,7 +91,7 @@ set(ALL_CLANG_TIDY_CHECKS
98 clangTidyReadabilityModule 91 clangTidyReadabilityModule
99 clangTidyZirconModule 92 clangTidyZirconModule
100 ) 93 )
101 -if(CLANG_TIDY_ENABLE_STATIC_ANALYZER) 94 +if(CLANG_ENABLE_STATIC_ANALYZER)
102 list(APPEND ALL_CLANG_TIDY_CHECKS clangTidyMPIModule) 95 list(APPEND ALL_CLANG_TIDY_CHECKS clangTidyMPIModule)
103 endif() 96 endif()
104 set(ALL_CLANG_TIDY_CHECKS ${ALL_CLANG_TIDY_CHECKS} PARENT_SCOPE) 97 set(ALL_CLANG_TIDY_CHECKS ${ALL_CLANG_TIDY_CHECKS} PARENT_SCOPE)
......
...@@ -20,11 +20,11 @@ ...@@ -20,11 +20,11 @@
20 #include "ClangTidyModuleRegistry.h" 20 #include "ClangTidyModuleRegistry.h"
21 #include "ClangTidyProfiling.h" 21 #include "ClangTidyProfiling.h"
22 #include "ExpandModularHeadersPPCallbacks.h" 22 #include "ExpandModularHeadersPPCallbacks.h"
23 -#include "clang-tidy-config.h"
24 #include "clang/AST/ASTConsumer.h" 23 #include "clang/AST/ASTConsumer.h"
25 #include "clang/AST/ASTContext.h" 24 #include "clang/AST/ASTContext.h"
26 #include "clang/AST/Decl.h" 25 #include "clang/AST/Decl.h"
27 #include "clang/ASTMatchers/ASTMatchFinder.h" 26 #include "clang/ASTMatchers/ASTMatchFinder.h"
27 +#include "clang/Config/config.h"
28 #include "clang/Format/Format.h" 28 #include "clang/Format/Format.h"
29 #include "clang/Frontend/ASTConsumers.h" 29 #include "clang/Frontend/ASTConsumers.h"
30 #include "clang/Frontend/CompilerInstance.h" 30 #include "clang/Frontend/CompilerInstance.h"
...@@ -47,10 +47,10 @@ ...@@ -47,10 +47,10 @@
47 #include <algorithm> 47 #include <algorithm>
48 #include <utility> 48 #include <utility>
49 49
50 -#if CLANG_TIDY_ENABLE_STATIC_ANALYZER 50 +#if CLANG_ENABLE_STATIC_ANALYZER
51 #include "clang/Analysis/PathDiagnostic.h" 51 #include "clang/Analysis/PathDiagnostic.h"
52 #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h" 52 #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
53 -#endif // CLANG_TIDY_ENABLE_STATIC_ANALYZER 53 +#endif // CLANG_ENABLE_STATIC_ANALYZER
54 54
55 using namespace clang::ast_matchers; 55 using namespace clang::ast_matchers;
56 using namespace clang::driver; 56 using namespace clang::driver;
...@@ -63,7 +63,7 @@ namespace clang { ...@@ -63,7 +63,7 @@ namespace clang {
63 namespace tidy { 63 namespace tidy {
64 64
65 namespace { 65 namespace {
66 -#if CLANG_TIDY_ENABLE_STATIC_ANALYZER 66 +#if CLANG_ENABLE_STATIC_ANALYZER
67 static const char *AnalyzerCheckNamePrefix = "clang-analyzer-"; 67 static const char *AnalyzerCheckNamePrefix = "clang-analyzer-";
68 68
69 class AnalyzerDiagnosticConsumer : public ento::PathDiagnosticConsumer { 69 class AnalyzerDiagnosticConsumer : public ento::PathDiagnosticConsumer {
...@@ -95,7 +95,7 @@ public: ...@@ -95,7 +95,7 @@ public:
95 private: 95 private:
96 ClangTidyContext &Context; 96 ClangTidyContext &Context;
97 }; 97 };
98 -#endif // CLANG_TIDY_ENABLE_STATIC_ANALYZER 98 +#endif // CLANG_ENABLE_STATIC_ANALYZER
99 99
100 class ErrorReporter { 100 class ErrorReporter {
101 public: 101 public:
...@@ -324,16 +324,17 @@ ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory( ...@@ -324,16 +324,17 @@ ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
324 } 324 }
325 } 325 }
326 326
327 -#if CLANG_TIDY_ENABLE_STATIC_ANALYZER 327 +#if CLANG_ENABLE_STATIC_ANALYZER
328 static void setStaticAnalyzerCheckerOpts(const ClangTidyOptions &Opts, 328 static void setStaticAnalyzerCheckerOpts(const ClangTidyOptions &Opts,
329 AnalyzerOptionsRef AnalyzerOptions) { 329 AnalyzerOptionsRef AnalyzerOptions) {
330 StringRef AnalyzerPrefix(AnalyzerCheckNamePrefix); 330 StringRef AnalyzerPrefix(AnalyzerCheckNamePrefix);
331 for (const auto &Opt : Opts.CheckOptions) { 331 for (const auto &Opt : Opts.CheckOptions) {
332 - StringRef OptName(Opt.getKey()); 332 + StringRef OptName(Opt.first);
333 - if (!OptName.consume_front(AnalyzerPrefix)) 333 + if (!OptName.startswith(AnalyzerPrefix))
334 continue; 334 continue;
335 // Analyzer options are always local options so we can ignore priority. 335 // Analyzer options are always local options so we can ignore priority.
336 - AnalyzerOptions->Config[OptName] = Opt.getValue().Value; 336 + AnalyzerOptions->Config[OptName.substr(AnalyzerPrefix.size())] =
337 + Opt.second.Value;
337 } 338 }
338 } 339 }
339 340
...@@ -369,7 +370,7 @@ static CheckersList getAnalyzerCheckersAndPackages(ClangTidyContext &Context, ...@@ -369,7 +370,7 @@ static CheckersList getAnalyzerCheckersAndPackages(ClangTidyContext &Context,
369 } 370 }
370 return List; 371 return List;
371 } 372 }
372 -#endif // CLANG_TIDY_ENABLE_STATIC_ANALYZER 373 +#endif // CLANG_ENABLE_STATIC_ANALYZER
373 374
374 std::unique_ptr<clang::ASTConsumer> 375 std::unique_ptr<clang::ASTConsumer>
375 ClangTidyASTConsumerFactory::CreateASTConsumer( 376 ClangTidyASTConsumerFactory::CreateASTConsumer(
...@@ -424,7 +425,7 @@ ClangTidyASTConsumerFactory::CreateASTConsumer( ...@@ -424,7 +425,7 @@ ClangTidyASTConsumerFactory::CreateASTConsumer(
424 if (!Checks.empty()) 425 if (!Checks.empty())
425 Consumers.push_back(Finder->newASTConsumer()); 426 Consumers.push_back(Finder->newASTConsumer());
426 427
427 -#if CLANG_TIDY_ENABLE_STATIC_ANALYZER 428 +#if CLANG_ENABLE_STATIC_ANALYZER
428 AnalyzerOptionsRef AnalyzerOptions = Compiler.getAnalyzerOpts(); 429 AnalyzerOptionsRef AnalyzerOptions = Compiler.getAnalyzerOpts();
429 AnalyzerOptions->CheckersAndPackages = getAnalyzerCheckersAndPackages( 430 AnalyzerOptions->CheckersAndPackages = getAnalyzerCheckersAndPackages(
430 Context, Context.canEnableAnalyzerAlphaCheckers()); 431 Context, Context.canEnableAnalyzerAlphaCheckers());
...@@ -440,7 +441,7 @@ ClangTidyASTConsumerFactory::CreateASTConsumer( ...@@ -440,7 +441,7 @@ ClangTidyASTConsumerFactory::CreateASTConsumer(
440 new AnalyzerDiagnosticConsumer(Context)); 441 new AnalyzerDiagnosticConsumer(Context));
441 Consumers.push_back(std::move(AnalysisConsumer)); 442 Consumers.push_back(std::move(AnalysisConsumer));
442 } 443 }
443 -#endif // CLANG_TIDY_ENABLE_STATIC_ANALYZER 444 +#endif // CLANG_ENABLE_STATIC_ANALYZER
444 return std::make_unique<ClangTidyASTConsumer>( 445 return std::make_unique<ClangTidyASTConsumer>(
445 std::move(Consumers), std::move(Profiling), std::move(Finder), 446 std::move(Consumers), std::move(Profiling), std::move(Finder),
446 std::move(Checks)); 447 std::move(Checks));
...@@ -449,15 +450,15 @@ ClangTidyASTConsumerFactory::CreateASTConsumer( ...@@ -449,15 +450,15 @@ ClangTidyASTConsumerFactory::CreateASTConsumer(
449 std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() { 450 std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() {
450 std::vector<std::string> CheckNames; 451 std::vector<std::string> CheckNames;
451 for (const auto &CheckFactory : *CheckFactories) { 452 for (const auto &CheckFactory : *CheckFactories) {
452 - if (Context.isCheckEnabled(CheckFactory.getKey())) 453 + if (Context.isCheckEnabled(CheckFactory.first))
453 - CheckNames.emplace_back(CheckFactory.getKey()); 454 + CheckNames.push_back(CheckFactory.first);
454 } 455 }
455 456
456 -#if CLANG_TIDY_ENABLE_STATIC_ANALYZER 457 +#if CLANG_ENABLE_STATIC_ANALYZER
457 for (const auto &AnalyzerCheck : getAnalyzerCheckersAndPackages( 458 for (const auto &AnalyzerCheck : getAnalyzerCheckersAndPackages(
458 Context, Context.canEnableAnalyzerAlphaCheckers())) 459 Context, Context.canEnableAnalyzerAlphaCheckers()))
459 CheckNames.push_back(AnalyzerCheckNamePrefix + AnalyzerCheck.first); 460 CheckNames.push_back(AnalyzerCheckNamePrefix + AnalyzerCheck.first);
460 -#endif // CLANG_TIDY_ENABLE_STATIC_ANALYZER 461 +#endif // CLANG_ENABLE_STATIC_ANALYZER
461 462
462 llvm::sort(CheckNames); 463 llvm::sort(CheckNames);
463 return CheckNames; 464 return CheckNames;
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
10 #include "llvm/ADT/SmallString.h" 10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/ADT/StringRef.h" 11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/Support/Error.h" 12 #include "llvm/Support/Error.h"
13 -#include "llvm/Support/WithColor.h"
14 #include "llvm/Support/raw_ostream.h" 13 #include "llvm/Support/raw_ostream.h"
15 14
16 namespace clang { 15 namespace clang {
...@@ -73,7 +72,7 @@ llvm::Expected<std::string> ...@@ -73,7 +72,7 @@ llvm::Expected<std::string>
73 ClangTidyCheck::OptionsView::get(StringRef LocalName) const { 72 ClangTidyCheck::OptionsView::get(StringRef LocalName) const {
74 const auto &Iter = CheckOptions.find(NamePrefix + LocalName.str()); 73 const auto &Iter = CheckOptions.find(NamePrefix + LocalName.str());
75 if (Iter != CheckOptions.end()) 74 if (Iter != CheckOptions.end())
76 - return Iter->getValue().Value; 75 + return Iter->second.Value;
77 return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str()); 76 return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str());
78 } 77 }
79 78
...@@ -86,7 +85,7 @@ findPriorityOption(const ClangTidyOptions::OptionMap &Options, StringRef NamePre ...@@ -86,7 +85,7 @@ findPriorityOption(const ClangTidyOptions::OptionMap &Options, StringRef NamePre
86 return IterGlobal; 85 return IterGlobal;
87 if (IterGlobal == Options.end()) 86 if (IterGlobal == Options.end())
88 return IterLocal; 87 return IterLocal;
89 - if (IterLocal->getValue().Priority >= IterGlobal->getValue().Priority) 88 + if (IterLocal->second.Priority >= IterGlobal->second.Priority)
90 return IterLocal; 89 return IterLocal;
91 return IterGlobal; 90 return IterGlobal;
92 } 91 }
...@@ -95,7 +94,7 @@ llvm::Expected<std::string> ...@@ -95,7 +94,7 @@ llvm::Expected<std::string>
95 ClangTidyCheck::OptionsView::getLocalOrGlobal(StringRef LocalName) const { 94 ClangTidyCheck::OptionsView::getLocalOrGlobal(StringRef LocalName) const {
96 auto Iter = findPriorityOption(CheckOptions, NamePrefix, LocalName); 95 auto Iter = findPriorityOption(CheckOptions, NamePrefix, LocalName);
97 if (Iter != CheckOptions.end()) 96 if (Iter != CheckOptions.end())
98 - return Iter->getValue().Value; 97 + return Iter->second.Value;
99 return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str()); 98 return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str());
100 } 99 }
101 100
...@@ -127,7 +126,7 @@ bool ClangTidyCheck::OptionsView::get<bool>(StringRef LocalName, ...@@ -127,7 +126,7 @@ bool ClangTidyCheck::OptionsView::get<bool>(StringRef LocalName,
127 llvm::Expected<bool> ValueOr = get<bool>(LocalName); 126 llvm::Expected<bool> ValueOr = get<bool>(LocalName);
128 if (ValueOr) 127 if (ValueOr)
129 return *ValueOr; 128 return *ValueOr;
130 - logIfOptionParsingError(ValueOr.takeError()); 129 + logErrToStdErr(ValueOr.takeError());
131 return Default; 130 return Default;
132 } 131 }
133 132
...@@ -136,7 +135,7 @@ llvm::Expected<bool> ...@@ -136,7 +135,7 @@ llvm::Expected<bool>
136 ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName) const { 135 ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName) const {
137 auto Iter = findPriorityOption(CheckOptions, NamePrefix, LocalName); 136 auto Iter = findPriorityOption(CheckOptions, NamePrefix, LocalName);
138 if (Iter != CheckOptions.end()) 137 if (Iter != CheckOptions.end())
139 - return getAsBool(Iter->getValue().Value, Iter->getKey()); 138 + return getAsBool(Iter->second.Value, Iter->first);
140 return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str()); 139 return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str());
141 } 140 }
142 141
...@@ -146,7 +145,7 @@ bool ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName, ...@@ -146,7 +145,7 @@ bool ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName,
146 llvm::Expected<bool> ValueOr = getLocalOrGlobal<bool>(LocalName); 145 llvm::Expected<bool> ValueOr = getLocalOrGlobal<bool>(LocalName);
147 if (ValueOr) 146 if (ValueOr)
148 return *ValueOr; 147 return *ValueOr;
149 - logIfOptionParsingError(ValueOr.takeError()); 148 + logErrToStdErr(ValueOr.takeError());
150 return Default; 149 return Default;
151 } 150 }
152 151
...@@ -169,16 +168,17 @@ void ClangTidyCheck::OptionsView::store<bool>( ...@@ -169,16 +168,17 @@ void ClangTidyCheck::OptionsView::store<bool>(
169 store(Options, LocalName, Value ? StringRef("true") : StringRef("false")); 168 store(Options, LocalName, Value ? StringRef("true") : StringRef("false"));
170 } 169 }
171 170
172 -llvm::Expected<int64_t> ClangTidyCheck::OptionsView::getEnumInt( 171 +llvm::Expected<int64_t>
173 - StringRef LocalName, ArrayRef<NameAndValue> Mapping, bool CheckGlobal, 172 +ClangTidyCheck::OptionsView::getEnumInt(StringRef LocalName,
174 - bool IgnoreCase) const { 173 + ArrayRef<NameAndValue> Mapping,
174 + bool CheckGlobal, bool IgnoreCase) {
175 auto Iter = CheckGlobal 175 auto Iter = CheckGlobal
176 ? findPriorityOption(CheckOptions, NamePrefix, LocalName) 176 ? findPriorityOption(CheckOptions, NamePrefix, LocalName)
177 : CheckOptions.find((NamePrefix + LocalName).str()); 177 : CheckOptions.find((NamePrefix + LocalName).str());
178 if (Iter == CheckOptions.end()) 178 if (Iter == CheckOptions.end())
179 return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str()); 179 return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str());
180 180
181 - StringRef Value = Iter->getValue().Value; 181 + StringRef Value = Iter->second.Value;
182 StringRef Closest; 182 StringRef Closest;
183 unsigned EditDistance = -1; 183 unsigned EditDistance = -1;
184 for (const auto &NameAndEnum : Mapping) { 184 for (const auto &NameAndEnum : Mapping) {
...@@ -200,38 +200,18 @@ llvm::Expected<int64_t> ClangTidyCheck::OptionsView::getEnumInt( ...@@ -200,38 +200,18 @@ llvm::Expected<int64_t> ClangTidyCheck::OptionsView::getEnumInt(
200 } 200 }
201 if (EditDistance < 3) 201 if (EditDistance < 3)
202 return llvm::make_error<UnparseableEnumOptionError>( 202 return llvm::make_error<UnparseableEnumOptionError>(
203 - Iter->getKey().str(), Iter->getValue().Value, Closest.str()); 203 + Iter->first, Iter->second.Value, std::string(Closest));
204 - return llvm::make_error<UnparseableEnumOptionError>(Iter->getKey().str(), 204 + return llvm::make_error<UnparseableEnumOptionError>(Iter->first,
205 - Iter->getValue().Value); 205 + Iter->second.Value);
206 } 206 }
207 207
208 -void ClangTidyCheck::OptionsView::logIfOptionParsingError(llvm::Error &&Err) { 208 +void ClangTidyCheck::OptionsView::logErrToStdErr(llvm::Error &&Err) {
209 - if (auto RemainingErrors = 209 + llvm::logAllUnhandledErrors(
210 - llvm::handleErrors(std::move(Err), [](const MissingOptionError &) {})) 210 + llvm::handleErrors(std::move(Err),
211 - llvm::logAllUnhandledErrors(std::move(RemainingErrors), 211 + [](const MissingOptionError &) -> llvm::Error {
212 - llvm::WithColor::warning()); 212 + return llvm::Error::success();
213 + }),
214 + llvm::errs(), "warning: ");
213 } 215 }
214 -
215 -template <>
216 -Optional<std::string> ClangTidyCheck::OptionsView::getOptional<std::string>(
217 - StringRef LocalName) const {
218 - if (auto ValueOr = get(LocalName))
219 - return *ValueOr;
220 - else
221 - consumeError(ValueOr.takeError());
222 - return llvm::None;
223 -}
224 -
225 -template <>
226 -Optional<std::string>
227 -ClangTidyCheck::OptionsView::getOptionalLocalOrGlobal<std::string>(
228 - StringRef LocalName) const {
229 - if (auto ValueOr = getLocalOrGlobal(LocalName))
230 - return *ValueOr;
231 - else
232 - consumeError(ValueOr.takeError());
233 - return llvm::None;
234 -}
235 -
236 } // namespace tidy 216 } // namespace tidy
237 } // namespace clang 217 } // namespace clang
......
...@@ -268,7 +268,7 @@ public: ...@@ -268,7 +268,7 @@ public:
268 if (llvm::Expected<T> ValueOr = get<T>(LocalName)) 268 if (llvm::Expected<T> ValueOr = get<T>(LocalName))
269 return *ValueOr; 269 return *ValueOr;
270 else 270 else
271 - logIfOptionParsingError(ValueOr.takeError()); 271 + logErrToStdErr(ValueOr.takeError());
272 return Default; 272 return Default;
273 } 273 }
274 274
...@@ -314,7 +314,7 @@ public: ...@@ -314,7 +314,7 @@ public:
314 if (llvm::Expected<T> ValueOr = getLocalOrGlobal<T>(LocalName)) 314 if (llvm::Expected<T> ValueOr = getLocalOrGlobal<T>(LocalName))
315 return *ValueOr; 315 return *ValueOr;
316 else 316 else
317 - logIfOptionParsingError(ValueOr.takeError()); 317 + logErrToStdErr(ValueOr.takeError());
318 return Default; 318 return Default;
319 } 319 }
320 320
...@@ -330,7 +330,7 @@ public: ...@@ -330,7 +330,7 @@ public:
330 /// supply the mapping required to convert between ``T`` and a string. 330 /// supply the mapping required to convert between ``T`` and a string.
331 template <typename T> 331 template <typename T>
332 std::enable_if_t<std::is_enum<T>::value, llvm::Expected<T>> 332 std::enable_if_t<std::is_enum<T>::value, llvm::Expected<T>>
333 - get(StringRef LocalName, bool IgnoreCase = false) const { 333 + get(StringRef LocalName, bool IgnoreCase = false) {
334 if (llvm::Expected<int64_t> ValueOr = 334 if (llvm::Expected<int64_t> ValueOr =
335 getEnumInt(LocalName, typeEraseMapping<T>(), false, IgnoreCase)) 335 getEnumInt(LocalName, typeEraseMapping<T>(), false, IgnoreCase))
336 return static_cast<T>(*ValueOr); 336 return static_cast<T>(*ValueOr);
...@@ -349,11 +349,11 @@ public: ...@@ -349,11 +349,11 @@ public:
349 /// supply the mapping required to convert between ``T`` and a string. 349 /// supply the mapping required to convert between ``T`` and a string.
350 template <typename T> 350 template <typename T>
351 std::enable_if_t<std::is_enum<T>::value, T> 351 std::enable_if_t<std::is_enum<T>::value, T>
352 - get(StringRef LocalName, T Default, bool IgnoreCase = false) const { 352 + get(StringRef LocalName, T Default, bool IgnoreCase = false) {
353 if (auto ValueOr = get<T>(LocalName, IgnoreCase)) 353 if (auto ValueOr = get<T>(LocalName, IgnoreCase))
354 return *ValueOr; 354 return *ValueOr;
355 else 355 else
356 - logIfOptionParsingError(ValueOr.takeError()); 356 + logErrToStdErr(ValueOr.takeError());
357 return Default; 357 return Default;
358 } 358 }
359 359
...@@ -370,7 +370,8 @@ public: ...@@ -370,7 +370,8 @@ public:
370 /// supply the mapping required to convert between ``T`` and a string. 370 /// supply the mapping required to convert between ``T`` and a string.
371 template <typename T> 371 template <typename T>
372 std::enable_if_t<std::is_enum<T>::value, llvm::Expected<T>> 372 std::enable_if_t<std::is_enum<T>::value, llvm::Expected<T>>
373 - getLocalOrGlobal(StringRef LocalName, bool IgnoreCase = false) const { 373 + getLocalOrGlobal(StringRef LocalName,
374 + bool IgnoreCase = false) {
374 if (llvm::Expected<int64_t> ValueOr = 375 if (llvm::Expected<int64_t> ValueOr =
375 getEnumInt(LocalName, typeEraseMapping<T>(), true, IgnoreCase)) 376 getEnumInt(LocalName, typeEraseMapping<T>(), true, IgnoreCase))
376 return static_cast<T>(*ValueOr); 377 return static_cast<T>(*ValueOr);
...@@ -390,40 +391,14 @@ public: ...@@ -390,40 +391,14 @@ public:
390 /// supply the mapping required to convert between ``T`` and a string. 391 /// supply the mapping required to convert between ``T`` and a string.
391 template <typename T> 392 template <typename T>
392 std::enable_if_t<std::is_enum<T>::value, T> 393 std::enable_if_t<std::is_enum<T>::value, T>
393 - getLocalOrGlobal(StringRef LocalName, T Default, 394 + getLocalOrGlobal(StringRef LocalName, T Default, bool IgnoreCase = false) {
394 - bool IgnoreCase = false) const {
395 if (auto ValueOr = getLocalOrGlobal<T>(LocalName, IgnoreCase)) 395 if (auto ValueOr = getLocalOrGlobal<T>(LocalName, IgnoreCase))
396 return *ValueOr; 396 return *ValueOr;
397 else 397 else
398 - logIfOptionParsingError(ValueOr.takeError()); 398 + logErrToStdErr(ValueOr.takeError());
399 return Default; 399 return Default;
400 } 400 }
401 401
402 - /// Returns the value for the option \p LocalName represented as a ``T``.
403 - /// If the option is missing returns None, if the option can't be parsed
404 - /// as a ``T``, log that to stderr and return None.
405 - template <typename T = std::string>
406 - llvm::Optional<T> getOptional(StringRef LocalName) const {
407 - if (auto ValueOr = get<T>(LocalName))
408 - return *ValueOr;
409 - else
410 - logIfOptionParsingError(ValueOr.takeError());
411 - return llvm::None;
412 - }
413 -
414 - /// Returns the value for the local or global option \p LocalName
415 - /// represented as a ``T``.
416 - /// If the option is missing returns None, if the
417 - /// option can't be parsed as a ``T``, log that to stderr and return None.
418 - template <typename T = std::string>
419 - llvm::Optional<T> getOptionalLocalOrGlobal(StringRef LocalName) const {
420 - if (auto ValueOr = getLocalOrGlobal<T>(LocalName))
421 - return *ValueOr;
422 - else
423 - logIfOptionParsingError(ValueOr.takeError());
424 - return llvm::None;
425 - }
426 -
427 /// Stores an option with the check-local name \p LocalName with 402 /// Stores an option with the check-local name \p LocalName with
428 /// string value \p Value to \p Options. 403 /// string value \p Value to \p Options.
429 void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, 404 void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
...@@ -445,8 +420,7 @@ public: ...@@ -445,8 +420,7 @@ public:
445 /// supply the mapping required to convert between ``T`` and a string. 420 /// supply the mapping required to convert between ``T`` and a string.
446 template <typename T> 421 template <typename T>
447 std::enable_if_t<std::is_enum<T>::value> 422 std::enable_if_t<std::is_enum<T>::value>
448 - store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, 423 + store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value) {
449 - T Value) const {
450 ArrayRef<std::pair<T, StringRef>> Mapping = 424 ArrayRef<std::pair<T, StringRef>> Mapping =
451 OptionEnumMapping<T>::getEnumMapping(); 425 OptionEnumMapping<T>::getEnumMapping();
452 auto Iter = llvm::find_if( 426 auto Iter = llvm::find_if(
...@@ -462,11 +436,11 @@ public: ...@@ -462,11 +436,11 @@ public:
462 436
463 llvm::Expected<int64_t> getEnumInt(StringRef LocalName, 437 llvm::Expected<int64_t> getEnumInt(StringRef LocalName,
464 ArrayRef<NameAndValue> Mapping, 438 ArrayRef<NameAndValue> Mapping,
465 - bool CheckGlobal, bool IgnoreCase) const; 439 + bool CheckGlobal, bool IgnoreCase);
466 440
467 template <typename T> 441 template <typename T>
468 std::enable_if_t<std::is_enum<T>::value, std::vector<NameAndValue>> 442 std::enable_if_t<std::is_enum<T>::value, std::vector<NameAndValue>>
469 - typeEraseMapping() const { 443 + typeEraseMapping() {
470 ArrayRef<std::pair<T, StringRef>> Mapping = 444 ArrayRef<std::pair<T, StringRef>> Mapping =
471 OptionEnumMapping<T>::getEnumMapping(); 445 OptionEnumMapping<T>::getEnumMapping();
472 std::vector<NameAndValue> Result; 446 std::vector<NameAndValue> Result;
...@@ -481,8 +455,7 @@ public: ...@@ -481,8 +455,7 @@ public:
481 void storeInt(ClangTidyOptions::OptionMap &Options, StringRef LocalName, 455 void storeInt(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
482 int64_t Value) const; 456 int64_t Value) const;
483 457
484 - /// Logs an Error to stderr if a \p Err is not a MissingOptionError. 458 + static void logErrToStdErr(llvm::Error &&Err);
485 - static void logIfOptionParsingError(llvm::Error &&Err);
486 459
487 std::string NamePrefix; 460 std::string NamePrefix;
488 const ClangTidyOptions::OptionMap &CheckOptions; 461 const ClangTidyOptions::OptionMap &CheckOptions;
...@@ -550,19 +523,6 @@ void ClangTidyCheck::OptionsView::store<bool>( ...@@ -550,19 +523,6 @@ void ClangTidyCheck::OptionsView::store<bool>(
550 ClangTidyOptions::OptionMap &Options, StringRef LocalName, 523 ClangTidyOptions::OptionMap &Options, StringRef LocalName,
551 bool Value) const; 524 bool Value) const;
552 525
553 -/// Returns the value for the option \p LocalName.
554 -/// If the option is missing returns None.
555 -template <>
556 -Optional<std::string> ClangTidyCheck::OptionsView::getOptional<std::string>(
557 - StringRef LocalName) const;
558 -
559 -/// Returns the value for the local or global option \p LocalName.
560 -/// If the option is missing returns None.
561 -template <>
562 -Optional<std::string>
563 -ClangTidyCheck::OptionsView::getOptionalLocalOrGlobal<std::string>(
564 - StringRef LocalName) const;
565 -
566 } // namespace tidy 526 } // namespace tidy
567 } // namespace clang 527 } // namespace clang
568 528
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
31 #include "llvm/ADT/STLExtras.h" 31 #include "llvm/ADT/STLExtras.h"
32 #include "llvm/ADT/SmallString.h" 32 #include "llvm/ADT/SmallString.h"
33 #include "llvm/ADT/StringMap.h" 33 #include "llvm/ADT/StringMap.h"
34 -#include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/FormatVariadic.h" 34 #include "llvm/Support/FormatVariadic.h"
36 #include "llvm/Support/Regex.h" 35 #include "llvm/Support/Regex.h"
37 #include <tuple> 36 #include <tuple>
...@@ -591,7 +590,6 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() { ...@@ -591,7 +590,6 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
591 // An event can be either the begin or the end of an interval. 590 // An event can be either the begin or the end of an interval.
592 enum EventType { 591 enum EventType {
593 ET_Begin = 1, 592 ET_Begin = 1,
594 - ET_Insert = 0,
595 ET_End = -1, 593 ET_End = -1,
596 }; 594 };
597 595
...@@ -623,17 +621,10 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() { ...@@ -623,17 +621,10 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
623 // one will be processed before, disallowing the second one, and the 621 // one will be processed before, disallowing the second one, and the
624 // end point of the first one will also be processed before, 622 // end point of the first one will also be processed before,
625 // disallowing the first one. 623 // disallowing the first one.
626 - switch (Type) { 624 + if (Type == ET_Begin)
627 - case ET_Begin:
628 Priority = std::make_tuple(Begin, Type, -End, -ErrorSize, ErrorId); 625 Priority = std::make_tuple(Begin, Type, -End, -ErrorSize, ErrorId);
629 - break; 626 + else
630 - case ET_Insert:
631 - Priority = std::make_tuple(Begin, Type, -End, ErrorSize, ErrorId);
632 - break;
633 - case ET_End:
634 Priority = std::make_tuple(End, Type, -Begin, ErrorSize, ErrorId); 627 Priority = std::make_tuple(End, Type, -Begin, ErrorSize, ErrorId);
635 - break;
636 - }
637 } 628 }
638 629
639 bool operator<(const Event &Other) const { 630 bool operator<(const Event &Other) const {
...@@ -671,19 +662,19 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() { ...@@ -671,19 +662,19 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
671 } 662 }
672 663
673 // Build events from error intervals. 664 // Build events from error intervals.
674 - llvm::StringMap<std::vector<Event>> FileEvents; 665 + std::map<std::string, std::vector<Event>> FileEvents;
675 for (unsigned I = 0; I < ErrorFixes.size(); ++I) { 666 for (unsigned I = 0; I < ErrorFixes.size(); ++I) {
676 for (const auto &FileAndReplace : *ErrorFixes[I].second) { 667 for (const auto &FileAndReplace : *ErrorFixes[I].second) {
677 for (const auto &Replace : FileAndReplace.second) { 668 for (const auto &Replace : FileAndReplace.second) {
678 unsigned Begin = Replace.getOffset(); 669 unsigned Begin = Replace.getOffset();
679 unsigned End = Begin + Replace.getLength(); 670 unsigned End = Begin + Replace.getLength();
680 - auto &Events = FileEvents[Replace.getFilePath()]; 671 + const std::string &FilePath = std::string(Replace.getFilePath());
681 - if (Begin == End) { 672 + // FIXME: Handle empty intervals, such as those from insertions.
682 - Events.emplace_back(Begin, End, Event::ET_Insert, I, Sizes[I]); 673 + if (Begin == End)
683 - } else { 674 + continue;
684 - Events.emplace_back(Begin, End, Event::ET_Begin, I, Sizes[I]); 675 + auto &Events = FileEvents[FilePath];
685 - Events.emplace_back(Begin, End, Event::ET_End, I, Sizes[I]); 676 + Events.emplace_back(Begin, End, Event::ET_Begin, I, Sizes[I]);
686 - } 677 + Events.emplace_back(Begin, End, Event::ET_End, I, Sizes[I]);
687 } 678 }
688 } 679 }
689 } 680 }
...@@ -695,20 +686,14 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() { ...@@ -695,20 +686,14 @@ void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
695 llvm::sort(Events); 686 llvm::sort(Events);
696 int OpenIntervals = 0; 687 int OpenIntervals = 0;
697 for (const auto &Event : Events) { 688 for (const auto &Event : Events) {
698 - switch (Event.Type) { 689 + if (Event.Type == Event::ET_End)
699 - case Event::ET_Begin: 690 + --OpenIntervals;
700 - if (OpenIntervals++ != 0) 691 + // This has to be checked after removing the interval from the count if it
701 - Apply[Event.ErrorId] = false; 692 + // is an end event, or before adding it if it is a begin event.
702 - break; 693 + if (OpenIntervals != 0)
703 - case Event::ET_Insert: 694 + Apply[Event.ErrorId] = false;
704 - if (OpenIntervals != 0) 695 + if (Event.Type == Event::ET_Begin)
705 - Apply[Event.ErrorId] = false; 696 + ++OpenIntervals;
706 - break;
707 - case Event::ET_End:
708 - if (--OpenIntervals != 0)
709 - Apply[Event.ErrorId] = false;
710 - break;
711 - }
712 } 697 }
713 assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match"); 698 assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
714 } 699 }
...@@ -744,7 +729,7 @@ struct EqualClangTidyError { ...@@ -744,7 +729,7 @@ struct EqualClangTidyError {
744 std::vector<ClangTidyError> ClangTidyDiagnosticConsumer::take() { 729 std::vector<ClangTidyError> ClangTidyDiagnosticConsumer::take() {
745 finalizeLastError(); 730 finalizeLastError();
746 731
747 - llvm::stable_sort(Errors, LessClangTidyError()); 732 + llvm::sort(Errors, LessClangTidyError());
748 Errors.erase(std::unique(Errors.begin(), Errors.end(), EqualClangTidyError()), 733 Errors.erase(std::unique(Errors.begin(), Errors.end(), EqualClangTidyError()),
749 Errors.end()); 734 Errors.end());
750 if (RemoveIncompatibleErrors) 735 if (RemoveIncompatibleErrors)
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYFORCELINKER_H 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYFORCELINKER_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYFORCELINKER_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYFORCELINKER_H
11 11
12 -#include "clang-tidy-config.h" 12 +#include "clang/Config/config.h"
13 #include "llvm/Support/Compiler.h" 13 #include "llvm/Support/Compiler.h"
14 14
15 namespace clang { 15 namespace clang {
...@@ -20,11 +20,6 @@ extern volatile int AbseilModuleAnchorSource; ...@@ -20,11 +20,6 @@ extern volatile int AbseilModuleAnchorSource;
20 static int LLVM_ATTRIBUTE_UNUSED AbseilModuleAnchorDestination = 20 static int LLVM_ATTRIBUTE_UNUSED AbseilModuleAnchorDestination =
21 AbseilModuleAnchorSource; 21 AbseilModuleAnchorSource;
22 22
23 -// This anchor is used to force the linker to link the AlteraModule.
24 -extern volatile int AlteraModuleAnchorSource;
25 -static int LLVM_ATTRIBUTE_UNUSED AlteraModuleAnchorDestination =
26 - AlteraModuleAnchorSource;
27 -
28 // This anchor is used to force the linker to link the AndroidModule. 23 // This anchor is used to force the linker to link the AndroidModule.
29 extern volatile int AndroidModuleAnchorSource; 24 extern volatile int AndroidModuleAnchorSource;
30 static int LLVM_ATTRIBUTE_UNUSED AndroidModuleAnchorDestination = 25 static int LLVM_ATTRIBUTE_UNUSED AndroidModuleAnchorDestination =
...@@ -95,7 +90,7 @@ extern volatile int ModernizeModuleAnchorSource; ...@@ -95,7 +90,7 @@ extern volatile int ModernizeModuleAnchorSource;
95 static int LLVM_ATTRIBUTE_UNUSED ModernizeModuleAnchorDestination = 90 static int LLVM_ATTRIBUTE_UNUSED ModernizeModuleAnchorDestination =
96 ModernizeModuleAnchorSource; 91 ModernizeModuleAnchorSource;
97 92
98 -#if CLANG_TIDY_ENABLE_STATIC_ANALYZER && \ 93 +#if CLANG_ENABLE_STATIC_ANALYZER && \
99 !defined(CLANG_TIDY_DISABLE_STATIC_ANALYZER_CHECKS) 94 !defined(CLANG_TIDY_DISABLE_STATIC_ANALYZER_CHECKS)
100 // This anchor is used to force the linker to link the MPIModule. 95 // This anchor is used to force the linker to link the MPIModule.
101 extern volatile int MPIModuleAnchorSource; 96 extern volatile int MPIModuleAnchorSource;
......
...@@ -18,15 +18,15 @@ namespace tidy { ...@@ -18,15 +18,15 @@ namespace tidy {
18 18
19 void ClangTidyCheckFactories::registerCheckFactory(StringRef Name, 19 void ClangTidyCheckFactories::registerCheckFactory(StringRef Name,
20 CheckFactory Factory) { 20 CheckFactory Factory) {
21 - Factories.insert_or_assign(Name, std::move(Factory)); 21 + Factories[std::string(Name)] = std::move(Factory);
22 } 22 }
23 23
24 std::vector<std::unique_ptr<ClangTidyCheck>> 24 std::vector<std::unique_ptr<ClangTidyCheck>>
25 ClangTidyCheckFactories::createChecks(ClangTidyContext *Context) { 25 ClangTidyCheckFactories::createChecks(ClangTidyContext *Context) {
26 std::vector<std::unique_ptr<ClangTidyCheck>> Checks; 26 std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
27 for (const auto &Factory : Factories) { 27 for (const auto &Factory : Factories) {
28 - if (Context->isCheckEnabled(Factory.getKey())) 28 + if (Context->isCheckEnabled(Factory.first))
29 - Checks.emplace_back(Factory.getValue()(Factory.getKey(), Context)); 29 + Checks.emplace_back(Factory.second(Factory.first, Context));
30 } 30 }
31 return Checks; 31 return Checks;
32 } 32 }
......
...@@ -69,7 +69,7 @@ public: ...@@ -69,7 +69,7 @@ public:
69 std::vector<std::unique_ptr<ClangTidyCheck>> 69 std::vector<std::unique_ptr<ClangTidyCheck>>
70 createChecks(ClangTidyContext *Context); 70 createChecks(ClangTidyContext *Context);
71 71
72 - typedef llvm::StringMap<CheckFactory> FactoryMap; 72 + typedef std::map<std::string, CheckFactory> FactoryMap;
73 FactoryMap::const_iterator begin() const { return Factories.begin(); } 73 FactoryMap::const_iterator begin() const { return Factories.begin(); }
74 FactoryMap::const_iterator end() const { return Factories.end(); } 74 FactoryMap::const_iterator end() const { return Factories.end(); }
75 bool empty() const { return Factories.empty(); } 75 bool empty() const { return Factories.empty(); }
......
...@@ -70,7 +70,7 @@ struct NOptionMap { ...@@ -70,7 +70,7 @@ struct NOptionMap {
70 NOptionMap(IO &, const ClangTidyOptions::OptionMap &OptionMap) { 70 NOptionMap(IO &, const ClangTidyOptions::OptionMap &OptionMap) {
71 Options.reserve(OptionMap.size()); 71 Options.reserve(OptionMap.size());
72 for (const auto &KeyValue : OptionMap) 72 for (const auto &KeyValue : OptionMap)
73 - Options.emplace_back(std::string(KeyValue.getKey()), KeyValue.getValue().Value); 73 + Options.emplace_back(KeyValue.first, KeyValue.second.Value);
74 } 74 }
75 ClangTidyOptions::OptionMap denormalize(IO &) { 75 ClangTidyOptions::OptionMap denormalize(IO &) {
76 ClangTidyOptions::OptionMap Map; 76 ClangTidyOptions::OptionMap Map;
...@@ -114,9 +114,11 @@ ClangTidyOptions ClangTidyOptions::getDefaults() { ...@@ -114,9 +114,11 @@ ClangTidyOptions ClangTidyOptions::getDefaults() {
114 Options.SystemHeaders = false; 114 Options.SystemHeaders = false;
115 Options.FormatStyle = "none"; 115 Options.FormatStyle = "none";
116 Options.User = llvm::None; 116 Options.User = llvm::None;
117 + unsigned Priority = 0;
117 for (const ClangTidyModuleRegistry::entry &Module : 118 for (const ClangTidyModuleRegistry::entry &Module :
118 ClangTidyModuleRegistry::entries()) 119 ClangTidyModuleRegistry::entries())
119 - Options = Options.mergeWith(Module.instantiate()->getModuleOptions(), 0); 120 + Options =
121 + Options.mergeWith(Module.instantiate()->getModuleOptions(), ++Priority);
120 return Options; 122 return Options;
121 } 123 }
122 124
...@@ -157,10 +159,8 @@ ClangTidyOptions ClangTidyOptions::mergeWith(const ClangTidyOptions &Other, ...@@ -157,10 +159,8 @@ ClangTidyOptions ClangTidyOptions::mergeWith(const ClangTidyOptions &Other,
157 mergeVectors(Result.ExtraArgsBefore, Other.ExtraArgsBefore); 159 mergeVectors(Result.ExtraArgsBefore, Other.ExtraArgsBefore);
158 160
159 for (const auto &KeyValue : Other.CheckOptions) { 161 for (const auto &KeyValue : Other.CheckOptions) {
160 - Result.CheckOptions.insert_or_assign( 162 + Result.CheckOptions[KeyValue.first] = ClangTidyValue(
161 - KeyValue.getKey(), 163 + KeyValue.second.Value, KeyValue.second.Priority + Priority);
162 - ClangTidyValue(KeyValue.getValue().Value,
163 - KeyValue.getValue().Priority + Priority));
164 } 164 }
165 165
166 return Result; 166 return Result;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 #include "llvm/Support/ErrorOr.h" 16 #include "llvm/Support/ErrorOr.h"
17 #include "llvm/Support/VirtualFileSystem.h" 17 #include "llvm/Support/VirtualFileSystem.h"
18 #include <functional> 18 #include <functional>
19 +#include <map>
19 #include <string> 20 #include <string>
20 #include <system_error> 21 #include <system_error>
21 #include <utility> 22 #include <utility>
...@@ -107,7 +108,7 @@ struct ClangTidyOptions { ...@@ -107,7 +108,7 @@ struct ClangTidyOptions {
107 unsigned Priority; 108 unsigned Priority;
108 }; 109 };
109 typedef std::pair<std::string, std::string> StringPair; 110 typedef std::pair<std::string, std::string> StringPair;
110 - typedef llvm::StringMap<ClangTidyValue> OptionMap; 111 + typedef std::map<std::string, ClangTidyValue> OptionMap;
111 112
112 /// Key-value mapping used to store check-specific options. 113 /// Key-value mapping used to store check-specific options.
113 OptionMap CheckOptions; 114 OptionMap CheckOptions;
......
...@@ -47,18 +47,14 @@ AST_POLYMORPHIC_MATCHER( ...@@ -47,18 +47,14 @@ AST_POLYMORPHIC_MATCHER(
47 if (PrefixPosition == StringRef::npos) 47 if (PrefixPosition == StringRef::npos)
48 return false; 48 return false;
49 Path = Path.drop_front(PrefixPosition + AbslPrefix.size()); 49 Path = Path.drop_front(PrefixPosition + AbslPrefix.size());
50 - static const char *AbseilLibraries[] = {"algorithm", "base", 50 + static const char *AbseilLibraries[] = {
51 - "container", "debugging", 51 + "algorithm", "base", "container", "debugging", "flags",
52 - "flags", "hash", 52 + "hash", "iterator", "memory", "meta", "numeric",
53 - "iterator", "memory", 53 + "random", "strings", "synchronization", "time", "types",
54 - "meta", "numeric", 54 + "utility"};
55 - "random", "status", 55 + return std::any_of(
56 - "strings", "synchronization", 56 + std::begin(AbseilLibraries), std::end(AbseilLibraries),
57 - "time", "types", 57 + [&](const char *Library) { return Path.startswith(Library); });
58 - "utility"};
59 - return llvm::any_of(AbseilLibraries, [&](const char *Library) {
60 - return Path.startswith(Library);
61 - });
62 } 58 }
63 59
64 } // namespace ast_matchers 60 } // namespace ast_matchers
......
...@@ -26,8 +26,8 @@ StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name, ...@@ -26,8 +26,8 @@ StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
26 : ClangTidyCheck(Name, Context), 26 : ClangTidyCheck(Name, Context),
27 StringLikeClasses(utils::options::parseStringList( 27 StringLikeClasses(utils::options::parseStringList(
28 Options.get("StringLikeClasses", "::std::basic_string"))), 28 Options.get("StringLikeClasses", "::std::basic_string"))),
29 - IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", 29 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
30 - utils::IncludeSorter::IS_LLVM)), 30 + utils::IncludeSorter::IS_LLVM)),
31 AbseilStringsMatchHeader( 31 AbseilStringsMatchHeader(
32 Options.get("AbseilStringsMatchHeader", "absl/strings/match.h")) {} 32 Options.get("AbseilStringsMatchHeader", "absl/strings/match.h")) {}
33 33
...@@ -105,21 +105,23 @@ void StringFindStartswithCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -105,21 +105,23 @@ void StringFindStartswithCheck::check(const MatchFinder::MatchResult &Result) {
105 105
106 // Create a preprocessor #include FixIt hint (CreateIncludeInsertion checks 106 // Create a preprocessor #include FixIt hint (CreateIncludeInsertion checks
107 // whether this already exists). 107 // whether this already exists).
108 - Diagnostic << IncludeInserter.createIncludeInsertion( 108 + Diagnostic << IncludeInserter->CreateIncludeInsertion(
109 - Source.getFileID(ComparisonExpr->getBeginLoc()), 109 + Source.getFileID(ComparisonExpr->getBeginLoc()), AbseilStringsMatchHeader,
110 - AbseilStringsMatchHeader); 110 + false);
111 } 111 }
112 112
113 void StringFindStartswithCheck::registerPPCallbacks( 113 void StringFindStartswithCheck::registerPPCallbacks(
114 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { 114 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
115 - IncludeInserter.registerPreprocessor(PP); 115 + IncludeInserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
116 + IncludeStyle);
117 + PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
116 } 118 }
117 119
118 void StringFindStartswithCheck::storeOptions( 120 void StringFindStartswithCheck::storeOptions(
119 ClangTidyOptions::OptionMap &Opts) { 121 ClangTidyOptions::OptionMap &Opts) {
120 Options.store(Opts, "StringLikeClasses", 122 Options.store(Opts, "StringLikeClasses",
121 utils::options::serializeStringList(StringLikeClasses)); 123 utils::options::serializeStringList(StringLikeClasses));
122 - Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); 124 + Options.store(Opts, "IncludeStyle", IncludeStyle);
123 Options.store(Opts, "AbseilStringsMatchHeader", AbseilStringsMatchHeader); 125 Options.store(Opts, "AbseilStringsMatchHeader", AbseilStringsMatchHeader);
124 } 126 }
125 127
......
...@@ -35,8 +35,9 @@ public: ...@@ -35,8 +35,9 @@ public:
35 void storeOptions(ClangTidyOptions::OptionMap &Opts) override; 35 void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
36 36
37 private: 37 private:
38 + std::unique_ptr<clang::tidy::utils::IncludeInserter> IncludeInserter;
38 const std::vector<std::string> StringLikeClasses; 39 const std::vector<std::string> StringLikeClasses;
39 - utils::IncludeInserter IncludeInserter; 40 + const utils::IncludeSorter::IncludeStyle IncludeStyle;
40 const std::string AbseilStringsMatchHeader; 41 const std::string AbseilStringsMatchHeader;
41 }; 42 };
42 43
......
...@@ -136,7 +136,7 @@ void %(check_name)s::registerMatchers(MatchFinder *Finder) { ...@@ -136,7 +136,7 @@ void %(check_name)s::registerMatchers(MatchFinder *Finder) {
136 void %(check_name)s::check(const MatchFinder::MatchResult &Result) { 136 void %(check_name)s::check(const MatchFinder::MatchResult &Result) {
137 // FIXME: Add callback implementation. 137 // FIXME: Add callback implementation.
138 const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("x"); 138 const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("x");
139 - if (!MatchedDecl->getIdentifier() || MatchedDecl->getName().startswith("awesome_")) 139 + if (MatchedDecl->getName().startswith("awesome_"))
140 return; 140 return;
141 diag(MatchedDecl->getLocation(), "function %%0 is insufficiently awesome") 141 diag(MatchedDecl->getLocation(), "function %%0 is insufficiently awesome")
142 << MatchedDecl; 142 << MatchedDecl;
......
1 -//===--- AlteraTidyModule.cpp - clang-tidy --------------------------------===//
2 -//
3 -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 -// See https://llvm.org/LICENSE.txt for license information.
5 -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 -//
7 -//===----------------------------------------------------------------------===//
8 -
9 -#include "../ClangTidy.h"
10 -#include "../ClangTidyModule.h"
11 -#include "../ClangTidyModuleRegistry.h"
12 -#include "StructPackAlignCheck.h"
13 -
14 -using namespace clang::ast_matchers;
15 -
16 -namespace clang {
17 -namespace tidy {
18 -namespace altera {
19 -
20 -class AlteraModule : public ClangTidyModule {
21 -public:
22 - void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
23 - CheckFactories.registerCheck<StructPackAlignCheck>(
24 - "altera-struct-pack-align");
25 - }
26 -};
27 -
28 -} // namespace altera
29 -
30 -// Register the AlteraTidyModule using this statically initialized variable.
31 -static ClangTidyModuleRegistry::Add<altera::AlteraModule>
32 - X("altera-module", "Adds Altera FPGA OpenCL lint checks.");
33 -
34 -// This anchor is used to force the linker to link in the generated object file
35 -// and thus register the AlteraModule.
36 -volatile int AlteraModuleAnchorSource = 0;
37 -
38 -} // namespace tidy
39 -} // namespace clang
1 -set(LLVM_LINK_COMPONENTS
2 - FrontendOpenMP
3 - support
4 - )
5 -
6 -add_clang_library(clangTidyAlteraModule
7 - AlteraTidyModule.cpp
8 - StructPackAlignCheck.cpp
9 -
10 - LINK_LIBS
11 - clangTidy
12 - clangTidyUtils
13 - )
14 -
15 -clang_target_link_libraries(clangTidyAlteraModule
16 - PRIVATE
17 - clangAnalysis
18 - clangAST
19 - clangASTMatchers
20 - clangBasic
21 - clangLex
22 - )
1 -//===--- StructPackAlignCheck.cpp - clang-tidy ----------------------------===//
2 -//
3 -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 -// See https://llvm.org/LICENSE.txt for license information.
5 -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 -//
7 -//===----------------------------------------------------------------------===//
8 -
9 -#include "StructPackAlignCheck.h"
10 -#include "clang/AST/ASTContext.h"
11 -#include "clang/AST/RecordLayout.h"
12 -#include "clang/ASTMatchers/ASTMatchFinder.h"
13 -#include <math.h>
14 -#include <sstream>
15 -
16 -using namespace clang::ast_matchers;
17 -
18 -namespace clang {
19 -namespace tidy {
20 -namespace altera {
21 -
22 -void StructPackAlignCheck::registerMatchers(MatchFinder *Finder) {
23 - Finder->addMatcher(recordDecl(isStruct(), isDefinition(),
24 - unless(isExpansionInSystemHeader()))
25 - .bind("struct"),
26 - this);
27 -}
28 -
29 -CharUnits
30 -StructPackAlignCheck::computeRecommendedAlignment(CharUnits MinByteSize) {
31 - CharUnits NewAlign = CharUnits::fromQuantity(1);
32 - if (!MinByteSize.isPowerOfTwo()) {
33 - int MSB = (int)MinByteSize.getQuantity();
34 - for (; MSB > 0; MSB /= 2) {
35 - NewAlign = NewAlign.alignTo(
36 - CharUnits::fromQuantity(((int)NewAlign.getQuantity()) * 2));
37 - // Abort if the computed alignment meets the maximum configured alignment.
38 - if (NewAlign.getQuantity() >= MaxConfiguredAlignment)
39 - break;
40 - }
41 - } else {
42 - NewAlign = MinByteSize;
43 - }
44 - return NewAlign;
45 -}
46 -
47 -void StructPackAlignCheck::check(const MatchFinder::MatchResult &Result) {
48 - const auto *Struct = Result.Nodes.getNodeAs<RecordDecl>("struct");
49 -
50 - // Do not trigger on templated struct declarations because the packing and
51 - // alignment requirements are unknown.
52 - if (Struct->isTemplated())
53 - return;
54 -
55 - // Get sizing info for the struct.
56 - llvm::SmallVector<std::pair<unsigned int, unsigned int>, 10> FieldSizes;
57 - unsigned int TotalBitSize = 0;
58 - for (const FieldDecl *StructField : Struct->fields()) {
59 - // For each StructField, record how big it is (in bits).
60 - // Would be good to use a pair of <offset, size> to advise a better
61 - // packing order.
62 - unsigned int StructFieldWidth =
63 - (unsigned int)Result.Context
64 - ->getTypeInfo(StructField->getType().getTypePtr())
65 - .Width;
66 - FieldSizes.emplace_back(StructFieldWidth, StructField->getFieldIndex());
67 - // FIXME: Recommend a reorganization of the struct (sort by StructField
68 - // size, largest to smallest).
69 - TotalBitSize += StructFieldWidth;
70 - }
71 -
72 - uint64_t CharSize = Result.Context->getCharWidth();
73 - CharUnits CurrSize = Result.Context->getASTRecordLayout(Struct).getSize();
74 - CharUnits MinByteSize =
75 - CharUnits::fromQuantity(ceil((float)TotalBitSize / CharSize));
76 - CharUnits MaxAlign = CharUnits::fromQuantity(
77 - ceil((float)Struct->getMaxAlignment() / CharSize));
78 - CharUnits CurrAlign =
79 - Result.Context->getASTRecordLayout(Struct).getAlignment();
80 - CharUnits NewAlign = computeRecommendedAlignment(MinByteSize);
81 -
82 - bool IsPacked = Struct->hasAttr<PackedAttr>();
83 - bool NeedsPacking = (MinByteSize < CurrSize) && (MaxAlign != NewAlign) &&
84 - (CurrSize != NewAlign);
85 - bool NeedsAlignment = CurrAlign.getQuantity() != NewAlign.getQuantity();
86 -
87 - if (!NeedsAlignment && !NeedsPacking)
88 - return;
89 -
90 - // If it's using much more space than it needs, suggest packing.
91 - // (Do not suggest packing if it is currently explicitly aligned to what the
92 - // minimum byte size would suggest as the new alignment.)
93 - if (NeedsPacking && !IsPacked) {
94 - diag(Struct->getLocation(),
95 - "accessing fields in struct %0 is inefficient due to padding; only "
96 - "needs %1 bytes but is using %2 bytes")
97 - << Struct << (int)MinByteSize.getQuantity()
98 - << (int)CurrSize.getQuantity()
99 - << FixItHint::CreateInsertion(Struct->getEndLoc().getLocWithOffset(1),
100 - " __attribute__((packed))");
101 - diag(Struct->getLocation(),
102 - "use \"__attribute__((packed))\" to reduce the amount of padding "
103 - "applied to struct %0",
104 - DiagnosticIDs::Note)
105 - << Struct;
106 - }
107 -
108 - FixItHint FixIt;
109 - AlignedAttr *Attribute = Struct->getAttr<AlignedAttr>();
110 - std::string NewAlignQuantity = std::to_string((int)NewAlign.getQuantity());
111 - if (Attribute) {
112 - std::ostringstream FixItString;
113 - FixItString << "aligned(" << NewAlignQuantity << ")";
114 - FixIt =
115 - FixItHint::CreateReplacement(Attribute->getRange(), FixItString.str());
116 - } else {
117 - std::ostringstream FixItString;
118 - FixItString << " __attribute__((aligned(" << NewAlignQuantity << ")))";
119 - FixIt = FixItHint::CreateInsertion(Struct->getEndLoc().getLocWithOffset(1),
120 - FixItString.str());
121 - }
122 -
123 - // And suggest the minimum power-of-two alignment for the struct as a whole
124 - // (with and without packing).
125 - if (NeedsAlignment) {
126 - diag(Struct->getLocation(),
127 - "accessing fields in struct %0 is inefficient due to poor alignment; "
128 - "currently aligned to %1 bytes, but recommended alignment is %2 bytes")
129 - << Struct << (int)CurrAlign.getQuantity() << NewAlignQuantity << FixIt;
130 -
131 - diag(Struct->getLocation(),
132 - "use \"__attribute__((aligned(%0)))\" to align struct %1 to %0 bytes",
133 - DiagnosticIDs::Note)
134 - << NewAlignQuantity << Struct;
135 - }
136 -}
137 -
138 -void StructPackAlignCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
139 - Options.store(Opts, "MaxConfiguredAlignment", MaxConfiguredAlignment);
140 -}
141 -
142 -} // namespace altera
143 -} // namespace tidy
144 -} // namespace clang
1 -//===--- StructPackAlignCheck.h - clang-tidy --------------------*- C++ -*-===//
2 -//
3 -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 -// See https://llvm.org/LICENSE.txt for license information.
5 -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 -//
7 -//===----------------------------------------------------------------------===//
8 -
9 -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_STRUCTPACKALIGNCHECK_H
10 -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_STRUCTPACKALIGNCHECK_H
11 -
12 -#include "../ClangTidyCheck.h"
13 -
14 -namespace clang {
15 -namespace tidy {
16 -namespace altera {
17 -
18 -/// Finds structs that are inefficiently packed or aligned, and recommends
19 -/// packing and/or aligning of said structs as needed.
20 -///
21 -/// For the user-facing documentation see:
22 -/// http://clang.llvm.org/extra/clang-tidy/checks/altera-struct-pack-align.html
23 -class StructPackAlignCheck : public ClangTidyCheck {
24 -public:
25 - StructPackAlignCheck(StringRef Name, ClangTidyContext *Context)
26 - : ClangTidyCheck(Name, Context),
27 - MaxConfiguredAlignment(Options.get("MaxConfiguredAlignment", 128)) {}
28 - void registerMatchers(ast_matchers::MatchFinder *Finder) override;
29 - void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
30 - void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
31 -
32 -private:
33 - const unsigned MaxConfiguredAlignment;
34 - CharUnits computeRecommendedAlignment(CharUnits MinByteSize);
35 -};
36 -
37 -} // namespace altera
38 -} // namespace tidy
39 -} // namespace clang
40 -
41 -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_STRUCTPACKALIGNCHECK_H
...@@ -18,17 +18,32 @@ namespace clang { ...@@ -18,17 +18,32 @@ namespace clang {
18 namespace tidy { 18 namespace tidy {
19 namespace android { 19 namespace android {
20 20
21 -ComparisonInTempFailureRetryCheck::ComparisonInTempFailureRetryCheck( 21 +namespace {
22 - StringRef Name, ClangTidyContext *Context) 22 +AST_MATCHER(BinaryOperator, isRHSATempFailureRetryArg) {
23 - : ClangTidyCheck(Name, Context), 23 + if (!Node.getBeginLoc().isMacroID())
24 - RawRetryList(Options.get("RetryMacros", "TEMP_FAILURE_RETRY")) { 24 + return false;
25 - StringRef(RawRetryList).split(RetryMacros, ",", -1, false); 25 +
26 -} 26 + const SourceManager &SM = Finder->getASTContext().getSourceManager();
27 + if (!SM.isMacroArgExpansion(Node.getRHS()->IgnoreParenCasts()->getBeginLoc()))
28 + return false;
29 +
30 + const LangOptions &Opts = Finder->getASTContext().getLangOpts();
31 + SourceLocation LocStart = Node.getBeginLoc();
32 + while (LocStart.isMacroID()) {
33 + SourceLocation Invocation = SM.getImmediateMacroCallerLoc(LocStart);
34 + Token Tok;
35 + if (!Lexer::getRawToken(SM.getSpellingLoc(Invocation), Tok, SM, Opts,
36 + /*IgnoreWhiteSpace=*/true)) {
37 + if (Tok.getKind() == tok::raw_identifier &&
38 + Tok.getRawIdentifier() == "TEMP_FAILURE_RETRY")
39 + return true;
40 + }
27 41
28 -void ComparisonInTempFailureRetryCheck::storeOptions( 42 + LocStart = Invocation;
29 - ClangTidyOptions::OptionMap &Opts) { 43 + }
30 - Options.store(Opts, "RetryMacros", RawRetryList); 44 + return false;
31 } 45 }
46 +} // namespace
32 47
33 void ComparisonInTempFailureRetryCheck::registerMatchers(MatchFinder *Finder) { 48 void ComparisonInTempFailureRetryCheck::registerMatchers(MatchFinder *Finder) {
34 // Both glibc's and Bionic's TEMP_FAILURE_RETRY macros structurally look like: 49 // Both glibc's and Bionic's TEMP_FAILURE_RETRY macros structurally look like:
...@@ -48,43 +63,15 @@ void ComparisonInTempFailureRetryCheck::registerMatchers(MatchFinder *Finder) { ...@@ -48,43 +63,15 @@ void ComparisonInTempFailureRetryCheck::registerMatchers(MatchFinder *Finder) {
48 Finder->addMatcher( 63 Finder->addMatcher(
49 binaryOperator(hasOperatorName("="), 64 binaryOperator(hasOperatorName("="),
50 hasRHS(ignoringParenCasts( 65 hasRHS(ignoringParenCasts(
51 - binaryOperator(isComparisonOperator()).bind("inner")))) 66 + binaryOperator(isComparisonOperator()).bind("binop"))),
52 - .bind("outer"), 67 + isRHSATempFailureRetryArg()),
53 this); 68 this);
54 } 69 }
55 70
56 void ComparisonInTempFailureRetryCheck::check( 71 void ComparisonInTempFailureRetryCheck::check(
57 const MatchFinder::MatchResult &Result) { 72 const MatchFinder::MatchResult &Result) {
58 - StringRef RetryMacroName; 73 + const auto &BinOp = *Result.Nodes.getNodeAs<BinaryOperator>("binop");
59 - const auto &Node = *Result.Nodes.getNodeAs<BinaryOperator>("outer"); 74 + diag(BinOp.getOperatorLoc(), "top-level comparison in TEMP_FAILURE_RETRY");
60 - if (!Node.getBeginLoc().isMacroID())
61 - return;
62 -
63 - const SourceManager &SM = *Result.SourceManager;
64 - if (!SM.isMacroArgExpansion(Node.getRHS()->IgnoreParenCasts()->getBeginLoc()))
65 - return;
66 -
67 - const LangOptions &Opts = Result.Context->getLangOpts();
68 - SourceLocation LocStart = Node.getBeginLoc();
69 - while (LocStart.isMacroID()) {
70 - SourceLocation Invocation = SM.getImmediateMacroCallerLoc(LocStart);
71 - Token Tok;
72 - if (!Lexer::getRawToken(SM.getSpellingLoc(Invocation), Tok, SM, Opts,
73 - /*IgnoreWhiteSpace=*/true)) {
74 - if (Tok.getKind() == tok::raw_identifier &&
75 - llvm::is_contained(RetryMacros, Tok.getRawIdentifier())) {
76 - RetryMacroName = Tok.getRawIdentifier();
77 - break;
78 - }
79 - }
80 -
81 - LocStart = Invocation;
82 - }
83 - if (RetryMacroName.empty())
84 - return;
85 -
86 - const auto &Inner = *Result.Nodes.getNodeAs<BinaryOperator>("inner");
87 - diag(Inner.getOperatorLoc(), "top-level comparison in %0") << RetryMacroName;
88 75
89 // FIXME: FixIts would be nice, but potentially nontrivial when nested macros 76 // FIXME: FixIts would be nice, but potentially nontrivial when nested macros
90 // happen, e.g. `TEMP_FAILURE_RETRY(IS_ZERO(foo()))` 77 // happen, e.g. `TEMP_FAILURE_RETRY(IS_ZERO(foo()))`
......
...@@ -10,9 +10,6 @@ ...@@ -10,9 +10,6 @@
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_COMPARISONINTEMPFAILURERETRYCHECK_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_COMPARISONINTEMPFAILURERETRYCHECK_H
11 11
12 #include "../ClangTidyCheck.h" 12 #include "../ClangTidyCheck.h"
13 -#include "llvm/ADT/SmallVector.h"
14 -#include "llvm/ADT/StringRef.h"
15 -#include <string>
16 13
17 namespace clang { 14 namespace clang {
18 namespace tidy { 15 namespace tidy {
...@@ -25,14 +22,10 @@ namespace android { ...@@ -25,14 +22,10 @@ namespace android {
25 /// TEMP_FAILURE_RETRY is a macro provided by both glibc and Bionic. 22 /// TEMP_FAILURE_RETRY is a macro provided by both glibc and Bionic.
26 class ComparisonInTempFailureRetryCheck : public ClangTidyCheck { 23 class ComparisonInTempFailureRetryCheck : public ClangTidyCheck {
27 public: 24 public:
28 - ComparisonInTempFailureRetryCheck(StringRef Name, ClangTidyContext *Context); 25 + ComparisonInTempFailureRetryCheck(StringRef Name, ClangTidyContext *Context)
29 - void storeOptions(ClangTidyOptions::OptionMap &Opts) override; 26 + : ClangTidyCheck(Name, Context) {}
30 void registerMatchers(ast_matchers::MatchFinder *Finder) override; 27 void registerMatchers(ast_matchers::MatchFinder *Finder) override;
31 void check(const ast_matchers::MatchFinder::MatchResult &Result) override; 28 void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
32 -
33 -private:
34 - const std::string RawRetryList;
35 - SmallVector<StringRef, 5> RetryMacros;
36 }; 29 };
37 30
38 } // namespace android 31 } // namespace android
......
...@@ -30,8 +30,7 @@ static Preprocessor *PP; ...@@ -30,8 +30,7 @@ static Preprocessor *PP;
30 30
31 void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult &Result) { 31 void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult &Result) {
32 const auto IsSigterm = [](const auto &KeyValue) -> bool { 32 const auto IsSigterm = [](const auto &KeyValue) -> bool {
33 - return KeyValue.first->getName() == "SIGTERM" && 33 + return KeyValue.first->getName() == "SIGTERM";
34 - KeyValue.first->hasMacroDefinition();
35 }; 34 };
36 const auto TryExpandAsInteger = 35 const auto TryExpandAsInteger =
37 [](Preprocessor::macro_iterator It) -> Optional<unsigned> { 36 [](Preprocessor::macro_iterator It) -> Optional<unsigned> {
...@@ -39,8 +38,6 @@ void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -39,8 +38,6 @@ void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult &Result) {
39 return llvm::None; 38 return llvm::None;
40 const MacroInfo *MI = PP->getMacroInfo(It->first); 39 const MacroInfo *MI = PP->getMacroInfo(It->first);
41 const Token &T = MI->tokens().back(); 40 const Token &T = MI->tokens().back();
42 - if (!T.isLiteral() || !T.getLiteralData())
43 - return llvm::None;
44 StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength()); 41 StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
45 42
46 llvm::APInt IntValue; 43 llvm::APInt IntValue;
......
...@@ -20,68 +20,53 @@ void BoolPointerImplicitConversionCheck::registerMatchers(MatchFinder *Finder) { ...@@ -20,68 +20,53 @@ void BoolPointerImplicitConversionCheck::registerMatchers(MatchFinder *Finder) {
20 Finder->addMatcher( 20 Finder->addMatcher(
21 traverse( 21 traverse(
22 ast_type_traits::TK_AsIs, 22 ast_type_traits::TK_AsIs,
23 - ifStmt( 23 + ifStmt(hasCondition(findAll(implicitCastExpr(
24 - hasCondition(findAll(implicitCastExpr( 24 + unless(hasParent(unaryOperator(hasOperatorName("!")))),
25 - unless(hasParent(unaryOperator(hasOperatorName("!")))), 25 + hasSourceExpression(expr(
26 - hasSourceExpression(expr( 26 + hasType(pointerType(pointee(booleanType()))),
27 - hasType(pointerType(pointee(booleanType()))), 27 + ignoringParenImpCasts(declRefExpr().bind("expr")))),
28 - ignoringParenImpCasts(anyOf(declRefExpr().bind("expr"), 28 + hasCastKind(CK_PointerToBoolean)))),
29 - memberExpr().bind("expr"))))), 29 + unless(isInTemplateInstantiation()))
30 - hasCastKind(CK_PointerToBoolean)))),
31 - unless(isInTemplateInstantiation()))
32 .bind("if")), 30 .bind("if")),
33 this); 31 this);
34 } 32 }
35 33
36 -static void checkImpl(const MatchFinder::MatchResult &Result, const Expr *Ref, 34 +void BoolPointerImplicitConversionCheck::check(
37 - const IfStmt *If, 35 + const MatchFinder::MatchResult &Result) {
38 - const ast_matchers::internal::Matcher<Expr> &RefMatcher, 36 + auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
39 - ClangTidyCheck &Check) { 37 + auto *Var = Result.Nodes.getNodeAs<DeclRefExpr>("expr");
38 +
40 // Ignore macros. 39 // Ignore macros.
41 - if (Ref->getBeginLoc().isMacroID()) 40 + if (Var->getBeginLoc().isMacroID())
42 return; 41 return;
43 42
44 - // Only allow variable accesses and member exprs for now, no function calls. 43 + // Only allow variable accesses for now, no function calls or member exprs.
45 // Check that we don't dereference the variable anywhere within the if. This 44 // Check that we don't dereference the variable anywhere within the if. This
46 // avoids false positives for checks of the pointer for nullptr before it is 45 // avoids false positives for checks of the pointer for nullptr before it is
47 // dereferenced. If there is a dereferencing operator on this variable don't 46 // dereferenced. If there is a dereferencing operator on this variable don't
48 // emit a diagnostic. Also ignore array subscripts. 47 // emit a diagnostic. Also ignore array subscripts.
49 - if (!match(findAll(unaryOperator(hasOperatorName("*"), 48 + const Decl *D = Var->getDecl();
50 - hasUnaryOperand(RefMatcher))), 49 + auto DeclRef = ignoringParenImpCasts(declRefExpr(to(equalsNode(D))));
50 + if (!match(findAll(
51 + unaryOperator(hasOperatorName("*"), hasUnaryOperand(DeclRef))),
51 *If, *Result.Context) 52 *If, *Result.Context)
52 .empty() || 53 .empty() ||
53 - !match(findAll(arraySubscriptExpr(hasBase(RefMatcher))), *If, 54 + !match(findAll(arraySubscriptExpr(hasBase(DeclRef))), *If,
54 *Result.Context) 55 *Result.Context)
55 .empty() || 56 .empty() ||
56 // FIXME: We should still warn if the paremater is implicitly converted to 57 // FIXME: We should still warn if the paremater is implicitly converted to
57 // bool. 58 // bool.
58 - !match( 59 + !match(findAll(callExpr(hasAnyArgument(ignoringParenImpCasts(DeclRef)))),
59 - findAll(callExpr(hasAnyArgument(ignoringParenImpCasts(RefMatcher)))), 60 + *If, *Result.Context)
60 - *If, *Result.Context)
61 .empty() || 61 .empty() ||
62 - !match( 62 + !match(findAll(cxxDeleteExpr(has(ignoringParenImpCasts(expr(DeclRef))))),
63 - findAll(cxxDeleteExpr(has(ignoringParenImpCasts(expr(RefMatcher))))), 63 + *If, *Result.Context)
64 - *If, *Result.Context)
65 .empty()) 64 .empty())
66 return; 65 return;
67 66
68 - Check.diag(Ref->getBeginLoc(), 67 + diag(Var->getBeginLoc(), "dubious check of 'bool *' against 'nullptr', did "
69 - "dubious check of 'bool *' against 'nullptr', did " 68 + "you mean to dereference it?")
70 - "you mean to dereference it?") 69 + << FixItHint::CreateInsertion(Var->getBeginLoc(), "*");
71 - << FixItHint::CreateInsertion(Ref->getBeginLoc(), "*");
72 -}
73 -
74 -void BoolPointerImplicitConversionCheck::check(
75 - const MatchFinder::MatchResult &Result) {
76 - const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
77 - if (const auto *E = Result.Nodes.getNodeAs<Expr>("expr")) {
78 - const Decl *D = isa<DeclRefExpr>(E) ? cast<DeclRefExpr>(E)->getDecl()
79 - : cast<MemberExpr>(E)->getMemberDecl();
80 - const auto M =
81 - ignoringParenImpCasts(anyOf(declRefExpr(to(equalsNode(D))),
82 - memberExpr(hasDeclaration(equalsNode(D)))));
83 - checkImpl(Result, E, If, M, *this);
84 - }
85 } 70 }
86 71
87 } // namespace bugprone 72 } // namespace bugprone
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
38 #include "NotNullTerminatedResultCheck.h" 38 #include "NotNullTerminatedResultCheck.h"
39 #include "ParentVirtualCallCheck.h" 39 #include "ParentVirtualCallCheck.h"
40 #include "PosixReturnCheck.h" 40 #include "PosixReturnCheck.h"
41 -#include "RedundantBranchConditionCheck.h"
42 #include "ReservedIdentifierCheck.h" 41 #include "ReservedIdentifierCheck.h"
43 #include "SignedCharMisuseCheck.h" 42 #include "SignedCharMisuseCheck.h"
44 #include "SizeofContainerCheck.h" 43 #include "SizeofContainerCheck.h"
...@@ -120,8 +119,6 @@ public: ...@@ -120,8 +119,6 @@ public:
120 "bugprone-move-forwarding-reference"); 119 "bugprone-move-forwarding-reference");
121 CheckFactories.registerCheck<MultipleStatementMacroCheck>( 120 CheckFactories.registerCheck<MultipleStatementMacroCheck>(
122 "bugprone-multiple-statement-macro"); 121 "bugprone-multiple-statement-macro");
123 - CheckFactories.registerCheck<RedundantBranchConditionCheck>(
124 - "bugprone-redundant-branch-condition");
125 CheckFactories.registerCheck<cppcoreguidelines::NarrowingConversionsCheck>( 122 CheckFactories.registerCheck<cppcoreguidelines::NarrowingConversionsCheck>(
126 "bugprone-narrowing-conversions"); 123 "bugprone-narrowing-conversions");
127 CheckFactories.registerCheck<NoEscapeCheck>("bugprone-no-escape"); 124 CheckFactories.registerCheck<NoEscapeCheck>("bugprone-no-escape");
......
...@@ -33,7 +33,6 @@ add_clang_library(clangTidyBugproneModule ...@@ -33,7 +33,6 @@ add_clang_library(clangTidyBugproneModule
33 NotNullTerminatedResultCheck.cpp 33 NotNullTerminatedResultCheck.cpp
34 ParentVirtualCallCheck.cpp 34 ParentVirtualCallCheck.cpp
35 PosixReturnCheck.cpp 35 PosixReturnCheck.cpp
36 - RedundantBranchConditionCheck.cpp
37 ReservedIdentifierCheck.cpp 36 ReservedIdentifierCheck.cpp
38 SignedCharMisuseCheck.cpp 37 SignedCharMisuseCheck.cpp
39 SizeofContainerCheck.cpp 38 SizeofContainerCheck.cpp
......
...@@ -77,9 +77,9 @@ void MisplacedPointerArithmeticInAllocCheck::check( ...@@ -77,9 +77,9 @@ void MisplacedPointerArithmeticInAllocCheck::check(
77 CallName = "operator new[]"; 77 CallName = "operator new[]";
78 } else { 78 } else {
79 const auto *CtrE = New->getConstructExpr(); 79 const auto *CtrE = New->getConstructExpr();
80 - if (!CtrE || !CtrE->getArg(CtrE->getNumArgs() - 1) 80 + if (!CtrE->getArg(CtrE->getNumArgs() - 1)
81 - ->getType() 81 + ->getType()
82 - ->isIntegralOrEnumerationType()) 82 + ->isIntegralOrEnumerationType())
83 return; 83 return;
84 CallName = "operator new"; 84 CallName = "operator new";
85 } 85 }
......
...@@ -802,16 +802,11 @@ void NotNullTerminatedResultCheck::check( ...@@ -802,16 +802,11 @@ void NotNullTerminatedResultCheck::check(
802 while (It != PP->macro_end() && !AreSafeFunctionsWanted.hasValue()) { 802 while (It != PP->macro_end() && !AreSafeFunctionsWanted.hasValue()) {
803 if (It->first->getName() == "__STDC_WANT_LIB_EXT1__") { 803 if (It->first->getName() == "__STDC_WANT_LIB_EXT1__") {
804 const auto *MI = PP->getMacroInfo(It->first); 804 const auto *MI = PP->getMacroInfo(It->first);
805 - // PP->getMacroInfo() returns nullptr if macro has no definition. 805 + const auto &T = MI->tokens().back();
806 - if (MI) { 806 + StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
807 - const auto &T = MI->tokens().back(); 807 + llvm::APInt IntValue;
808 - if (T.isLiteral() && T.getLiteralData()) { 808 + ValueStr.getAsInteger(10, IntValue);
809 - StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength()); 809 + AreSafeFunctionsWanted = IntValue.getZExtValue();
810 - llvm::APInt IntValue;
811 - ValueStr.getAsInteger(10, IntValue);
812 - AreSafeFunctionsWanted = IntValue.getZExtValue();
813 - }
814 - }
815 } 810 }
816 811
817 ++It; 812 ++It;
......
1 -//===--- RedundantBranchConditionCheck.cpp - clang-tidy -------------------------===//
2 -//
3 -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 -// See https://llvm.org/LICENSE.txt for license information.
5 -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 -//
7 -//===----------------------------------------------------------------------===//
8 -
9 -#include "RedundantBranchConditionCheck.h"
10 -#include "../utils/Aliasing.h"
11 -#include "clang/AST/ASTContext.h"
12 -#include "clang/ASTMatchers/ASTMatchFinder.h"
13 -#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
14 -#include "clang/Lex/Lexer.h"
15 -
16 -using namespace clang::ast_matchers;
17 -using clang::tidy::utils::hasPtrOrReferenceInFunc;
18 -
19 -namespace clang {
20 -namespace tidy {
21 -namespace bugprone {
22 -
23 -static const char CondVarStr[] = "cond_var";
24 -static const char OuterIfStr[] = "outer_if";
25 -static const char InnerIfStr[] = "inner_if";
26 -static const char FuncStr[] = "func";
27 -
28 -/// Returns whether `Var` is changed in `S` before `NextS`.
29 -static bool isChangedBefore(const Stmt *S, const Stmt *NextS,
30 - const VarDecl *Var, ASTContext *Context) {
31 - ExprMutationAnalyzer MutAn(*S, *Context);
32 - const auto &SM = Context->getSourceManager();
33 - const Stmt *MutS = MutAn.findMutation(Var);
34 - return MutS &&
35 - SM.isBeforeInTranslationUnit(MutS->getEndLoc(), NextS->getBeginLoc());
36 -}
37 -
38 -void RedundantBranchConditionCheck::registerMatchers(MatchFinder *Finder) {
39 - const auto ImmutableVar =
40 - varDecl(anyOf(parmVarDecl(), hasLocalStorage()), hasType(isInteger()),
41 - unless(hasType(isVolatileQualified())))
42 - .bind(CondVarStr);
43 - Finder->addMatcher(
44 - ifStmt(
45 - hasCondition(ignoringParenImpCasts(anyOf(
46 - declRefExpr(hasDeclaration(ImmutableVar)),
47 - binaryOperator(hasOperatorName("&&"),
48 - hasEitherOperand(ignoringParenImpCasts(declRefExpr(
49 - hasDeclaration(ImmutableVar)))))))),
50 - hasThen(hasDescendant(
51 - ifStmt(hasCondition(ignoringParenImpCasts(
52 - anyOf(declRefExpr(hasDeclaration(
53 - varDecl(equalsBoundNode(CondVarStr)))),
54 - binaryOperator(
55 - hasAnyOperatorName("&&", "||"),
56 - hasEitherOperand(ignoringParenImpCasts(
57 - declRefExpr(hasDeclaration(varDecl(
58 - equalsBoundNode(CondVarStr)))))))))))
59 - .bind(InnerIfStr))),
60 - forFunction(functionDecl().bind(FuncStr)))
61 - .bind(OuterIfStr),
62 - this);
63 - // FIXME: Handle longer conjunctive and disjunctive clauses.
64 -}
65 -
66 -void RedundantBranchConditionCheck::check(const MatchFinder::MatchResult &Result) {
67 - const auto *OuterIf = Result.Nodes.getNodeAs<IfStmt>(OuterIfStr);
68 - const auto *InnerIf = Result.Nodes.getNodeAs<IfStmt>(InnerIfStr);
69 - const auto *CondVar = Result.Nodes.getNodeAs<VarDecl>(CondVarStr);
70 - const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>(FuncStr);
71 -
72 - // If the variable has an alias then it can be changed by that alias as well.
73 - // FIXME: could potentially support tracking pointers and references in the
74 - // future to improve catching true positives through aliases.
75 - if (hasPtrOrReferenceInFunc(Func, CondVar))
76 - return;
77 -
78 - if (isChangedBefore(OuterIf->getThen(), InnerIf, CondVar, Result.Context))
79 - return;
80 -
81 - auto Diag = diag(InnerIf->getBeginLoc(), "redundant condition %0") << CondVar;
82 -
83 - // For standalone condition variables and for "or" binary operations we simply
84 - // remove the inner `if`.
85 - const auto *BinOpCond = dyn_cast<BinaryOperator>(InnerIf->getCond());
86 - if (isa<DeclRefExpr>(InnerIf->getCond()->IgnoreParenImpCasts()) ||
87 - (BinOpCond && BinOpCond->getOpcode() == BO_LOr)) {
88 - SourceLocation IfBegin = InnerIf->getBeginLoc();
89 - const Stmt *Body = InnerIf->getThen();
90 - const Expr *OtherSide = nullptr;
91 - if (BinOpCond) {
92 - const auto *LeftDRE =
93 - dyn_cast<DeclRefExpr>(BinOpCond->getLHS()->IgnoreParenImpCasts());
94 - if (LeftDRE && LeftDRE->getDecl() == CondVar)
95 - OtherSide = BinOpCond->getRHS();
96 - else
97 - OtherSide = BinOpCond->getLHS();
98 - }
99 -
100 - SourceLocation IfEnd = Body->getBeginLoc().getLocWithOffset(-1);
101 -
102 - // For compound statements also remove the left brace.
103 - if (isa<CompoundStmt>(Body))
104 - IfEnd = Body->getBeginLoc();
105 -
106 - // If the other side has side effects then keep it.
107 - if (OtherSide && OtherSide->HasSideEffects(*Result.Context)) {
108 - SourceLocation BeforeOtherSide =
109 - OtherSide->getBeginLoc().getLocWithOffset(-1);
110 - SourceLocation AfterOtherSide =
111 - Lexer::findNextToken(OtherSide->getEndLoc(), *Result.SourceManager,
112 - getLangOpts())
113 - ->getLocation();
114 - Diag << FixItHint::CreateRemoval(
115 - CharSourceRange::getTokenRange(IfBegin, BeforeOtherSide))
116 - << FixItHint::CreateInsertion(AfterOtherSide, ";")
117 - << FixItHint::CreateRemoval(
118 - CharSourceRange::getTokenRange(AfterOtherSide, IfEnd));
119 - } else {
120 - Diag << FixItHint::CreateRemoval(
121 - CharSourceRange::getTokenRange(IfBegin, IfEnd));
122 - }
123 -
124 - // For comound statements also remove the right brace at the end.
125 - if (isa<CompoundStmt>(Body))
126 - Diag << FixItHint::CreateRemoval(
127 - CharSourceRange::getTokenRange(Body->getEndLoc(), Body->getEndLoc()));
128 -
129 - // For "and" binary operations we remove the "and" operation with the
130 - // condition variable from the inner if.
131 - } else {
132 - const auto *CondOp = cast<BinaryOperator>(InnerIf->getCond());
133 - const auto *LeftDRE =
134 - dyn_cast<DeclRefExpr>(CondOp->getLHS()->IgnoreParenImpCasts());
135 - if (LeftDRE && LeftDRE->getDecl() == CondVar) {
136 - SourceLocation BeforeRHS =
137 - CondOp->getRHS()->getBeginLoc().getLocWithOffset(-1);
138 - Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
139 - CondOp->getLHS()->getBeginLoc(), BeforeRHS));
140 - } else {
141 - SourceLocation AfterLHS =
142 - Lexer::findNextToken(CondOp->getLHS()->getEndLoc(),
143 - *Result.SourceManager, getLangOpts())
144 - ->getLocation();
145 - Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
146 - AfterLHS, CondOp->getRHS()->getEndLoc()));
147 - }
148 - }
149 -}
150 -
151 -} // namespace bugprone
152 -} // namespace tidy
153 -} // namespace clang
1 -//===--- RedundantBranchConditionCheck.h - clang-tidy -----------*- C++ -*-===//
2 -//
3 -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 -// See https://llvm.org/LICENSE.txt for license information.
5 -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 -//
7 -//===----------------------------------------------------------------------===//
8 -
9 -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_REDUNDANTBRANCHCONDITIONCHECK_H
10 -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_REDUNDANTBRANCHCONDITIONCHECK_H
11 -
12 -#include "../ClangTidyCheck.h"
13 -
14 -namespace clang {
15 -namespace tidy {
16 -namespace bugprone {
17 -
18 -/// Finds condition variables in nested `if` statements that were also checked
19 -/// in the outer `if` statement and were not changed.
20 -///
21 -/// For the user-facing documentation see:
22 -/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-redundant-branch-condition.html
23 -class RedundantBranchConditionCheck : public ClangTidyCheck {
24 -public:
25 - RedundantBranchConditionCheck(StringRef Name, ClangTidyContext *Context)
26 - : ClangTidyCheck(Name, Context) {}
27 - void registerMatchers(ast_matchers::MatchFinder *Finder) override;
28 - void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
29 -};
30 -
31 -} // namespace bugprone
32 -} // namespace tidy
33 -} // namespace clang
34 -
35 -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_REDUNDANTBRANCHCONDITIONCHECK_H
1 -/* This generated file is for internal use. Do not include it from headers. */
2 -
3 -#ifdef CLANG_TIDY_CONFIG_H
4 -#error clang-tidy-config.h can only be included once
5 -#else
6 -#define CLANG_TIDY_CONFIG_H
7 -
8 -#cmakedefine01 CLANG_TIDY_ENABLE_STATIC_ANALYZER
9 -
10 -#endif
...@@ -13,7 +13,6 @@ add_clang_library(clangTidyCppCoreGuidelinesModule ...@@ -13,7 +13,6 @@ add_clang_library(clangTidyCppCoreGuidelinesModule
13 NarrowingConversionsCheck.cpp 13 NarrowingConversionsCheck.cpp
14 NoMallocCheck.cpp 14 NoMallocCheck.cpp
15 OwningMemoryCheck.cpp 15 OwningMemoryCheck.cpp
16 - PreferMemberInitializerCheck.cpp
17 ProBoundsArrayToPointerDecayCheck.cpp 16 ProBoundsArrayToPointerDecayCheck.cpp
18 ProBoundsConstantArrayIndexCheck.cpp 17 ProBoundsConstantArrayIndexCheck.cpp
19 ProBoundsPointerArithmeticCheck.cpp 18 ProBoundsPointerArithmeticCheck.cpp
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
22 #include "NarrowingConversionsCheck.h" 22 #include "NarrowingConversionsCheck.h"
23 #include "NoMallocCheck.h" 23 #include "NoMallocCheck.h"
24 #include "OwningMemoryCheck.h" 24 #include "OwningMemoryCheck.h"
25 -#include "PreferMemberInitializerCheck.h"
26 #include "ProBoundsArrayToPointerDecayCheck.h" 25 #include "ProBoundsArrayToPointerDecayCheck.h"
27 #include "ProBoundsConstantArrayIndexCheck.h" 26 #include "ProBoundsConstantArrayIndexCheck.h"
28 #include "ProBoundsPointerArithmeticCheck.h" 27 #include "ProBoundsPointerArithmeticCheck.h"
...@@ -67,8 +66,6 @@ public: ...@@ -67,8 +66,6 @@ public:
67 "cppcoreguidelines-non-private-member-variables-in-classes"); 66 "cppcoreguidelines-non-private-member-variables-in-classes");
68 CheckFactories.registerCheck<OwningMemoryCheck>( 67 CheckFactories.registerCheck<OwningMemoryCheck>(
69 "cppcoreguidelines-owning-memory"); 68 "cppcoreguidelines-owning-memory");
70 - CheckFactories.registerCheck<PreferMemberInitializerCheck>(
71 - "cppcoreguidelines-prefer-member-initializer");
72 CheckFactories.registerCheck<ProBoundsArrayToPointerDecayCheck>( 69 CheckFactories.registerCheck<ProBoundsArrayToPointerDecayCheck>(
73 "cppcoreguidelines-pro-bounds-array-to-pointer-decay"); 70 "cppcoreguidelines-pro-bounds-array-to-pointer-decay");
74 CheckFactories.registerCheck<ProBoundsConstantArrayIndexCheck>( 71 CheckFactories.registerCheck<ProBoundsConstantArrayIndexCheck>(
......
...@@ -26,12 +26,12 @@ AST_MATCHER(VarDecl, isLocalVarDecl) { return Node.isLocalVarDecl(); } ...@@ -26,12 +26,12 @@ AST_MATCHER(VarDecl, isLocalVarDecl) { return Node.isLocalVarDecl(); }
26 InitVariablesCheck::InitVariablesCheck(StringRef Name, 26 InitVariablesCheck::InitVariablesCheck(StringRef Name,
27 ClangTidyContext *Context) 27 ClangTidyContext *Context)
28 : ClangTidyCheck(Name, Context), 28 : ClangTidyCheck(Name, Context),
29 - IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", 29 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
30 - utils::IncludeSorter::IS_LLVM)), 30 + utils::IncludeSorter::IS_LLVM)),
31 - MathHeader(Options.get("MathHeader", "<math.h>")) {} 31 + MathHeader(Options.get("MathHeader", "math.h")) {}
32 32
33 void InitVariablesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { 33 void InitVariablesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
34 - Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); 34 + Options.store(Opts, "IncludeStyle", IncludeStyle);
35 Options.store(Opts, "MathHeader", MathHeader); 35 Options.store(Opts, "MathHeader", MathHeader);
36 } 36 }
37 37
...@@ -51,7 +51,9 @@ void InitVariablesCheck::registerMatchers(MatchFinder *Finder) { ...@@ -51,7 +51,9 @@ void InitVariablesCheck::registerMatchers(MatchFinder *Finder) {
51 void InitVariablesCheck::registerPPCallbacks(const SourceManager &SM, 51 void InitVariablesCheck::registerPPCallbacks(const SourceManager &SM,
52 Preprocessor *PP, 52 Preprocessor *PP,
53 Preprocessor *ModuleExpanderPP) { 53 Preprocessor *ModuleExpanderPP) {
54 - IncludeInserter.registerPreprocessor(PP); 54 + IncludeInserter =
55 + std::make_unique<utils::IncludeInserter>(SM, getLangOpts(), IncludeStyle);
56 + PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
55 } 57 }
56 58
57 void InitVariablesCheck::check(const MatchFinder::MatchResult &Result) { 59 void InitVariablesCheck::check(const MatchFinder::MatchResult &Result) {
...@@ -102,8 +104,8 @@ void InitVariablesCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -102,8 +104,8 @@ void InitVariablesCheck::check(const MatchFinder::MatchResult &Result) {
102 MatchedDecl->getName().size()), 104 MatchedDecl->getName().size()),
103 InitializationString); 105 InitializationString);
104 if (AddMathInclude) { 106 if (AddMathInclude) {
105 - Diagnostic << IncludeInserter.createIncludeInsertion( 107 + Diagnostic << IncludeInserter->CreateIncludeInsertion(
106 - Source.getFileID(MatchedDecl->getBeginLoc()), MathHeader); 108 + Source.getFileID(MatchedDecl->getBeginLoc()), MathHeader, false);
107 } 109 }
108 } 110 }
109 } 111 }
......
...@@ -31,7 +31,8 @@ public: ...@@ -31,7 +31,8 @@ public:
31 void check(const ast_matchers::MatchFinder::MatchResult &Result) override; 31 void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
32 32
33 private: 33 private:
34 - utils::IncludeInserter IncludeInserter; 34 + std::unique_ptr<clang::tidy::utils::IncludeInserter> IncludeInserter;
35 + const utils::IncludeSorter::IncludeStyle IncludeStyle;
35 const std::string MathHeader; 36 const std::string MathHeader;
36 }; 37 };
37 38
......
...@@ -79,8 +79,9 @@ static QualType getUnqualifiedType(const Expr &E) { ...@@ -79,8 +79,9 @@ static QualType getUnqualifiedType(const Expr &E) {
79 } 79 }
80 80
81 static APValue getConstantExprValue(const ASTContext &Ctx, const Expr &E) { 81 static APValue getConstantExprValue(const ASTContext &Ctx, const Expr &E) {
82 - if (auto IntegerConstant = E.getIntegerConstantExpr(Ctx)) 82 + llvm::APSInt IntegerConstant;
83 - return APValue(*IntegerConstant); 83 + if (E.isIntegerConstantExpr(IntegerConstant, Ctx))
84 + return APValue(IntegerConstant);
84 APValue Constant; 85 APValue Constant;
85 if (Ctx.getLangOpts().CPlusPlus && E.isCXX11ConstantExpr(Ctx, &Constant)) 86 if (Ctx.getLangOpts().CPlusPlus && E.isCXX11ConstantExpr(Ctx, &Constant))
86 return Constant; 87 return Constant;
......
1 -//===--- PreferMemberInitializerCheck.cpp - clang-tidy -------------------===//
2 -//
3 -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 -// See https://llvm.org/LICENSE.txt for license information.
5 -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 -//
7 -//===----------------------------------------------------------------------===//
8 -
9 -#include "PreferMemberInitializerCheck.h"
10 -#include "clang/AST/ASTContext.h"
11 -#include "clang/ASTMatchers/ASTMatchFinder.h"
12 -#include "clang/Lex/Lexer.h"
13 -
14 -using namespace clang::ast_matchers;
15 -
16 -namespace clang {
17 -namespace tidy {
18 -namespace cppcoreguidelines {
19 -
20 -static bool isControlStatement(const Stmt *S) {
21 - return isa<IfStmt, SwitchStmt, ForStmt, WhileStmt, DoStmt, ReturnStmt,
22 - GotoStmt, CXXTryStmt, CXXThrowExpr>(S);
23 -}
24 -
25 -static bool isNoReturnCallStatement(const Stmt *S) {
26 - const auto *Call = dyn_cast<CallExpr>(S);
27 - if (!Call)
28 - return false;
29 -
30 - const FunctionDecl *Func = Call->getDirectCallee();
31 - if (!Func)
32 - return false;
33 -
34 - return Func->isNoReturn();
35 -}
36 -
37 -static bool isLiteral(const Expr *E) {
38 - return isa<StringLiteral, CharacterLiteral, IntegerLiteral, FloatingLiteral,
39 - CXXBoolLiteralExpr, CXXNullPtrLiteralExpr>(E);
40 -}
41 -
42 -static bool isUnaryExprOfLiteral(const Expr *E) {
43 - if (const auto *UnOp = dyn_cast<UnaryOperator>(E))
44 - return isLiteral(UnOp->getSubExpr());
45 - return false;
46 -}
47 -
48 -static bool shouldBeDefaultMemberInitializer(const Expr *Value) {
49 - if (isLiteral(Value) || isUnaryExprOfLiteral(Value))
50 - return true;
51 -
52 - if (const auto *DRE = dyn_cast<DeclRefExpr>(Value))
53 - return isa<EnumConstantDecl>(DRE->getDecl());
54 -
55 - return false;
56 -}
57 -
58 -static const std::pair<const FieldDecl *, const Expr *>
59 -isAssignmentToMemberOf(const RecordDecl *Rec, const Stmt *S) {
60 - if (const auto *BO = dyn_cast<BinaryOperator>(S)) {
61 - if (BO->getOpcode() != BO_Assign)
62 - return std::make_pair(nullptr, nullptr);
63 -
64 - const auto *ME = dyn_cast<MemberExpr>(BO->getLHS()->IgnoreParenImpCasts());
65 - if (!ME)
66 - return std::make_pair(nullptr, nullptr);
67 -
68 - const auto *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
69 - if (!Field)
70 - return std::make_pair(nullptr, nullptr);
71 -
72 - if (isa<CXXThisExpr>(ME->getBase()))
73 - return std::make_pair(Field, BO->getRHS()->IgnoreParenImpCasts());
74 - } else if (const auto *COCE = dyn_cast<CXXOperatorCallExpr>(S)) {
75 - if (COCE->getOperator() != OO_Equal)
76 - return std::make_pair(nullptr, nullptr);
77 -
78 - const auto *ME =
79 - dyn_cast<MemberExpr>(COCE->getArg(0)->IgnoreParenImpCasts());
80 - if (!ME)
81 - return std::make_pair(nullptr, nullptr);
82 -
83 - const auto *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
84 - if (!Field)
85 - return std::make_pair(nullptr, nullptr);
86 -
87 - if (isa<CXXThisExpr>(ME->getBase()))
88 - return std::make_pair(Field, COCE->getArg(1)->IgnoreParenImpCasts());
89 - }
90 -
91 - return std::make_pair(nullptr, nullptr);
92 -}
93 -
94 -PreferMemberInitializerCheck::PreferMemberInitializerCheck(
95 - StringRef Name, ClangTidyContext *Context)
96 - : ClangTidyCheck(Name, Context),
97 - IsUseDefaultMemberInitEnabled(
98 - Context->isCheckEnabled("modernize-use-default-member-init")),
99 - UseAssignment(OptionsView("modernize-use-default-member-init",
100 - Context->getOptions().CheckOptions)
101 - .get("UseAssignment", false)) {}
102 -
103 -void PreferMemberInitializerCheck::storeOptions(
104 - ClangTidyOptions::OptionMap &Opts) {
105 - Options.store(Opts, "UseAssignment", UseAssignment);
106 -}
107 -
108 -void PreferMemberInitializerCheck::registerMatchers(MatchFinder *Finder) {
109 - Finder->addMatcher(
110 - cxxConstructorDecl(hasBody(compoundStmt()), unless(isInstantiated()))
111 - .bind("ctor"),
112 - this);
113 -}
114 -
115 -void PreferMemberInitializerCheck::check(
116 - const MatchFinder::MatchResult &Result) {
117 - const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor");
118 - const auto *Body = cast<CompoundStmt>(Ctor->getBody());
119 -
120 - const CXXRecordDecl *Class = Ctor->getParent();
121 - SourceLocation InsertPos;
122 - bool FirstToCtorInits = true;
123 -
124 - for (const Stmt *S : Body->body()) {
125 - if (S->getBeginLoc().isMacroID()) {
126 - StringRef MacroName =
127 - Lexer::getImmediateMacroName(S->getBeginLoc(), *Result.SourceManager,
128 - getLangOpts());
129 - if (MacroName.contains_lower("assert"))
130 - return;
131 - }
132 - if (isControlStatement(S))
133 - return;
134 -
135 - if (isNoReturnCallStatement(S))
136 - return;
137 -
138 - if (const auto *CondOp = dyn_cast<ConditionalOperator>(S)) {
139 - if (isNoReturnCallStatement(CondOp->getLHS()) ||
140 - isNoReturnCallStatement(CondOp->getRHS()))
141 - return;
142 - }
143 -
144 - const FieldDecl *Field;
145 - const Expr *InitValue;
146 - std::tie(Field, InitValue) = isAssignmentToMemberOf(Class, S);
147 - if (Field) {
148 - if (IsUseDefaultMemberInitEnabled && getLangOpts().CPlusPlus11 &&
149 - Ctor->isDefaultConstructor() &&
150 - (getLangOpts().CPlusPlus20 || !Field->isBitField()) &&
151 - (!isa<RecordDecl>(Class->getDeclContext()) ||
152 - !cast<RecordDecl>(Class->getDeclContext())->isUnion()) &&
153 - shouldBeDefaultMemberInitializer(InitValue)) {
154 - auto Diag =
155 - diag(S->getBeginLoc(), "%0 should be initialized in an in-class"
156 - " default member initializer")
157 - << Field;
158 -
159 - SourceLocation FieldEnd =
160 - Lexer::getLocForEndOfToken(Field->getSourceRange().getEnd(), 0,
161 - *Result.SourceManager, getLangOpts());
162 - Diag << FixItHint::CreateInsertion(FieldEnd,
163 - UseAssignment ? " = " : "{")
164 - << FixItHint::CreateInsertionFromRange(
165 - FieldEnd,
166 - CharSourceRange(InitValue->getSourceRange(), true))
167 - << FixItHint::CreateInsertion(FieldEnd, UseAssignment ? "" : "}");
168 -
169 - SourceLocation SemiColonEnd =
170 - Lexer::findNextToken(S->getEndLoc(), *Result.SourceManager,
171 - getLangOpts())
172 - ->getEndLoc();
173 - CharSourceRange StmtRange =
174 - CharSourceRange::getCharRange(S->getBeginLoc(), SemiColonEnd);
175 -
176 - Diag << FixItHint::CreateRemoval(StmtRange);
177 - } else {
178 - auto Diag =
179 - diag(S->getBeginLoc(), "%0 should be initialized in a member"
180 - " initializer of the constructor")
181 - << Field;
182 -
183 - bool AddComma = false;
184 - if (!Ctor->getNumCtorInitializers() && FirstToCtorInits) {
185 - SourceLocation BodyPos = Ctor->getBody()->getBeginLoc();
186 - SourceLocation NextPos = Ctor->getBeginLoc();
187 - do {
188 - InsertPos = NextPos;
189 - NextPos = Lexer::findNextToken(NextPos, *Result.SourceManager,
190 - getLangOpts())
191 - ->getLocation();
192 - } while (NextPos != BodyPos);
193 - InsertPos = Lexer::getLocForEndOfToken(
194 - InsertPos, 0, *Result.SourceManager, getLangOpts());
195 -
196 - Diag << FixItHint::CreateInsertion(InsertPos, " : ");
197 - } else {
198 - bool Found = false;
199 - for (const auto *Init : Ctor->inits()) {
200 - if (Init->isMemberInitializer()) {
201 - if (Result.SourceManager->isBeforeInTranslationUnit(
202 - Field->getLocation(), Init->getMember()->getLocation())) {
203 - InsertPos = Init->getSourceLocation();
204 - Found = true;
205 - break;
206 - }
207 - }
208 - }
209 -
210 - if (!Found) {
211 - if (Ctor->getNumCtorInitializers()) {
212 - InsertPos = Lexer::getLocForEndOfToken(
213 - (*Ctor->init_rbegin())->getSourceRange().getEnd(), 0,
214 - *Result.SourceManager, getLangOpts());
215 - }
216 - Diag << FixItHint::CreateInsertion(InsertPos, ", ");
217 - } else {
218 - AddComma = true;
219 - }
220 - }
221 - Diag << FixItHint::CreateInsertion(InsertPos, Field->getName())
222 - << FixItHint::CreateInsertion(InsertPos, "(")
223 - << FixItHint::CreateInsertionFromRange(
224 - InsertPos,
225 - CharSourceRange(InitValue->getSourceRange(), true))
226 - << FixItHint::CreateInsertion(InsertPos, ")");
227 - if (AddComma)
228 - Diag << FixItHint::CreateInsertion(InsertPos, ", ");
229 -
230 - SourceLocation SemiColonEnd =
231 - Lexer::findNextToken(S->getEndLoc(), *Result.SourceManager,
232 - getLangOpts())
233 - ->getEndLoc();
234 - CharSourceRange StmtRange =
235 - CharSourceRange::getCharRange(S->getBeginLoc(), SemiColonEnd);
236 -
237 - Diag << FixItHint::CreateRemoval(StmtRange);
238 - FirstToCtorInits = false;
239 - }
240 - }
241 - }
242 -}
243 -
244 -} // namespace cppcoreguidelines
245 -} // namespace tidy
246 -} // namespace clang
1 -//===--- PreferMemberInitializerCheck.h - clang-tidy ------------*- C++ -*-===//
2 -//
3 -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 -// See https://llvm.org/LICENSE.txt for license information.
5 -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 -//
7 -//===----------------------------------------------------------------------===//
8 -
9 -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PREFERMEMBERINITIALIZERCHECK_H
10 -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PREFERMEMBERINITIALIZERCHECK_H
11 -
12 -#include "../ClangTidyCheck.h"
13 -
14 -namespace clang {
15 -namespace tidy {
16 -namespace cppcoreguidelines {
17 -
18 -/// Finds member initializations in the constructor body which can be placed
19 -/// into the initialization list instead.
20 -///
21 -/// For the user-facing documentation see:
22 -/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-prefer-member-initializer.html
23 -class PreferMemberInitializerCheck : public ClangTidyCheck {
24 -public:
25 - PreferMemberInitializerCheck(StringRef Name, ClangTidyContext *Context);
26 - bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
27 - return LangOpts.CPlusPlus;
28 - }
29 - void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
30 - void registerMatchers(ast_matchers::MatchFinder *Finder) override;
31 - void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
32 -
33 - const bool IsUseDefaultMemberInitEnabled;
34 - const bool UseAssignment;
35 -};
36 -
37 -} // namespace cppcoreguidelines
38 -} // namespace tidy
39 -} // namespace clang
40 -
41 -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PREFERMEMBERINITIALIZERCHECK_H
...@@ -21,18 +21,20 @@ namespace cppcoreguidelines { ...@@ -21,18 +21,20 @@ namespace cppcoreguidelines {
21 ProBoundsConstantArrayIndexCheck::ProBoundsConstantArrayIndexCheck( 21 ProBoundsConstantArrayIndexCheck::ProBoundsConstantArrayIndexCheck(
22 StringRef Name, ClangTidyContext *Context) 22 StringRef Name, ClangTidyContext *Context)
23 : ClangTidyCheck(Name, Context), GslHeader(Options.get("GslHeader", "")), 23 : ClangTidyCheck(Name, Context), GslHeader(Options.get("GslHeader", "")),
24 - Inserter(Options.getLocalOrGlobal("IncludeStyle", 24 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
25 - utils::IncludeSorter::IS_LLVM)) {} 25 + utils::IncludeSorter::IS_LLVM)) {}
26 26
27 void ProBoundsConstantArrayIndexCheck::storeOptions( 27 void ProBoundsConstantArrayIndexCheck::storeOptions(
28 ClangTidyOptions::OptionMap &Opts) { 28 ClangTidyOptions::OptionMap &Opts) {
29 Options.store(Opts, "GslHeader", GslHeader); 29 Options.store(Opts, "GslHeader", GslHeader);
30 - Options.store(Opts, "IncludeStyle", Inserter.getStyle()); 30 + Options.store(Opts, "IncludeStyle", IncludeStyle);
31 } 31 }
32 32
33 void ProBoundsConstantArrayIndexCheck::registerPPCallbacks( 33 void ProBoundsConstantArrayIndexCheck::registerPPCallbacks(
34 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { 34 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
35 - Inserter.registerPreprocessor(PP); 35 + Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
36 + IncludeStyle);
37 + PP->addPPCallbacks(Inserter->CreatePPCallbacks());
36 } 38 }
37 39
38 void ProBoundsConstantArrayIndexCheck::registerMatchers(MatchFinder *Finder) { 40 void ProBoundsConstantArrayIndexCheck::registerMatchers(MatchFinder *Finder) {
...@@ -63,9 +65,9 @@ void ProBoundsConstantArrayIndexCheck::check( ...@@ -63,9 +65,9 @@ void ProBoundsConstantArrayIndexCheck::check(
63 if (IndexExpr->isValueDependent()) 65 if (IndexExpr->isValueDependent())
64 return; // We check in the specialization. 66 return; // We check in the specialization.
65 67
66 - Optional<llvm::APSInt> Index = 68 + llvm::APSInt Index;
67 - IndexExpr->getIntegerConstantExpr(*Result.Context); 69 + if (!IndexExpr->isIntegerConstantExpr(Index, *Result.Context, nullptr,
68 - if (!Index) { 70 + /*isEvaluated=*/true)) {
69 SourceRange BaseRange; 71 SourceRange BaseRange;
70 if (const auto *ArraySubscriptE = dyn_cast<ArraySubscriptExpr>(Matched)) 72 if (const auto *ArraySubscriptE = dyn_cast<ArraySubscriptExpr>(Matched))
71 BaseRange = ArraySubscriptE->getBase()->getSourceRange(); 73 BaseRange = ArraySubscriptE->getBase()->getSourceRange();
...@@ -85,7 +87,9 @@ void ProBoundsConstantArrayIndexCheck::check( ...@@ -85,7 +87,9 @@ void ProBoundsConstantArrayIndexCheck::check(
85 IndexRange.getBegin().getLocWithOffset(-1)), 87 IndexRange.getBegin().getLocWithOffset(-1)),
86 ", ") 88 ", ")
87 << FixItHint::CreateReplacement(Matched->getEndLoc(), ")") 89 << FixItHint::CreateReplacement(Matched->getEndLoc(), ")")
88 - << Inserter.createMainFileIncludeInsertion(GslHeader); 90 + << Inserter->CreateIncludeInsertion(
91 + Result.SourceManager->getMainFileID(), GslHeader,
92 + /*IsAngled=*/false);
89 } 93 }
90 return; 94 return;
91 } 95 }
...@@ -97,9 +101,9 @@ void ProBoundsConstantArrayIndexCheck::check( ...@@ -97,9 +101,9 @@ void ProBoundsConstantArrayIndexCheck::check(
97 if (!StdArrayDecl) 101 if (!StdArrayDecl)
98 return; 102 return;
99 103
100 - if (Index->isSigned() && Index->isNegative()) { 104 + if (Index.isSigned() && Index.isNegative()) {
101 diag(Matched->getExprLoc(), "std::array<> index %0 is negative") 105 diag(Matched->getExprLoc(), "std::array<> index %0 is negative")
102 - << Index->toString(10); 106 + << Index.toString(10);
103 return; 107 return;
104 } 108 }
105 109
...@@ -114,11 +118,11 @@ void ProBoundsConstantArrayIndexCheck::check( ...@@ -114,11 +118,11 @@ void ProBoundsConstantArrayIndexCheck::check(
114 118
115 // Get uint64_t values, because different bitwidths would lead to an assertion 119 // Get uint64_t values, because different bitwidths would lead to an assertion
116 // in APInt::uge. 120 // in APInt::uge.
117 - if (Index->getZExtValue() >= ArraySize.getZExtValue()) { 121 + if (Index.getZExtValue() >= ArraySize.getZExtValue()) {
118 diag(Matched->getExprLoc(), 122 diag(Matched->getExprLoc(),
119 "std::array<> index %0 is past the end of the array " 123 "std::array<> index %0 is past the end of the array "
120 "(which contains %1 elements)") 124 "(which contains %1 elements)")
121 - << Index->toString(10) << ArraySize.toString(10, false); 125 + << Index.toString(10) << ArraySize.toString(10, false);
122 } 126 }
123 } 127 }
124 128
......
...@@ -23,7 +23,8 @@ namespace cppcoreguidelines { ...@@ -23,7 +23,8 @@ namespace cppcoreguidelines {
23 /// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.html 23 /// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.html
24 class ProBoundsConstantArrayIndexCheck : public ClangTidyCheck { 24 class ProBoundsConstantArrayIndexCheck : public ClangTidyCheck {
25 const std::string GslHeader; 25 const std::string GslHeader;
26 - utils::IncludeInserter Inserter; 26 + const utils::IncludeSorter::IncludeStyle IncludeStyle;
27 + std::unique_ptr<utils::IncludeInserter> Inserter;
27 28
28 public: 29 public:
29 ProBoundsConstantArrayIndexCheck(StringRef Name, ClangTidyContext *Context); 30 ProBoundsConstantArrayIndexCheck(StringRef Name, ClangTidyContext *Context);
......
...@@ -500,13 +500,7 @@ static bool retrieveIntegerConstantExpr(const MatchFinder::MatchResult &Result, ...@@ -500,13 +500,7 @@ static bool retrieveIntegerConstantExpr(const MatchFinder::MatchResult &Result,
500 const Expr *&ConstExpr) { 500 const Expr *&ConstExpr) {
501 std::string CstId = (Id + "-const").str(); 501 std::string CstId = (Id + "-const").str();
502 ConstExpr = Result.Nodes.getNodeAs<Expr>(CstId); 502 ConstExpr = Result.Nodes.getNodeAs<Expr>(CstId);
503 - if (!ConstExpr) 503 + return ConstExpr && ConstExpr->isIntegerConstantExpr(Value, *Result.Context);
504 - return false;
505 - Optional<llvm::APSInt> R = ConstExpr->getIntegerConstantExpr(*Result.Context);
506 - if (!R)
507 - return false;
508 - Value = *R;
509 - return true;
510 } 504 }
511 505
512 // Overloaded `retrieveIntegerConstantExpr` for compatibility. 506 // Overloaded `retrieveIntegerConstantExpr` for compatibility.
...@@ -679,7 +673,7 @@ static bool retrieveRelationalIntegerConstantExpr( ...@@ -679,7 +673,7 @@ static bool retrieveRelationalIntegerConstantExpr(
679 673
680 if (const auto *Arg = OverloadedOperatorExpr->getArg(1)) { 674 if (const auto *Arg = OverloadedOperatorExpr->getArg(1)) {
681 if (!Arg->isValueDependent() && 675 if (!Arg->isValueDependent() &&
682 - !Arg->isIntegerConstantExpr(*Result.Context)) 676 + !Arg->isIntegerConstantExpr(Value, *Result.Context))
683 return false; 677 return false;
684 } 678 }
685 Symbol = OverloadedOperatorExpr->getArg(0); 679 Symbol = OverloadedOperatorExpr->getArg(0);
...@@ -1271,23 +1265,21 @@ void RedundantExpressionCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -1271,23 +1265,21 @@ void RedundantExpressionCheck::check(const MatchFinder::MatchResult &Result) {
1271 "left-right-shift-confusion")) { 1265 "left-right-shift-confusion")) {
1272 const auto *ShiftingConst = Result.Nodes.getNodeAs<Expr>("shift-const"); 1266 const auto *ShiftingConst = Result.Nodes.getNodeAs<Expr>("shift-const");
1273 assert(ShiftingConst && "Expr* 'ShiftingConst' is nullptr!"); 1267 assert(ShiftingConst && "Expr* 'ShiftingConst' is nullptr!");
1274 - Optional<llvm::APSInt> ShiftingValue = 1268 + APSInt ShiftingValue;
1275 - ShiftingConst->getIntegerConstantExpr(*Result.Context);
1276 1269
1277 - if (!ShiftingValue) 1270 + if (!ShiftingConst->isIntegerConstantExpr(ShiftingValue, *Result.Context))
1278 return; 1271 return;
1279 1272
1280 const auto *AndConst = Result.Nodes.getNodeAs<Expr>("and-const"); 1273 const auto *AndConst = Result.Nodes.getNodeAs<Expr>("and-const");
1281 assert(AndConst && "Expr* 'AndCont' is nullptr!"); 1274 assert(AndConst && "Expr* 'AndCont' is nullptr!");
1282 - Optional<llvm::APSInt> AndValue = 1275 + APSInt AndValue;
1283 - AndConst->getIntegerConstantExpr(*Result.Context); 1276 + if (!AndConst->isIntegerConstantExpr(AndValue, *Result.Context))
1284 - if (!AndValue)
1285 return; 1277 return;
1286 1278
1287 // If ShiftingConst is shifted left with more bits than the position of the 1279 // If ShiftingConst is shifted left with more bits than the position of the
1288 // leftmost 1 in the bit representation of AndValue, AndConstant is 1280 // leftmost 1 in the bit representation of AndValue, AndConstant is
1289 // ineffective. 1281 // ineffective.
1290 - if (AndValue->getActiveBits() > *ShiftingValue) 1282 + if (AndValue.getActiveBits() > ShiftingValue)
1291 return; 1283 return;
1292 1284
1293 auto Diag = diag(BinaryAndExpr->getOperatorLoc(), 1285 auto Diag = diag(BinaryAndExpr->getOperatorLoc(),
......
...@@ -438,12 +438,11 @@ static bool arrayMatchesBoundExpr(ASTContext *Context, ...@@ -438,12 +438,11 @@ static bool arrayMatchesBoundExpr(ASTContext *Context,
438 Context->getAsConstantArrayType(ArrayType); 438 Context->getAsConstantArrayType(ArrayType);
439 if (!ConstType) 439 if (!ConstType)
440 return false; 440 return false;
441 - Optional<llvm::APSInt> ConditionSize = 441 + llvm::APSInt ConditionSize;
442 - ConditionExpr->getIntegerConstantExpr(*Context); 442 + if (!ConditionExpr->isIntegerConstantExpr(ConditionSize, *Context))
443 - if (!ConditionSize)
444 return false; 443 return false;
445 llvm::APSInt ArraySize(ConstType->getSize()); 444 llvm::APSInt ArraySize(ConstType->getSize());
446 - return llvm::APSInt::isSameValue(*ConditionSize, ArraySize); 445 + return llvm::APSInt::isSameValue(ConditionSize, ArraySize);
447 } 446 }
448 447
449 ForLoopIndexUseVisitor::ForLoopIndexUseVisitor(ASTContext *Context, 448 ForLoopIndexUseVisitor::ForLoopIndexUseVisitor(ASTContext *Context,
......
...@@ -19,6 +19,7 @@ namespace modernize { ...@@ -19,6 +19,7 @@ namespace modernize {
19 19
20 namespace { 20 namespace {
21 21
22 +constexpr char StdMemoryHeader[] = "memory";
22 constexpr char ConstructorCall[] = "constructorCall"; 23 constexpr char ConstructorCall[] = "constructorCall";
23 constexpr char ResetCall[] = "resetCall"; 24 constexpr char ResetCall[] = "resetCall";
24 constexpr char NewExpression[] = "newExpression"; 25 constexpr char NewExpression[] = "newExpression";
...@@ -43,16 +44,16 @@ const char MakeSmartPtrCheck::PointerType[] = "pointerType"; ...@@ -43,16 +44,16 @@ const char MakeSmartPtrCheck::PointerType[] = "pointerType";
43 MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context, 44 MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
44 StringRef MakeSmartPtrFunctionName) 45 StringRef MakeSmartPtrFunctionName)
45 : ClangTidyCheck(Name, Context), 46 : ClangTidyCheck(Name, Context),
46 - Inserter(Options.getLocalOrGlobal("IncludeStyle", 47 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
47 - utils::IncludeSorter::IS_LLVM)), 48 + utils::IncludeSorter::IS_LLVM)),
48 MakeSmartPtrFunctionHeader( 49 MakeSmartPtrFunctionHeader(
49 - Options.get("MakeSmartPtrFunctionHeader", "<memory>")), 50 + Options.get("MakeSmartPtrFunctionHeader", StdMemoryHeader)),
50 MakeSmartPtrFunctionName( 51 MakeSmartPtrFunctionName(
51 Options.get("MakeSmartPtrFunction", MakeSmartPtrFunctionName)), 52 Options.get("MakeSmartPtrFunction", MakeSmartPtrFunctionName)),
52 IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {} 53 IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {}
53 54
54 void MakeSmartPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { 55 void MakeSmartPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
55 - Options.store(Opts, "IncludeStyle", Inserter.getStyle()); 56 + Options.store(Opts, "IncludeStyle", IncludeStyle);
56 Options.store(Opts, "MakeSmartPtrFunctionHeader", MakeSmartPtrFunctionHeader); 57 Options.store(Opts, "MakeSmartPtrFunctionHeader", MakeSmartPtrFunctionHeader);
57 Options.store(Opts, "MakeSmartPtrFunction", MakeSmartPtrFunctionName); 58 Options.store(Opts, "MakeSmartPtrFunction", MakeSmartPtrFunctionName);
58 Options.store(Opts, "IgnoreMacros", IgnoreMacros); 59 Options.store(Opts, "IgnoreMacros", IgnoreMacros);
...@@ -66,7 +67,9 @@ bool MakeSmartPtrCheck::isLanguageVersionSupported( ...@@ -66,7 +67,9 @@ bool MakeSmartPtrCheck::isLanguageVersionSupported(
66 void MakeSmartPtrCheck::registerPPCallbacks(const SourceManager &SM, 67 void MakeSmartPtrCheck::registerPPCallbacks(const SourceManager &SM,
67 Preprocessor *PP, 68 Preprocessor *PP,
68 Preprocessor *ModuleExpanderPP) { 69 Preprocessor *ModuleExpanderPP) {
69 - Inserter.registerPreprocessor(PP); 70 + Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
71 + IncludeStyle);
72 + PP->addPPCallbacks(Inserter->CreatePPCallbacks());
70 } 73 }
71 74
72 void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) { 75 void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
...@@ -429,7 +432,9 @@ void MakeSmartPtrCheck::insertHeader(DiagnosticBuilder &Diag, FileID FD) { ...@@ -429,7 +432,9 @@ void MakeSmartPtrCheck::insertHeader(DiagnosticBuilder &Diag, FileID FD) {
429 if (MakeSmartPtrFunctionHeader.empty()) { 432 if (MakeSmartPtrFunctionHeader.empty()) {
430 return; 433 return;
431 } 434 }
432 - Diag << Inserter.createIncludeInsertion(FD, MakeSmartPtrFunctionHeader); 435 + Diag << Inserter->CreateIncludeInsertion(
436 + FD, MakeSmartPtrFunctionHeader,
437 + /*IsAngled=*/MakeSmartPtrFunctionHeader == StdMemoryHeader);
433 } 438 }
434 439
435 } // namespace modernize 440 } // namespace modernize
......
...@@ -46,7 +46,8 @@ protected: ...@@ -46,7 +46,8 @@ protected:
46 static const char PointerType[]; 46 static const char PointerType[];
47 47
48 private: 48 private:
49 - utils::IncludeInserter Inserter; 49 + std::unique_ptr<utils::IncludeInserter> Inserter;
50 + const utils::IncludeSorter::IncludeStyle IncludeStyle;
50 const std::string MakeSmartPtrFunctionHeader; 51 const std::string MakeSmartPtrFunctionHeader;
51 const std::string MakeSmartPtrFunctionName; 52 const std::string MakeSmartPtrFunctionName;
52 const bool IgnoreMacros; 53 const bool IgnoreMacros;
......
...@@ -120,12 +120,12 @@ collectParamDecls(const CXXConstructorDecl *Ctor, ...@@ -120,12 +120,12 @@ collectParamDecls(const CXXConstructorDecl *Ctor,
120 120
121 PassByValueCheck::PassByValueCheck(StringRef Name, ClangTidyContext *Context) 121 PassByValueCheck::PassByValueCheck(StringRef Name, ClangTidyContext *Context)
122 : ClangTidyCheck(Name, Context), 122 : ClangTidyCheck(Name, Context),
123 - Inserter(Options.getLocalOrGlobal("IncludeStyle", 123 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
124 - utils::IncludeSorter::IS_LLVM)), 124 + utils::IncludeSorter::IS_LLVM)),
125 ValuesOnly(Options.get("ValuesOnly", false)) {} 125 ValuesOnly(Options.get("ValuesOnly", false)) {}
126 126
127 void PassByValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { 127 void PassByValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
128 - Options.store(Opts, "IncludeStyle", Inserter.getStyle()); 128 + Options.store(Opts, "IncludeStyle", IncludeStyle);
129 Options.store(Opts, "ValuesOnly", ValuesOnly); 129 Options.store(Opts, "ValuesOnly", ValuesOnly);
130 } 130 }
131 131
...@@ -167,7 +167,9 @@ void PassByValueCheck::registerMatchers(MatchFinder *Finder) { ...@@ -167,7 +167,9 @@ void PassByValueCheck::registerMatchers(MatchFinder *Finder) {
167 void PassByValueCheck::registerPPCallbacks(const SourceManager &SM, 167 void PassByValueCheck::registerPPCallbacks(const SourceManager &SM,
168 Preprocessor *PP, 168 Preprocessor *PP,
169 Preprocessor *ModuleExpanderPP) { 169 Preprocessor *ModuleExpanderPP) {
170 - Inserter.registerPreprocessor(PP); 170 + Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
171 + IncludeStyle);
172 + PP->addPPCallbacks(Inserter->CreatePPCallbacks());
171 } 173 }
172 174
173 void PassByValueCheck::check(const MatchFinder::MatchResult &Result) { 175 void PassByValueCheck::check(const MatchFinder::MatchResult &Result) {
...@@ -214,9 +216,10 @@ void PassByValueCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -214,9 +216,10 @@ void PassByValueCheck::check(const MatchFinder::MatchResult &Result) {
214 Diag << FixItHint::CreateInsertion(Initializer->getRParenLoc(), ")") 216 Diag << FixItHint::CreateInsertion(Initializer->getRParenLoc(), ")")
215 << FixItHint::CreateInsertion( 217 << FixItHint::CreateInsertion(
216 Initializer->getLParenLoc().getLocWithOffset(1), "std::move(") 218 Initializer->getLParenLoc().getLocWithOffset(1), "std::move(")
217 - << Inserter.createIncludeInsertion( 219 + << Inserter->CreateIncludeInsertion(
218 Result.SourceManager->getFileID(Initializer->getSourceLocation()), 220 Result.SourceManager->getFileID(Initializer->getSourceLocation()),
219 - "<utility>"); 221 + "utility",
222 + /*IsAngled=*/true);
220 } 223 }
221 224
222 } // namespace modernize 225 } // namespace modernize
......
...@@ -31,7 +31,8 @@ public: ...@@ -31,7 +31,8 @@ public:
31 void check(const ast_matchers::MatchFinder::MatchResult &Result) override; 31 void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
32 32
33 private: 33 private:
34 - utils::IncludeInserter Inserter; 34 + std::unique_ptr<utils::IncludeInserter> Inserter;
35 + const utils::IncludeSorter::IncludeStyle IncludeStyle;
35 const bool ValuesOnly; 36 const bool ValuesOnly;
36 }; 37 };
37 38
......
...@@ -74,11 +74,11 @@ AST_MATCHER(Decl, isFromStdNamespace) { ...@@ -74,11 +74,11 @@ AST_MATCHER(Decl, isFromStdNamespace) {
74 ReplaceAutoPtrCheck::ReplaceAutoPtrCheck(StringRef Name, 74 ReplaceAutoPtrCheck::ReplaceAutoPtrCheck(StringRef Name,
75 ClangTidyContext *Context) 75 ClangTidyContext *Context)
76 : ClangTidyCheck(Name, Context), 76 : ClangTidyCheck(Name, Context),
77 - Inserter(Options.getLocalOrGlobal("IncludeStyle", 77 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
78 - utils::IncludeSorter::IS_LLVM)) {} 78 + utils::IncludeSorter::IS_LLVM)) {}
79 79
80 void ReplaceAutoPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { 80 void ReplaceAutoPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
81 - Options.store(Opts, "IncludeStyle", Inserter.getStyle()); 81 + Options.store(Opts, "IncludeStyle", IncludeStyle);
82 } 82 }
83 83
84 void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) { 84 void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
...@@ -131,7 +131,9 @@ void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) { ...@@ -131,7 +131,9 @@ void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
131 void ReplaceAutoPtrCheck::registerPPCallbacks(const SourceManager &SM, 131 void ReplaceAutoPtrCheck::registerPPCallbacks(const SourceManager &SM,
132 Preprocessor *PP, 132 Preprocessor *PP,
133 Preprocessor *ModuleExpanderPP) { 133 Preprocessor *ModuleExpanderPP) {
134 - Inserter.registerPreprocessor(PP); 134 + Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
135 + IncludeStyle);
136 + PP->addPPCallbacks(Inserter->CreatePPCallbacks());
135 } 137 }
136 138
137 void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) { 139 void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
...@@ -144,10 +146,12 @@ void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -144,10 +146,12 @@ void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
144 if (Range.isInvalid()) 146 if (Range.isInvalid())
145 return; 147 return;
146 148
147 - auto Diag = diag(Range.getBegin(), "use std::move to transfer ownership") 149 + auto Diag =
148 - << FixItHint::CreateInsertion(Range.getBegin(), "std::move(") 150 + diag(Range.getBegin(), "use std::move to transfer ownership")
149 - << FixItHint::CreateInsertion(Range.getEnd(), ")") 151 + << FixItHint::CreateInsertion(Range.getBegin(), "std::move(")
150 - << Inserter.createMainFileIncludeInsertion("<utility>"); 152 + << FixItHint::CreateInsertion(Range.getEnd(), ")")
153 + << Inserter->CreateIncludeInsertion(SM.getMainFileID(), "utility",
154 + /*IsAngled=*/true);
151 155
152 return; 156 return;
153 } 157 }
......
...@@ -53,7 +53,8 @@ public: ...@@ -53,7 +53,8 @@ public:
53 void check(const ast_matchers::MatchFinder::MatchResult &Result) override; 53 void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
54 54
55 private: 55 private:
56 - utils::IncludeInserter Inserter; 56 + std::unique_ptr<utils::IncludeInserter> Inserter;
57 + const utils::IncludeSorter::IncludeStyle IncludeStyle;
57 }; 58 };
58 59
59 } // namespace modernize 60 } // namespace modernize
......
...@@ -23,9 +23,8 @@ namespace modernize { ...@@ -23,9 +23,8 @@ namespace modernize {
23 ReplaceRandomShuffleCheck::ReplaceRandomShuffleCheck(StringRef Name, 23 ReplaceRandomShuffleCheck::ReplaceRandomShuffleCheck(StringRef Name,
24 ClangTidyContext *Context) 24 ClangTidyContext *Context)
25 : ClangTidyCheck(Name, Context), 25 : ClangTidyCheck(Name, Context),
26 - IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", 26 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
27 - utils::IncludeSorter::IS_LLVM)) { 27 + utils::IncludeSorter::IS_LLVM)) {}
28 -}
29 28
30 void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) { 29 void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) {
31 const auto Begin = hasArgument(0, expr()); 30 const auto Begin = hasArgument(0, expr());
...@@ -45,12 +44,14 @@ void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) { ...@@ -45,12 +44,14 @@ void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) {
45 44
46 void ReplaceRandomShuffleCheck::registerPPCallbacks( 45 void ReplaceRandomShuffleCheck::registerPPCallbacks(
47 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { 46 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
48 - IncludeInserter.registerPreprocessor(PP); 47 + IncludeInserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
48 + IncludeStyle);
49 + PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
49 } 50 }
50 51
51 void ReplaceRandomShuffleCheck::storeOptions( 52 void ReplaceRandomShuffleCheck::storeOptions(
52 ClangTidyOptions::OptionMap &Opts) { 53 ClangTidyOptions::OptionMap &Opts) {
53 - Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); 54 + Options.store(Opts, "IncludeStyle", IncludeStyle);
54 } 55 }
55 56
56 void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) { 57 void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) {
...@@ -91,10 +92,10 @@ void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -91,10 +92,10 @@ void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) {
91 92
92 Diag << FixItHint::CreateRemoval(MatchedDecl->getSourceRange()); 93 Diag << FixItHint::CreateRemoval(MatchedDecl->getSourceRange());
93 Diag << FixItHint::CreateInsertion(MatchedDecl->getBeginLoc(), NewName); 94 Diag << FixItHint::CreateInsertion(MatchedDecl->getBeginLoc(), NewName);
94 - Diag << IncludeInserter.createIncludeInsertion( 95 + Diag << IncludeInserter->CreateIncludeInsertion(
95 Result.Context->getSourceManager().getFileID( 96 Result.Context->getSourceManager().getFileID(
96 MatchedCallExpr->getBeginLoc()), 97 MatchedCallExpr->getBeginLoc()),
97 - "<random>"); 98 + "random", /*IsAngled=*/true);
98 } 99 }
99 100
100 } // namespace modernize 101 } // namespace modernize
......
...@@ -34,7 +34,8 @@ public: ...@@ -34,7 +34,8 @@ public:
34 void check(const ast_matchers::MatchFinder::MatchResult &Result) override; 34 void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
35 35
36 private: 36 private:
37 - utils::IncludeInserter IncludeInserter; 37 + std::unique_ptr<utils::IncludeInserter> IncludeInserter;
38 + const utils::IncludeSorter::IncludeStyle IncludeStyle;
38 }; 39 };
39 40
40 } // namespace modernize 41 } // namespace modernize
......
...@@ -119,11 +119,16 @@ AST_MATCHER_P(QualType, isSugarFor, Matcher<QualType>, SugarMatcher) { ...@@ -119,11 +119,16 @@ AST_MATCHER_P(QualType, isSugarFor, Matcher<QualType>, SugarMatcher) {
119 /// \endcode 119 /// \endcode
120 /// 120 ///
121 /// namedDecl(hasStdIteratorName()) matches \c I and \c CI. 121 /// namedDecl(hasStdIteratorName()) matches \c I and \c CI.
122 -Matcher<NamedDecl> hasStdIteratorName() { 122 +AST_MATCHER(NamedDecl, hasStdIteratorName) {
123 - static const StringRef IteratorNames[] = {"iterator", "reverse_iterator", 123 + static const char *const IteratorNames[] = {"iterator", "reverse_iterator",
124 - "const_iterator", 124 + "const_iterator",
125 - "const_reverse_iterator"}; 125 + "const_reverse_iterator"};
126 - return hasAnyName(IteratorNames); 126 +
127 + for (const char *Name : IteratorNames) {
128 + if (hasName(Name).matches(Node, Finder, Builder))
129 + return true;
130 + }
131 + return false;
127 } 132 }
128 133
129 /// Matches named declarations that have one of the standard container 134 /// Matches named declarations that have one of the standard container
...@@ -138,21 +143,26 @@ Matcher<NamedDecl> hasStdIteratorName() { ...@@ -138,21 +143,26 @@ Matcher<NamedDecl> hasStdIteratorName() {
138 /// 143 ///
139 /// recordDecl(hasStdContainerName()) matches \c vector and \c forward_list 144 /// recordDecl(hasStdContainerName()) matches \c vector and \c forward_list
140 /// but not \c my_vec. 145 /// but not \c my_vec.
141 -Matcher<NamedDecl> hasStdContainerName() { 146 +AST_MATCHER(NamedDecl, hasStdContainerName) {
142 - static StringRef ContainerNames[] = {"array", "deque", 147 + static const char *const ContainerNames[] = {
143 - "forward_list", "list", 148 + "array", "deque",
144 - "vector", 149 + "forward_list", "list",
150 + "vector",
145 151
146 - "map", "multimap", 152 + "map", "multimap",
147 - "set", "multiset", 153 + "set", "multiset",
148 154
149 - "unordered_map", "unordered_multimap", 155 + "unordered_map", "unordered_multimap",
150 - "unordered_set", "unordered_multiset", 156 + "unordered_set", "unordered_multiset",
151 157
152 - "queue", "priority_queue", 158 + "queue", "priority_queue",
153 - "stack"}; 159 + "stack"};
154 160
155 - return hasAnyName(ContainerNames); 161 + for (const char *Name : ContainerNames) {
162 + if (hasName(Name).matches(Node, Finder, Builder))
163 + return true;
164 + }
165 + return false;
156 } 166 }
157 167
158 /// Matches declarations whose declaration context is the C++ standard library 168 /// Matches declarations whose declaration context is the C++ standard library
...@@ -338,7 +348,7 @@ void UseAutoCheck::replaceIterators(const DeclStmt *D, ASTContext *Context) { ...@@ -338,7 +348,7 @@ void UseAutoCheck::replaceIterators(const DeclStmt *D, ASTContext *Context) {
338 348
339 // Drill down to the as-written initializer. 349 // Drill down to the as-written initializer.
340 const Expr *E = (*Construct->arg_begin())->IgnoreParenImpCasts(); 350 const Expr *E = (*Construct->arg_begin())->IgnoreParenImpCasts();
341 - if (E != E->IgnoreConversionOperatorSingleStep()) { 351 + if (E != E->IgnoreConversionOperator()) {
342 // We hit a conversion operator. Early-out now as they imply an implicit 352 // We hit a conversion operator. Early-out now as they imply an implicit
343 // conversion from a different type. Could also mean an explicit 353 // conversion from a different type. Could also mean an explicit
344 // conversion from the same type but that's pretty rare. 354 // conversion from the same type but that's pretty rare.
......
...@@ -36,12 +36,12 @@ void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) { ...@@ -36,12 +36,12 @@ void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) {
36 Finder->addMatcher( 36 Finder->addMatcher(
37 cxxMethodDecl( 37 cxxMethodDecl(
38 PrivateSpecialFn, 38 PrivateSpecialFn,
39 - unless(anyOf(hasAnyBody(stmt()), isDefaulted(), isDeleted(), 39 + unless(anyOf(hasBody(stmt()), isDefaulted(), isDeleted(),
40 ast_matchers::isTemplateInstantiation(), 40 ast_matchers::isTemplateInstantiation(),
41 // Ensure that all methods except private special member 41 // Ensure that all methods except private special member
42 // functions are defined. 42 // functions are defined.
43 hasParent(cxxRecordDecl(hasMethod(unless( 43 hasParent(cxxRecordDecl(hasMethod(unless(
44 - anyOf(PrivateSpecialFn, hasAnyBody(stmt()), isPure(), 44 + anyOf(PrivateSpecialFn, hasBody(stmt()), isPure(),
45 isDefaulted(), isDeleted())))))))) 45 isDefaulted(), isDeleted()))))))))
46 .bind(SpecialFunction), 46 .bind(SpecialFunction),
47 this); 47 this);
......
...@@ -77,16 +77,13 @@ void UseNoexceptCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -77,16 +77,13 @@ void UseNoexceptCheck::check(const MatchFinder::MatchResult &Result) {
77 .getExceptionSpecRange(); 77 .getExceptionSpecRange();
78 } 78 }
79 79
80 - assert(FnTy && "FunctionProtoType is null.");
81 - if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
82 - return;
83 -
84 assert(Range.isValid() && "Exception Source Range is invalid."); 80 assert(Range.isValid() && "Exception Source Range is invalid.");
85 81
86 CharSourceRange CRange = Lexer::makeFileCharRange( 82 CharSourceRange CRange = Lexer::makeFileCharRange(
87 CharSourceRange::getTokenRange(Range), *Result.SourceManager, 83 CharSourceRange::getTokenRange(Range), *Result.SourceManager,
88 Result.Context->getLangOpts()); 84 Result.Context->getLangOpts());
89 85
86 + assert(FnTy && "FunctionProtoType is null.");
90 bool IsNoThrow = FnTy->isNothrow(); 87 bool IsNoThrow = FnTy->isNothrow();
91 StringRef ReplacementStr = 88 StringRef ReplacementStr =
92 IsNoThrow 89 IsNoThrow
......
...@@ -66,11 +66,6 @@ public: ...@@ -66,11 +66,6 @@ public:
66 ->getName())) 66 ->getName()))
67 return false; 67 return false;
68 break; 68 break;
69 - case TypeLoc::Typedef:
70 - if (VisitUnqualName(
71 - TL.getAs<TypedefTypeLoc>().getTypePtr()->getDecl()->getName()))
72 - return false;
73 - break;
74 default: 69 default:
75 break; 70 break;
76 } 71 }
...@@ -266,8 +261,8 @@ static bool hasAnyNestedLocalQualifiers(QualType Type) { ...@@ -266,8 +261,8 @@ static bool hasAnyNestedLocalQualifiers(QualType Type) {
266 } 261 }
267 262
268 SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange( 263 SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange(
269 - const FunctionDecl &F, const TypeLoc &ReturnLoc, const ASTContext &Ctx, 264 + const FunctionDecl &F, const ASTContext &Ctx, const SourceManager &SM,
270 - const SourceManager &SM, const LangOptions &LangOpts) { 265 + const LangOptions &LangOpts) {
271 266
272 // We start with the range of the return type and expand to neighboring 267 // We start with the range of the return type and expand to neighboring
273 // qualifiers (const, volatile and restrict). 268 // qualifiers (const, volatile and restrict).
...@@ -279,35 +274,6 @@ SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange( ...@@ -279,35 +274,6 @@ SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange(
279 return {}; 274 return {};
280 } 275 }
281 276
282 - // If the return type is a constrained 'auto' or 'decltype(auto)', we need to
283 - // include the tokens after the concept. Unfortunately, the source range of an
284 - // AutoTypeLoc, if it is constrained, does not include the 'auto' or
285 - // 'decltype(auto)'. If the return type is a plain 'decltype(...)', the
286 - // source range only contains the first 'decltype' token.
287 - auto ATL = ReturnLoc.getAs<AutoTypeLoc>();
288 - if ((ATL && (ATL.isConstrained() ||
289 - ATL.getAutoKeyword() == AutoTypeKeyword::DecltypeAuto)) ||
290 - ReturnLoc.getAs<DecltypeTypeLoc>()) {
291 - SourceLocation End =
292 - expandIfMacroId(ReturnLoc.getSourceRange().getEnd(), SM);
293 - SourceLocation BeginNameF = expandIfMacroId(F.getLocation(), SM);
294 -
295 - // Extend the ReturnTypeRange until the last token before the function
296 - // name.
297 - std::pair<FileID, unsigned> Loc = SM.getDecomposedLoc(End);
298 - StringRef File = SM.getBufferData(Loc.first);
299 - const char *TokenBegin = File.data() + Loc.second;
300 - Lexer Lexer(SM.getLocForStartOfFile(Loc.first), LangOpts, File.begin(),
301 - TokenBegin, File.end());
302 - Token T;
303 - SourceLocation LastTLoc = End;
304 - while (!Lexer.LexFromRawLexer(T) &&
305 - SM.isBeforeInTranslationUnit(T.getLocation(), BeginNameF)) {
306 - LastTLoc = T.getLocation();
307 - }
308 - ReturnTypeRange.setEnd(LastTLoc);
309 - }
310 -
311 // If the return type has no local qualifiers, it's source range is accurate. 277 // If the return type has no local qualifiers, it's source range is accurate.
312 if (!hasAnyNestedLocalQualifiers(F.getReturnType())) 278 if (!hasAnyNestedLocalQualifiers(F.getReturnType()))
313 return ReturnTypeRange; 279 return ReturnTypeRange;
...@@ -351,7 +317,7 @@ SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange( ...@@ -351,7 +317,7 @@ SourceRange UseTrailingReturnTypeCheck::findReturnTypeAndCVSourceRange(
351 return ReturnTypeRange; 317 return ReturnTypeRange;
352 } 318 }
353 319
354 -void UseTrailingReturnTypeCheck::keepSpecifiers( 320 +bool UseTrailingReturnTypeCheck::keepSpecifiers(
355 std::string &ReturnType, std::string &Auto, SourceRange ReturnTypeCVRange, 321 std::string &ReturnType, std::string &Auto, SourceRange ReturnTypeCVRange,
356 const FunctionDecl &F, const FriendDecl *Fr, const ASTContext &Ctx, 322 const FunctionDecl &F, const FriendDecl *Fr, const ASTContext &Ctx,
357 const SourceManager &SM, const LangOptions &LangOpts) { 323 const SourceManager &SM, const LangOptions &LangOpts) {
...@@ -361,14 +327,14 @@ void UseTrailingReturnTypeCheck::keepSpecifiers( ...@@ -361,14 +327,14 @@ void UseTrailingReturnTypeCheck::keepSpecifiers(
361 if (!F.isConstexpr() && !F.isInlineSpecified() && 327 if (!F.isConstexpr() && !F.isInlineSpecified() &&
362 F.getStorageClass() != SC_Extern && F.getStorageClass() != SC_Static && 328 F.getStorageClass() != SC_Extern && F.getStorageClass() != SC_Static &&
363 !Fr && !(M && M->isVirtualAsWritten())) 329 !Fr && !(M && M->isVirtualAsWritten()))
364 - return; 330 + return true;
365 331
366 // Tokenize return type. If it contains macros which contain a mix of 332 // Tokenize return type. If it contains macros which contain a mix of
367 // qualifiers, specifiers and types, give up. 333 // qualifiers, specifiers and types, give up.
368 llvm::Optional<SmallVector<ClassifiedToken, 8>> MaybeTokens = 334 llvm::Optional<SmallVector<ClassifiedToken, 8>> MaybeTokens =
369 classifyTokensBeforeFunctionName(F, Ctx, SM, LangOpts); 335 classifyTokensBeforeFunctionName(F, Ctx, SM, LangOpts);
370 if (!MaybeTokens) 336 if (!MaybeTokens)
371 - return; 337 + return false;
372 338
373 // Find specifiers, remove them from the return type, add them to 'auto'. 339 // Find specifiers, remove them from the return type, add them to 'auto'.
374 unsigned int ReturnTypeBeginOffset = 340 unsigned int ReturnTypeBeginOffset =
...@@ -401,12 +367,14 @@ void UseTrailingReturnTypeCheck::keepSpecifiers( ...@@ -401,12 +367,14 @@ void UseTrailingReturnTypeCheck::keepSpecifiers(
401 ReturnType.erase(TOffsetInRT, TLengthWithWS); 367 ReturnType.erase(TOffsetInRT, TLengthWithWS);
402 DeletedChars += TLengthWithWS; 368 DeletedChars += TLengthWithWS;
403 } 369 }
370 +
371 + return true;
404 } 372 }
405 373
406 void UseTrailingReturnTypeCheck::registerMatchers(MatchFinder *Finder) { 374 void UseTrailingReturnTypeCheck::registerMatchers(MatchFinder *Finder) {
407 - auto F = functionDecl( 375 + auto F = functionDecl(unless(anyOf(hasTrailingReturn(), returns(voidType()),
408 - unless(anyOf(hasTrailingReturn(), returns(voidType()), 376 + returns(autoType()), cxxConversionDecl(),
409 - cxxConversionDecl(), cxxMethodDecl(isImplicit())))) 377 + cxxMethodDecl(isImplicit()))))
410 .bind("Func"); 378 .bind("Func");
411 379
412 Finder->addMatcher(F, this); 380 Finder->addMatcher(F, this);
...@@ -429,17 +397,11 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -429,17 +397,11 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) {
429 if (F->getLocation().isInvalid()) 397 if (F->getLocation().isInvalid())
430 return; 398 return;
431 399
432 - // Skip functions which return just 'auto'.
433 - const auto *AT = F->getDeclaredReturnType()->getAs<AutoType>();
434 - if (AT != nullptr && !AT->isConstrained() &&
435 - AT->getKeyword() == AutoTypeKeyword::Auto &&
436 - !hasAnyNestedLocalQualifiers(F->getDeclaredReturnType()))
437 - return;
438 -
439 // TODO: implement those 400 // TODO: implement those
440 if (F->getDeclaredReturnType()->isFunctionPointerType() || 401 if (F->getDeclaredReturnType()->isFunctionPointerType() ||
441 F->getDeclaredReturnType()->isMemberFunctionPointerType() || 402 F->getDeclaredReturnType()->isMemberFunctionPointerType() ||
442 - F->getDeclaredReturnType()->isMemberPointerType()) { 403 + F->getDeclaredReturnType()->isMemberPointerType() ||
404 + F->getDeclaredReturnType()->getAs<DecltypeType>() != nullptr) {
443 diag(F->getLocation(), Message); 405 diag(F->getLocation(), Message);
444 return; 406 return;
445 } 407 }
...@@ -473,7 +435,7 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -473,7 +435,7 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) {
473 // discards user formatting and order of const, volatile, type, whitespace, 435 // discards user formatting and order of const, volatile, type, whitespace,
474 // space before & ... . 436 // space before & ... .
475 SourceRange ReturnTypeCVRange = 437 SourceRange ReturnTypeCVRange =
476 - findReturnTypeAndCVSourceRange(*F, FTL.getReturnLoc(), Ctx, SM, LangOpts); 438 + findReturnTypeAndCVSourceRange(*F, Ctx, SM, LangOpts);
477 if (ReturnTypeCVRange.isInvalid()) 439 if (ReturnTypeCVRange.isInvalid())
478 return; 440 return;
479 441
......
...@@ -50,11 +50,10 @@ private: ...@@ -50,11 +50,10 @@ private:
50 const SourceManager &SM, 50 const SourceManager &SM,
51 const LangOptions &LangOpts); 51 const LangOptions &LangOpts);
52 SourceRange findReturnTypeAndCVSourceRange(const FunctionDecl &F, 52 SourceRange findReturnTypeAndCVSourceRange(const FunctionDecl &F,
53 - const TypeLoc &ReturnLoc,
54 const ASTContext &Ctx, 53 const ASTContext &Ctx,
55 const SourceManager &SM, 54 const SourceManager &SM,
56 const LangOptions &LangOpts); 55 const LangOptions &LangOpts);
57 - void keepSpecifiers(std::string &ReturnType, std::string &Auto, 56 + bool keepSpecifiers(std::string &ReturnType, std::string &Auto,
58 SourceRange ReturnTypeCVRange, const FunctionDecl &F, 57 SourceRange ReturnTypeCVRange, const FunctionDecl &F,
59 const FriendDecl *Fr, const ASTContext &Ctx, 58 const FriendDecl *Fr, const ASTContext &Ctx,
60 const SourceManager &SM, const LangOptions &LangOpts); 59 const SourceManager &SM, const LangOptions &LangOpts);
......
...@@ -23,8 +23,8 @@ namespace performance { ...@@ -23,8 +23,8 @@ namespace performance {
23 MoveConstructorInitCheck::MoveConstructorInitCheck(StringRef Name, 23 MoveConstructorInitCheck::MoveConstructorInitCheck(StringRef Name,
24 ClangTidyContext *Context) 24 ClangTidyContext *Context)
25 : ClangTidyCheck(Name, Context), 25 : ClangTidyCheck(Name, Context),
26 - Inserter(Options.getLocalOrGlobal("IncludeStyle", 26 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
27 - utils::IncludeSorter::IS_LLVM)) {} 27 + utils::IncludeSorter::IS_LLVM)) {}
28 28
29 void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) { 29 void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) {
30 Finder->addMatcher( 30 Finder->addMatcher(
...@@ -90,11 +90,13 @@ void MoveConstructorInitCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -90,11 +90,13 @@ void MoveConstructorInitCheck::check(const MatchFinder::MatchResult &Result) {
90 90
91 void MoveConstructorInitCheck::registerPPCallbacks( 91 void MoveConstructorInitCheck::registerPPCallbacks(
92 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { 92 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
93 - Inserter.registerPreprocessor(PP); 93 + Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
94 + IncludeStyle);
95 + PP->addPPCallbacks(Inserter->CreatePPCallbacks());
94 } 96 }
95 97
96 void MoveConstructorInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { 98 void MoveConstructorInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
97 - Options.store(Opts, "IncludeStyle", Inserter.getStyle()); 99 + Options.store(Opts, "IncludeStyle", IncludeStyle);
98 } 100 }
99 101
100 } // namespace performance 102 } // namespace performance
......
...@@ -36,7 +36,8 @@ public: ...@@ -36,7 +36,8 @@ public:
36 void storeOptions(ClangTidyOptions::OptionMap &Opts) override; 36 void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
37 37
38 private: 38 private:
39 - utils::IncludeInserter Inserter; 39 + std::unique_ptr<utils::IncludeInserter> Inserter;
40 + const utils::IncludeSorter::IncludeStyle IncludeStyle;
40 }; 41 };
41 42
42 } // namespace performance 43 } // namespace performance
......
...@@ -31,18 +31,19 @@ AST_MATCHER_P(Type, isBuiltinType, BuiltinType::Kind, Kind) { ...@@ -31,18 +31,19 @@ AST_MATCHER_P(Type, isBuiltinType, BuiltinType::Kind, Kind) {
31 TypePromotionInMathFnCheck::TypePromotionInMathFnCheck( 31 TypePromotionInMathFnCheck::TypePromotionInMathFnCheck(
32 StringRef Name, ClangTidyContext *Context) 32 StringRef Name, ClangTidyContext *Context)
33 : ClangTidyCheck(Name, Context), 33 : ClangTidyCheck(Name, Context),
34 - IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", 34 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
35 - utils::IncludeSorter::IS_LLVM)) { 35 + utils::IncludeSorter::IS_LLVM)) {}
36 -}
37 36
38 void TypePromotionInMathFnCheck::registerPPCallbacks( 37 void TypePromotionInMathFnCheck::registerPPCallbacks(
39 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { 38 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
40 - IncludeInserter.registerPreprocessor(PP); 39 + IncludeInserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
40 + IncludeStyle);
41 + PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
41 } 42 }
42 43
43 void TypePromotionInMathFnCheck::storeOptions( 44 void TypePromotionInMathFnCheck::storeOptions(
44 ClangTidyOptions::OptionMap &Opts) { 45 ClangTidyOptions::OptionMap &Opts) {
45 - Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); 46 + Options.store(Opts, "IncludeStyle", IncludeStyle);
46 } 47 }
47 48
48 void TypePromotionInMathFnCheck::registerMatchers(MatchFinder *Finder) { 49 void TypePromotionInMathFnCheck::registerMatchers(MatchFinder *Finder) {
...@@ -190,9 +191,9 @@ void TypePromotionInMathFnCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -190,9 +191,9 @@ void TypePromotionInMathFnCheck::check(const MatchFinder::MatchResult &Result) {
190 // <math.h>, because the functions we're suggesting moving away from are all 191 // <math.h>, because the functions we're suggesting moving away from are all
191 // declared in <math.h>. 192 // declared in <math.h>.
192 if (FnInCmath) 193 if (FnInCmath)
193 - Diag << IncludeInserter.createIncludeInsertion( 194 + Diag << IncludeInserter->CreateIncludeInsertion(
194 Result.Context->getSourceManager().getFileID(Call->getBeginLoc()), 195 Result.Context->getSourceManager().getFileID(Call->getBeginLoc()),
195 - "<cmath>"); 196 + "cmath", /*IsAngled=*/true);
196 } 197 }
197 198
198 } // namespace performance 199 } // namespace performance
......
...@@ -36,7 +36,8 @@ public: ...@@ -36,7 +36,8 @@ public:
36 void check(const ast_matchers::MatchFinder::MatchResult &Result) override; 36 void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
37 37
38 private: 38 private:
39 - utils::IncludeInserter IncludeInserter; 39 + std::unique_ptr<utils::IncludeInserter> IncludeInserter;
40 + const utils::IncludeSorter::IncludeStyle IncludeStyle;
40 }; 41 };
41 42
42 } // namespace performance 43 } // namespace performance
......
...@@ -54,8 +54,7 @@ void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) { ...@@ -54,8 +54,7 @@ void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) {
54 on(declRefExpr(to(varDecl().bind("objectArg"))))); 54 on(declRefExpr(to(varDecl().bind("objectArg")))));
55 auto ConstRefReturningFunctionCall = 55 auto ConstRefReturningFunctionCall =
56 callExpr(callee(functionDecl(returns(ConstReference))), 56 callExpr(callee(functionDecl(returns(ConstReference))),
57 - unless(callee(cxxMethodDecl()))) 57 + unless(callee(cxxMethodDecl())));
58 - .bind("initFunctionCall");
59 58
60 auto localVarCopiedFrom = [this](const internal::Matcher<Expr> &CopyCtorArg) { 59 auto localVarCopiedFrom = [this](const internal::Matcher<Expr> &CopyCtorArg) {
61 return compoundStmt( 60 return compoundStmt(
...@@ -97,8 +96,6 @@ void UnnecessaryCopyInitialization::check( ...@@ -97,8 +96,6 @@ void UnnecessaryCopyInitialization::check(
97 const auto *ObjectArg = Result.Nodes.getNodeAs<VarDecl>("objectArg"); 96 const auto *ObjectArg = Result.Nodes.getNodeAs<VarDecl>("objectArg");
98 const auto *BlockStmt = Result.Nodes.getNodeAs<Stmt>("blockStmt"); 97 const auto *BlockStmt = Result.Nodes.getNodeAs<Stmt>("blockStmt");
99 const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>("ctorCall"); 98 const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>("ctorCall");
100 - const auto *InitFunctionCall =
101 - Result.Nodes.getNodeAs<CallExpr>("initFunctionCall");
102 99
103 TraversalKindScope RAII(*Result.Context, ast_type_traits::TK_AsIs); 100 TraversalKindScope RAII(*Result.Context, ast_type_traits::TK_AsIs);
104 101
...@@ -116,11 +113,6 @@ void UnnecessaryCopyInitialization::check( ...@@ -116,11 +113,6 @@ void UnnecessaryCopyInitialization::check(
116 return; 113 return;
117 114
118 if (OldVar == nullptr) { 115 if (OldVar == nullptr) {
119 - // Only allow initialization of a const reference from a free function if it
120 - // has no arguments. Otherwise it could return an alias to one of its
121 - // arguments and the arguments need to be checked for const use as well.
122 - if (InitFunctionCall != nullptr && InitFunctionCall->getNumArgs() > 0)
123 - return;
124 handleCopyFromMethodReturn(*NewVar, *BlockStmt, IssueFix, ObjectArg, 116 handleCopyFromMethodReturn(*NewVar, *BlockStmt, IssueFix, ObjectArg,
125 *Result.Context); 117 *Result.Context);
126 } else { 118 } else {
......
...@@ -68,8 +68,8 @@ bool isExplicitTemplateSpecialization(const FunctionDecl &Function) { ...@@ -68,8 +68,8 @@ bool isExplicitTemplateSpecialization(const FunctionDecl &Function) {
68 UnnecessaryValueParamCheck::UnnecessaryValueParamCheck( 68 UnnecessaryValueParamCheck::UnnecessaryValueParamCheck(
69 StringRef Name, ClangTidyContext *Context) 69 StringRef Name, ClangTidyContext *Context)
70 : ClangTidyCheck(Name, Context), 70 : ClangTidyCheck(Name, Context),
71 - Inserter(Options.getLocalOrGlobal("IncludeStyle", 71 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
72 - utils::IncludeSorter::IS_LLVM)), 72 + utils::IncludeSorter::IS_LLVM)),
73 AllowedTypes( 73 AllowedTypes(
74 utils::options::parseStringList(Options.get("AllowedTypes", ""))) {} 74 utils::options::parseStringList(Options.get("AllowedTypes", ""))) {}
75 75
...@@ -173,12 +173,14 @@ void UnnecessaryValueParamCheck::check(const MatchFinder::MatchResult &Result) { ...@@ -173,12 +173,14 @@ void UnnecessaryValueParamCheck::check(const MatchFinder::MatchResult &Result) {
173 173
174 void UnnecessaryValueParamCheck::registerPPCallbacks( 174 void UnnecessaryValueParamCheck::registerPPCallbacks(
175 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { 175 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
176 - Inserter.registerPreprocessor(PP); 176 + Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
177 + IncludeStyle);
178 + PP->addPPCallbacks(Inserter->CreatePPCallbacks());
177 } 179 }
178 180
179 void UnnecessaryValueParamCheck::storeOptions( 181 void UnnecessaryValueParamCheck::storeOptions(
180 ClangTidyOptions::OptionMap &Opts) { 182 ClangTidyOptions::OptionMap &Opts) {
181 - Options.store(Opts, "IncludeStyle", Inserter.getStyle()); 183 + Options.store(Opts, "IncludeStyle", IncludeStyle);
182 Options.store(Opts, "AllowedTypes", 184 Options.store(Opts, "AllowedTypes",
183 utils::options::serializeStringList(AllowedTypes)); 185 utils::options::serializeStringList(AllowedTypes));
184 } 186 }
...@@ -202,8 +204,9 @@ void UnnecessaryValueParamCheck::handleMoveFix(const ParmVarDecl &Var, ...@@ -202,8 +204,9 @@ void UnnecessaryValueParamCheck::handleMoveFix(const ParmVarDecl &Var,
202 Context.getLangOpts()); 204 Context.getLangOpts());
203 Diag << FixItHint::CreateInsertion(CopyArgument.getBeginLoc(), "std::move(") 205 Diag << FixItHint::CreateInsertion(CopyArgument.getBeginLoc(), "std::move(")
204 << FixItHint::CreateInsertion(EndLoc, ")") 206 << FixItHint::CreateInsertion(EndLoc, ")")
205 - << Inserter.createIncludeInsertion( 207 + << Inserter->CreateIncludeInsertion(
206 - SM.getFileID(CopyArgument.getBeginLoc()), "<utility>"); 208 + SM.getFileID(CopyArgument.getBeginLoc()), "utility",
209 + /*IsAngled=*/true);
207 } 210 }
208 211
209 } // namespace performance 212 } // namespace performance
......
...@@ -41,7 +41,8 @@ private: ...@@ -41,7 +41,8 @@ private:
41 41
42 llvm::DenseMap<const FunctionDecl *, FunctionParmMutationAnalyzer> 42 llvm::DenseMap<const FunctionDecl *, FunctionParmMutationAnalyzer>
43 MutationAnalyzers; 43 MutationAnalyzers;
44 - utils::IncludeInserter Inserter; 44 + std::unique_ptr<utils::IncludeInserter> Inserter;
45 + const utils::IncludeSorter::IncludeStyle IncludeStyle;
45 const std::vector<std::string> AllowedTypes; 46 const std::vector<std::string> AllowedTypes;
46 }; 47 };
47 48
......
...@@ -12,7 +12,6 @@ add_clang_library(clangTidyReadabilityModule ...@@ -12,7 +12,6 @@ add_clang_library(clangTidyReadabilityModule
12 DeleteNullPointerCheck.cpp 12 DeleteNullPointerCheck.cpp
13 DeletedDefaultCheck.cpp 13 DeletedDefaultCheck.cpp
14 ElseAfterReturnCheck.cpp 14 ElseAfterReturnCheck.cpp
15 - FunctionCognitiveComplexityCheck.cpp
16 FunctionSizeCheck.cpp 15 FunctionSizeCheck.cpp
17 IdentifierNamingCheck.cpp 16 IdentifierNamingCheck.cpp
18 ImplicitBoolConversionCheck.cpp 17 ImplicitBoolConversionCheck.cpp
......
1 -//===--- FunctionCognitiveComplexityCheck.h - clang-tidy --------*- C++ -*-===//
2 -//
3 -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 -// See https://llvm.org/LICENSE.txt for license information.
5 -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 -//
7 -//===----------------------------------------------------------------------===//
8 -
9 -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_FUNCTIONCOGNITIVECOMPLEXITYCHECK_H
10 -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_FUNCTIONCOGNITIVECOMPLEXITYCHECK_H
11 -
12 -#include "../ClangTidyCheck.h"
13 -
14 -namespace clang {
15 -namespace tidy {
16 -namespace readability {
17 -
18 -/// Checks function Cognitive Complexity metric.
19 -///
20 -/// There is only one configuration option:
21 -///
22 -/// * `Threshold` - flag functions with Cognitive Complexity exceeding
23 -/// this number. The default is `25`.
24 -///
25 -/// For the user-facing documentation see:
26 -/// http://clang.llvm.org/extra/clang-tidy/checks/readability-function-cognitive-complexity.html
27 -class FunctionCognitiveComplexityCheck : public ClangTidyCheck {
28 -public:
29 - FunctionCognitiveComplexityCheck(StringRef Name, ClangTidyContext *Context);
30 -
31 - void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
32 - void registerMatchers(ast_matchers::MatchFinder *Finder) override;
33 - void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
34 -
35 -private:
36 - const unsigned Threshold;
37 -};
38 -
39 -} // namespace readability
40 -} // namespace tidy
41 -} // namespace clang
42 -
43 -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_FUNCTIONCOGNITIVECOMPLEXITYCHECK_H
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
11 11
12 #include "../utils/RenamerClangTidyCheck.h" 12 #include "../utils/RenamerClangTidyCheck.h"
13 -#include "llvm/ADT/Optional.h"
14 namespace clang { 13 namespace clang {
15 14
16 class MacroInfo; 15 class MacroInfo;
...@@ -70,17 +69,7 @@ private: ...@@ -70,17 +69,7 @@ private:
70 DiagInfo GetDiagInfo(const NamingCheckId &ID, 69 DiagInfo GetDiagInfo(const NamingCheckId &ID,
71 const NamingCheckFailure &Failure) const override; 70 const NamingCheckFailure &Failure) const override;
72 71
73 - ArrayRef<llvm::Optional<NamingStyle>> 72 + std::vector<llvm::Optional<NamingStyle>> NamingStyles;
74 - getStyleForFile(StringRef FileName) const;
75 -
76 - /// Stores the style options as a vector, indexed by the specified \ref
77 - /// StyleKind, for a given directory.
78 - mutable llvm::StringMap<std::vector<llvm::Optional<NamingStyle>>>
79 - NamingStylesCache;
80 - ArrayRef<llvm::Optional<NamingStyle>> MainFileStyle;
81 - ClangTidyContext *const Context;
82 - const std::string CheckName;
83 - const bool GetConfigPerFile;
84 const bool IgnoreFailedSplit; 73 const bool IgnoreFailedSplit;
85 const bool IgnoreMainLikeFunctions; 74 const bool IgnoreMainLikeFunctions;
86 }; 75 };
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
17 #include "DeleteNullPointerCheck.h" 17 #include "DeleteNullPointerCheck.h"
18 #include "DeletedDefaultCheck.h" 18 #include "DeletedDefaultCheck.h"
19 #include "ElseAfterReturnCheck.h" 19 #include "ElseAfterReturnCheck.h"
20 -#include "FunctionCognitiveComplexityCheck.h"
21 #include "FunctionSizeCheck.h" 20 #include "FunctionSizeCheck.h"
22 #include "IdentifierNamingCheck.h" 21 #include "IdentifierNamingCheck.h"
23 #include "ImplicitBoolConversionCheck.h" 22 #include "ImplicitBoolConversionCheck.h"
...@@ -71,8 +70,6 @@ public: ...@@ -71,8 +70,6 @@ public:
71 "readability-deleted-default"); 70 "readability-deleted-default");
72 CheckFactories.registerCheck<ElseAfterReturnCheck>( 71 CheckFactories.registerCheck<ElseAfterReturnCheck>(
73 "readability-else-after-return"); 72 "readability-else-after-return");
74 - CheckFactories.registerCheck<FunctionCognitiveComplexityCheck>(
75 - "readability-function-cognitive-complexity");
76 CheckFactories.registerCheck<FunctionSizeCheck>( 73 CheckFactories.registerCheck<FunctionSizeCheck>(
77 "readability-function-size"); 74 "readability-function-size");
78 CheckFactories.registerCheck<IdentifierNamingCheck>( 75 CheckFactories.registerCheck<IdentifierNamingCheck>(
......
...@@ -58,28 +58,16 @@ const char SimplifyConditionDiagnostic[] = ...@@ -58,28 +58,16 @@ const char SimplifyConditionDiagnostic[] =
58 const char SimplifyConditionalReturnDiagnostic[] = 58 const char SimplifyConditionalReturnDiagnostic[] =
59 "redundant boolean literal in conditional return statement"; 59 "redundant boolean literal in conditional return statement";
60 60
61 -const Expr *getBoolLiteral(const MatchFinder::MatchResult &Result, 61 +const CXXBoolLiteralExpr *getBoolLiteral(const MatchFinder::MatchResult &Result,
62 - StringRef Id) { 62 + StringRef Id) {
63 - if (const Expr *Literal = Result.Nodes.getNodeAs<CXXBoolLiteralExpr>(Id)) 63 + const auto *Literal = Result.Nodes.getNodeAs<CXXBoolLiteralExpr>(Id);
64 - return Literal->getBeginLoc().isMacroID() ? nullptr : Literal; 64 + return (Literal && Literal->getBeginLoc().isMacroID()) ? nullptr : Literal;
65 - if (const auto *Negated = Result.Nodes.getNodeAs<UnaryOperator>(Id)) {
66 - if (Negated->getOpcode() == UO_LNot &&
67 - isa<CXXBoolLiteralExpr>(Negated->getSubExpr()))
68 - return Negated->getBeginLoc().isMacroID() ? nullptr : Negated;
69 - }
70 - return nullptr;
71 -}
72 -
73 -internal::BindableMatcher<Stmt> literalOrNegatedBool(bool Value) {
74 - return expr(anyOf(cxxBoolLiteral(equals(Value)),
75 - unaryOperator(hasUnaryOperand(ignoringParenImpCasts(
76 - cxxBoolLiteral(equals(!Value)))),
77 - hasOperatorName("!"))));
78 } 65 }
79 66
80 internal::Matcher<Stmt> returnsBool(bool Value, StringRef Id = "ignored") { 67 internal::Matcher<Stmt> returnsBool(bool Value, StringRef Id = "ignored") {
81 - auto SimpleReturnsBool = returnStmt(has(literalOrNegatedBool(Value).bind(Id))) 68 + auto SimpleReturnsBool =
82 - .bind("returns-bool"); 69 + returnStmt(has(cxxBoolLiteral(equals(Value)).bind(Id)))
70 + .bind("returns-bool");
83 return anyOf(SimpleReturnsBool, 71 return anyOf(SimpleReturnsBool,
84 compoundStmt(statementCountIs(1), has(SimpleReturnsBool))); 72 compoundStmt(statementCountIs(1), has(SimpleReturnsBool)));
85 } 73 }
...@@ -205,7 +193,7 @@ std::string compareExpressionToZero(const MatchFinder::MatchResult &Result, ...@@ -205,7 +193,7 @@ std::string compareExpressionToZero(const MatchFinder::MatchResult &Result,
205 193
206 std::string replacementExpression(const MatchFinder::MatchResult &Result, 194 std::string replacementExpression(const MatchFinder::MatchResult &Result,
207 bool Negated, const Expr *E) { 195 bool Negated, const Expr *E) {
208 - E = E->IgnoreParenBaseCasts(); 196 + E = E->ignoreParenBaseCasts();
209 if (const auto *EC = dyn_cast<ExprWithCleanups>(E)) 197 if (const auto *EC = dyn_cast<ExprWithCleanups>(E))
210 E = EC->getSubExpr(); 198 E = EC->getSubExpr();
211 199
...@@ -281,25 +269,16 @@ std::string replacementExpression(const MatchFinder::MatchResult &Result, ...@@ -281,25 +269,16 @@ std::string replacementExpression(const MatchFinder::MatchResult &Result,
281 return asBool(getText(Result, *E), NeedsStaticCast); 269 return asBool(getText(Result, *E), NeedsStaticCast);
282 } 270 }
283 271
284 -const Expr *stmtReturnsBool(const ReturnStmt *Ret, bool Negated) { 272 +const CXXBoolLiteralExpr *stmtReturnsBool(const ReturnStmt *Ret, bool Negated) {
285 if (const auto *Bool = dyn_cast<CXXBoolLiteralExpr>(Ret->getRetValue())) { 273 if (const auto *Bool = dyn_cast<CXXBoolLiteralExpr>(Ret->getRetValue())) {
286 if (Bool->getValue() == !Negated) 274 if (Bool->getValue() == !Negated)
287 return Bool; 275 return Bool;
288 } 276 }
289 - if (const auto *Unary = dyn_cast<UnaryOperator>(Ret->getRetValue())) {
290 - if (Unary->getOpcode() == UO_LNot) {
291 - if (const auto *Bool =
292 - dyn_cast<CXXBoolLiteralExpr>(Unary->getSubExpr())) {
293 - if (Bool->getValue() == Negated)
294 - return Bool;
295 - }
296 - }
297 - }
298 277
299 return nullptr; 278 return nullptr;
300 } 279 }
301 280
302 -const Expr *stmtReturnsBool(const IfStmt *IfRet, bool Negated) { 281 +const CXXBoolLiteralExpr *stmtReturnsBool(const IfStmt *IfRet, bool Negated) {
303 if (IfRet->getElse() != nullptr) 282 if (IfRet->getElse() != nullptr)
304 return nullptr; 283 return nullptr;
305 284
...@@ -444,7 +423,7 @@ void SimplifyBooleanExprCheck::matchBoolCondition(MatchFinder *Finder, ...@@ -444,7 +423,7 @@ void SimplifyBooleanExprCheck::matchBoolCondition(MatchFinder *Finder,
444 StringRef BooleanId) { 423 StringRef BooleanId) {
445 Finder->addMatcher( 424 Finder->addMatcher(
446 ifStmt(unless(isInTemplateInstantiation()), 425 ifStmt(unless(isInTemplateInstantiation()),
447 - hasCondition(literalOrNegatedBool(Value).bind(BooleanId))) 426 + hasCondition(cxxBoolLiteral(equals(Value)).bind(BooleanId)))
448 .bind(IfStmtId), 427 .bind(IfStmtId),
449 this); 428 this);
450 } 429 }
...@@ -454,8 +433,8 @@ void SimplifyBooleanExprCheck::matchTernaryResult(MatchFinder *Finder, ...@@ -454,8 +433,8 @@ void SimplifyBooleanExprCheck::matchTernaryResult(MatchFinder *Finder,
454 StringRef TernaryId) { 433 StringRef TernaryId) {
455 Finder->addMatcher( 434 Finder->addMatcher(
456 conditionalOperator(unless(isInTemplateInstantiation()), 435 conditionalOperator(unless(isInTemplateInstantiation()),
457 - hasTrueExpression(literalOrNegatedBool(Value)), 436 + hasTrueExpression(cxxBoolLiteral(equals(Value))),
458 - hasFalseExpression(literalOrNegatedBool(!Value))) 437 + hasFalseExpression(cxxBoolLiteral(equals(!Value))))
459 .bind(TernaryId), 438 .bind(TernaryId),
460 this); 439 this);
461 } 440 }
...@@ -486,12 +465,12 @@ void SimplifyBooleanExprCheck::matchIfAssignsBool(MatchFinder *Finder, ...@@ -486,12 +465,12 @@ void SimplifyBooleanExprCheck::matchIfAssignsBool(MatchFinder *Finder,
486 auto SimpleThen = 465 auto SimpleThen =
487 binaryOperator(hasOperatorName("="), hasLHS(anyOf(VarAssign, MemAssign)), 466 binaryOperator(hasOperatorName("="), hasLHS(anyOf(VarAssign, MemAssign)),
488 hasLHS(expr().bind(IfAssignVariableId)), 467 hasLHS(expr().bind(IfAssignVariableId)),
489 - hasRHS(literalOrNegatedBool(Value).bind(IfAssignLocId))); 468 + hasRHS(cxxBoolLiteral(equals(Value)).bind(IfAssignLocId)));
490 auto Then = anyOf(SimpleThen, compoundStmt(statementCountIs(1), 469 auto Then = anyOf(SimpleThen, compoundStmt(statementCountIs(1),
491 hasAnySubstatement(SimpleThen))); 470 hasAnySubstatement(SimpleThen)));
492 auto SimpleElse = 471 auto SimpleElse =
493 binaryOperator(hasOperatorName("="), hasLHS(anyOf(VarRef, MemRef)), 472 binaryOperator(hasOperatorName("="), hasLHS(anyOf(VarRef, MemRef)),
494 - hasRHS(literalOrNegatedBool(!Value))); 473 + hasRHS(cxxBoolLiteral(equals(!Value))));
495 auto Else = anyOf(SimpleElse, compoundStmt(statementCountIs(1), 474 auto Else = anyOf(SimpleElse, compoundStmt(statementCountIs(1),
496 hasAnySubstatement(SimpleElse))); 475 hasAnySubstatement(SimpleElse)));
497 if (ChainedConditionalAssignment) 476 if (ChainedConditionalAssignment)
...@@ -516,7 +495,7 @@ void SimplifyBooleanExprCheck::matchCompoundIfReturnsBool(MatchFinder *Finder, ...@@ -516,7 +495,7 @@ void SimplifyBooleanExprCheck::matchCompoundIfReturnsBool(MatchFinder *Finder,
516 hasAnySubstatement( 495 hasAnySubstatement(
517 ifStmt(hasThen(returnsBool(Value)), unless(hasElse(stmt())))), 496 ifStmt(hasThen(returnsBool(Value)), unless(hasElse(stmt())))),
518 hasAnySubstatement(returnStmt(has(ignoringParenImpCasts( 497 hasAnySubstatement(returnStmt(has(ignoringParenImpCasts(
519 - literalOrNegatedBool(!Value)))) 498 + cxxBoolLiteral(equals(!Value)))))
520 .bind(CompoundReturnId))) 499 .bind(CompoundReturnId)))
521 .bind(Id), 500 .bind(Id),
522 this); 501 this);
...@@ -550,10 +529,10 @@ void SimplifyBooleanExprCheck::registerMatchers(MatchFinder *Finder) { ...@@ -550,10 +529,10 @@ void SimplifyBooleanExprCheck::registerMatchers(MatchFinder *Finder) {
550 void SimplifyBooleanExprCheck::check(const MatchFinder::MatchResult &Result) { 529 void SimplifyBooleanExprCheck::check(const MatchFinder::MatchResult &Result) {
551 if (Result.Nodes.getNodeAs<TranslationUnitDecl>("top")) 530 if (Result.Nodes.getNodeAs<TranslationUnitDecl>("top"))
552 Visitor(this, Result).TraverseAST(*Result.Context); 531 Visitor(this, Result).TraverseAST(*Result.Context);
553 - else if (const Expr *TrueConditionRemoved = 532 + else if (const CXXBoolLiteralExpr *TrueConditionRemoved =
554 getBoolLiteral(Result, ConditionThenStmtId)) 533 getBoolLiteral(Result, ConditionThenStmtId))
555 replaceWithThenStatement(Result, TrueConditionRemoved); 534 replaceWithThenStatement(Result, TrueConditionRemoved);
556 - else if (const Expr *FalseConditionRemoved = 535 + else if (const CXXBoolLiteralExpr *FalseConditionRemoved =
557 getBoolLiteral(Result, ConditionElseStmtId)) 536 getBoolLiteral(Result, ConditionElseStmtId))
558 replaceWithElseStatement(Result, FalseConditionRemoved); 537 replaceWithElseStatement(Result, FalseConditionRemoved);
559 else if (const auto *Ternary = 538 else if (const auto *Ternary =
...@@ -595,7 +574,8 @@ void SimplifyBooleanExprCheck::issueDiag( ...@@ -595,7 +574,8 @@ void SimplifyBooleanExprCheck::issueDiag(
595 } 574 }
596 575
597 void SimplifyBooleanExprCheck::replaceWithThenStatement( 576 void SimplifyBooleanExprCheck::replaceWithThenStatement(
598 - const MatchFinder::MatchResult &Result, const Expr *TrueConditionRemoved) { 577 + const MatchFinder::MatchResult &Result,
578 + const CXXBoolLiteralExpr *TrueConditionRemoved) {
599 const auto *IfStatement = Result.Nodes.getNodeAs<IfStmt>(IfStmtId); 579 const auto *IfStatement = Result.Nodes.getNodeAs<IfStmt>(IfStmtId);
600 issueDiag(Result, TrueConditionRemoved->getBeginLoc(), 580 issueDiag(Result, TrueConditionRemoved->getBeginLoc(),
601 SimplifyConditionDiagnostic, IfStatement->getSourceRange(), 581 SimplifyConditionDiagnostic, IfStatement->getSourceRange(),
...@@ -603,7 +583,8 @@ void SimplifyBooleanExprCheck::replaceWithThenStatement( ...@@ -603,7 +583,8 @@ void SimplifyBooleanExprCheck::replaceWithThenStatement(
603 } 583 }
604 584
605 void SimplifyBooleanExprCheck::replaceWithElseStatement( 585 void SimplifyBooleanExprCheck::replaceWithElseStatement(
606 - const MatchFinder::MatchResult &Result, const Expr *FalseConditionRemoved) { 586 + const MatchFinder::MatchResult &Result,
587 + const CXXBoolLiteralExpr *FalseConditionRemoved) {
607 const auto *IfStatement = Result.Nodes.getNodeAs<IfStmt>(IfStmtId); 588 const auto *IfStatement = Result.Nodes.getNodeAs<IfStmt>(IfStmtId);
608 const Stmt *ElseStatement = IfStatement->getElse(); 589 const Stmt *ElseStatement = IfStatement->getElse();
609 issueDiag(Result, FalseConditionRemoved->getBeginLoc(), 590 issueDiag(Result, FalseConditionRemoved->getBeginLoc(),
...@@ -650,7 +631,7 @@ void SimplifyBooleanExprCheck::replaceCompoundReturnWithCondition( ...@@ -650,7 +631,7 @@ void SimplifyBooleanExprCheck::replaceCompoundReturnWithCondition(
650 for (++After; After != Compound->body_end() && *Current != Ret; 631 for (++After; After != Compound->body_end() && *Current != Ret;
651 ++Current, ++After) { 632 ++Current, ++After) {
652 if (const auto *If = dyn_cast<IfStmt>(*Current)) { 633 if (const auto *If = dyn_cast<IfStmt>(*Current)) {
653 - if (const Expr *Lit = stmtReturnsBool(If, Negated)) { 634 + if (const CXXBoolLiteralExpr *Lit = stmtReturnsBool(If, Negated)) {
654 if (*After == Ret) { 635 if (*After == Ret) {
655 if (!ChainedConditionalReturn && BeforeIf) 636 if (!ChainedConditionalReturn && BeforeIf)
656 continue; 637 continue;
......
...@@ -51,11 +51,11 @@ private: ...@@ -51,11 +51,11 @@ private:
51 51
52 void 52 void
53 replaceWithThenStatement(const ast_matchers::MatchFinder::MatchResult &Result, 53 replaceWithThenStatement(const ast_matchers::MatchFinder::MatchResult &Result,
54 - const Expr *BoolLiteral); 54 + const CXXBoolLiteralExpr *BoolLiteral);
55 55
56 void 56 void
57 replaceWithElseStatement(const ast_matchers::MatchFinder::MatchResult &Result, 57 replaceWithElseStatement(const ast_matchers::MatchFinder::MatchResult &Result,
58 - const Expr *FalseConditionRemoved); 58 + const CXXBoolLiteralExpr *FalseConditionRemoved);
59 59
60 void 60 void
61 replaceWithCondition(const ast_matchers::MatchFinder::MatchResult &Result, 61 replaceWithCondition(const ast_matchers::MatchFinder::MatchResult &Result,
......
...@@ -123,7 +123,12 @@ public: ...@@ -123,7 +123,12 @@ public:
123 123
124 // Emit warnings for headers that are missing guards. 124 // Emit warnings for headers that are missing guards.
125 checkGuardlessHeaders(); 125 checkGuardlessHeaders();
126 - clearAllState(); 126 +
127 + // Clear all state.
128 + Macros.clear();
129 + Files.clear();
130 + Ifndefs.clear();
131 + EndIfs.clear();
127 } 132 }
128 133
129 bool wouldFixEndifComment(StringRef FileName, SourceLocation EndIf, 134 bool wouldFixEndifComment(StringRef FileName, SourceLocation EndIf,
...@@ -250,13 +255,6 @@ public: ...@@ -250,13 +255,6 @@ public:
250 } 255 }
251 256
252 private: 257 private:
253 - void clearAllState() {
254 - Macros.clear();
255 - Files.clear();
256 - Ifndefs.clear();
257 - EndIfs.clear();
258 - }
259 -
260 std::vector<std::pair<Token, const MacroInfo *>> Macros; 258 std::vector<std::pair<Token, const MacroInfo *>> Macros;
261 llvm::StringMap<const FileEntry *> Files; 259 llvm::StringMap<const FileEntry *> Files;
262 std::map<const IdentifierInfo *, std::pair<SourceLocation, SourceLocation>> 260 std::map<const IdentifierInfo *, std::pair<SourceLocation, SourceLocation>>
......
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
7 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
8 8
9 #include "IncludeInserter.h" 9 #include "IncludeInserter.h"
10 -#include "clang/Lex/PPCallbacks.h"
11 -#include "clang/Lex/Preprocessor.h"
12 #include "clang/Lex/Token.h" 10 #include "clang/Lex/Token.h"
13 11
14 namespace clang { 12 namespace clang {
...@@ -28,7 +26,7 @@ public: ...@@ -28,7 +26,7 @@ public:
28 StringRef /*SearchPath*/, StringRef /*RelativePath*/, 26 StringRef /*SearchPath*/, StringRef /*RelativePath*/,
29 const Module * /*ImportedModule*/, 27 const Module * /*ImportedModule*/,
30 SrcMgr::CharacteristicKind /*FileType*/) override { 28 SrcMgr::CharacteristicKind /*FileType*/) override {
31 - Inserter->addInclude(FileNameRef, IsAngled, HashLocation, 29 + Inserter->AddInclude(FileNameRef, IsAngled, HashLocation,
32 IncludeToken.getEndLoc()); 30 IncludeToken.getEndLoc());
33 } 31 }
34 32
...@@ -36,76 +34,45 @@ private: ...@@ -36,76 +34,45 @@ private:
36 IncludeInserter *Inserter; 34 IncludeInserter *Inserter;
37 }; 35 };
38 36
39 -IncludeInserter::IncludeInserter(IncludeSorter::IncludeStyle Style) 37 +IncludeInserter::IncludeInserter(const SourceManager &SourceMgr,
40 - : Style(Style) {} 38 + const LangOptions &LangOpts,
39 + IncludeSorter::IncludeStyle Style)
40 + : SourceMgr(SourceMgr), Style(Style) {}
41 41
42 -void IncludeInserter::registerPreprocessor(Preprocessor *PP) { 42 +IncludeInserter::~IncludeInserter() {}
43 - assert(PP && "PP shouldn't be null");
44 - SourceMgr = &PP->getSourceManager();
45 43
46 - // If this gets registered multiple times, clear the maps 44 +std::unique_ptr<PPCallbacks> IncludeInserter::CreatePPCallbacks() {
47 - if (!IncludeSorterByFile.empty()) 45 + return std::make_unique<IncludeInserterCallback>(this);
48 - IncludeSorterByFile.clear();
49 - if (!InsertedHeaders.empty())
50 - InsertedHeaders.clear();
51 - PP->addPPCallbacks(std::make_unique<IncludeInserterCallback>(this));
52 } 46 }
53 47
54 IncludeSorter &IncludeInserter::getOrCreate(FileID FileID) { 48 IncludeSorter &IncludeInserter::getOrCreate(FileID FileID) {
55 - assert(SourceMgr && "SourceMgr shouldn't be null; did you remember to call "
56 - "registerPreprocessor()?");
57 // std::unique_ptr is cheap to construct, so force a construction now to save 49 // std::unique_ptr is cheap to construct, so force a construction now to save
58 // the lookup needed if we were to insert into the map. 50 // the lookup needed if we were to insert into the map.
59 std::unique_ptr<IncludeSorter> &Entry = IncludeSorterByFile[FileID]; 51 std::unique_ptr<IncludeSorter> &Entry = IncludeSorterByFile[FileID];
60 if (!Entry) { 52 if (!Entry) {
61 // If it wasn't found, Entry will be default constructed to nullptr. 53 // If it wasn't found, Entry will be default constructed to nullptr.
62 Entry = std::make_unique<IncludeSorter>( 54 Entry = std::make_unique<IncludeSorter>(
63 - SourceMgr, FileID, 55 + &SourceMgr, FileID,
64 - SourceMgr->getFilename(SourceMgr->getLocForStartOfFile(FileID)), Style); 56 + SourceMgr.getFilename(SourceMgr.getLocForStartOfFile(FileID)), Style);
65 } 57 }
66 return *Entry; 58 return *Entry;
67 } 59 }
68 60
69 llvm::Optional<FixItHint> 61 llvm::Optional<FixItHint>
70 -IncludeInserter::createIncludeInsertion(FileID FileID, StringRef Header, 62 +IncludeInserter::CreateIncludeInsertion(FileID FileID, StringRef Header,
71 bool IsAngled) { 63 bool IsAngled) {
72 // We assume the same Header will never be included both angled and not 64 // We assume the same Header will never be included both angled and not
73 // angled. 65 // angled.
74 - if (!InsertedHeaders[FileID].insert(Header).second) 66 + if (!InsertedHeaders[FileID].insert(std::string(Header)).second)
75 return llvm::None; 67 return llvm::None;
76 68
77 return getOrCreate(FileID).CreateIncludeInsertion(Header, IsAngled); 69 return getOrCreate(FileID).CreateIncludeInsertion(Header, IsAngled);
78 } 70 }
79 71
80 -llvm::Optional<FixItHint> 72 +void IncludeInserter::AddInclude(StringRef FileName, bool IsAngled,
81 -IncludeInserter::createIncludeInsertion(FileID FileID, llvm::StringRef Header) {
82 - bool IsAngled = Header.consume_front("<");
83 - if (IsAngled != Header.consume_back(">"))
84 - return llvm::None;
85 - return createIncludeInsertion(FileID, Header, IsAngled);
86 -}
87 -
88 -llvm::Optional<FixItHint>
89 -IncludeInserter::createMainFileIncludeInsertion(StringRef Header,
90 - bool IsAngled) {
91 - assert(SourceMgr && "SourceMgr shouldn't be null; did you remember to call "
92 - "registerPreprocessor()?");
93 - return createIncludeInsertion(SourceMgr->getMainFileID(), Header, IsAngled);
94 -}
95 -
96 -llvm::Optional<FixItHint>
97 -IncludeInserter::createMainFileIncludeInsertion(StringRef Header) {
98 - assert(SourceMgr && "SourceMgr shouldn't be null; did you remember to call "
99 - "registerPreprocessor()?");
100 - return createIncludeInsertion(SourceMgr->getMainFileID(), Header);
101 -}
102 -
103 -void IncludeInserter::addInclude(StringRef FileName, bool IsAngled,
104 SourceLocation HashLocation, 73 SourceLocation HashLocation,
105 SourceLocation EndLocation) { 74 SourceLocation EndLocation) {
106 - assert(SourceMgr && "SourceMgr shouldn't be null; did you remember to call " 75 + FileID FileID = SourceMgr.getFileID(HashLocation);
107 - "registerPreprocessor()?");
108 - FileID FileID = SourceMgr->getFileID(HashLocation);
109 getOrCreate(FileID).AddInclude(FileName, IsAngled, HashLocation, EndLocation); 76 getOrCreate(FileID).AddInclude(FileName, IsAngled, HashLocation, EndLocation);
110 } 77 }
111 78
......
...@@ -11,11 +11,13 @@ ...@@ -11,11 +11,13 @@
11 11
12 #include "IncludeSorter.h" 12 #include "IncludeSorter.h"
13 #include "clang/Basic/Diagnostic.h" 13 #include "clang/Basic/Diagnostic.h"
14 -#include "llvm/ADT/StringSet.h" 14 +#include "clang/Basic/LangOptions.h"
15 +#include "clang/Basic/SourceManager.h"
16 +#include "clang/Lex/PPCallbacks.h"
15 #include <memory> 17 #include <memory>
18 +#include <string>
16 19
17 namespace clang { 20 namespace clang {
18 -class Preprocessor;
19 namespace tidy { 21 namespace tidy {
20 namespace utils { 22 namespace utils {
21 23
...@@ -24,17 +26,16 @@ namespace utils { ...@@ -24,17 +26,16 @@ namespace utils {
24 /// 26 ///
25 /// ``IncludeInserter`` can be used in clang-tidy checks in the following way: 27 /// ``IncludeInserter`` can be used in clang-tidy checks in the following way:
26 /// \code 28 /// \code
27 -/// #include "../ClangTidyCheck.h"
28 /// #include "../utils/IncludeInserter.h" 29 /// #include "../utils/IncludeInserter.h"
29 -/// 30 +/// #include "clang/Frontend/CompilerInstance.h"
30 -/// namespace clang {
31 -/// namespace tidy {
32 /// 31 ///
33 /// class MyCheck : public ClangTidyCheck { 32 /// class MyCheck : public ClangTidyCheck {
34 /// public: 33 /// public:
35 /// void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, 34 /// void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
36 /// Preprocessor *ModuleExpanderPP) override { 35 /// Preprocessor *ModuleExpanderPP) override {
37 -/// Inserter.registerPreprocessor(); 36 +/// Inserter = std::make_unique<IncludeInserter>(
37 +/// SM, getLangOpts(), utils::IncludeSorter::IS_Google);
38 +/// PP->addPPCallbacks(Inserter->CreatePPCallbacks());
38 /// } 39 /// }
39 /// 40 ///
40 /// void registerMatchers(ast_matchers::MatchFinder* Finder) override { ... } 41 /// void registerMatchers(ast_matchers::MatchFinder* Finder) override { ... }
...@@ -42,73 +43,39 @@ namespace utils { ...@@ -42,73 +43,39 @@ namespace utils {
42 /// void check( 43 /// void check(
43 /// const ast_matchers::MatchFinder::MatchResult& Result) override { 44 /// const ast_matchers::MatchFinder::MatchResult& Result) override {
44 /// ... 45 /// ...
45 -/// Inserter.createMainFileIncludeInsertion("path/to/Header.h", 46 +/// Inserter->CreateIncludeInsertion(
46 -/// /*IsAngled=*/false); 47 +/// Result.SourceManager->getMainFileID(), "path/to/Header.h",
48 +/// /*IsAngled=*/false);
47 /// ... 49 /// ...
48 /// } 50 /// }
49 /// 51 ///
50 /// private: 52 /// private:
51 -/// utils::IncludeInserter Inserter{utils::IncludeSorter::IS_Google}; 53 +/// std::unique_ptr<clang::tidy::utils::IncludeInserter> Inserter;
52 /// }; 54 /// };
53 -/// } // namespace tidy
54 -/// } // namespace clang
55 /// \endcode 55 /// \endcode
56 class IncludeInserter { 56 class IncludeInserter {
57 public: 57 public:
58 - /// Initializes the IncludeInserter using the IncludeStyle \p Style. 58 + IncludeInserter(const SourceManager &SourceMgr, const LangOptions &LangOpts,
59 - /// In most cases the \p Style will be retrieved from the ClangTidyOptions 59 + IncludeSorter::IncludeStyle Style);
60 - /// using \code 60 + ~IncludeInserter();
61 - /// Options.getLocalOrGlobal("IncludeStyle", <DefaultStyle>)
62 - /// \endcode
63 - explicit IncludeInserter(IncludeSorter::IncludeStyle Style);
64 -
65 - /// Registers this with the Preprocessor \p PP, must be called before this
66 - /// class is used.
67 - void registerPreprocessor(Preprocessor *PP);
68 -
69 - /// Creates a \p Header inclusion directive fixit in the File \p FileID.
70 - /// Returns ``llvm::None`` on error or if the inclusion directive already
71 - /// exists.
72 - /// FIXME: This should be removed once the clients are migrated to the
73 - /// overload without the ``IsAngled`` parameter.
74 - llvm::Optional<FixItHint>
75 - createIncludeInsertion(FileID FileID, llvm::StringRef Header, bool IsAngled);
76 61
77 - /// Creates a \p Header inclusion directive fixit in the File \p FileID. 62 + /// Create ``PPCallbacks`` for registration with the compiler's preprocessor.
78 - /// When \p Header is enclosed in angle brackets, uses angle brackets in the 63 + std::unique_ptr<PPCallbacks> CreatePPCallbacks();
79 - /// inclusion directive, otherwise uses quotes.
80 - /// Returns ``llvm::None`` on error or if the inclusion directive already
81 - /// exists.
82 - llvm::Optional<FixItHint> createIncludeInsertion(FileID FileID,
83 - llvm::StringRef Header);
84 64
85 - /// Creates a \p Header inclusion directive fixit in the main file. 65 + /// Creates a \p Header inclusion directive fixit. Returns ``llvm::None`` on
86 - /// Returns``llvm::None`` on error or if the inclusion directive already 66 + /// error or if inclusion directive already exists.
87 - /// exists.
88 - /// FIXME: This should be removed once the clients are migrated to the
89 - /// overload without the ``IsAngled`` parameter.
90 llvm::Optional<FixItHint> 67 llvm::Optional<FixItHint>
91 - createMainFileIncludeInsertion(llvm::StringRef Header, bool IsAngled); 68 + CreateIncludeInsertion(FileID FileID, llvm::StringRef Header, bool IsAngled);
92 -
93 - /// Creates a \p Header inclusion directive fixit in the main file.
94 - /// When \p Header is enclosed in angle brackets, uses angle brackets in the
95 - /// inclusion directive, otherwise uses quotes.
96 - /// Returns``llvm::None`` on error or if the inclusion directive already
97 - /// exists.
98 - llvm::Optional<FixItHint>
99 - createMainFileIncludeInsertion(llvm::StringRef Header);
100 -
101 - IncludeSorter::IncludeStyle getStyle() const { return Style; }
102 69
103 private: 70 private:
104 - void addInclude(StringRef FileName, bool IsAngled, 71 + void AddInclude(StringRef FileName, bool IsAngled,
105 SourceLocation HashLocation, SourceLocation EndLocation); 72 SourceLocation HashLocation, SourceLocation EndLocation);
106 73
107 IncludeSorter &getOrCreate(FileID FileID); 74 IncludeSorter &getOrCreate(FileID FileID);
108 75
109 llvm::DenseMap<FileID, std::unique_ptr<IncludeSorter>> IncludeSorterByFile; 76 llvm::DenseMap<FileID, std::unique_ptr<IncludeSorter>> IncludeSorterByFile;
110 - llvm::DenseMap<FileID, llvm::StringSet<>> InsertedHeaders; 77 + llvm::DenseMap<FileID, std::set<std::string>> InsertedHeaders;
111 - const SourceManager *SourceMgr{nullptr}; 78 + const SourceManager &SourceMgr;
112 const IncludeSorter::IncludeStyle Style; 79 const IncludeSorter::IncludeStyle Style;
113 friend class IncludeInserterCallback; 80 friend class IncludeInserterCallback;
114 }; 81 };
......
...@@ -32,8 +32,8 @@ TransformerClangTidyCheck::TransformerClangTidyCheck( ...@@ -32,8 +32,8 @@ TransformerClangTidyCheck::TransformerClangTidyCheck(
32 MakeRule, 32 MakeRule,
33 StringRef Name, ClangTidyContext *Context) 33 StringRef Name, ClangTidyContext *Context)
34 : ClangTidyCheck(Name, Context), Rule(MakeRule(getLangOpts(), Options)), 34 : ClangTidyCheck(Name, Context), Rule(MakeRule(getLangOpts(), Options)),
35 - Inserter( 35 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
36 - Options.getLocalOrGlobal("IncludeStyle", IncludeSorter::IS_LLVM)) { 36 + IncludeSorter::IS_LLVM)) {
37 if (Rule) 37 if (Rule)
38 assert(llvm::all_of(Rule->Cases, hasExplanation) && 38 assert(llvm::all_of(Rule->Cases, hasExplanation) &&
39 "clang-tidy checks must have an explanation by default;" 39 "clang-tidy checks must have an explanation by default;"
...@@ -44,8 +44,8 @@ TransformerClangTidyCheck::TransformerClangTidyCheck(RewriteRule R, ...@@ -44,8 +44,8 @@ TransformerClangTidyCheck::TransformerClangTidyCheck(RewriteRule R,
44 StringRef Name, 44 StringRef Name,
45 ClangTidyContext *Context) 45 ClangTidyContext *Context)
46 : ClangTidyCheck(Name, Context), Rule(std::move(R)), 46 : ClangTidyCheck(Name, Context), Rule(std::move(R)),
47 - Inserter( 47 + IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
48 - Options.getLocalOrGlobal("IncludeStyle", IncludeSorter::IS_LLVM)) { 48 + IncludeSorter::IS_LLVM)) {
49 assert(llvm::all_of(Rule->Cases, hasExplanation) && 49 assert(llvm::all_of(Rule->Cases, hasExplanation) &&
50 "clang-tidy checks must have an explanation by default;" 50 "clang-tidy checks must have an explanation by default;"
51 " explicitly provide an empty explanation if none is desired"); 51 " explicitly provide an empty explanation if none is desired");
...@@ -53,7 +53,15 @@ TransformerClangTidyCheck::TransformerClangTidyCheck(RewriteRule R, ...@@ -53,7 +53,15 @@ TransformerClangTidyCheck::TransformerClangTidyCheck(RewriteRule R,
53 53
54 void TransformerClangTidyCheck::registerPPCallbacks( 54 void TransformerClangTidyCheck::registerPPCallbacks(
55 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { 55 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
56 - Inserter.registerPreprocessor(PP); 56 + // Only allocate and register the IncludeInsert when some `Case` will add
57 + // includes.
58 + if (Rule && llvm::any_of(Rule->Cases, [](const RewriteRule::Case &C) {
59 + return !C.AddedIncludes.empty();
60 + })) {
61 + Inserter =
62 + std::make_unique<IncludeInserter>(SM, getLangOpts(), IncludeStyle);
63 + PP->addPPCallbacks(Inserter->CreatePPCallbacks());
64 + }
57 } 65 }
58 66
59 void TransformerClangTidyCheck::registerMatchers( 67 void TransformerClangTidyCheck::registerMatchers(
...@@ -91,24 +99,18 @@ void TransformerClangTidyCheck::check( ...@@ -91,24 +99,18 @@ void TransformerClangTidyCheck::check(
91 // Associate the diagnostic with the location of the first change. 99 // Associate the diagnostic with the location of the first change.
92 DiagnosticBuilder Diag = diag((*Edits)[0].Range.getBegin(), *Explanation); 100 DiagnosticBuilder Diag = diag((*Edits)[0].Range.getBegin(), *Explanation);
93 for (const auto &T : *Edits) 101 for (const auto &T : *Edits)
94 - switch (T.Kind) { 102 + Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
95 - case transformer::EditKind::Range: 103 +
96 - Diag << FixItHint::CreateReplacement(T.Range, T.Replacement); 104 + for (const auto &I : Case.AddedIncludes) {
97 - break; 105 + Diag << Inserter->CreateIncludeInsertion(
98 - case transformer::EditKind::AddInclude: { 106 + Result.SourceManager->getMainFileID(), I.first,
99 - StringRef FileName = T.Replacement; 107 + /*IsAngled=*/I.second == transformer::IncludeFormat::Angled);
100 - bool IsAngled = FileName.startswith("<") && FileName.endswith(">"); 108 + }
101 - Diag << Inserter.createMainFileIncludeInsertion(
102 - IsAngled ? FileName.substr(1, FileName.size() - 2) : FileName,
103 - IsAngled);
104 - break;
105 - }
106 - }
107 } 109 }
108 110
109 void TransformerClangTidyCheck::storeOptions( 111 void TransformerClangTidyCheck::storeOptions(
110 ClangTidyOptions::OptionMap &Opts) { 112 ClangTidyOptions::OptionMap &Opts) {
111 - Options.store(Opts, "IncludeStyle", Inserter.getStyle()); 113 + Options.store(Opts, "IncludeStyle", IncludeStyle);
112 } 114 }
113 115
114 } // namespace utils 116 } // namespace utils
......
...@@ -70,7 +70,8 @@ public: ...@@ -70,7 +70,8 @@ public:
70 70
71 private: 71 private:
72 Optional<transformer::RewriteRule> Rule; 72 Optional<transformer::RewriteRule> Rule;
73 - IncludeInserter Inserter; 73 + const IncludeSorter::IncludeStyle IncludeStyle;
74 + std::unique_ptr<IncludeInserter> Inserter;
74 }; 75 };
75 76
76 } // namespace utils 77 } // namespace utils
......
...@@ -15,7 +15,6 @@ if (NOT DEFINED CLANGD_BUILD_XPC) ...@@ -15,7 +15,6 @@ if (NOT DEFINED CLANGD_BUILD_XPC)
15 endif () 15 endif ()
16 16
17 llvm_canonicalize_cmake_booleans(CLANGD_BUILD_XPC) 17 llvm_canonicalize_cmake_booleans(CLANGD_BUILD_XPC)
18 -llvm_canonicalize_cmake_booleans(CLANGD_ENABLE_REMOTE)
19 18
20 configure_file( 19 configure_file(
21 ${CMAKE_CURRENT_SOURCE_DIR}/Features.inc.in 20 ${CMAKE_CURRENT_SOURCE_DIR}/Features.inc.in
...@@ -28,15 +27,6 @@ set(LLVM_LINK_COMPONENTS ...@@ -28,15 +27,6 @@ set(LLVM_LINK_COMPONENTS
28 FrontendOpenMP 27 FrontendOpenMP
29 Option 28 Option
30 ) 29 )
31 -
32 -include(${CMAKE_CURRENT_SOURCE_DIR}/quality/CompletionModel.cmake)
33 -gen_decision_forest(${CMAKE_CURRENT_SOURCE_DIR}/quality/model CompletionModel clang::clangd::Example)
34 -
35 -if(MSVC AND NOT CLANG_CL)
36 - set_source_files_properties(CompileCommands.cpp PROPERTIES COMPILE_FLAGS -wd4130) # disables C4130: logical operation on address of string constant
37 -endif()
38 -
39 -include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}/../clang-tidy")
40 30
41 add_clang_library(clangDaemon 31 add_clang_library(clangDaemon
42 AST.cpp 32 AST.cpp
...@@ -80,7 +70,6 @@ add_clang_library(clangDaemon ...@@ -80,7 +70,6 @@ add_clang_library(clangDaemon
80 TUScheduler.cpp 70 TUScheduler.cpp
81 URI.cpp 71 URI.cpp
82 XRefs.cpp 72 XRefs.cpp
83 - ${CMAKE_CURRENT_BINARY_DIR}/CompletionModel.cpp
84 73
85 index/Background.cpp 74 index/Background.cpp
86 index/BackgroundIndexLoader.cpp 75 index/BackgroundIndexLoader.cpp
...@@ -121,11 +110,6 @@ add_clang_library(clangDaemon ...@@ -121,11 +110,6 @@ add_clang_library(clangDaemon
121 omp_gen 110 omp_gen
122 ) 111 )
123 112
124 -# Include generated CompletionModel headers.
125 -target_include_directories(clangDaemon PUBLIC
126 - $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
127 -)
128 -
129 clang_target_link_libraries(clangDaemon 113 clang_target_link_libraries(clangDaemon
130 PRIVATE 114 PRIVATE
131 clangAST 115 clangAST
......
...@@ -36,24 +36,17 @@ class SymbolIndex; ...@@ -36,24 +36,17 @@ class SymbolIndex;
36 /// The server also supports $/cancelRequest (MessageHandler provides this). 36 /// The server also supports $/cancelRequest (MessageHandler provides this).
37 class ClangdLSPServer : private ClangdServer::Callbacks { 37 class ClangdLSPServer : private ClangdServer::Callbacks {
38 public: 38 public:
39 - struct Options : ClangdServer::Options { 39 + /// If \p CompileCommandsDir has a value, compile_commands.json will be
40 - /// Look for compilation databases, rather than using compile commands 40 + /// loaded only from \p CompileCommandsDir. Otherwise, clangd will look
41 - /// set via LSP (extensions) only. 41 + /// for compile_commands.json in all parent directories of each file.
42 - bool UseDirBasedCDB = true; 42 + /// If UseDirBasedCDB is false, compile commands are not read from disk.
43 - /// A fixed directory to search for a compilation database in. 43 + // FIXME: Clean up signature around CDBs.
44 - /// If not set, we search upward from the source file.
45 - llvm::Optional<Path> CompileCommandsDir;
46 - /// The offset-encoding to use, or None to negotiate it over LSP.
47 - llvm::Optional<OffsetEncoding> Encoding;
48 -
49 - /// Per-feature options. Generally ClangdServer lets these vary
50 - /// per-request, but LSP allows limited/no customizations.
51 - clangd::CodeCompleteOptions CodeComplete;
52 - clangd::RenameOptions Rename;
53 - };
54 -
55 ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS, 44 ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS,
56 - const ClangdLSPServer::Options &Opts); 45 + const clangd::CodeCompleteOptions &CCOpts,
46 + const clangd::RenameOptions &RenameOpts,
47 + llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
48 + llvm::Optional<OffsetEncoding> ForcedOffsetEncoding,
49 + const ClangdServer::Options &Opts);
57 /// The destructor blocks on any outstanding background tasks. 50 /// The destructor blocks on any outstanding background tasks.
58 ~ClangdLSPServer(); 51 ~ClangdLSPServer();
59 52
...@@ -187,39 +180,22 @@ private: ...@@ -187,39 +180,22 @@ private:
187 std::unique_ptr<MessageHandler> MsgHandler; 180 std::unique_ptr<MessageHandler> MsgHandler;
188 std::mutex TranspWriter; 181 std::mutex TranspWriter;
189 182
190 - template <typename T>
191 - static Expected<T> parse(const llvm::json::Value &Raw,
192 - llvm::StringRef PayloadName,
193 - llvm::StringRef PayloadKind) {
194 - T Result;
195 - llvm::json::Path::Root Root;
196 - if (!fromJSON(Raw, Result, Root)) {
197 - elog("Failed to decode {0} {1}: {2}", PayloadName, PayloadKind,
198 - Root.getError());
199 - // Dump the relevant parts of the broken message.
200 - std::string Context;
201 - llvm::raw_string_ostream OS(Context);
202 - Root.printErrorContext(Raw, OS);
203 - vlog("{0}", OS.str());
204 - // Report the error (e.g. to the client).
205 - return llvm::make_error<LSPError>(
206 - llvm::formatv("failed to decode {0} {1}: {2}", PayloadName,
207 - PayloadKind, fmt_consume(Root.getError())),
208 - ErrorCode::InvalidParams);
209 - }
210 - return std::move(Result);
211 - }
212 -
213 template <typename Response> 183 template <typename Response>
214 void call(StringRef Method, llvm::json::Value Params, Callback<Response> CB) { 184 void call(StringRef Method, llvm::json::Value Params, Callback<Response> CB) {
215 // Wrap the callback with LSP conversion and error-handling. 185 // Wrap the callback with LSP conversion and error-handling.
216 auto HandleReply = 186 auto HandleReply =
217 - [CB = std::move(CB), Ctx = Context::current().clone(), 187 + [CB = std::move(CB), Ctx = Context::current().clone()](
218 - Method = Method.str()](
219 llvm::Expected<llvm::json::Value> RawResponse) mutable { 188 llvm::Expected<llvm::json::Value> RawResponse) mutable {
220 - if (!RawResponse) 189 + Response Rsp;
221 - return CB(RawResponse.takeError()); 190 + if (!RawResponse) {
222 - CB(parse<Response>(*RawResponse, Method, "response")); 191 + CB(RawResponse.takeError());
192 + } else if (fromJSON(*RawResponse, Rsp)) {
193 + CB(std::move(Rsp));
194 + } else {
195 + elog("Failed to decode {0} response", *RawResponse);
196 + CB(llvm::make_error<LSPError>("failed to decode response",
197 + ErrorCode::InvalidParams));
198 + }
223 }; 199 };
224 callRaw(Method, std::move(Params), std::move(HandleReply)); 200 callRaw(Method, std::move(Params), std::move(HandleReply));
225 } 201 }
...@@ -234,6 +210,10 @@ private: ...@@ -234,6 +210,10 @@ private:
234 } 210 }
235 211
236 const ThreadsafeFS &TFS; 212 const ThreadsafeFS &TFS;
213 + /// Options used for code completion
214 + clangd::CodeCompleteOptions CCOpts;
215 + /// Options used for rename.
216 + clangd::RenameOptions RenameOpts;
237 /// Options used for diagnostics. 217 /// Options used for diagnostics.
238 ClangdDiagnosticOptions DiagOpts; 218 ClangdDiagnosticOptions DiagOpts;
239 /// The supported kinds of the client. 219 /// The supported kinds of the client.
...@@ -271,11 +251,14 @@ private: ...@@ -271,11 +251,14 @@ private:
271 // Store of the current versions of the open documents. 251 // Store of the current versions of the open documents.
272 DraftStore DraftMgr; 252 DraftStore DraftMgr;
273 253
274 - Options Opts;
275 // The CDB is created by the "initialize" LSP method. 254 // The CDB is created by the "initialize" LSP method.
255 + bool UseDirBasedCDB; // FIXME: make this a capability.
256 + llvm::Optional<Path> CompileCommandsDir; // FIXME: merge with capability?
276 std::unique_ptr<GlobalCompilationDatabase> BaseCDB; 257 std::unique_ptr<GlobalCompilationDatabase> BaseCDB;
277 // CDB is BaseCDB plus any commands overridden via LSP extensions. 258 // CDB is BaseCDB plus any commands overridden via LSP extensions.
278 llvm::Optional<OverlayCDB> CDB; 259 llvm::Optional<OverlayCDB> CDB;
260 + ClangdServer::Options ClangdServerOpts;
261 + llvm::Optional<OffsetEncoding> NegotiatedOffsetEncoding;
279 // The ClangdServer is created by the "initialize" LSP method. 262 // The ClangdServer is created by the "initialize" LSP method.
280 llvm::Optional<ClangdServer> Server; 263 llvm::Optional<ClangdServer> Server;
281 }; 264 };
......
...@@ -111,9 +111,6 @@ public: ...@@ -111,9 +111,6 @@ public:
111 /// on background threads. The index is stored in the project root. 111 /// on background threads. The index is stored in the project root.
112 bool BackgroundIndex = false; 112 bool BackgroundIndex = false;
113 113
114 - /// Store refs to main-file symbols in the index.
115 - bool CollectMainFileRefs = false;
116 -
117 /// If set, use this index to augment code completion results. 114 /// If set, use this index to augment code completion results.
118 SymbolIndex *StaticIndex = nullptr; 115 SymbolIndex *StaticIndex = nullptr;
119 116
...@@ -131,7 +128,7 @@ public: ...@@ -131,7 +128,7 @@ public:
131 bool BuildRecoveryAST = true; 128 bool BuildRecoveryAST = true;
132 129
133 /// If true, turn on the `-frecovery-ast-type` clang flag. 130 /// If true, turn on the `-frecovery-ast-type` clang flag.
134 - bool PreserveRecoveryASTType = true; 131 + bool PreserveRecoveryASTType = false;
135 132
136 /// Clangd's workspace root. Relevant for "workspace" operations not bound 133 /// Clangd's workspace root. Relevant for "workspace" operations not bound
137 /// to a particular file. 134 /// to a particular file.
...@@ -273,12 +270,9 @@ public: ...@@ -273,12 +270,9 @@ public:
273 StringRef TriggerText, Callback<std::vector<TextEdit>> CB); 270 StringRef TriggerText, Callback<std::vector<TextEdit>> CB);
274 271
275 /// Test the validity of a rename operation. 272 /// Test the validity of a rename operation.
276 - ///
277 - /// The returned result describes edits in the main-file only (all
278 - /// occurrences of the renamed symbol are simply deleted.
279 void prepareRename(PathRef File, Position Pos, 273 void prepareRename(PathRef File, Position Pos,
280 const RenameOptions &RenameOpts, 274 const RenameOptions &RenameOpts,
281 - Callback<RenameResult> CB); 275 + Callback<llvm::Optional<Range>> CB);
282 276
283 /// Rename all occurrences of the symbol at the \p Pos in \p File to 277 /// Rename all occurrences of the symbol at the \p Pos in \p File to
284 /// \p NewName. 278 /// \p NewName.
...@@ -286,12 +280,12 @@ public: ...@@ -286,12 +280,12 @@ public:
286 /// embedders could use this method to get all occurrences of the symbol (e.g. 280 /// embedders could use this method to get all occurrences of the symbol (e.g.
287 /// highlighting them in prepare stage). 281 /// highlighting them in prepare stage).
288 void rename(PathRef File, Position Pos, llvm::StringRef NewName, 282 void rename(PathRef File, Position Pos, llvm::StringRef NewName,
289 - const RenameOptions &Opts, Callback<RenameResult> CB); 283 + const RenameOptions &Opts, Callback<FileEdits> CB);
290 284
291 struct TweakRef { 285 struct TweakRef {
292 std::string ID; /// ID to pass for applyTweak. 286 std::string ID; /// ID to pass for applyTweak.
293 std::string Title; /// A single-line message to show in the UI. 287 std::string Title; /// A single-line message to show in the UI.
294 - llvm::StringLiteral Kind; 288 + Tweak::Intent Intent;
295 }; 289 };
296 /// Enumerate the code tweaks available to the user at a specified point. 290 /// Enumerate the code tweaks available to the user at a specified point.
297 void enumerateTweaks(PathRef File, Range Sel, 291 void enumerateTweaks(PathRef File, Range Sel,
...@@ -301,6 +295,10 @@ public: ...@@ -301,6 +295,10 @@ public:
301 void applyTweak(PathRef File, Range Sel, StringRef ID, 295 void applyTweak(PathRef File, Range Sel, StringRef ID,
302 Callback<Tweak::Effect> CB); 296 Callback<Tweak::Effect> CB);
303 297
298 + /// Only for testing purposes.
299 + /// Waits until all requests to worker thread are finished and dumps AST for
300 + /// \p File. \p File must be in the list of added documents.
301 + void dumpAST(PathRef File, llvm::unique_function<void(std::string)> Callback);
304 /// Called when an event occurs for a watched file in the workspace. 302 /// Called when an event occurs for a watched file in the workspace.
305 void onFileEvent(const DidChangeWatchedFilesParams &Params); 303 void onFileEvent(const DidChangeWatchedFilesParams &Params);
306 304
...@@ -319,13 +317,6 @@ public: ...@@ -319,13 +317,6 @@ public:
319 void semanticHighlights(PathRef File, 317 void semanticHighlights(PathRef File,
320 Callback<std::vector<HighlightingToken>>); 318 Callback<std::vector<HighlightingToken>>);
321 319
322 - /// Runs an arbitrary action that has access to the AST of the specified file.
323 - /// The action will execute on one of ClangdServer's internal threads.
324 - /// The AST is only valid for the duration of the callback.
325 - /// As with other actions, the file must have been opened.
326 - void customAction(PathRef File, llvm::StringRef Name,
327 - Callback<InputsAndAST> Action);
328 -
329 /// Returns estimated memory usage and other statistics for each of the 320 /// Returns estimated memory usage and other statistics for each of the
330 /// currently open files. 321 /// currently open files.
331 /// Overall memory usage of clangd may be significantly more than reported 322 /// Overall memory usage of clangd may be significantly more than reported
......
...@@ -333,7 +333,8 @@ struct CodeCompletionBuilder { ...@@ -333,7 +333,8 @@ struct CodeCompletionBuilder {
333 return ResolvedInserted.takeError(); 333 return ResolvedInserted.takeError();
334 auto Spelled = Includes.calculateIncludePath(*ResolvedInserted, FileName); 334 auto Spelled = Includes.calculateIncludePath(*ResolvedInserted, FileName);
335 if (!Spelled) 335 if (!Spelled)
336 - return error("Header not on include path"); 336 + return llvm::createStringError(llvm::inconvertibleErrorCode(),
337 + "Header not on include path");
337 return std::make_pair( 338 return std::make_pair(
338 std::move(*Spelled), 339 std::move(*Spelled),
339 Includes.shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted)); 340 Includes.shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted));
...@@ -1616,52 +1617,13 @@ private: ...@@ -1616,52 +1617,13 @@ private:
1616 1617
1617 llvm::Optional<float> fuzzyScore(const CompletionCandidate &C) { 1618 llvm::Optional<float> fuzzyScore(const CompletionCandidate &C) {
1618 // Macros can be very spammy, so we only support prefix completion. 1619 // Macros can be very spammy, so we only support prefix completion.
1619 - if (((C.SemaResult && 1620 + // We won't end up with underfull index results, as macros are sema-only.
1620 - C.SemaResult->Kind == CodeCompletionResult::RK_Macro) || 1621 + if (C.SemaResult && C.SemaResult->Kind == CodeCompletionResult::RK_Macro &&
1621 - (C.IndexResult &&
1622 - C.IndexResult->SymInfo.Kind == index::SymbolKind::Macro)) &&
1623 !C.Name.startswith_lower(Filter->pattern())) 1622 !C.Name.startswith_lower(Filter->pattern()))
1624 return None; 1623 return None;
1625 return Filter->match(C.Name); 1624 return Filter->match(C.Name);
1626 } 1625 }
1627 1626
1628 - CodeCompletion::Scores
1629 - evaluateCompletion(const SymbolQualitySignals &Quality,
1630 - const SymbolRelevanceSignals &Relevance) {
1631 - using RM = CodeCompleteOptions::CodeCompletionRankingModel;
1632 - CodeCompletion::Scores Scores;
1633 - switch (Opts.RankingModel) {
1634 - case RM::Heuristics:
1635 - Scores.Quality = Quality.evaluateHeuristics();
1636 - Scores.Relevance = Relevance.evaluateHeuristics();
1637 - Scores.Total =
1638 - evaluateSymbolAndRelevance(Scores.Quality, Scores.Relevance);
1639 - // NameMatch is in fact a multiplier on total score, so rescoring is
1640 - // sound.
1641 - Scores.ExcludingName = Relevance.NameMatch
1642 - ? Scores.Total / Relevance.NameMatch
1643 - : Scores.Quality;
1644 - return Scores;
1645 -
1646 - case RM::DecisionForest:
1647 - Scores.Quality = 0;
1648 - Scores.Relevance = 0;
1649 - // Exponentiating DecisionForest prediction makes the score of each tree a
1650 - // multiplciative boost (like NameMatch). This allows us to weigh the
1651 - // prediciton score and NameMatch appropriately.
1652 - Scores.ExcludingName = pow(Opts.DecisionForestBase,
1653 - evaluateDecisionForest(Quality, Relevance));
1654 - // NeedsFixIts is not part of the DecisionForest as generating training
1655 - // data that needs fixits is not-feasible.
1656 - if (Relevance.NeedsFixIts)
1657 - Scores.ExcludingName *= 0.5;
1658 - // NameMatch should be a multiplier on total score to support rescoring.
1659 - Scores.Total = Relevance.NameMatch * Scores.ExcludingName;
1660 - return Scores;
1661 - }
1662 - llvm_unreachable("Unhandled CodeCompletion ranking model.");
1663 - }
1664 -
1665 // Scores a candidate and adds it to the TopN structure. 1627 // Scores a candidate and adds it to the TopN structure.
1666 void addCandidate(TopN<ScoredBundle, ScoredBundleGreater> &Candidates, 1628 void addCandidate(TopN<ScoredBundle, ScoredBundleGreater> &Candidates,
1667 CompletionCandidate::Bundle Bundle) { 1629 CompletionCandidate::Bundle Bundle) {
...@@ -1669,7 +1631,6 @@ private: ...@@ -1669,7 +1631,6 @@ private:
1669 SymbolRelevanceSignals Relevance; 1631 SymbolRelevanceSignals Relevance;
1670 Relevance.Context = CCContextKind; 1632 Relevance.Context = CCContextKind;
1671 Relevance.Name = Bundle.front().Name; 1633 Relevance.Name = Bundle.front().Name;
1672 - Relevance.FilterLength = HeuristicPrefix.Name.size();
1673 Relevance.Query = SymbolRelevanceSignals::CodeComplete; 1634 Relevance.Query = SymbolRelevanceSignals::CodeComplete;
1674 Relevance.FileProximityMatch = FileProximity.getPointer(); 1635 Relevance.FileProximityMatch = FileProximity.getPointer();
1675 if (ScopeProximity) 1636 if (ScopeProximity)
...@@ -1718,7 +1679,15 @@ private: ...@@ -1718,7 +1679,15 @@ private:
1718 } 1679 }
1719 } 1680 }
1720 1681
1721 - CodeCompletion::Scores Scores = evaluateCompletion(Quality, Relevance); 1682 + CodeCompletion::Scores Scores;
1683 + Scores.Quality = Quality.evaluate();
1684 + Scores.Relevance = Relevance.evaluate();
1685 + Scores.Total = evaluateSymbolAndRelevance(Scores.Quality, Scores.Relevance);
1686 + // NameMatch is in fact a multiplier on total score, so rescoring is sound.
1687 + Scores.ExcludingName = Relevance.NameMatch
1688 + ? Scores.Total / Relevance.NameMatch
1689 + : Scores.Quality;
1690 +
1722 if (Opts.RecordCCResult) 1691 if (Opts.RecordCCResult)
1723 Opts.RecordCCResult(toCodeCompletion(Bundle), Quality, Relevance, 1692 Opts.RecordCCResult(toCodeCompletion(Bundle), Quality, Relevance,
1724 Scores.Total); 1693 Scores.Total);
......
...@@ -147,22 +147,6 @@ struct CodeCompleteOptions { ...@@ -147,22 +147,6 @@ struct CodeCompleteOptions {
147 std::function<void(const CodeCompletion &, const SymbolQualitySignals &, 147 std::function<void(const CodeCompletion &, const SymbolQualitySignals &,
148 const SymbolRelevanceSignals &, float Score)> 148 const SymbolRelevanceSignals &, float Score)>
149 RecordCCResult; 149 RecordCCResult;
150 -
151 - /// Model to use for ranking code completion candidates.
152 - enum CodeCompletionRankingModel {
153 - Heuristics,
154 - DecisionForest,
155 - } RankingModel = Heuristics;
156 -
157 - /// Weight for combining NameMatch and Prediction of DecisionForest.
158 - /// CompletionScore is NameMatch * pow(Base, Prediction).
159 - /// The optimal value of Base largely depends on the semantics of the model
160 - /// and prediction score (e.g. algorithm used during training, number of
161 - /// trees, etc.). Usually if the range of Prediciton is [-20, 20] then a Base
162 - /// in [1.2, 1.7] works fine.
163 - /// Semantics: E.g. the completion score reduces by 50% if the Prediciton
164 - /// score is reduced by 2.6 points for Base = 1.3.
165 - float DecisionForestBase = 1.3f;
166 }; 150 };
167 151
168 // Semi-structured representation of a code-complete suggestion for our C++ API. 152 // Semi-structured representation of a code-complete suggestion for our C++ API.
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
12 #include "clang/AST/RawCommentList.h" 12 #include "clang/AST/RawCommentList.h"
13 #include "clang/Basic/SourceManager.h" 13 #include "clang/Basic/SourceManager.h"
14 #include "clang/Sema/CodeCompleteConsumer.h" 14 #include "clang/Sema/CodeCompleteConsumer.h"
15 -#include "llvm/Support/JSON.h"
16 #include <limits> 15 #include <limits>
17 #include <utility> 16 #include <utility>
18 17
...@@ -87,12 +86,7 @@ std::string getDeclComment(const ASTContext &Ctx, const NamedDecl &Decl) { ...@@ -87,12 +86,7 @@ std::string getDeclComment(const ASTContext &Ctx, const NamedDecl &Decl) {
87 assert(!Ctx.getSourceManager().isLoadedSourceLocation(RC->getBeginLoc())); 86 assert(!Ctx.getSourceManager().isLoadedSourceLocation(RC->getBeginLoc()));
88 std::string Doc = 87 std::string Doc =
89 RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics()); 88 RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics());
90 - if (!looksLikeDocComment(Doc)) 89 + return looksLikeDocComment(Doc) ? Doc : "";
91 - return "";
92 - // Clang requires source to be UTF-8, but doesn't enforce this in comments.
93 - if (!llvm::json::isUTF8(Doc))
94 - Doc = llvm::json::fixUTF8(Doc);
95 - return Doc;
96 } 90 }
97 91
98 void getSignature(const CodeCompletionString &CCS, std::string *Signature, 92 void getSignature(const CodeCompletionString &CCS, std::string *Signature,
......
...@@ -271,7 +271,6 @@ std::pair<unsigned, unsigned> getArgCount(const llvm::opt::Option &Opt) { ...@@ -271,7 +271,6 @@ std::pair<unsigned, unsigned> getArgCount(const llvm::opt::Option &Opt) {
271 case Option::RemainingArgsJoinedClass: 271 case Option::RemainingArgsJoinedClass:
272 return {Rest, Rest}; 272 return {Rest, Rest};
273 } 273 }
274 - llvm_unreachable("Unhandled option kind");
275 } 274 }
276 275
277 // Flag-parsing mode, which affects which flags are available. 276 // Flag-parsing mode, which affects which flags are available.
...@@ -322,7 +321,7 @@ unsigned char getModes(const llvm::opt::Option &Opt) { ...@@ -322,7 +321,7 @@ unsigned char getModes(const llvm::opt::Option &Opt) {
322 } 321 }
323 } 322 }
324 return Result; 323 return Result;
325 -} 324 +};
326 325
327 } // namespace 326 } // namespace
328 327
...@@ -476,7 +475,7 @@ void ArgStripper::process(std::vector<std::string> &Args) const { ...@@ -476,7 +475,7 @@ void ArgStripper::process(std::vector<std::string> &Args) const {
476 bool WasXclang = false; 475 bool WasXclang = false;
477 while (Read < Args.size()) { 476 while (Read < Args.size()) {
478 unsigned ArgCount = 0; 477 unsigned ArgCount = 0;
479 - if (matchingRule(Args[Read], CurrentMode, ArgCount)) { 478 + if (const Rule *R = matchingRule(Args[Read], CurrentMode, ArgCount)) {
480 // Delete it and its args. 479 // Delete it and its args.
481 if (WasXclang) { 480 if (WasXclang) {
482 assert(Write > 0); 481 assert(Write > 0);
......
...@@ -78,8 +78,6 @@ buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D, ...@@ -78,8 +78,6 @@ buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D,
78 CI->getPreprocessorOpts().PCHThroughHeader.clear(); 78 CI->getPreprocessorOpts().PCHThroughHeader.clear();
79 CI->getPreprocessorOpts().PCHWithHdrStop = false; 79 CI->getPreprocessorOpts().PCHWithHdrStop = false;
80 CI->getPreprocessorOpts().PCHWithHdrStopCreate = false; 80 CI->getPreprocessorOpts().PCHWithHdrStopCreate = false;
81 - // Don't crash on `#pragma clang __debug parser_crash`
82 - CI->getPreprocessorOpts().DisablePragmaDebugCrash = true;
83 81
84 // Recovery expression currently only works for C++. 82 // Recovery expression currently only works for C++.
85 if (CI->getLangOpts()->CPlusPlus) { 83 if (CI->getLangOpts()->CPlusPlus) {
......
...@@ -62,14 +62,6 @@ struct Config { ...@@ -62,14 +62,6 @@ struct Config {
62 /// Whether this TU should be indexed. 62 /// Whether this TU should be indexed.
63 BackgroundPolicy Background = BackgroundPolicy::Build; 63 BackgroundPolicy Background = BackgroundPolicy::Build;
64 } Index; 64 } Index;
65 -
66 - /// Style of the codebase.
67 - struct {
68 - // Namespaces that should always be fully qualified, meaning no "using"
69 - // declarations, always spell out the whole name (with or without leading
70 - // ::). All nested namespaces are affected as well.
71 - std::vector<std::string> FullyQualifiedNamespaces;
72 - } Style;
73 }; 65 };
74 66
75 } // namespace clangd 67 } // namespace clangd
......
...@@ -208,25 +208,6 @@ struct FragmentCompiler { ...@@ -208,25 +208,6 @@ struct FragmentCompiler {
208 } 208 }
209 } 209 }
210 210
211 - void compile(Fragment::StyleBlock &&F) {
212 - if (!F.FullyQualifiedNamespaces.empty()) {
213 - std::vector<std::string> FullyQualifiedNamespaces;
214 - for (auto &N : F.FullyQualifiedNamespaces) {
215 - // Normalize the data by dropping both leading and trailing ::
216 - StringRef Namespace(*N);
217 - Namespace.consume_front("::");
218 - Namespace.consume_back("::");
219 - FullyQualifiedNamespaces.push_back(Namespace.str());
220 - }
221 - Out.Apply.push_back([FullyQualifiedNamespaces(
222 - std::move(FullyQualifiedNamespaces))](Config &C) {
223 - C.Style.FullyQualifiedNamespaces.insert(
224 - C.Style.FullyQualifiedNamespaces.begin(),
225 - FullyQualifiedNamespaces.begin(), FullyQualifiedNamespaces.end());
226 - });
227 - }
228 - }
229 -
230 constexpr static llvm::SourceMgr::DiagKind Error = llvm::SourceMgr::DK_Error; 211 constexpr static llvm::SourceMgr::DiagKind Error = llvm::SourceMgr::DK_Error;
231 constexpr static llvm::SourceMgr::DiagKind Warning = 212 constexpr static llvm::SourceMgr::DiagKind Warning =
232 llvm::SourceMgr::DK_Warning; 213 llvm::SourceMgr::DK_Warning;
......
...@@ -161,16 +161,6 @@ struct Fragment { ...@@ -161,16 +161,6 @@ struct Fragment {
161 llvm::Optional<Located<std::string>> Background; 161 llvm::Optional<Located<std::string>> Background;
162 }; 162 };
163 IndexBlock Index; 163 IndexBlock Index;
164 -
165 - // Describes the style of the codebase, beyond formatting.
166 - struct StyleBlock {
167 - // Namespaces that should always be fully qualified, meaning no "using"
168 - // declarations, always spell out the whole name (with or without leading
169 - // ::). All nested namespaces are affected as well.
170 - // Affects availability of the AddUsing tweak.
171 - std::vector<Located<std::string>> FullyQualifiedNamespaces;
172 - };
173 - StyleBlock Style;
174 }; 164 };
175 165
176 } // namespace config 166 } // namespace config
......
...@@ -209,11 +209,7 @@ Provider::combine(std::vector<const Provider *> Providers) { ...@@ -209,11 +209,7 @@ Provider::combine(std::vector<const Provider *> Providers) {
209 }; 209 };
210 auto Result = std::make_unique<CombinedProvider>(); 210 auto Result = std::make_unique<CombinedProvider>();
211 Result->Providers = std::move(Providers); 211 Result->Providers = std::move(Providers);
212 - // FIXME: This is a workaround for a bug in older versions of clang (< 3.9) 212 + return Result;
213 - // The constructor that is supposed to allow for Derived to Base
214 - // conversion does not work. Remove this if we drop support for such
215 - // configurations.
216 - return std::unique_ptr<Provider>(Result.release());
217 } 213 }
218 214
219 Config Provider::getConfig(const Params &P, DiagnosticCallback DC) const { 215 Config Provider::getConfig(const Params &P, DiagnosticCallback DC) const {
......
...@@ -39,7 +39,6 @@ public: ...@@ -39,7 +39,6 @@ public:
39 Dict.handle("If", [&](Node &N) { parse(F.If, N); }); 39 Dict.handle("If", [&](Node &N) { parse(F.If, N); });
40 Dict.handle("CompileFlags", [&](Node &N) { parse(F.CompileFlags, N); }); 40 Dict.handle("CompileFlags", [&](Node &N) { parse(F.CompileFlags, N); });
41 Dict.handle("Index", [&](Node &N) { parse(F.Index, N); }); 41 Dict.handle("Index", [&](Node &N) { parse(F.Index, N); });
42 - Dict.handle("Style", [&](Node &N) { parse(F.Style, N); });
43 Dict.parse(N); 42 Dict.parse(N);
44 return !(N.failed() || HadError); 43 return !(N.failed() || HadError);
45 } 44 }
...@@ -73,15 +72,6 @@ private: ...@@ -73,15 +72,6 @@ private:
73 Dict.parse(N); 72 Dict.parse(N);
74 } 73 }
75 74
76 - void parse(Fragment::StyleBlock &F, Node &N) {
77 - DictParser Dict("Style", this);
78 - Dict.handle("FullyQualifiedNamespaces", [&](Node &N) {
79 - if (auto Values = scalarValues(N))
80 - F.FullyQualifiedNamespaces = std::move(*Values);
81 - });
82 - Dict.parse(N);
83 - }
84 -
85 void parse(Fragment::IndexBlock &F, Node &N) { 75 void parse(Fragment::IndexBlock &F, Node &N) {
86 DictParser Dict("Index", this); 76 DictParser Dict("Index", this);
87 Dict.handle("Background", 77 Dict.handle("Background",
......
...@@ -411,8 +411,6 @@ void toLSPDiags( ...@@ -411,8 +411,6 @@ void toLSPDiags(
411 Main.codeActions.emplace(); 411 Main.codeActions.emplace();
412 for (const auto &Fix : D.Fixes) 412 for (const auto &Fix : D.Fixes)
413 Main.codeActions->push_back(toCodeAction(Fix, File)); 413 Main.codeActions->push_back(toCodeAction(Fix, File));
414 - if (Main.codeActions->size() == 1)
415 - Main.codeActions->front().isPreferred = true;
416 } 414 }
417 if (Opts.SendDiagnosticCategory && !D.Category.empty()) 415 if (Opts.SendDiagnosticCategory && !D.Category.empty())
418 Main.category = D.Category; 416 Main.category = D.Category;
...@@ -520,17 +518,13 @@ std::vector<Diag> StoreDiags::take(const clang::tidy::ClangTidyContext *Tidy) { ...@@ -520,17 +518,13 @@ std::vector<Diag> StoreDiags::take(const clang::tidy::ClangTidyContext *Tidy) {
520 } 518 }
521 519
522 void StoreDiags::BeginSourceFile(const LangOptions &Opts, 520 void StoreDiags::BeginSourceFile(const LangOptions &Opts,
523 - const Preprocessor *PP) { 521 + const Preprocessor *) {
524 LangOpts = Opts; 522 LangOpts = Opts;
525 - if (PP) {
526 - OrigSrcMgr = &PP->getSourceManager();
527 - }
528 } 523 }
529 524
530 void StoreDiags::EndSourceFile() { 525 void StoreDiags::EndSourceFile() {
531 flushLastDiag(); 526 flushLastDiag();
532 LangOpts = None; 527 LangOpts = None;
533 - OrigSrcMgr = nullptr;
534 } 528 }
535 529
536 /// Sanitizes a piece for presenting it in a synthesized fix message. Ensures 530 /// Sanitizes a piece for presenting it in a synthesized fix message. Ensures
...@@ -566,16 +560,6 @@ static void fillNonLocationData(DiagnosticsEngine::Level DiagLevel, ...@@ -566,16 +560,6 @@ static void fillNonLocationData(DiagnosticsEngine::Level DiagLevel,
566 560
567 void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 561 void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
568 const clang::Diagnostic &Info) { 562 const clang::Diagnostic &Info) {
569 - // If the diagnostic was generated for a different SourceManager, skip it.
570 - // This happens when a module is imported and needs to be implicitly built.
571 - // The compilation of that module will use the same StoreDiags, but different
572 - // SourceManager.
573 - if (OrigSrcMgr && Info.hasSourceManager() &&
574 - OrigSrcMgr != &Info.getSourceManager()) {
575 - IgnoreDiagnostics::log(DiagLevel, Info);
576 - return;
577 - }
578 -
579 DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info); 563 DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
580 bool OriginallyError = 564 bool OriginallyError =
581 Info.getDiags()->getDiagnosticIDs()->isDefaultMappingAsError( 565 Info.getDiags()->getDiagnosticIDs()->isDefaultMappingAsError(
......
...@@ -122,8 +122,7 @@ public: ...@@ -122,8 +122,7 @@ public:
122 // The ClangTidyContext populates Source and Name for clang-tidy diagnostics. 122 // The ClangTidyContext populates Source and Name for clang-tidy diagnostics.
123 std::vector<Diag> take(const clang::tidy::ClangTidyContext *Tidy = nullptr); 123 std::vector<Diag> take(const clang::tidy::ClangTidyContext *Tidy = nullptr);
124 124
125 - void BeginSourceFile(const LangOptions &Opts, 125 + void BeginSourceFile(const LangOptions &Opts, const Preprocessor *) override;
126 - const Preprocessor *PP) override;
127 void EndSourceFile() override; 126 void EndSourceFile() override;
128 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 127 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
129 const clang::Diagnostic &Info) override; 128 const clang::Diagnostic &Info) override;
...@@ -149,7 +148,6 @@ private: ...@@ -149,7 +148,6 @@ private:
149 llvm::Optional<Diag> LastDiag; 148 llvm::Optional<Diag> LastDiag;
150 llvm::Optional<FullSourceLoc> LastDiagLoc; // Valid only when LastDiag is set. 149 llvm::Optional<FullSourceLoc> LastDiagLoc; // Valid only when LastDiag is set.
151 bool LastDiagOriginallyError = false; // Valid only when LastDiag is set. 150 bool LastDiagOriginallyError = false; // Valid only when LastDiag is set.
152 - SourceManager *OrigSrcMgr = nullptr;
153 151
154 llvm::DenseSet<std::pair<unsigned, unsigned>> IncludedErrorLocations; 152 llvm::DenseSet<std::pair<unsigned, unsigned>> IncludedErrorLocations;
155 bool LastPrimaryDiagnosticWasSuppressed = false; 153 bool LastPrimaryDiagnosticWasSuppressed = false;
......
...@@ -64,9 +64,9 @@ llvm::Expected<DraftStore::Draft> DraftStore::updateDraft( ...@@ -64,9 +64,9 @@ llvm::Expected<DraftStore::Draft> DraftStore::updateDraft(
64 64
65 auto EntryIt = Drafts.find(File); 65 auto EntryIt = Drafts.find(File);
66 if (EntryIt == Drafts.end()) { 66 if (EntryIt == Drafts.end()) {
67 - return error(llvm::errc::invalid_argument, 67 + return llvm::make_error<llvm::StringError>(
68 - "Trying to do incremental update on non-added document: {0}", 68 + "Trying to do incremental update on non-added document: " + File,
69 - File); 69 + llvm::errc::invalid_argument);
70 } 70 }
71 Draft &D = EntryIt->second; 71 Draft &D = EntryIt->second;
72 std::string Contents = EntryIt->second.Contents; 72 std::string Contents = EntryIt->second.Contents;
...@@ -89,9 +89,11 @@ llvm::Expected<DraftStore::Draft> DraftStore::updateDraft( ...@@ -89,9 +89,11 @@ llvm::Expected<DraftStore::Draft> DraftStore::updateDraft(
89 return EndIndex.takeError(); 89 return EndIndex.takeError();
90 90
91 if (*EndIndex < *StartIndex) 91 if (*EndIndex < *StartIndex)
92 - return error(llvm::errc::invalid_argument, 92 + return llvm::make_error<llvm::StringError>(
93 - "Range's end position ({0}) is before start position ({1})", 93 + llvm::formatv(
94 - End, Start); 94 + "Range's end position ({0}) is before start position ({1})", End,
95 + Start),
96 + llvm::errc::invalid_argument);
95 97
96 // Since the range length between two LSP positions is dependent on the 98 // Since the range length between two LSP positions is dependent on the
97 // contents of the buffer we compute the range length between the start and 99 // contents of the buffer we compute the range length between the start and
...@@ -104,10 +106,11 @@ llvm::Expected<DraftStore::Draft> DraftStore::updateDraft( ...@@ -104,10 +106,11 @@ llvm::Expected<DraftStore::Draft> DraftStore::updateDraft(
104 lspLength(Contents.substr(*StartIndex, *EndIndex - *StartIndex)); 106 lspLength(Contents.substr(*StartIndex, *EndIndex - *StartIndex));
105 107
106 if (Change.rangeLength && ComputedRangeLength != *Change.rangeLength) 108 if (Change.rangeLength && ComputedRangeLength != *Change.rangeLength)
107 - return error(llvm::errc::invalid_argument, 109 + return llvm::make_error<llvm::StringError>(
108 - "Change's rangeLength ({0}) doesn't match the " 110 + llvm::formatv("Change's rangeLength ({0}) doesn't match the "
109 - "computed range length ({1}).", 111 + "computed range length ({1}).",
110 - *Change.rangeLength, ComputedRangeLength); 112 + *Change.rangeLength, ComputedRangeLength),
113 + llvm::errc::invalid_argument);
111 114
112 std::string NewContents; 115 std::string NewContents;
113 NewContents.reserve(*StartIndex + Change.text.length() + 116 NewContents.reserve(*StartIndex + Change.text.length() +
......
1 #define CLANGD_BUILD_XPC @CLANGD_BUILD_XPC@ 1 #define CLANGD_BUILD_XPC @CLANGD_BUILD_XPC@
2 -#define CLANGD_ENABLE_REMOTE @CLANGD_ENABLE_REMOTE@
......
...@@ -43,9 +43,12 @@ struct ScoredSymbolGreater { ...@@ -43,9 +43,12 @@ struct ScoredSymbolGreater {
43 llvm::Expected<Location> indexToLSPLocation(const SymbolLocation &Loc, 43 llvm::Expected<Location> indexToLSPLocation(const SymbolLocation &Loc,
44 llvm::StringRef TUPath) { 44 llvm::StringRef TUPath) {
45 auto Path = URI::resolve(Loc.FileURI, TUPath); 45 auto Path = URI::resolve(Loc.FileURI, TUPath);
46 - if (!Path) 46 + if (!Path) {
47 - return error("Could not resolve path for file '{0}': {1}", Loc.FileURI, 47 + return llvm::make_error<llvm::StringError>(
48 - Path.takeError()); 48 + llvm::formatv("Could not resolve path for file '{0}': {1}", Loc.FileURI,
49 + llvm::toString(Path.takeError())),
50 + llvm::inconvertibleErrorCode());
51 + }
49 Location L; 52 Location L;
50 L.uri = URIForFile::canonicalize(*Path, TUPath); 53 L.uri = URIForFile::canonicalize(*Path, TUPath);
51 Position Start, End; 54 Position Start, End;
...@@ -116,8 +119,8 @@ getWorkspaceSymbols(llvm::StringRef Query, int Limit, ...@@ -116,8 +119,8 @@ getWorkspaceSymbols(llvm::StringRef Query, int Limit,
116 return; 119 return;
117 } 120 }
118 Relevance.merge(Sym); 121 Relevance.merge(Sym);
119 - auto Score = evaluateSymbolAndRelevance(Quality.evaluateHeuristics(), 122 + auto Score =
120 - Relevance.evaluateHeuristics()); 123 + evaluateSymbolAndRelevance(Quality.evaluate(), Relevance.evaluate());
121 dlog("FindSymbols: {0}{1} = {2}\n{3}{4}\n", Sym.Scope, Sym.Name, Score, 124 dlog("FindSymbols: {0}{1} = {2}\n{3}{4}\n", Sym.Scope, Sym.Name, Score,
122 Quality, Relevance); 125 Quality, Relevance);
123 126
...@@ -185,7 +188,7 @@ public: ...@@ -185,7 +188,7 @@ public:
185 } 188 }
186 189
187 private: 190 private:
188 - enum class VisitKind { No, OnlyDecl, OnlyChildren, DeclAndChildren }; 191 + enum class VisitKind { No, OnlyDecl, DeclAndChildren };
189 192
190 void traverseDecl(Decl *D, std::vector<DocumentSymbol> &Results) { 193 void traverseDecl(Decl *D, std::vector<DocumentSymbol> &Results) {
191 if (auto *Templ = llvm::dyn_cast<TemplateDecl>(D)) { 194 if (auto *Templ = llvm::dyn_cast<TemplateDecl>(D)) {
...@@ -193,25 +196,18 @@ private: ...@@ -193,25 +196,18 @@ private:
193 if (auto *TD = Templ->getTemplatedDecl()) 196 if (auto *TD = Templ->getTemplatedDecl())
194 D = TD; 197 D = TD;
195 } 198 }
196 - 199 + auto *ND = llvm::dyn_cast<NamedDecl>(D);
197 - VisitKind Visit = shouldVisit(D); 200 + if (!ND)
201 + return;
202 + VisitKind Visit = shouldVisit(ND);
198 if (Visit == VisitKind::No) 203 if (Visit == VisitKind::No)
199 return; 204 return;
200 - 205 + llvm::Optional<DocumentSymbol> Sym = declToSym(AST.getASTContext(), *ND);
201 - if (Visit == VisitKind::OnlyChildren)
202 - return traverseChildren(D, Results);
203 -
204 - auto *ND = llvm::cast<NamedDecl>(D);
205 - auto Sym = declToSym(AST.getASTContext(), *ND);
206 if (!Sym) 206 if (!Sym)
207 return; 207 return;
208 + if (Visit == VisitKind::DeclAndChildren)
209 + traverseChildren(D, Sym->children);
208 Results.push_back(std::move(*Sym)); 210 Results.push_back(std::move(*Sym));
209 -
210 - if (Visit == VisitKind::OnlyDecl)
211 - return;
212 -
213 - assert(Visit == VisitKind::DeclAndChildren && "Unexpected VisitKind");
214 - traverseChildren(ND, Results.back().children);
215 } 211 }
216 212
217 void traverseChildren(Decl *D, std::vector<DocumentSymbol> &Results) { 213 void traverseChildren(Decl *D, std::vector<DocumentSymbol> &Results) {
...@@ -222,16 +218,10 @@ private: ...@@ -222,16 +218,10 @@ private:
222 traverseDecl(C, Results); 218 traverseDecl(C, Results);
223 } 219 }
224 220
225 - VisitKind shouldVisit(Decl *D) { 221 + VisitKind shouldVisit(NamedDecl *D) {
226 if (D->isImplicit()) 222 if (D->isImplicit())
227 return VisitKind::No; 223 return VisitKind::No;
228 224
229 - if (llvm::isa<LinkageSpecDecl>(D) || llvm::isa<ExportDecl>(D))
230 - return VisitKind::OnlyChildren;
231 -
232 - if (!llvm::isa<NamedDecl>(D))
233 - return VisitKind::No;
234 -
235 if (auto Func = llvm::dyn_cast<FunctionDecl>(D)) { 225 if (auto Func = llvm::dyn_cast<FunctionDecl>(D)) {
236 // Some functions are implicit template instantiations, those should be 226 // Some functions are implicit template instantiations, those should be
237 // ignored. 227 // ignored.
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.