[PATCH] D71846: [ASTMatchers] Fix for https://bugs.llvm.org/show_bug.cgi?id=44364

2019-12-25 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 235278.
njames93 added a comment.

I added test cases for the matchers and the check, wasn't able to add the 
CXXRangeFor to the matcher as that class uses a different dialect for the 
initializer statement handling. I also couldn't generate the new documentation 
as the script always fails on my machine, even without the changes i have made, 
resulting in the ASTMatcher html being empty


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D71846/new/

https://reviews.llvm.org/D71846

Files:
  clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/readability-else-after-return.cpp
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1071,6 +1071,20 @@
  LanguageMode::Cxx17OrLater));
 }
 
+TEST(hasInitStorage, MatchesSelectionInitializers) {
+  EXPECT_TRUE(matches("void baz() { if (int i = 1; i > 0) {} }",
+  ifStmt(hasInitStorage()), LanguageMode::Cxx17OrLater));
+  EXPECT_TRUE(
+  notMatches("void baz() { if (int i = 1) {} }", ifStmt(hasInitStorage(;
+  EXPECT_TRUE(
+  notMatches("void baz() { if (1 > 0) {} }", ifStmt(hasInitStorage(;
+  EXPECT_TRUE(
+  matches("void baz(int i) { switch (int j = i; j) { default: break; } }",
+  switchStmt(hasInitStorage()), LanguageMode::Cxx17OrLater));
+  EXPECT_TRUE(notMatches("void baz(int i) { switch (i) { default: break; } }",
+ switchStmt(hasInitStorage(;
+}
+
 TEST(TemplateArgumentCountIs, Matches) {
   EXPECT_TRUE(
 matches("template struct C {}; C c;",
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -279,6 +279,7 @@
   REGISTER_MATCHER(hasIndex);
   REGISTER_MATCHER(hasInit);
   REGISTER_MATCHER(hasInitializer);
+  REGISTER_MATCHER(hasInitStorage);
   REGISTER_MATCHER(hasKeywordSelector);
   REGISTER_MATCHER(hasLHS);
   REGISTER_MATCHER(hasLocalQualifiers);
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4297,6 +4297,22 @@
   return Node.isConstexpr();
 }
 
+/// Matches selection statements with initializer.
+///
+/// Given:
+/// \code
+///  if (int foo = bar(); bar > 0) {}
+///  switch (int baz = bar(); baz) {}
+/// \endcode
+/// ifStmt(hasInitStorage())
+///   matches the declaration of foo.
+/// switchStmt(hasInitStorage())
+///   matches the declaration of baz.
+AST_POLYMORPHIC_MATCHER(hasInitStorage,
+AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, SwitchStmt)) {
+  return Node.hasInitStorage();
+}
+
 /// Matches the condition expression of an if statement, for loop,
 /// switch statement or conditional operator.
 ///
Index: clang-tools-extra/test/clang-tidy/checkers/readability-else-after-return.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/readability-else-after-return.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-else-after-return.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s readability-else-after-return %t -- -- -fexceptions
+// RUN: %check_clang_tidy %s readability-else-after-return %t -- -- -fexceptions -std=c++17
 
 namespace std {
 struct string {
@@ -117,3 +117,12 @@
 return x;
   }
 }
+
+int *init_and_condition() {
+  if (int *x = g(); x != nullptr) {
+return x;
+  } else {
+h();
+return x;
+  }
+}
Index: clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp
@@ -26,12 +26,14 @@
   compoundStmt(forEach(
   ifStmt(unless(isConstexpr()),
  // FIXME: Explore alternatives for the
- // `if (T x = ...) {... return; } else {  }`
- // pattern:
+ // `if (T x = ...) {... return; } else {  }` and
+ // 'if (T x = ...; cond) {... return; } else { use  }'
+ // patterns:
  //   * warn, but don't fix;
  //   * fix by pulling out the variable declaration out of
  // the condition.
  unless(hasConditionVariableStatement(anything())),
+ 

[PATCH] D73052: [clang-tidy] RenamerClangTidy now renames dependent member expr when the member can be resolved

2020-02-12 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 244087.
njames93 added a comment.

- Made AggressiveDependentMemberLookup option Global


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73052/new/

https://reviews.llvm.org/D73052

Files:
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.h
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/readability-identifier-naming.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-member-decl-usage.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-member-decl-usage.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-member-decl-usage.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-member-decl-usage.cpp
@@ -1,7 +1,9 @@
 // RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: readability-identifier-naming.MemberCase, value: CamelCase}, \
-// RUN: {key: readability-identifier-naming.ParameterCase, value: CamelCase} \
+// RUN: {key: readability-identifier-naming.ParameterCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.MethodCase, value: camelBack}, \
+// RUN: {key: readability-identifier-naming.AggressiveDependentMemberLookup, value: 1} \
 // RUN:  ]}' -- -fno-delayed-template-parsing
 
 int set_up(int);
@@ -63,32 +65,23 @@
   // CHECK-FIXES: {{^}}  int getBar2() const { return this->BarBaz; } // comment-9
 };
 
-TempTest x; //force an instantiation
-
-int blah() {
-  return x.getBar2(); // gotta have a reference to the getBar2 so that the
-  // compiler will generate the function and resolve
-  // the DependantScopeMemberExpr
-}
-
 namespace Bug41122 {
 namespace std {
 
 // for this example we aren't bothered about how std::vector is treated
-template  //NOLINT
-class vector { //NOLINT
-public:
-  void push_back(bool); //NOLINT
-  void pop_back(); //NOLINT
-}; //NOLINT
-}; // namespace std
+template// NOLINT
+struct vector { // NOLINT
+  void push_back(bool); // NOLINT
+  void pop_back();  // NOLINT
+};  // NOLINT
+};  // namespace std
 
-class Foo { 
+class Foo {
   std::vector 
   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: invalid case style for member 'stack' [readability-identifier-naming]
 public:
   Foo(std::vector )
-  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: invalid case style for parameter 'stack' [readability-identifier-naming]
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: invalid case style for parameter 'stack' [readability-identifier-naming]
   // CHECK-FIXES: {{^}}  Foo(std::vector )
   : stack(stack) {
 // CHECK-FIXES: {{^}}  : Stack(Stack) {
@@ -134,4 +127,92 @@
 void foo() {
   Container container;
 }
-}; // namespace CtorInits
+} // namespace CtorInits
+
+namespace resolved_dependance {
+template 
+struct A0 {
+  int value;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for member 'value'
+  A0 =(const A0 ) {
+value = Other.value;   // A0
+this->value = Other.value; // A0
+// CHECK-FIXES:  {{^}}Value = Other.Value;   // A0
+// CHECK-FIXES-NEXT: {{^}}this->Value = Other.Value; // A0
+return *this;
+  }
+  void outOfLineReset();
+};
+
+template 
+void A0::outOfLineReset() {
+  this->value -= value; // A0
+  // CHECK-FIXES: {{^}}  this->Value -= Value; // A0
+}
+
+template 
+struct A1 {
+  int value; // A1
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for member 'value'
+  // CHECK-FIXES: {{^}}  int Value; // A1
+  int GetValue() const { return value; } // A1
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for method 'GetValue'
+  // CHECK-FIXES {{^}}  int getValue() const { return Value; } // A1
+  void SetValue(int Value) { this->value = Value; } // A1
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: invalid case style for method 'SetValue'
+  // CHECK-FIXES {{^}}  void setValue(int Value) { this->Value = Value; } // A1
+  A1 =(const A1 ) {
+this->SetValue(Other.GetValue()); // A1
+this->value = Other.value;// A1
+// CHECK-FIXES:  {{^}}this->setValue(Other.getValue()); // A1
+// CHECK-FIXES-NEXT: {{^}}this->Value = Other.Value;// A1
+return *this;
+  }
+  void outOfLineReset();
+};
+
+template 
+void A1::outOfLineReset() {
+  this->value -= value; // A1
+  // CHECK-FIXES: {{^}}  this->Value 

[PATCH] D74374: [clang-tidy] Added check to disable bugprone-infinite-loop on known false condition

2020-02-10 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
Herald added subscribers: cfe-commits, xazax.hun.
Herald added a project: clang.
njames93 edited the summary of this revision.
njames93 added reviewers: aaron.ballman, alexfh, hokein, gribozavr2, JonasToth.
njames93 added a project: clang-tools-extra.

Addresses bugprone-infinite-loop false positive with CATCH2 
 by disabling the check on loops 
where the condition is known to always eval as false, in other words not a loop.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D74374

Files:
  clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
@@ -354,3 +354,12 @@
 (*p)++;
   } while (i < Limit);
 }
+
+void evaluatable(bool CondVar) {
+  for (; false && CondVar;) {
+  }
+  while (false && CondVar) {
+  }
+  do {
+  } while (false && CondVar);
+}
Index: clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -152,6 +152,13 @@
   return Result;
 }
 
+static bool isKnownFalse(const Expr , const ASTContext ) {
+  bool Result = false;
+  if (Cond.EvaluateAsBooleanCondition(Result, Ctx))
+return !Result;
+  return false;
+}
+
 void InfiniteLoopCheck::registerMatchers(MatchFinder *Finder) {
   const auto LoopCondition = allOf(
   hasCondition(
@@ -170,6 +177,9 @@
   const auto *LoopStmt = Result.Nodes.getNodeAs("loop-stmt");
   const auto *Func = Result.Nodes.getNodeAs("func");
 
+  if (isKnownFalse(*Cond, *Result.Context))
+return;
+
   bool ShouldHaveConditionVariables = true;
   if (const auto *While = dyn_cast(LoopStmt)) {
 if (const VarDecl *LoopVarDecl = While->getConditionVariable()) {


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
@@ -354,3 +354,12 @@
 (*p)++;
   } while (i < Limit);
 }
+
+void evaluatable(bool CondVar) {
+  for (; false && CondVar;) {
+  }
+  while (false && CondVar) {
+  }
+  do {
+  } while (false && CondVar);
+}
Index: clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -152,6 +152,13 @@
   return Result;
 }
 
+static bool isKnownFalse(const Expr , const ASTContext ) {
+  bool Result = false;
+  if (Cond.EvaluateAsBooleanCondition(Result, Ctx))
+return !Result;
+  return false;
+}
+
 void InfiniteLoopCheck::registerMatchers(MatchFinder *Finder) {
   const auto LoopCondition = allOf(
   hasCondition(
@@ -170,6 +177,9 @@
   const auto *LoopStmt = Result.Nodes.getNodeAs("loop-stmt");
   const auto *Func = Result.Nodes.getNodeAs("func");
 
+  if (isKnownFalse(*Cond, *Result.Context))
+return;
+
   bool ShouldHaveConditionVariables = true;
   if (const auto *While = dyn_cast(LoopStmt)) {
 if (const VarDecl *LoopVarDecl = While->getConditionVariable()) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75134: [clang-tidy] Improved renamer check logic

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: aaron.ballman, Eugene.Zelenko, gribozavr2, alexfh, 
hokein.
Herald added subscribers: cfe-commits, xazax.hun.
Herald added a project: clang.

Factored out some similar code in add_new_check.py and rename_check.py.
Made rename_check.py less error prone by targetting string replacements
Haven't linted the code as that is a can of worms given the 100+ different 
style options currently used in the python files


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75134

Files:
  clang-tools-extra/clang-tidy/add_new_check.py
  clang-tools-extra/clang-tidy/rename_check.py
  clang-tools-extra/clang-tidy/utils/__init__.py
  clang-tools-extra/clang-tidy/utils/modify_check.py

Index: clang-tools-extra/clang-tidy/utils/modify_check.py
===
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/modify_check.py
@@ -0,0 +1,122 @@
+import os
+import re
+
+def get_camel_name(check_name):
+  return ''.join(map(lambda elem: elem.capitalize(),
+ check_name.split('-'))) + 'Check'
+
+# Adapts the module's CMakelist file. Returns 'True' if it could add a new entry
+# and 'False' if the entry already existed.
+def adapt_cmake(module_path, check_name_camel):
+  filename = os.path.join(module_path, 'CMakeLists.txt')
+  with open(filename, 'r') as f:
+lines = f.readlines()
+
+  cpp_file = check_name_camel + '.cpp'
+
+  # Figure out whether this check already exists.
+  for line in lines:
+if line.strip() == cpp_file:
+  return False
+
+  print('Updating %s...' % filename)
+  with open(filename, 'w') as f:
+cpp_found = False
+file_added = False
+for line in lines:
+  cpp_line = line.strip().endswith('.cpp')
+  if (not file_added) and (cpp_line or cpp_found):
+cpp_found = True
+if (line.strip() > cpp_file) or (not cpp_line):
+  f.write('  ' + cpp_file + '\n')
+  file_added = True
+  f.write(line)
+
+  return True
+
+# Recreates the list of checks in the docs/clang-tidy/checks directory.
+def update_checks_list(clang_tidy_path):
+  docs_dir = os.path.join(clang_tidy_path, '../docs/clang-tidy/checks')
+  filename = os.path.normpath(os.path.join(docs_dir, 'list.rst'))
+  # Read the content of the current list.rst file
+  with open(filename, 'r') as f:
+lines = f.readlines()
+  # Get all existing docs
+  doc_files = list(filter(lambda s: s.endswith('.rst') and s != 'list.rst',
+ os.listdir(docs_dir)))
+  doc_files.sort()
+
+  def has_auto_fix(check_name):
+dirname, _, check_name = check_name.partition("-")
+
+checkerCode = os.path.join(dirname, get_camel_name(check_name)) + ".cpp"
+
+if not os.path.isfile(checkerCode):
+  return ""
+
+with open(checkerCode) as f:
+  code = f.read()
+  if 'FixItHint' in code or "ReplacementText" in code or "fixit" in code:
+# Some simple heuristics to figure out if a checker has an autofix or not.
+return ' "Yes"'
+return ""
+
+  def process_doc(doc_file):
+check_name = doc_file.replace('.rst', '')
+
+with open(os.path.join(docs_dir, doc_file), 'r') as doc:
+  content = doc.read()
+  match = re.search('.*:orphan:.*', content)
+
+  if match:
+# Orphan page, don't list it.
+return '', ''
+
+  match = re.search('.*:http-equiv=refresh: \d+;URL=(.*).html.*',
+content)
+  # Is it a redirect?
+  return check_name, match
+
+  def format_link(doc_file):
+check_name, match = process_doc(doc_file)
+if not match and check_name:
+  return '   `%(check)s <%(check)s.html>`_,%(autofix)s\n' % {
+'check': check_name,
+'autofix': has_auto_fix(check_name)
+  }
+else:
+  return ''
+
+  def format_link_alias(doc_file):
+check_name, match = process_doc(doc_file)
+if match and check_name:
+  if match.group(1) == 'https://clang.llvm.org/docs/analyzer/checkers':
+title_redirect = 'Clang Static Analyzer'
+  else:
+title_redirect = match.group(1)
+  # The checker is just a redirect.
+  return '   `%(check)s <%(check)s.html>`_, `%(title)s <%(target)s.html>`_,%(autofix)s\n' % {
+'check': check_name,
+'target': match.group(1),
+'title': title_redirect,
+'autofix': has_auto_fix(match.group(1))
+  }
+return ''
+
+  checks = map(format_link, doc_files)
+  checks_alias = map(format_link_alias, doc_files)
+
+  print('Updating %s...' % filename)
+  with open(filename, 'w') as f:
+for line in lines:
+  f.write(line)
+  if line.strip() == ".. csv-table::":
+# We dump the checkers
+f.write('   :header: "Name", "Offers fixes"\n\n')
+f.writelines(checks)
+# and the aliases
+f.write('\n\n')
+f.write('.. csv-table:: Aliases..\n')
+f.write('   :header: "Name", "Redirect", "Offers fixes"\n\n')
+

[PATCH] D75134: [clang-tidy] Improved renamer check logic

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246534.
njames93 added a comment.

- Remove unnecessary debug print


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75134/new/

https://reviews.llvm.org/D75134

Files:
  clang-tools-extra/clang-tidy/add_new_check.py
  clang-tools-extra/clang-tidy/rename_check.py
  clang-tools-extra/clang-tidy/utils/__init__.py
  clang-tools-extra/clang-tidy/utils/modify_check.py

Index: clang-tools-extra/clang-tidy/utils/modify_check.py
===
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/modify_check.py
@@ -0,0 +1,122 @@
+import os
+import re
+
+def get_camel_name(check_name):
+  return ''.join(map(lambda elem: elem.capitalize(),
+ check_name.split('-'))) + 'Check'
+
+# Adapts the module's CMakelist file. Returns 'True' if it could add a new entry
+# and 'False' if the entry already existed.
+def adapt_cmake(module_path, check_name_camel):
+  filename = os.path.join(module_path, 'CMakeLists.txt')
+  with open(filename, 'r') as f:
+lines = f.readlines()
+
+  cpp_file = check_name_camel + '.cpp'
+
+  # Figure out whether this check already exists.
+  for line in lines:
+if line.strip() == cpp_file:
+  return False
+
+  print('Updating %s...' % filename)
+  with open(filename, 'w') as f:
+cpp_found = False
+file_added = False
+for line in lines:
+  cpp_line = line.strip().endswith('.cpp')
+  if (not file_added) and (cpp_line or cpp_found):
+cpp_found = True
+if (line.strip() > cpp_file) or (not cpp_line):
+  f.write('  ' + cpp_file + '\n')
+  file_added = True
+  f.write(line)
+
+  return True
+
+# Recreates the list of checks in the docs/clang-tidy/checks directory.
+def update_checks_list(clang_tidy_path):
+  docs_dir = os.path.join(clang_tidy_path, '../docs/clang-tidy/checks')
+  filename = os.path.normpath(os.path.join(docs_dir, 'list.rst'))
+  # Read the content of the current list.rst file
+  with open(filename, 'r') as f:
+lines = f.readlines()
+  # Get all existing docs
+  doc_files = list(filter(lambda s: s.endswith('.rst') and s != 'list.rst',
+ os.listdir(docs_dir)))
+  doc_files.sort()
+
+  def has_auto_fix(check_name):
+dirname, _, check_name = check_name.partition("-")
+
+checkerCode = os.path.join(dirname, get_camel_name(check_name)) + ".cpp"
+
+if not os.path.isfile(checkerCode):
+  return ""
+
+with open(checkerCode) as f:
+  code = f.read()
+  if 'FixItHint' in code or "ReplacementText" in code or "fixit" in code:
+# Some simple heuristics to figure out if a checker has an autofix or not.
+return ' "Yes"'
+return ""
+
+  def process_doc(doc_file):
+check_name = doc_file.replace('.rst', '')
+
+with open(os.path.join(docs_dir, doc_file), 'r') as doc:
+  content = doc.read()
+  match = re.search('.*:orphan:.*', content)
+
+  if match:
+# Orphan page, don't list it.
+return '', ''
+
+  match = re.search('.*:http-equiv=refresh: \d+;URL=(.*).html.*',
+content)
+  # Is it a redirect?
+  return check_name, match
+
+  def format_link(doc_file):
+check_name, match = process_doc(doc_file)
+if not match and check_name:
+  return '   `%(check)s <%(check)s.html>`_,%(autofix)s\n' % {
+'check': check_name,
+'autofix': has_auto_fix(check_name)
+  }
+else:
+  return ''
+
+  def format_link_alias(doc_file):
+check_name, match = process_doc(doc_file)
+if match and check_name:
+  if match.group(1) == 'https://clang.llvm.org/docs/analyzer/checkers':
+title_redirect = 'Clang Static Analyzer'
+  else:
+title_redirect = match.group(1)
+  # The checker is just a redirect.
+  return '   `%(check)s <%(check)s.html>`_, `%(title)s <%(target)s.html>`_,%(autofix)s\n' % {
+'check': check_name,
+'target': match.group(1),
+'title': title_redirect,
+'autofix': has_auto_fix(match.group(1))
+  }
+return ''
+
+  checks = map(format_link, doc_files)
+  checks_alias = map(format_link_alias, doc_files)
+
+  print('Updating %s...' % filename)
+  with open(filename, 'w') as f:
+for line in lines:
+  f.write(line)
+  if line.strip() == ".. csv-table::":
+# We dump the checkers
+f.write('   :header: "Name", "Offers fixes"\n\n')
+f.writelines(checks)
+# and the aliases
+f.write('\n\n')
+f.write('.. csv-table:: Aliases..\n')
+f.write('   :header: "Name", "Redirect", "Offers fixes"\n\n')
+f.writelines(checks_alias)
+break
Index: clang-tools-extra/clang-tidy/rename_check.py
===
--- clang-tools-extra/clang-tidy/rename_check.py
+++ clang-tools-extra/clang-tidy/rename_check.py
@@ -12,6 +12,7 @@
 import glob
 import 

[PATCH] D75134: [clang-tidy] Improved renamer check logic

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246610.
njames93 added a comment.

- Linted entire checks and moved more code into common module


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75134/new/

https://reviews.llvm.org/D75134

Files:
  clang-tools-extra/clang-tidy/add_new_check.py
  clang-tools-extra/clang-tidy/rename_check.py
  clang-tools-extra/clang-tidy/utils/__init__.py
  clang-tools-extra/clang-tidy/utils/modify_check.py

Index: clang-tools-extra/clang-tidy/utils/modify_check.py
===
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/modify_check.py
@@ -0,0 +1,158 @@
+#!/usr/bin/env python
+#
+# ===- modify_check.py - clang-tidy check generator --*- python -*--===#
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===---===#
+
+import os
+import re
+
+
+def getCamelName(CheckName):
+  return ''.join(map(lambda elem: elem.capitalize(),
+ CheckName.split('-'))) + 'Check'
+
+
+# Adapts the module's CMakelist file. Returns 'True' if it could add a new entry
+# and 'False' if the entry already existed.
+def adaptCmake(module_path, CheckNameCamel):
+  Filename = os.path.join(module_path, 'CMakeLists.txt')
+  with open(Filename, 'r') as F:
+Lines = F.readlines()
+
+  CppFile = CheckNameCamel + '.cpp'
+
+  # Figure out whether this check already exists.
+  for Line in Lines:
+if Line.strip() == CppFile:
+  return False
+
+  print('Updating %s...' % Filename)
+  with open(Filename, 'w') as F:
+CppFound = False
+FileAdded = False
+for Line in Lines:
+  CppLine = Line.strip().endswith('.cpp')
+  if (not FileAdded) and (CppLine or CppFound):
+CppFound = True
+if (Line.strip() > CppFile) or (not CppLine):
+  F.write('  ' + CppFile + '\n')
+  FileAdded = True
+  F.write(Line)
+
+  return True
+
+
+# Recreates the list of checks in the docs/clang-tidy/checks directory.
+def updateChecksList(clang_tidy_path):
+  DocsDir = os.path.join(clang_tidy_path, '../docs/clang-tidy/checks')
+  Filename = os.path.normpath(os.path.join(DocsDir, 'list.rst'))
+  # Read the content of the current list.rst file
+  with open(Filename, 'r') as F:
+Lines = F.readlines()
+  # Get all existing docs
+  DocFiles = list(
+  filter(lambda s: s.endswith('.rst') and s != 'list.rst',
+ os.listdir(DocsDir)))
+  DocFiles.sort()
+
+  def hasAutoFix(CheckName):
+DirName, _, CheckName = CheckName.partition("-")
+
+CheckerCode = os.path.join(DirName, getCamelName(CheckName)) + ".cpp"
+
+if not os.path.isfile(CheckerCode):
+  return ""
+
+with open(CheckerCode) as F:
+  code = F.read()
+  if 'FixItHint' in code or "ReplacementText" in code or "fixit" in code:
+# Some simple heuristics to figure out if a checker has an autofix.
+return ' "Yes"'
+return ""
+
+  def processDoc(DocFile):
+CheckName = DocFile.replace('.rst', '')
+
+with open(os.path.join(DocsDir, DocFile), 'r') as Doc:
+  content = Doc.read()
+  Match = re.search('.*:orphan:.*', content)
+
+  if Match:
+# Orphan page, don't list it.
+return '', ''
+
+  Match = re.search(r'.*:http-equiv=refresh: \d+;URL=(.*).html.*', content)
+  # Is it a redirect?
+  return CheckName, Match
+
+  def formatLink(DocFile):
+CheckName, Match = processDoc(DocFile)
+if not Match and CheckName:
+  return '   `%(check)s <%(check)s.html>`_,%(autofix)s\n' % {
+  'check': CheckName,
+  'autofix': hasAutoFix(CheckName)
+  }
+else:
+  return ''
+
+  def formatLinkAlias(DocFile):
+CheckName, Match = processDoc(DocFile)
+if Match and CheckName:
+  if Match.group(1) == 'https://clang.llvm.org/docs/analyzer/checkers':
+TitleRedirect = 'Clang Static Analyzer'
+  else:
+TitleRedirect = Match.group(1)
+  # The checker is just a redirect.
+  return '   `%(check)s <%(check)s.html>`_, `%(title)s <%(target)s.html>`_,%(autofix)s\n' % {
+  'check': CheckName,
+  'target': Match.group(1),
+  'title': TitleRedirect,
+  'autofix': hasAutoFix(Match.group(1))
+  }
+return ''
+
+  Checks = map(formatLink, DocFiles)
+  ChecksAlias = map(formatLinkAlias, DocFiles)
+
+  print('Updating %s...' % Filename)
+  with open(Filename, 'w') as F:
+for Line in Lines:
+  F.write(Line)
+  if Line.strip() == ".. csv-table::":
+# We dump the checkers
+F.write('   :header: "Name", "Offers fixes"\n\n')
+F.writelines(Checks)
+# and the aliases
+F.write('\n\n')
+F.write('.. csv-table:: Aliases..\n')
+F.write('   :header: "Name", 

[PATCH] D74669: [clang-tidy] New check: misc-no-include-cpp

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

In D74669#1892577 , @jroelofs wrote:

> Implement review feedback:
>
> - Re-purpose `HeaderFileExtensionsUtils.h` to support headers *and* sources.
> - Surround file extension in diagnostic with `''`s.
>
> I have these as two separate patches locally, but I don't know how to 
> represent that in phabricator, so I've uploaded the diff across both. If this 
> gets approved, I intend to push them as separate commits.


You can create a review that just re-purposes HeaderFileExtensionsUtils then 
set that review as a parent of this review


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74669/new/

https://reviews.llvm.org/D74669



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75134: [clang-tidy] Improved renamer check logic

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246614.
njames93 added a comment.

- Fix typo


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75134/new/

https://reviews.llvm.org/D75134

Files:
  clang-tools-extra/clang-tidy/add_new_check.py
  clang-tools-extra/clang-tidy/rename_check.py
  clang-tools-extra/clang-tidy/utils/__init__.py
  clang-tools-extra/clang-tidy/utils/modify_check.py

Index: clang-tools-extra/clang-tidy/utils/modify_check.py
===
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/modify_check.py
@@ -0,0 +1,158 @@
+#!/usr/bin/env python
+#
+# ===- modify_check.py - clang-tidy check generator --*- python -*--===#
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===---===#
+
+import os
+import re
+
+
+def getCamelName(CheckName):
+  return ''.join(map(lambda elem: elem.capitalize(),
+ CheckName.split('-'))) + 'Check'
+
+
+# Adapts the module's CMakelist file. Returns 'True' if it could add a new entry
+# and 'False' if the entry already existed.
+def adaptCmake(module_path, CheckNameCamel):
+  Filename = os.path.join(module_path, 'CMakeLists.txt')
+  with open(Filename, 'r') as F:
+Lines = F.readlines()
+
+  CppFile = CheckNameCamel + '.cpp'
+
+  # Figure out whether this check already exists.
+  for Line in Lines:
+if Line.strip() == CppFile:
+  return False
+
+  print('Updating %s...' % Filename)
+  with open(Filename, 'w') as F:
+CppFound = False
+FileAdded = False
+for Line in Lines:
+  CppLine = Line.strip().endswith('.cpp')
+  if (not FileAdded) and (CppLine or CppFound):
+CppFound = True
+if (Line.strip() > CppFile) or (not CppLine):
+  F.write('  ' + CppFile + '\n')
+  FileAdded = True
+  F.write(Line)
+
+  return True
+
+
+# Recreates the list of checks in the docs/clang-tidy/checks directory.
+def updateChecksList(clang_tidy_path):
+  DocsDir = os.path.join(clang_tidy_path, '../docs/clang-tidy/checks')
+  Filename = os.path.normpath(os.path.join(DocsDir, 'list.rst'))
+  # Read the content of the current list.rst file
+  with open(Filename, 'r') as F:
+Lines = F.readlines()
+  # Get all existing docs
+  DocFiles = list(
+  filter(lambda s: s.endswith('.rst') and s != 'list.rst',
+ os.listdir(DocsDir)))
+  DocFiles.sort()
+
+  def hasAutoFix(CheckName):
+DirName, _, CheckName = CheckName.partition("-")
+
+CheckerCode = os.path.join(DirName, getCamelName(CheckName)) + ".cpp"
+
+if not os.path.isfile(CheckerCode):
+  return ""
+
+with open(CheckerCode) as F:
+  code = F.read()
+  if 'FixItHint' in code or "ReplacementText" in code or "fixit" in code:
+# Some simple heuristics to figure out if a checker has an autofix.
+return ' "Yes"'
+return ""
+
+  def processDoc(DocFile):
+CheckName = DocFile.replace('.rst', '')
+
+with open(os.path.join(DocsDir, DocFile), 'r') as Doc:
+  content = Doc.read()
+  Match = re.search('.*:orphan:.*', content)
+
+  if Match:
+# Orphan page, don't list it.
+return '', ''
+
+  Match = re.search(r'.*:http-equiv=refresh: \d+;URL=(.*).html.*', content)
+  # Is it a redirect?
+  return CheckName, Match
+
+  def formatLink(DocFile):
+CheckName, Match = processDoc(DocFile)
+if not Match and CheckName:
+  return '   `%(check)s <%(check)s.html>`_,%(autofix)s\n' % {
+  'check': CheckName,
+  'autofix': hasAutoFix(CheckName)
+  }
+else:
+  return ''
+
+  def formatLinkAlias(DocFile):
+CheckName, Match = processDoc(DocFile)
+if Match and CheckName:
+  if Match.group(1) == 'https://clang.llvm.org/docs/analyzer/checkers':
+TitleRedirect = 'Clang Static Analyzer'
+  else:
+TitleRedirect = Match.group(1)
+  # The checker is just a redirect.
+  return '   `%(check)s <%(check)s.html>`_, `%(title)s <%(target)s.html>`_,%(autofix)s\n' % {
+  'check': CheckName,
+  'target': Match.group(1),
+  'title': TitleRedirect,
+  'autofix': hasAutoFix(Match.group(1))
+  }
+return ''
+
+  Checks = map(formatLink, DocFiles)
+  ChecksAlias = map(formatLinkAlias, DocFiles)
+
+  print('Updating %s...' % Filename)
+  with open(Filename, 'w') as F:
+for Line in Lines:
+  F.write(Line)
+  if Line.strip() == ".. csv-table::":
+# We dump the checkers
+F.write('   :header: "Name", "Offers fixes"\n\n')
+F.writelines(Checks)
+# and the aliases
+F.write('\n\n')
+F.write('.. csv-table:: Aliases..\n')
+F.write('   :header: "Name", "Redirect", "Offers fixes"\n\n')
+

[PATCH] D75134: [clang-tidy] Improved renamer check logic

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

In D75134#1892607 , @Eugene.Zelenko 
wrote:

> It'll be reasonable to find out what are naming conventions for Python in 
> LLVM.


I just stuck to the trusty old c++ naming conventions. Having a look I see most 
of it is using `lower_case` for all identifiers but then in there are always 
failures in the files along with that


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75134/new/

https://reviews.llvm.org/D75134



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75113: [docs] dump-ast-matchers removes const from Matcher args and handles template functions slightly better

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb653ab0e7019: [docs] dump-ast-matchers removes const from 
Matcher args and handles template… (authored by njames93).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75113/new/

https://reviews.llvm.org/D75113

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/tools/dump_ast_matchers.py

Index: clang/docs/tools/dump_ast_matchers.py
===
--- clang/docs/tools/dump_ast_matchers.py
+++ clang/docs/tools/dump_ast_matchers.py
@@ -101,6 +101,8 @@
   args = re.sub(r'extern const\s+(.*)&', r'\1 ', args)
   args = re.sub(r'&', r' ', args)
   args = re.sub(r'(^|\s)M\d?(\s)', r'\1Matcher<*>\2', args)
+  args = re.sub(r'BindableMatcher', r'Matcher', args)
+  args = re.sub(r'const Matcher', r'Matcher', args)
   return args
 
 def unify_type(result_type):
@@ -125,7 +127,8 @@
 'id': matcher_id,
   }
   if is_dyncast:
-node_matchers[result_type + name] = matcher_html
+dict = node_matchers
+lookup = result_type + name
   # Use a heuristic to figure out whether a matcher is a narrowing or
   # traversal matcher. By default, matchers that take other matchers as
   # arguments (and are not node matchers) do traversal. We specifically
@@ -133,9 +136,14 @@
   # arguments.
   elif ('Matcher<' not in args or
 name in ['allOf', 'anyOf', 'anything', 'unless']):
-narrowing_matchers[result_type + name + esc(args)] = matcher_html
+dict = narrowing_matchers
+lookup = result_type + name + esc(args)
   else:
-traversal_matchers[result_type + name + esc(args)] = matcher_html
+dict = traversal_matchers
+lookup = result_type + name + esc(args)
+  
+  if dict.get(lookup) is None or len(dict.get(lookup)) < len(matcher_html):
+dict[lookup] = matcher_html
 
 def act_on_decl(declaration, comment, allowed_types):
   """Parse the matcher out of the given declaration and comment.
@@ -145,6 +153,9 @@
  definition.
   """
   if declaration.strip():
+
+if re.match(r'^\s?(#|namespace|using)', declaration): return
+
 # Node matchers are defined by writing:
 #   VariadicDynCastAllOfMatcher name;
 m = re.match(r""".*Variadic(?:DynCast)?AllOfMatcher\s*<
@@ -317,16 +328,27 @@
 
 # Parse free standing matcher functions, like:
 #   Matcher Name(Matcher InnerMatcher) {
-m = re.match(r"""^\s*(.*)\s+
+m = re.match(r"""^\s*(?:template\s+<\s*(?:class|typename)\s+(.+)\s*>\s+)?   
+ (.*)\s+
  ([^\s\(]+)\s*\(
  (.*)
  \)\s*{""", declaration, re.X)
 if m:
-  result, name, args = m.groups()
+  template_name, result, name, args = m.groups()
+  if template_name:
+matcherTemplateArgs = re.findall(r'Matcher<\s*(%s)\s*>' % template_name, args)
+templateArgs = re.findall(r'(?:^|[\s,<])(%s)(?:$|[\s,>])' % template_name, args)
+if len(matcherTemplateArgs) < len(templateArgs):
+  # The template name is used naked, so don't replace with `*`` later on
+  template_name = None
+else :
+  args = re.sub(r'(^|[\s,<])%s($|[\s,>])' % template_name, r'\1*\2', args)
   args = ', '.join(p.strip() for p in args.split(','))
-  m = re.match(r'.*\s+internal::(Bindable)?Matcher<([^>]+)>$', result)
+  m = re.match(r'(?:^|.*\s+)internal::(?:Bindable)?Matcher<([^>]+)>$', result)
   if m:
-result_types = [m.group(2)]
+result_types = [m.group(1)]
+if template_name and len(result_types) is 1 and result_types[0] == template_name:
+  result_types = ['*']
   else:
 result_types = extract_result_types(comment)
   if not result_types:
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -4669,6 +4669,22 @@
 
 
 
+Matcher*findAllMatcher*  Matcher
+Matches if the node or any descendant matches.
+
+Generates results for each match.
+
+For example, in:
+  class A { class B {}; class C {}; };
+The matcher:
+  cxxRecordDecl(hasName("::A"),
+findAll(cxxRecordDecl(isDefinition()).bind("m")))
+will generate results for A, B and C.
+
+Usable as: Any Matcher
+
+
+
 Matcher*forEachDescendantMatcher*
 Matches AST nodes that have descendant AST nodes that match the
 provided matcher.
@@ -4803,6 +4819,22 @@
 
 
 
+Matcher*traverseTraversalKind TK, Matcher*  InnerMatcher
+Causes all nested matchers to be matched with the specified traversal kind.
+
+Given
+  void foo()
+  {
+  int i = 3.0;
+  }
+The matcher
+  traverse(TK_IgnoreImplicitCastsAndParentheses,
+varDecl(hasInitializer(floatLiteral().bind("init")))
+  )
+matches the variable declaration with "init" bound to the "3.0".
+
+
+
 

[PATCH] D75152: Fix typo

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75152

Files:
  clang-tools-extra/clang-tidy/add_new_check.py


Index: clang-tools-extra/clang-tidy/add_new_check.py
===
--- clang-tools-extra/clang-tidy/add_new_check.py
+++ clang-tools-extra/clang-tidy/add_new_check.py
@@ -129,7 +129,7 @@
 HeaderFound = False
 CheckAdded = False
 CheckFqName = Module + '-' + CheckName
-CHeckDecl = ('CheckFactories.registerCheck<' + CheckNameCamel
+CheckDecl = ('CheckFactories.registerCheck<' + CheckNameCamel
  + '>(\n"' + CheckFqName + '");\n')
 
 Lines = iter(Lines)
@@ -150,7 +150,7 @@
 if not CheckAdded:
   if Line.strip() == '}':
 CheckAdded = True
-F.write(CHeckDecl)
+F.write(CheckDecl)
   else:
 Match = re.search(r'registerCheck<(.*)> *\( *(?:"([^"]*)")?', Line)
 PrevLine = None
@@ -166,7 +166,7 @@
   CurrentCheckName = Match.group(1)
   if CurrentCheckName > CheckFqName:
 CheckAdded = True
-F.write(CHeckDecl)
+F.write(CheckDecl)
   if PrevLine:
 F.write(PrevLine)
 F.write(Line)


Index: clang-tools-extra/clang-tidy/add_new_check.py
===
--- clang-tools-extra/clang-tidy/add_new_check.py
+++ clang-tools-extra/clang-tidy/add_new_check.py
@@ -129,7 +129,7 @@
 HeaderFound = False
 CheckAdded = False
 CheckFqName = Module + '-' + CheckName
-CHeckDecl = ('CheckFactories.registerCheck<' + CheckNameCamel
+CheckDecl = ('CheckFactories.registerCheck<' + CheckNameCamel
  + '>(\n"' + CheckFqName + '");\n')
 
 Lines = iter(Lines)
@@ -150,7 +150,7 @@
 if not CheckAdded:
   if Line.strip() == '}':
 CheckAdded = True
-F.write(CHeckDecl)
+F.write(CheckDecl)
   else:
 Match = re.search(r'registerCheck<(.*)> *\( *(?:"([^"]*)")?', Line)
 PrevLine = None
@@ -166,7 +166,7 @@
   CurrentCheckName = Match.group(1)
   if CurrentCheckName > CheckFqName:
 CheckAdded = True
-F.write(CHeckDecl)
+F.write(CheckDecl)
   if PrevLine:
 F.write(PrevLine)
 F.write(Line)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75134: [clang-tidy] Improved renamer check logic

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

Feel free to apply this and see how it works. Tested with checks that have 
alias variants which seem to respond well. Renaming a check then renaming it 
back reverts the state to how it was before apart from release notes and maybe 
some non standard comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75134/new/

https://reviews.llvm.org/D75134



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75152: Fix typo

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
njames93 closed this revision.
njames93 added a comment.

In D75152#1892621 , @echristo wrote:

> This probably qualifies as "obvious" :)


This was arc diff screwing up and creating a new revision instead of updating :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75152/new/

https://reviews.llvm.org/D75152



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75046: [docs] dump_ast_matchers strips internal::(Bindable)?Matcher from Result_type

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGe6f9cb025cd7: [docs] dump_ast_matchers strips 
internal::(Bindable)?Matcher from Result_type (authored by njames93).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75046/new/

https://reviews.llvm.org/D75046

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/tools/dump_ast_matchers.py
  clang/include/clang/ASTMatchers/ASTMatchers.h

Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -307,7 +307,7 @@
 ///
 /// FIXME: Change to be a polymorphic matcher that works on any syntactic
 /// node. There's nothing `Stmt`-specific about it.
-AST_MATCHER_P(clang::Stmt, isExpandedFromMacro, llvm::StringRef, MacroName) {
+AST_MATCHER_P(Stmt, isExpandedFromMacro, llvm::StringRef, MacroName) {
   // Verifies that the statement' beginning and ending are both expanded from
   // the same instance of the given macro.
   auto& Context = Finder->getASTContext();
Index: clang/docs/tools/dump_ast_matchers.py
===
--- clang/docs/tools/dump_ast_matchers.py
+++ clang/docs/tools/dump_ast_matchers.py
@@ -103,6 +103,11 @@
   args = re.sub(r'(^|\s)M\d?(\s)', r'\1Matcher<*>\2', args)
   return args
 
+def unify_type(result_type):
+  """Gets rid of anything the user doesn't care about in the type name."""
+  result_type = re.sub(r'^internal::(Bindable)?Matcher<([a-zA-Z_][a-zA-Z0-9_]*)>$', r'\2', result_type)
+  return result_type
+
 def add_matcher(result_type, name, args, comment, is_dyncast=False):
   """Adds a matcher to one of our categories."""
   if name == 'id':
@@ -111,6 +116,7 @@
   matcher_id = '%s%d' % (name, ids[name])
   ids[name] += 1
   args = unify_arguments(args)
+  result_type = unify_type(result_type)
   matcher_html = TD_TEMPLATE % {
 'result': esc('Matcher<%s>' % result_type),
 'name': name,
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -2948,6 +2948,19 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Decl.html;>DeclisInstantiated
+Matches declarations that are template instantiations or are inside
+template instantiations.
+
+Given
+  templatetypename T void A(T t) { T i; }
+  A(0);
+  A(0U);
+functionDecl(isInstantiated())
+  matches 'A(int) {...};' and 'A(unsigned) {...}'.
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Decl.html;>DeclisPrivate
 Matches private C++ declarations.
 
@@ -3516,6 +3529,16 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html;>NamedDeclhasAnyNameStringRef, ..., StringRef
+Matches NamedDecl nodes that have any of the specified names.
+
+This matcher is only provided as a performance optimization of hasName.
+hasAnyName(a, b, c)
+ is equivalent to, but faster than
+anyOf(hasName(a), hasName(b), hasName(c))
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html;>NamedDeclhasExternalFormalLinkage
 Matches a declaration that has external formal linkage.
 
@@ -3679,6 +3702,17 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html;>ObjCMessageExprhasAnySelectorStringRef, ..., StringRef
+Matches when at least one of the supplied string equals to the
+Selector.getAsString()
+
+ matcher = objCMessageExpr(hasSelector("methodA:", "methodB:"));
+ matches both of the expressions below:
+[myObj methodA:argA];
+[myObj methodB:argB];
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html;>ObjCMessageExprhasKeywordSelector
 Matches when the selector is a keyword selector
 
@@ -4015,6 +4049,17 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtisExpandedFromMacrollvm::StringRef MacroName
+Matches statements that are (transitively) expanded from the named macro.
+Does not match if only part of the statement is expanded from that macro or
+if different parts of the the statement are expanded from different
+appearances of the macro.
+
+FIXME: Change to be a polymorphic matcher that works on any syntactic
+node. There's nothing `Stmt`-specific about it.
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtisExpansionInFileMatchingstd::string RegExp
 Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
@@ -4058,6 +4103,22 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtisInTemplateInstantiation
+Matches statements inside of a template instantiation.
+
+Given
+  int j;
+  templatetypename T void A(T t) { T i; j += 42;}
+  A(0);
+  A(0U);
+declStmt(isInTemplateInstantiation())
+  matches 'int i;' and 'unsigned 

[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246335.
njames93 added a comment.

- Rebase with trunk


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/tools/dump_ast_matchers.py
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1123,6 +1123,19 @@
   EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
 }
 
+TEST(MatchBinaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher =
+  binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
+
+  EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
+  EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
+  // Ensure '+= isn't mistaken.
+  EXPECT_TRUE(notMatches("void x(int ) { I += 1; }", Matcher));
+}
+
 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
   StatementMatcher OperatorTrueFalse =
 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
@@ -1255,6 +1268,18 @@
   EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
 }
 
+TEST(MatchUnaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
+
+  EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { I++; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { ++I; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { I--; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { --I; }", Matcher));
+  EXPECT_TRUE(notMatches("int *x(int ) { return  }", Matcher));
+}
+
 TEST(MatchUnaryOperator, HasUnaryOperand) {
   StatementMatcher OperatorOnFalse =
 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -243,6 +243,7 @@
   REGISTER_MATCHER(hasAnyConstructorInitializer);
   REGISTER_MATCHER(hasAnyDeclaration);
   REGISTER_MATCHER(hasAnyName);
+  REGISTER_MATCHER(hasAnyOperatorName);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnyPlacementArg);
   REGISTER_MATCHER(hasAnySelector);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -380,6 +380,10 @@
   return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
 }
 
+HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef NameRefs) {
+  return HasOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
 HasNameMatcher::HasNameMatcher(std::vector N)
 : UseUnqualifiedMatch(std::all_of(
   N.begin(), N.end(),
@@ -854,6 +858,10 @@
 const internal::VariadicFunction, StringRef,
  internal::hasAnyNameFunc>
 hasAnyName = {};
+
+const internal::VariadicFunction
+hasAnyOperatorName = {};
 const internal::VariadicFunction, StringRef,
  internal::hasAnySelectorFunc>
 hasAnySelector = {};
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1858,6 +1858,47 @@
 llvm::Optional
 getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
const ASTContext );
+
+/// Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be std::vector>.
+template >
+class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface {
+  static_assert(std::is_same::value ||
+std::is_same::value,
+"Matcher only supports `BinaryOperator` and `UnaryOperator`");
+  static_assert(std::is_same>::value,
+"Matcher ArgT must be std::vector");
+
+public:
+  explicit HasAnyOperatorNameMatcher(std::vector Names)
+  : SingleNodeMatcherInterface(), Names(std::move(Names)) {}
+
+  bool matchesNode(const T ) const 

[PATCH] D75134: [clang-tidy] Improved renamer check logic

2020-02-26 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246653.
njames93 added a comment.

- Moved shared code into __init__


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75134/new/

https://reviews.llvm.org/D75134

Files:
  clang-tools-extra/clang-tidy/add_new_check.py
  clang-tools-extra/clang-tidy/rename_check.py
  clang-tools-extra/clang-tidy/utils/__init__.py

Index: clang-tools-extra/clang-tidy/utils/__init__.py
===
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/__init__.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+#
+# ===- __init__.py - clang-tidy check generator utils *- python -*--===#
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===---===#
+
+import os
+import re
+
+
+def get_camel_name(check_name):
+  return ''.join(map(lambda elem: elem.capitalize(),
+ check_name.split('-'))) + 'Check'
+
+
+# Adapts the module's CMakelist file. Returns 'True' if it could add a new entry
+# and 'False' if the entry already existed.
+def adapt_cmake(module_path, check_name_camel):
+  filename = os.path.join(module_path, 'CMakeLists.txt')
+  with open(filename, 'r') as f:
+lines = f.readlines()
+
+  cpp_file = check_name_camel + '.cpp'
+
+  # Figure out whether this check already exists.
+  for line in lines:
+if line.strip() == cpp_file:
+  return False
+
+  print('Updating %s...' % filename)
+  with open(filename, 'w') as f:
+cpp_found = False
+file_added = False
+for line in lines:
+  cpp_line = line.strip().endswith('.cpp')
+  if (not file_added) and (cpp_line or cpp_found):
+cpp_found = True
+if (line.strip() > cpp_file) or (not cpp_line):
+  f.write('  ' + cpp_file + '\n')
+  file_added = True
+  f.write(line)
+
+  return True
+
+
+# Recreates the list of checks in the docs/clang-tidy/checks directory.
+def update_checks_list(clang_tidy_path):
+  docs_dir = os.path.join(clang_tidy_path, '../docs/clang-tidy/checks')
+  filename = os.path.normpath(os.path.join(docs_dir, 'list.rst'))
+  # Read the content of the current list.rst file
+  with open(filename, 'r') as f:
+lies = f.readlines()
+  # Get all existing docs
+  doc_files = list(
+  filter(lambda s: s.endswith('.rst') and s != 'list.rst',
+ os.listdir(docs_dir)))
+  doc_files.sort()
+
+  def has_autofix(check_name):
+dir_name, _, check_name = check_name.partition("-")
+
+checker_code = os.path.join(dir_name, get_camel_name(check_name)) + ".cpp"
+
+if not os.path.isfile(checker_code):
+  return ""
+
+with open(checker_code) as f:
+  code = f.read()
+  if 'FixItHint' in code or "ReplacementText" in code or "fixit" in code:
+# Some simple heuristics to figure out if a checker has an autofix.
+return ' "Yes"'
+return ""
+
+  def process_doc(doc_file):
+check_name = doc_file.replace('.rst', '')
+
+with open(os.path.join(docs_dir, doc_file), 'r') as doc:
+  content = doc.read()
+  match = re.search('.*:orphan:.*', content)
+
+  if match:
+# Orphan page, don't list it.
+return '', ''
+
+  match = re.search(r'.*:http-equiv=refresh: \d+;URL=(.*).html.*', content)
+  # Is it a redirect?
+  return check_name, match
+
+  def format_link(doc_file):
+check_name, match = process_doc(doc_file)
+if not match and check_name:
+  return '   `%(check)s <%(check)s.html>`_,%(autofix)s\n' % {
+  'check': check_name,
+  'autofix': has_autofix(check_name)
+  }
+else:
+  return ''
+
+  def format_link_alias(doc_file):
+check_name, match = process_doc(doc_file)
+if match and check_name:
+  if match.group(1) == 'https://clang.llvm.org/docs/analyzer/checkers':
+title_redirect = 'Clang Static Analyzer'
+  else:
+title_redirect = match.group(1)
+  # The checker is just a redirect.
+  return '   `%(check)s <%(check)s.html>`_, \
+`%(title)s <%(target)s.html>`_,%(autofix)s\n' % {
+  'check': check_name,
+  'target': match.group(1),
+  'title': title_redirect,
+  'autofix': has_autofix(match.group(1))
+  }
+return ''
+
+  checks = map(format_link, doc_files)
+  checks_alias = map(format_link_alias, doc_files)
+
+  print('Updating %s...' % filename)
+  with open(filename, 'w') as f:
+for line in lies:
+  f.write(line)
+  if line.strip() == ".. csv-table::":
+# We dump the checkers
+f.write('   :header: "Name", "Offers fixes"\n\n')
+f.writelines(checks)
+# and the aliases
+f.write('\n\n')
+f.write('.. csv-table:: Aliases..\n')
+f.write('   :header: "Name", "Redirect", 

[PATCH] D75134: [clang-tidy] Improved renamer check logic

2020-02-26 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246650.
njames93 added a comment.

- Changed naming to what appears to be llvm python style


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75134/new/

https://reviews.llvm.org/D75134

Files:
  clang-tools-extra/clang-tidy/add_new_check.py
  clang-tools-extra/clang-tidy/rename_check.py
  clang-tools-extra/clang-tidy/utils/__init__.py
  clang-tools-extra/clang-tidy/utils/modify_check.py

Index: clang-tools-extra/clang-tidy/utils/modify_check.py
===
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/modify_check.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+#
+# ===- modify_check.py - clang-tidy check generator --*- python -*--===#
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===---===#
+
+import os
+import re
+
+
+def get_camel_name(check_name):
+  return ''.join(map(lambda elem: elem.capitalize(),
+ check_name.split('-'))) + 'Check'
+
+
+# Adapts the module's CMakelist file. Returns 'True' if it could add a new entry
+# and 'False' if the entry already existed.
+def adapt_cmake(module_path, check_name_camel):
+  filename = os.path.join(module_path, 'CMakeLists.txt')
+  with open(filename, 'r') as f:
+lines = f.readlines()
+
+  cpp_file = check_name_camel + '.cpp'
+
+  # Figure out whether this check already exists.
+  for line in lines:
+if line.strip() == cpp_file:
+  return False
+
+  print('Updating %s...' % filename)
+  with open(filename, 'w') as f:
+cpp_found = False
+file_added = False
+for line in lines:
+  cpp_line = line.strip().endswith('.cpp')
+  if (not file_added) and (cpp_line or cpp_found):
+cpp_found = True
+if (line.strip() > cpp_file) or (not cpp_line):
+  f.write('  ' + cpp_file + '\n')
+  file_added = True
+  f.write(line)
+
+  return True
+
+
+# Recreates the list of checks in the docs/clang-tidy/checks directory.
+def update_checks_list(clang_tidy_path):
+  docs_dir = os.path.join(clang_tidy_path, '../docs/clang-tidy/checks')
+  filename = os.path.normpath(os.path.join(docs_dir, 'list.rst'))
+  # Read the content of the current list.rst file
+  with open(filename, 'r') as f:
+lies = f.readlines()
+  # Get all existing docs
+  doc_files = list(
+  filter(lambda s: s.endswith('.rst') and s != 'list.rst',
+ os.listdir(docs_dir)))
+  doc_files.sort()
+
+  def has_autofix(check_name):
+dir_name, _, check_name = check_name.partition("-")
+
+checker_code = os.path.join(dir_name, get_camel_name(check_name)) + ".cpp"
+
+if not os.path.isfile(checker_code):
+  return ""
+
+with open(checker_code) as f:
+  code = f.read()
+  if 'FixItHint' in code or "ReplacementText" in code or "fixit" in code:
+# Some simple heuristics to figure out if a checker has an autofix.
+return ' "Yes"'
+return ""
+
+  def process_doc(doc_file):
+check_name = doc_file.replace('.rst', '')
+
+with open(os.path.join(docs_dir, doc_file), 'r') as doc:
+  content = doc.read()
+  match = re.search('.*:orphan:.*', content)
+
+  if match:
+# Orphan page, don't list it.
+return '', ''
+
+  match = re.search(r'.*:http-equiv=refresh: \d+;URL=(.*).html.*', content)
+  # Is it a redirect?
+  return check_name, match
+
+  def format_link(doc_file):
+check_name, match = process_doc(doc_file)
+if not match and check_name:
+  return '   `%(check)s <%(check)s.html>`_,%(autofix)s\n' % {
+  'check': check_name,
+  'autofix': has_autofix(check_name)
+  }
+else:
+  return ''
+
+  def format_link_alias(doc_file):
+check_name, match = process_doc(doc_file)
+if match and check_name:
+  if match.group(1) == 'https://clang.llvm.org/docs/analyzer/checkers':
+title_redirect = 'Clang Static Analyzer'
+  else:
+title_redirect = match.group(1)
+  # The checker is just a redirect.
+  return '   `%(check)s <%(check)s.html>`_, \
+`%(title)s <%(target)s.html>`_,%(autofix)s\n' % {
+  'check': check_name,
+  'target': match.group(1),
+  'title': title_redirect,
+  'autofix': has_autofix(match.group(1))
+  }
+return ''
+
+  checks = map(format_link, doc_files)
+  checks_alias = map(format_link_alias, doc_files)
+
+  print('Updating %s...' % filename)
+  with open(filename, 'w') as f:
+for line in lies:
+  f.write(line)
+  if line.strip() == ".. csv-table::":
+# We dump the checkers
+f.write('   :header: "Name", "Offers fixes"\n\n')
+f.writelines(checks)
+# and the aliases
+f.write('\n\n')
+

[PATCH] D75202: [ASTMatchers] HasNameMatcher handles `extern "C"`

2020-02-26 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: klimek, aaron.ballman, gribozavr2.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Fixes hasName AST matcher is confused by extern "C" in namespace. 



Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75202

Files:
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp


Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1643,6 +1643,15 @@
   EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m";
 }
 
+TEST(Matcher, HasNameQualifiedSupportsLinkage) {
+  // https://bugs.llvm.org/show_bug.cgi?id=42193
+  std::string code = R"cpp(namespace foo { extern "C" void test(); })cpp";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test";
+  EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test";
+}
+
 TEST(Matcher, HasAnyName) {
   const std::string Code = "namespace a { namespace b { class C; } }";
 
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -513,7 +513,13 @@
   if (Ctx->isFunctionOrMethod())
 return Patterns.foundMatch(/*AllowFullyQualified=*/false);
 
-  for (; Ctx && isa(Ctx); Ctx = Ctx->getParent()) {
+  for (; Ctx; Ctx = Ctx->getParent()) {
+// Linkage Spec can just be ignored
+// FIXME: Any other DeclContext kinds that can be safely disregarded
+if (isa(Ctx))
+  continue;
+if (!isa(Ctx))
+  break;
 if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
   return true;
 


Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1643,6 +1643,15 @@
   EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m";
 }
 
+TEST(Matcher, HasNameQualifiedSupportsLinkage) {
+  // https://bugs.llvm.org/show_bug.cgi?id=42193
+  std::string code = R"cpp(namespace foo { extern "C" void test(); })cpp";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test";
+  EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test";
+}
+
 TEST(Matcher, HasAnyName) {
   const std::string Code = "namespace a { namespace b { class C; } }";
 
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -513,7 +513,13 @@
   if (Ctx->isFunctionOrMethod())
 return Patterns.foundMatch(/*AllowFullyQualified=*/false);
 
-  for (; Ctx && isa(Ctx); Ctx = Ctx->getParent()) {
+  for (; Ctx; Ctx = Ctx->getParent()) {
+// Linkage Spec can just be ignored
+// FIXME: Any other DeclContext kinds that can be safely disregarded
+if (isa(Ctx))
+  continue;
+if (!isa(Ctx))
+  break;
 if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
   return true;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75202: [ASTMatchers] HasNameMatcher handles `extern "C"`

2020-02-26 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246829.
njames93 marked an inline comment as done.
njames93 added a comment.

- Add extra test case


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75202/new/

https://reviews.llvm.org/D75202

Files:
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp


Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1643,6 +1643,21 @@
   EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m";
 }
 
+TEST(Matcher, HasNameQualifiedSupportsLinkage) {
+  // https://bugs.llvm.org/show_bug.cgi?id=42193
+  std::string code = R"cpp(namespace foo { extern "C" void test(); })cpp";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test";
+  EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test";
+
+  code = R"cpp(namespace foo { extern "C" { void test(); } })cpp";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test";
+  EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test";
+}
+
 TEST(Matcher, HasAnyName) {
   const std::string Code = "namespace a { namespace b { class C; } }";
 
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -513,7 +513,13 @@
   if (Ctx->isFunctionOrMethod())
 return Patterns.foundMatch(/*AllowFullyQualified=*/false);
 
-  for (; Ctx && isa(Ctx); Ctx = Ctx->getParent()) {
+  for (; Ctx; Ctx = Ctx->getParent()) {
+// Linkage Spec can just be ignored
+// FIXME: Any other DeclContext kinds that can be safely disregarded
+if (isa(Ctx))
+  continue;
+if (!isa(Ctx))
+  break;
 if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
   return true;
 


Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1643,6 +1643,21 @@
   EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m";
 }
 
+TEST(Matcher, HasNameQualifiedSupportsLinkage) {
+  // https://bugs.llvm.org/show_bug.cgi?id=42193
+  std::string code = R"cpp(namespace foo { extern "C" void test(); })cpp";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test";
+  EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test";
+
+  code = R"cpp(namespace foo { extern "C" { void test(); } })cpp";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test";
+  EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test";
+}
+
 TEST(Matcher, HasAnyName) {
   const std::string Code = "namespace a { namespace b { class C; } }";
 
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -513,7 +513,13 @@
   if (Ctx->isFunctionOrMethod())
 return Patterns.foundMatch(/*AllowFullyQualified=*/false);
 
-  for (; Ctx && isa(Ctx); Ctx = Ctx->getParent()) {
+  for (; Ctx; Ctx = Ctx->getParent()) {
+// Linkage Spec can just be ignored
+// FIXME: Any other DeclContext kinds that can be safely disregarded
+if (isa(Ctx))
+  continue;
+if (!isa(Ctx))
+  break;
 if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
   return true;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75202: [ASTMatchers] HasNameMatcher handles `extern "C"`

2020-02-26 Thread Nathan James via Phabricator via cfe-commits
njames93 marked an inline comment as done.
njames93 added inline comments.



Comment at: clang/lib/ASTMatchers/ASTMatchersInternal.cpp:518
+// Linkage Spec can just be ignored
+// FIXME: Any other DeclContext kinds that can be safely disregarded
+if (isa(Ctx))

aaron.ballman wrote:
> I would imagine we'd want to skip an `ExternCContextDecl` for similar 
> reasons, though I am struggling to find a test case that actually generates 
> that context.
I couldn't figure a way to generate one of those either. However if a context 
type that isnt found matched the assertions should go off and we can look into 
the issue again


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75202/new/

https://reviews.llvm.org/D75202



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75202: [ASTMatchers] HasNameMatcher handles `extern "C"`

2020-02-26 Thread Nathan James via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG16cabf278fc8: [ASTMatchers] HasNameMatcher handles `extern 
C` (authored by njames93).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75202/new/

https://reviews.llvm.org/D75202

Files:
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp


Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1643,6 +1643,21 @@
   EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m";
 }
 
+TEST(Matcher, HasNameQualifiedSupportsLinkage) {
+  // https://bugs.llvm.org/show_bug.cgi?id=42193
+  std::string code = R"cpp(namespace foo { extern "C" void test(); })cpp";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test";
+  EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test";
+
+  code = R"cpp(namespace foo { extern "C" { void test(); } })cpp";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test";
+  EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test";
+}
+
 TEST(Matcher, HasAnyName) {
   const std::string Code = "namespace a { namespace b { class C; } }";
 
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -513,7 +513,13 @@
   if (Ctx->isFunctionOrMethod())
 return Patterns.foundMatch(/*AllowFullyQualified=*/false);
 
-  for (; Ctx && isa(Ctx); Ctx = Ctx->getParent()) {
+  for (; Ctx; Ctx = Ctx->getParent()) {
+// Linkage Spec can just be ignored
+// FIXME: Any other DeclContext kinds that can be safely disregarded
+if (isa(Ctx))
+  continue;
+if (!isa(Ctx))
+  break;
 if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
   return true;
 


Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1643,6 +1643,21 @@
   EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m";
 }
 
+TEST(Matcher, HasNameQualifiedSupportsLinkage) {
+  // https://bugs.llvm.org/show_bug.cgi?id=42193
+  std::string code = R"cpp(namespace foo { extern "C" void test(); })cpp";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test";
+  EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test";
+
+  code = R"cpp(namespace foo { extern "C" { void test(); } })cpp";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("foo::test";
+  EXPECT_TRUE(matches(code, functionDecl(hasName("::foo::test";
+  EXPECT_TRUE(notMatches(code, functionDecl(hasName("::test";
+}
+
 TEST(Matcher, HasAnyName) {
   const std::string Code = "namespace a { namespace b { class C; } }";
 
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -513,7 +513,13 @@
   if (Ctx->isFunctionOrMethod())
 return Patterns.foundMatch(/*AllowFullyQualified=*/false);
 
-  for (; Ctx && isa(Ctx); Ctx = Ctx->getParent()) {
+  for (; Ctx; Ctx = Ctx->getParent()) {
+// Linkage Spec can just be ignored
+// FIXME: Any other DeclContext kinds that can be safely disregarded
+if (isa(Ctx))
+  continue;
+if (!isa(Ctx))
+  break;
 if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
   return true;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75332: [clang-tidy] Add module for llvm-libc and restrict-system-libc-header-check.

2020-03-01 Thread Nathan James via Phabricator via cfe-commits
njames93 added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp:40
+SrcMgr::CharacteristicKind FileType) {
+  if (SrcMgr::isSystem(FileType)) {
+if (!SM.isInMainFile(HashLoc)) {

abrachet wrote:
> Could you whitelist the freestanding/compiler provided headers like stddef, 
> stdatomic...
Or have a user configurable whitelist 



Comment at: 
clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp:42
+if (!SM.isInMainFile(HashLoc)) {
+  auto D = Check.diag(
+  HashLoc,

Don't use auto when the type isn't an iterator or spelled out on the 
initialisation. 



Comment at: 
clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp:47
+} else {
+  auto D = Check.diag(HashLoc, "system libc header %0 not allowed");
+  D << FileName;

Ditto


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75332/new/

https://reviews.llvm.org/D75332



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73052: [clang-tidy] RenamerClangTidy now renames dependent member expr when the member can be resolved

2020-03-01 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73052/new/

https://reviews.llvm.org/D73052



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75429: [clangd] DefineOutline removes `override` specified from overridden methods.

2020-03-01 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, 
MaskRay, ilya-biryukov.
Herald added a project: clang.
njames93 edited the summary of this revision.
njames93 added a project: clang-tools-extra.

The define out of line refactor tool previously would copy the override 
specifier into the out of line definition. 
This results in malformed code as the specifiers aren't allowed outside the 
class definition.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75429

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp


Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,24 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Overridden Methods
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
Index: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
===
--- clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -16,6 +16,7 @@
 #include "SourceCode.h"
 #include "refactor/Tweak.h"
 #include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
@@ -211,6 +212,18 @@
 }
   }
 
+  // Removes the override specifier if it exists as it doesn't belong in the
+  // function out-of-line definition.
+  if (FD->hasAttr()) {
+const auto *Override = FD->getAttr();
+assert(Override);
+CharSourceRange DelRange =
+CharSourceRange::getTokenRange(Override->getLocation());
+if (auto Err =
+QualifierInsertions.add(tooling::Replacement(SM, DelRange, "")))
+  Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
+  }
+
   if (Errors)
 return std::move(Errors);
   return getFunctionSourceAfterReplacements(FD, QualifierInsertions);


Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,24 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Overridden Methods
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
Index: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
===
--- clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -16,6 +16,7 @@
 #include "SourceCode.h"
 #include "refactor/Tweak.h"
 #include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
@@ -211,6 +212,18 @@
 }
   }
 
+  // Removes the override specifier if it exists as it doesn't belong in the
+  // function out-of-line definition.
+  if (FD->hasAttr()) {
+const auto *Override = FD->getAttr();
+assert(Override);
+CharSourceRange DelRange =
+CharSourceRange::getTokenRange(Override->getLocation());
+if (auto Err =
+QualifierInsertions.add(tooling::Replacement(SM, DelRange, "")))
+  Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
+  }
+
   if (Errors)
 return std::move(Errors);
   return getFunctionSourceAfterReplacements(FD, QualifierInsertions);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75429: [clangd] DefineOutline removes `override` specified from overridden methods.

2020-03-01 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 247538.
njames93 added a comment.

- Fix assertion when no Attrs are present


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,52 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Overridden Methods
+  {
+  R"cpp(
+struct A {
+  virtual void f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() ;
+};)cpp",
+  " void A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
Index: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
===
--- clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -16,6 +16,7 @@
 #include "SourceCode.h"
 #include "refactor/Tweak.h"
 #include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
@@ -211,6 +212,60 @@
 }
   }
 
+  // Remove the virtual, override and final specifiers.
+  if (FD->hasAttrs()) {
+for (auto *Attr : FD->getAttrs()) {
+  if (isa(Attr) || isa(Attr)) {
+assert(Attr->getLocation().isValid());
+if (Attr->getLocation().isMacroID()) {
+  Errors = llvm::joinErrors(
+  std::move(Errors),
+  llvm::createStringError(llvm::inconvertibleErrorCode(),
+  isa(Attr)
+  ? "define outline: Can't move out of "
+"line as function has "
+"a macro `override` specifier"
+  : "define outline: Can't move out of "
+"line as function has "
+"a macro `final` specifier"));
+  continue;
+}
+CharSourceRange DelRange =
+CharSourceRange::getTokenRange(Attr->getLocation());
+if (auto Err =
+QualifierInsertions.add(tooling::Replacement(SM, DelRange, "")))
+  Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
+  }
+}
+  }
+  if (FD->isVirtualAsWritten()) {
+SourceRange SpecRange{FD->getBeginLoc(), FD->getLocation()};
+bool Any = false;
+// Clang allows duplicating virtual specifiers so check for multiple
+// occurances.
+for (const syntax::Token  : TokBuf.expandedTokens(SpecRange)) {
+  if (Tok.kind() == tok::kw_virtual) {
+assert(Tok.location().isValid());
+if (Tok.location().isMacroID()) {
+  Errors =
+  llvm::joinErrors(std::move(Errors),
+   llvm::createStringError(
+   llvm::inconvertibleErrorCode(),
+   "define outline: Can't move out of line as "
+   "function has a macro `virtual` specifier"));
+  continue;
+}
+Any = true;
+CharSourceRange DelRange =
+CharSourceRange::getTokenRange(Tok.location());
+if (auto Err =
+QualifierInsertions.add(tooling::Replacement(SM, DelRange, "")))
+  Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
+  }
+}
+assert(Any); // Ensure at least one virtual was found
+  }
+
   if (Errors)
 return std::move(Errors);
   return getFunctionSourceAfterReplacements(FD, QualifierInsertions);

[PATCH] D75429: [clangd] DefineOutline removes `override` specified from overridden methods.

2020-03-01 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 247533.
njames93 added a comment.

- Extend to add virtual and final support


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,52 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Overridden Methods
+  {
+  R"cpp(
+struct A {
+  virtual void f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() ;
+};)cpp",
+  " void A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
Index: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
===
--- clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -16,6 +16,7 @@
 #include "SourceCode.h"
 #include "refactor/Tweak.h"
 #include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
@@ -211,6 +212,34 @@
 }
   }
 
+  // Remove the virtual, override and final specifiers.
+  for (auto *Attr : FD->getAttrs()) {
+if (isa(Attr) || isa(Attr)) {
+  CharSourceRange DelRange =
+  CharSourceRange::getTokenRange(Attr->getLocation());
+  if (auto Err =
+  QualifierInsertions.add(tooling::Replacement(SM, DelRange, "")))
+Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
+}
+  }
+  if (FD->isVirtualAsWritten()) {
+SourceRange SpecRange{FD->getBeginLoc(), FD->getLocation()};
+bool Any = false;
+// Clang allows duplicating virtual specifiers so check for multiple
+// occurances.
+for (const syntax::Token  : TokBuf.expandedTokens(SpecRange)) {
+  if (Tok.kind() == tok::kw_virtual) {
+Any = true;
+CharSourceRange DelRange =
+CharSourceRange::getTokenRange(Tok.location());
+if (auto Err =
+QualifierInsertions.add(tooling::Replacement(SM, DelRange, "")))
+  Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
+  }
+}
+assert(Any); // Ensure at least one virtual was found
+  }
+
   if (Errors)
 return std::move(Errors);
   return getFunctionSourceAfterReplacements(FD, QualifierInsertions);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75429: [clangd] DefineOutline removes `override` specified from overridden methods.

2020-03-01 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 247535.
njames93 added a comment.

- Made the replacements macro safe


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,52 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Overridden Methods
+  {
+  R"cpp(
+struct A {
+  virtual void f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() ;
+};)cpp",
+  " void A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
Index: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
===
--- clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -16,6 +16,7 @@
 #include "SourceCode.h"
 #include "refactor/Tweak.h"
 #include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
@@ -211,6 +212,57 @@
 }
   }
 
+  // Remove the virtual, override and final specifiers.
+  for (auto *Attr : FD->getAttrs()) {
+if (isa(Attr) || isa(Attr)) {
+  assert(Attr->getLocation().isValid());
+  if (Attr->getLocation().isMacroID()) {
+Errors = llvm::joinErrors(
+std::move(Errors),
+llvm::createStringError(
+llvm::inconvertibleErrorCode(),
+isa(Attr)
+? "define outline: Can't move out of line as function has "
+  "a macro override specifier"
+: "define outline: Can't move out of line as function has "
+  "a macro final specifier"));
+continue;
+  }
+  CharSourceRange DelRange =
+  CharSourceRange::getTokenRange(Attr->getLocation());
+  if (auto Err =
+  QualifierInsertions.add(tooling::Replacement(SM, DelRange, "")))
+Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
+}
+  }
+  if (FD->isVirtualAsWritten()) {
+SourceRange SpecRange{FD->getBeginLoc(), FD->getLocation()};
+bool Any = false;
+// Clang allows duplicating virtual specifiers so check for multiple
+// occurances.
+for (const syntax::Token  : TokBuf.expandedTokens(SpecRange)) {
+  if (Tok.kind() == tok::kw_virtual) {
+assert(Tok.location().isValid());
+if (Tok.location().isMacroID()) {
+  Errors =
+  llvm::joinErrors(std::move(Errors),
+   llvm::createStringError(
+   llvm::inconvertibleErrorCode(),
+   "define outline: Can't move out of line as "
+   "function has a macro virtual specifier"));
+  continue;
+}
+Any = true;
+CharSourceRange DelRange =
+CharSourceRange::getTokenRange(Tok.location());
+if (auto Err =
+QualifierInsertions.add(tooling::Replacement(SM, DelRange, "")))
+  Errors = llvm::joinErrors(std::move(Errors), std::move(Err));
+  }
+}
+assert(Any); // Ensure at least one virtual was found
+  }
+
   if (Errors)
 return std::move(Errors);
   return getFunctionSourceAfterReplacements(FD, QualifierInsertions);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73052: [clang-tidy] RenamerClangTidy now renames dependent member expr when the member can be resolved

2020-01-21 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 239253.
njames93 added a comment.

- Fix assertion causing failing tests in debug


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73052/new/

https://reviews.llvm.org/D73052

Files:
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-member-decl-usage.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-member-decl-usage.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-member-decl-usage.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-member-decl-usage.cpp
@@ -1,7 +1,8 @@
 // RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
 // RUN:   -config='{CheckOptions: [ \
 // RUN: {key: readability-identifier-naming.MemberCase, value: CamelCase}, \
-// RUN: {key: readability-identifier-naming.ParameterCase, value: CamelCase} \
+// RUN: {key: readability-identifier-naming.ParameterCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.MethodCase, value: camelBack} \
 // RUN:  ]}' -- -fno-delayed-template-parsing
 
 int set_up(int);
@@ -83,12 +84,12 @@
 }; //NOLINT
 }; // namespace std
 
-class Foo { 
+class Foo {
   std::vector 
   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: invalid case style for member 'stack' [readability-identifier-naming]
 public:
   Foo(std::vector )
-  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: invalid case style for parameter 'stack' [readability-identifier-naming]
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: invalid case style for parameter 'stack' [readability-identifier-naming]
   // CHECK-FIXES: {{^}}  Foo(std::vector )
   : stack(stack) {
 // CHECK-FIXES: {{^}}  : Stack(Stack) {
@@ -134,4 +135,94 @@
 void foo() {
   Container container;
 }
-}; // namespace CtorInits
+} // namespace CtorInits
+
+namespace resolved_dependance {
+template 
+struct A0 {
+  int value;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for member 'value'
+  A0 =(const A0 ) {
+value = Other.value;   // A0
+this->value = Other.value; // A0
+// CHECK-FIXES:  {{^}}Value = Other.Value;   // A0
+// CHECK-FIXES-NEXT: {{^}}this->Value = Other.Value; // A0
+return *this;
+  }
+  void outOfLineReset();
+};
+
+template 
+void A0::outOfLineReset() {
+  this->value -= value; // A0
+  // CHECK-FIXES: {{^}}  this->Value -= Value; // A0
+}
+
+template 
+struct A1 {
+  int value; // A1
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for member 'value'
+  // CHECK-FIXES: {{^}}  int Value; // A1
+  int GetValue() const { return value; } // A1
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for method 'GetValue'
+  // CHECK-FIXES {{^}}  int getValue() const { return Value; } // A1
+  void SetValue(int Value) { this->value = Value; } // A1
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: invalid case style for method 'SetValue'
+  // CHECK-FIXES {{^}}  void setValue(int Value) { this->Value = Value; } // A1
+  A1 =(const A1 ) {
+this->SetValue(Other.GetValue()); // A1
+this->value = Other.value;// A1
+// CHECK-FIXES:  {{^}}this->setValue(Other.getValue()); // A1
+// CHECK-FIXES-NEXT: {{^}}this->Value = Other.Value;// A1
+return *this;
+  }
+  void outOfLineReset();
+};
+
+template 
+void A1::outOfLineReset() {
+  this->value -= value; // A1
+  // CHECK-FIXES: {{^}}  this->Value -= Value; // A1
+}
+
+template 
+struct A2 {
+  int value; // A2
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for member 'value'
+  // CHECK-FIXES: {{^}}  int Value; // A2
+  A2 =(const A2 ) {
+value = Other.value;   // A2
+this->value = Other.value; // A2
+// CHECK-FIXES:  {{^}}Value = Other.Value;   // A2
+// CHECK-FIXES-NEXT: {{^}}this->Value = Other.Value; // A2
+return *this;
+  }
+};
+
+// create some instances to check it works when instantiated.
+A1 AInt{};
+A1 BInt = (AInt.outOfLineReset(), AInt);
+A1 AUnsigned{};
+A1 BUnsigned = AUnsigned;
+} // namespace resolved_dependance
+
+namespace unresolved_dependance {
+template 
+struct DependentBase {
+  int depValue;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for member 'depValue'
+};
+
+template 
+struct Derived : DependentBase {
+  Derived =(const Derived ) {
+this->depValue = Other.depValue;
+// CHECK-FIXES-NOT: {{^}}this->DepValue = Other.DepValue;
+return *this;
+  }
+};
+
+Derived AInt{};
+Derived BInt = AInt;
+
+} // namespace unresolved_dependance
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ 

[PATCH] D73098: [clang-tidy] readability-identifier-naming disregards parameters restrictions on main like functions

2020-01-21 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: aaron.ballman, JonasToth, alexfh, hokein.
njames93 added projects: clang, clang-tools-extra.
Herald added subscribers: kristof.beyls, xazax.hun.

Typically most main functions have the signature:

  int main(int argc, char *argv[])

To stick with convention when renaming parameters we should ignore the `argc` 
and `argv` names even if the parameter style says they should be renamed. This 
patch addresses this by checking all ParmVarDecls if they form part of a 
function with a signature that matches main `int name(int argc, char * argv[], 
(optional char *env[]))`


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73098

Files:
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  
clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: readability-identifier-naming.ParameterCase, value: CamelCase} \
+// RUN:  ]}'
+
+int mainLike(int argc, char **argv);
+int mainLike(int argc, char **argv, const char **env);
+int mainLike(int argc, const char **argv);
+int mainLike(int argc, const char **argv, const char **env);
+int mainLike(int argc, char *argv[]);
+int mainLike(int argc, const char *argv[]);
+int mainLike(int argc, char *argv[], char *env[]);
+int mainLike(int argc, const char *argv[], const char *env[]);
+void notMain(int argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+void notMain(int argc, char **argv, char **env);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: warning: invalid case style for parameter 'env'
+int notMain(int argc, char **argv, char **env, int Extra);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: warning: invalid case style for parameter 'env'
+int notMain(int argc, char **argv, int Extra);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char *argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:29: warning: invalid case style for parameter 'argv'
+int notMain(unsigned argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:35: warning: invalid case style for parameter 'argv'
+int notMain(long argc, char *argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char16_t **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char argv[]);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: invalid case style for parameter 'argv'
+typedef char myFunChar;
+typedef int myFunInt;
+typedef char **myFunCharPtr;
+typedef long myFunLong;
+myFunInt mainLikeTypedef(myFunInt argc, myFunChar **argv);
+int mainLikeTypedef(int argc, myFunCharPtr argv);
+int notMainTypedef(myFunLong argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:43: warning: invalid case style for parameter 'argv'
Index: clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
@@ -324,6 +324,43 @@
   return Fixup;
 }
 
+static bool isParamInMainLikeFunction(const ParmVarDecl ) {
+  auto IsCharPtrPtr = [](QualType QType) {
+if (QType.isNull())
+  return false;
+if (QType = QType->getPointeeType(), QType.isNull())
+  return false;
+if (QType = QType->getPointeeType(), QType.isNull())
+  return false;
+return QType->isCharType();
+  };
+  auto IsIntType = 

[PATCH] D73098: [clang-tidy] readability-identifier-naming disregards parameters restrictions on main like functions

2020-01-21 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

For the record this convention appears everywhere in LLVM even though LLVM 
style is to have parameters starting with uppercase letters


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73098/new/

https://reviews.llvm.org/D73098



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73090: [clang-tidy] Fix PR#44528 'modernize-use-using and enums'

2020-01-21 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

If you are using diff to create a patch, use `-U99` to get the full context 
of the patch




Comment at: 
clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp:274
+// CHECK-FIXES: using EnumT = enum { ea, eb };
\ No newline at end of file


Can you put a new line here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73090/new/

https://reviews.llvm.org/D73090



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75621: [clang-tidy] Use ; as separator for HeaderFileExtensions

2020-03-04 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

The `llvm::StringRef::split` function can take multiple split characters, So it 
would be best to split on both for the time being but mark cases where `,` is 
used as deprecated. This way we keep the options in line with other clang-tidy 
checks but keep some backwards compatibility but in future change it to just 
using `;`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75621/new/

https://reviews.llvm.org/D75621



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75538: [clang-tidy] Updated language supported restrictions on some checks

2020-03-04 Thread Nathan James via Phabricator via cfe-commits
njames93 marked an inline comment as done.
njames93 added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/modernize-use-nullptr-basic.cpp:1
-// RUN: %check_clang_tidy -std=c++98 %s modernize-use-nullptr %t -- -- 
-Wno-non-literal-null-conversion
-//

alexfh wrote:
> gribozavr2 wrote:
> > njames93 wrote:
> > > alexfh wrote:
> > > > IIRC, some of the modernize- checks were meant to be useful to make the 
> > > > pre-C++11 code compile in C++11. This check is an example of this 
> > > > (maybe the only one?). Limiting the check to C++11 and deleting this 
> > > > test is a bit too radical.
> > > I'm lost, this check is all about replacing assignment of pointer to 0 
> > > with `nullptr` a keyword which doesn't exist pre c++11, so this test case 
> > > will just result in invalid code. Or am I missing the point?
> > The idea, if I understand correctly, is that you start with C++98 code, 
> > apply modernize-* checks, and get C++11 code.
> Yep, at least for this particular check there are cases, which won't compile 
> in C++11, but will compile after its fixes are applied. Not sure if this was 
> ever used like this though.
My understanding of the modernize module was its designed to convert the old 
c++98/03 code to use newer (safer) c++ constructs. Its purpose isn't to fix 
compiler errors in c++11 mode that compile OK in c++98 mode


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75538/new/

https://reviews.llvm.org/D75538



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75621: [clang-tidy] Use ; as separator for HeaderFileExtensions

2020-03-04 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

In D75621#1905879 , @jroelofs wrote:

> Preserve backwards compatibility of ',' as a delimiter (for now).
>
> > The llvm::StringRef::split function can take multiple split characters,
>
> AFAIU, that's for multi-character delimiters, not multiple delimiters.


Yeah just checked it out my bad.




Comment at: clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.cpp:41
+  for (const char Delimiter : Delimiters) {
+if (StringRef::npos != AllFileExtensions.find(Delimiter)) {
+  if (Delimiter == ',') {

`if (AllFileExtensions.contains(Delimeter)) {`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75621/new/

https://reviews.llvm.org/D75621



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75569: [clang-tidy] New check for methods marked __attribute__((unavailable)) that do not override a method from a superclass.

2020-03-05 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

Fix the test case.




Comment at: 
clang-tools-extra/clang-tidy/objc/MethodUnavailableNotOverrideCheck.cpp:29
+// intended to be matched here.
+AST_MATCHER(ObjCMethodDecl, isUnavailableMethodNotOverriding) {
+  return !Node.isOverriding() && Node.hasAttr();

Should probably be in an anonymous namespace this as you don't intend it to be 
visible in another translation unit.



Comment at: 
clang-tools-extra/clang-tidy/objc/MethodUnavailableNotOverrideCheck.cpp:34
+void MethodUnavailableNotOverrideCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().ObjC)
+return;

See https://reviews.llvm.org/D75340



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/objc-method-unavailable-not-override.m:34
+// Verify check when using a macro that expands to the unavailable attribute.
+- (void)methodC NS_UNAVAILABLE;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: method 'methodC' is marked 
unavailable but does not override a superclass method 
[objc-method-unavailable-not-override]

Generally we are cautious about modifying MACRO usages in clang_tidy as we 
don't know if its definition can change based on configuration, perhaps its 
safer to just warn instead of providing a fix it



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/objc-method-unavailable-not-override.m:51
+// Verify that fixes exist to delete entire method declarations:
+// CHECK-FIXES: {{^\s*$}}

This is not a satisfactory check, it will ensure at least one method has been 
deleted but it wont ensure all methods have been deleted. Would probably be 
safer putting a unique comment on the line and having a check fix that checks 
for an empty line and the comment for each case.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75569/new/

https://reviews.llvm.org/D75569



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74669: [clang-tidy] New check: bugprone-suspicious-include

2020-03-05 Thread Nathan James via Phabricator via cfe-commits
njames93 added inline comments.



Comment at: clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h:38
+/// extensions.
+inline StringRef defaultHeaderFileExtensions() { return ",h,hh,hpp,hxx"; }
+

lebedev.ri wrote:
> njames93 wrote:
> > A lot of configuration options for clang tidy use semi-colon `;` seperated 
> > lists. Would it not be wise to carry on the convention and use semi colon 
> > here (and below) as well. It could break a few peoples configuration but 
> > that would be realised  fairly quickly and updated
> I think i'm missing the point of D75621.
> Why can't we keep using `,` as delimitter?
> Why do we have to change everything, introduce inconsistency
> (is it still documented that `,` is still valid?),
> and spam into terminal if `,` is found?
This reason
```
➜  ~ clang-tidy test.cpp --config="{CheckOptions: [{ key: HeaderFileExtensions, 
value: h,,hpp,hxx }]}" -- -std=c++17
YAML:1:59: error: unknown key 'hpp'
{CheckOptions: [{ key: HeaderFileExtensions, value: h,,hpp,hxx }]}
  ^
Error: invalid configuration specified.
Invalid argument
➜  ~ clang-tidy test.cpp --config="{CheckOptions: [{ key: HeaderFileExtensions, 
value: h;;hpp;hxx }]}" -- -std=c++17
➜  ~ 

```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74669/new/

https://reviews.llvm.org/D74669



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75441: [clang-tidy] Add helper base check classes that only run on specific language versions

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 marked an inline comment as done.
njames93 added a comment.

I suppose the only other way would be having another virtual function like 
inside the helper classes

  virtual bool additionalLanguageConstraints(const LangOptions& LangOpts) const 
{ return true; }
  
  bool isLanguageVersionSupported(const LangOptions ) const final {
return LangOpts.CPlusPlus && additionalLanguageConstraints(LangOpts);
  }

However I'm not a huge fan of that extra boilerplate


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75441/new/

https://reviews.llvm.org/D75441



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75429: [clangd] DefineOutline won't copy virtual specifiers on methods

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 247640.
njames93 added a comment.

- Fixed clang tidy warning, wont fix format as it's contradicting with the 
style of the rest of the function


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,80 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Virt specifiers.
+  {
+  R"cpp(
+struct A {
+  virtual void f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() ;
+};)cpp",
+  " void A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual virtual void virtual f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual virtual void virtual foo() ;
+};)cpp",
+  "  void  A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final override ;
+};)cpp",
+  "void B::foo()   {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2081,6 +2155,8 @@
   llvm::StringMap EditedFiles;
   ExtraFiles["Test.cpp"] = "";
   FileName = "Test.hpp";
+  ExtraArgs.push_back("-DVIRTUAL=virtual");
+  ExtraArgs.push_back("-DOVER=override");
 
   struct {
 llvm::StringRef Test;
@@ -2118,6 +2194,42 @@
   #define TARGET foo
   void TARGET();)cpp",
"void TARGET(){ return; }"},
+  {R"cpp(#define VIRT virtual
+  struct A {
+VIRT void f^oo() {}
+  };)cpp",
+   R"cpp(#define VIRT virtual
+  struct A {
+VIRT void foo() ;
+  };)cpp",
+" void A::foo() {}\n",
+  },
+  {R"cpp(
+  struct A {
+VIRTUAL void f^oo() {}
+  };)cpp",
+   R"cpp(
+  struct A {
+VIRTUAL void foo() ;
+  };)cpp",
+" void A::foo() {}\n",
+  },
+  {R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void fo^o() OVER {}
+  };)cpp",
+   R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void foo() OVER ;
+  };)cpp",
+"void B::foo()  {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2229,6 +2341,49 @@
 << Case.TestHeader;
   }
 }
+
+TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
+  FileName = "Test.hpp";
+  ExtraFiles["Test.cpp"] = "";
+  ExtraArgs.push_back("-DFINALOVER=final override");
+
+  std::pair Cases[] = {
+  {
+  R"cpp(
+  #define VIRT virtual void
+  struct A {
+VIRT fo^o() {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `virtual` specifier."},
+  {
+  R"cpp(
+  #define OVERFINAL final override
+  struct A {
+virtual void foo() {}
+  };
+  struct B : A {
+void fo^o() OVERFINAL {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `override` specifier.\ndefine outline: Can't move out of line "
+  "as function has a macro `final` specifier."},
+  {
+  R"cpp(
+  struct A 

[PATCH] D75429: [clangd] DefineOutline won't copy virtual specifiers on methods

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 247620.
njames93 added a comment.

- Macro handling more in line with rest of clangd


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,69 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Virt specifiers.
+  {
+  R"cpp(
+struct A {
+  virtual void f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() ;
+};)cpp",
+  " void A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final override ;
+};)cpp",
+  "void B::foo()   {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2081,6 +2144,8 @@
   llvm::StringMap EditedFiles;
   ExtraFiles["Test.cpp"] = "";
   FileName = "Test.hpp";
+  ExtraArgs.push_back("-DVIRTUAL=virtual");
+  ExtraArgs.push_back("-DOVER=override");
 
   struct {
 llvm::StringRef Test;
@@ -2118,6 +2183,42 @@
   #define TARGET foo
   void TARGET();)cpp",
"void TARGET(){ return; }"},
+  {R"cpp(#define VIRT virtual
+  struct A {
+VIRT void f^oo() {}
+  };)cpp",
+   R"cpp(#define VIRT virtual
+  struct A {
+VIRT void foo() ;
+  };)cpp",
+" void A::foo() {}\n",
+  },
+  {R"cpp(
+  struct A {
+VIRTUAL void f^oo() {}
+  };)cpp",
+   R"cpp(
+  struct A {
+VIRTUAL void foo() ;
+  };)cpp",
+" void A::foo() {}\n",
+  },
+  {R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void fo^o() OVER {}
+  };)cpp",
+   R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void foo() OVER ;
+  };)cpp",
+"void B::foo()  {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2229,6 +2330,49 @@
 << Case.TestHeader;
   }
 }
+
+TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
+  FileName = "Test.hpp";
+  ExtraFiles["Test.cpp"] = "";
+  ExtraArgs.push_back("-DFINALOVER=final override");
+
+  std::pair Cases[] = {
+  {
+  R"cpp(
+  #define VIRT virtual void
+  struct A {
+VIRT fo^o() {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `virtual` specifier."},
+  {
+  R"cpp(
+  #define OVERFINAL final override
+  struct A {
+virtual void foo() {}
+  };
+  struct B : A {
+void fo^o() OVERFINAL {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `override` specifier.\ndefine outline: Can't move out of line "
+  "as function has a macro `final` specifier."},
+  {
+  R"cpp(
+  struct A {
+virtual void foo() {}
+  };
+  struct B : A {
+void fo^o() FINALOVER {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `override` specifier.\ndefine outline: Can't move out of line "
+  "as function has a macro `final` 

[PATCH] D75429: [clangd] DefineOutline won't copy virtual specifiers on methods

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 247621.
njames93 marked 3 inline comments as done.
njames93 added a comment.

- added virtual virtual


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,80 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Virt specifiers.
+  {
+  R"cpp(
+struct A {
+  virtual void f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() ;
+};)cpp",
+  " void A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual virtual void virtual f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual virtual void virtual foo() ;
+};)cpp",
+  "  void  A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final override ;
+};)cpp",
+  "void B::foo()   {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2081,6 +2155,8 @@
   llvm::StringMap EditedFiles;
   ExtraFiles["Test.cpp"] = "";
   FileName = "Test.hpp";
+  ExtraArgs.push_back("-DVIRTUAL=virtual");
+  ExtraArgs.push_back("-DOVER=override");
 
   struct {
 llvm::StringRef Test;
@@ -2118,6 +2194,42 @@
   #define TARGET foo
   void TARGET();)cpp",
"void TARGET(){ return; }"},
+  {R"cpp(#define VIRT virtual
+  struct A {
+VIRT void f^oo() {}
+  };)cpp",
+   R"cpp(#define VIRT virtual
+  struct A {
+VIRT void foo() ;
+  };)cpp",
+" void A::foo() {}\n",
+  },
+  {R"cpp(
+  struct A {
+VIRTUAL void f^oo() {}
+  };)cpp",
+   R"cpp(
+  struct A {
+VIRTUAL void foo() ;
+  };)cpp",
+" void A::foo() {}\n",
+  },
+  {R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void fo^o() OVER {}
+  };)cpp",
+   R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void foo() OVER ;
+  };)cpp",
+"void B::foo()  {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2229,6 +2341,49 @@
 << Case.TestHeader;
   }
 }
+
+TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
+  FileName = "Test.hpp";
+  ExtraFiles["Test.cpp"] = "";
+  ExtraArgs.push_back("-DFINALOVER=final override");
+
+  std::pair Cases[] = {
+  {
+  R"cpp(
+  #define VIRT virtual void
+  struct A {
+VIRT fo^o() {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `virtual` specifier."},
+  {
+  R"cpp(
+  #define OVERFINAL final override
+  struct A {
+virtual void foo() {}
+  };
+  struct B : A {
+void fo^o() OVERFINAL {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `override` specifier.\ndefine outline: Can't move out of line "
+  "as function has a macro `final` specifier."},
+  {
+  R"cpp(
+  struct A {
+virtual void foo() {}
+  

[PATCH] D75429: [clangd] DefineOutline won't copy virtual specifiers on methods

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

In D75429#1901073 , @kadircet wrote:

> In D75429#1901018 , @njames93 wrote:
>
> > - Fixed clang tidy warning, wont fix format as it's contradicting with the 
> > style of the rest of the function
>
>
> I believe the formatting linter messages results from the fact that you are 
> finishing the structs with a `}` on a newline, it should be right next to 
> expected output, without any newlines in between.


The linter messages are actually to do with the no new line after the `{` and 
bad indentation inside the braced init list, however that's how the rest look.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75429: [clangd] DefineOutline won't copy virtual specifiers on methods

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 marked 2 inline comments as done.
njames93 added inline comments.



Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp:220
+assert(Attr->getLocation().isValid());
+if (Attr->getLocation().isMacroID()) {
+  Errors = llvm::joinErrors(

kadircet wrote:
> njames93 wrote:
> > kadircet wrote:
> > > can you add some test cases for this branch ? In theory it should be ok 
> > > to drop this if full expansion is just the attr, i.e.
> > > 
> > > ```
> > > #define FNL final
> > > struct A { virtual void foo() FNL {} };
> > > ```
> > > 
> > > but should possibly fail in :
> > > ```
> > > #define MACRO foo() final
> > > struct A { virtual void MACRO {} };
> > > ```
> > it's not a great idea refactoring functions with MACRO attributes, we can 
> > never know if there are side effects based on different definitions due to 
> > things like build configs.
> well that's definitely one way to go, but while designing this code action we 
> decided user should know better and clangd currently provides this code 
> action in cases involving macros, see `DefineOutlineTest.HandleMacros` and it 
> would be inconsistent with rest of the behavior if it bailed out in half of 
> the cases and kept working for the rest.
> 
> Also this case is even safer than the rest, since it is only trying to drop 
> those qualifiers and not duplicate them in the definition side.
Thanks for explaining that for me, I'll give it a go and see how the test cases 
are handled



Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp:244
+bool Any = false;
+// Clang allows duplicating virtual specifiers so check for multiple
+// occurances.

kadircet wrote:
> kadircet wrote:
> > again could you please add tests checking this case?
> sorry, i still don't see any cases with multiple virtual keywords.
Ah I thought you meant a test case just containing virtual which there is, I'll 
get the second one added.
Should I even support multiple virtual decls, https://godbolt.org/z/kGbF22 
clang treats this as a warning, but for gcc its an error.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75429: [clangd] DefineOutline won't copy virtual specifiers on methods

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

I'm not entirely sure how to get the spelledTokens working in a good macro safe 
way?




Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp:220
+assert(Attr->getLocation().isValid());
+if (Attr->getLocation().isMacroID()) {
+  Errors = llvm::joinErrors(

kadircet wrote:
> can you add some test cases for this branch ? In theory it should be ok to 
> drop this if full expansion is just the attr, i.e.
> 
> ```
> #define FNL final
> struct A { virtual void foo() FNL {} };
> ```
> 
> but should possibly fail in :
> ```
> #define MACRO foo() final
> struct A { virtual void MACRO {} };
> ```
it's not a great idea refactoring functions with MACRO attributes, we can never 
know if there are side effects based on different definitions due to things 
like build configs.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75441: [clang-tidy] Add helper base check classes that only run on specific language versions

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 marked an inline comment as done.
njames93 added inline comments.



Comment at: clang-tools-extra/clang-tidy/ClangTidyCheck.h:224
+/// Helper class for clang-tidy checks that only register when in `c++11` mode.
+class Cpp11ClangTidyCheck : public ClangTidyCheck {
+  using ClangTidyCheck::ClangTidyCheck;

Given the amount of new stuff added in c++11 and how many checks require c++11 
I thought having a separate c++11 mode class would be a good idea, c++14/17 
probably not so much though.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75441/new/

https://reviews.llvm.org/D75441



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75340: [clang-tidy] Change checks to use new isLanguageVersionSupported restriction

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 planned changes to this revision.
njames93 added a comment.

Made another pull request that could neaten this implementation up - 
https://reviews.llvm.org/D75441, will wait to see how that goes down before 
getting this pushed.




Comment at: 
clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.h:30
+  bool isLanguageVersionSupported(const LangOptions ) const override {
+return LangOpts.CPlusPlus && !LangOpts.CPlusPlus17;
+  }

gribozavr2 wrote:
> I think CPlusPlus17 implies CPlusPlus.
This is saying it needs c++ but not c++17, so c++98->c++14 are Ok but not 17 or 
20. Besides this is the current behaviour in the cpp file


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75340/new/

https://reviews.llvm.org/D75340



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75429: [clangd] DefineOutline won't copy virtual specifiers on methods

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 247601.
njames93 marked 8 inline comments as done.
njames93 added a comment.

- Refactor and extra test cases


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,69 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Virt specifiers.
+  {
+  R"cpp(
+struct A {
+  virtual void f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() ;
+};)cpp",
+  " void A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final override ;
+};)cpp",
+  "void B::foo()   {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2229,6 +2292,61 @@
 << Case.TestHeader;
   }
 }
+
+TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
+  FileName = "Test.hpp";
+  ExtraFiles["Test.cpp"] = "";
+
+  std::pair Cases[] = {
+  {
+  R"cpp(
+  #define VIRT virtual
+  struct A {
+VIRT void fo^o() {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `virtual` specifier."},
+  {
+  R"cpp(
+  #define OVER override
+  struct A {
+virtual void foo() {}
+  };
+  struct B : A {
+void fo^o() OVER {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `override` specifier."},
+  {
+  R"cpp(
+  #define FINAL final
+  #define OVER override
+  struct A {
+virtual void foo() {}
+  };
+  struct B : A {
+void fo^o() FINAL OVER {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `override` specifier.\ndefine outline: Can't move out of line "
+  "as function has a macro `final` specifier."},
+  {
+  R"cpp(
+  #define FINALOVER final override
+  struct A {
+virtual void foo() {}
+  };
+  struct B : A {
+void fo^o() FINALOVER {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `override` specifier.\ndefine outline: Can't move out of line "
+  "as function has a macro `final` specifier."},
+  };
+  for (const auto  : Cases) {
+EXPECT_EQ(apply(Case.first), Case.second);
+  }
+}
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
===
--- clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -16,6 +16,7 @@
 #include "SourceCode.h"
 #include "refactor/Tweak.h"
 #include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
@@ -156,7 +157,7 @@
 "define outline: couldn't find a context for target");
 
   llvm::Error Errors = llvm::Error::success();
-  tooling::Replacements QualifierInsertions;
+  tooling::Replacements DeclarationCleanups;
 
   // Finds the first unqualified name in 

[PATCH] D75538: [clang-tidy] Updated language supported restrictions on some checks

2020-03-03 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: aaron.ballman, gribozavr2, alexfh.
Herald added subscribers: cfe-commits, dexonsmith, steven_wu, hiraditya, 
xazax.hun.
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75538

Files:
  clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.h
  clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.h
  clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.h
  clang-tools-extra/clang-tidy/modernize/UseAutoCheck.h
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
  clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.h
  clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h
  clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.h
  clang-tools-extra/test/clang-tidy/checkers/modernize-use-nullptr-basic.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize-use-nullptr-basic.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize-use-nullptr-basic.cpp
+++ /dev/null
@@ -1,362 +0,0 @@
-// RUN: %check_clang_tidy -std=c++98 %s modernize-use-nullptr %t -- -- -Wno-non-literal-null-conversion
-//
-// Some parts of the test (e.g. assignment of `const int` to `int *`) fail in
-// C++11, so we need to run the test in C++98 mode.
-//
-// FIXME: Make the test work in all language modes.
-
-const unsigned int g_null = 0;
-#define NULL 0
-
-void test_assignment() {
-  int *p1 = 0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr [modernize-use-nullptr]
-  // CHECK-FIXES: int *p1 = nullptr;
-  p1 = 0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
-  // CHECK-FIXES: p1 = nullptr;
-
-  int *p2 = NULL;
-  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
-  // CHECK-FIXES: int *p2 = nullptr;
-
-  p2 = p1;
-  // CHECK-FIXES: p2 = p1;
-
-  const int null = 0;
-  int *p3 = null;
-  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
-  // CHECK-FIXES: int *p3 = nullptr;
-
-  p3 = NULL;
-  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
-  // CHECK-FIXES: p3 = nullptr;
-
-  int *p4 = p3;
-  // CHECK-FIXES: int *p4 = p3;
-
-  p4 = null;
-  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
-  // CHECK-FIXES: p4 = nullptr;
-
-  int i1 = 0;
-
-  int i2 = NULL;
-
-  int i3 = null;
-
-  int *p5, *p6, *p7;
-  p5 = p6 = p7 = NULL;
-  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
-  // CHECK-FIXES: p5 = p6 = p7 = nullptr;
-}
-
-struct Foo {
-  Foo(int *p = NULL) : m_p1(p) {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
-  // CHECK-FIXES: Foo(int *p = nullptr) : m_p1(p) {}
-
-  void bar(int *p = 0) {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use nullptr
-  // CHECK-FIXES: void bar(int *p = nullptr) {}
-
-  void baz(int i = 0) {}
-
-  int *m_p1;
-  static int *m_p2;
-};
-
-int *Foo::m_p2 = NULL;
-// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
-// CHECK-FIXES: int *Foo::m_p2 = nullptr;
-
-template 
-struct Bar {
-  Bar(T *p) : m_p(p) {
-m_p = static_cast(NULL);
-// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr
-// CHECK-FIXES: m_p = static_cast(nullptr);
-
-m_p = static_cast(reinterpret_cast((void*)NULL));
-// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr
-// CHECK-FIXES: m_p = static_cast(nullptr);
-
-m_p = static_cast(p ? p : static_cast(g_null));
-// CHECK-MESSAGES: :[[@LINE-1]]:54: warning: use nullptr
-// CHECK-FIXES: m_p = static_cast(p ? p : static_cast(nullptr));
-
-T *p2 = static_cast(reinterpret_cast((void*)NULL));
-// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use nullptr
-// CHECK-FIXES: T *p2 = static_cast(nullptr);
-
-m_p = NULL;
-// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr
-// CHECK-FIXES: m_p = nullptr;
-
-int i = static_cast(0.f);
-T *i2 = static_cast(0.f);
-// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
-// CHECK-FIXES: T *i2 = nullptr;
-  }
-
-  T *m_p;
-};
-
-struct Baz {
-  Baz() : i(0) {}
-  int i;
-};
-
-void test_cxx_cases() {
-  Foo f(g_null);
-  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
-  // CHECK-FIXES: Foo f(nullptr);
-
-  f.bar(NULL);
-  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
-  // CHECK-FIXES: f.bar(nullptr);
-
-  f.baz(g_null);
-
-  f.m_p1 = 0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
-  // CHECK-FIXES: f.m_p1 = nullptr;
-
-  Bar b(g_null);
-  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr
-  // CHECK-FIXES: Bar b(nullptr);
-
-  Baz b2;
-  int Baz::*memptr(0);
-  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use nullptr
-  // CHECK-FIXES: int Baz::*memptr(nullptr);
-
-  memptr = 0;
-  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
-  // CHECK-FIXES: memptr = nullptr;
-}
-
-void test_function_default_param1(void *p = 0);
-// CHECK-MESSAGES: 

[PATCH] D75340: [clang-tidy] Change checks to use new isLanguageVersionSupported restriction

2020-03-03 Thread Nathan James via Phabricator via cfe-commits
njames93 requested review of this revision.
njames93 added a comment.

Support for the previous point didnt go too well so will stick with the current 
implementation


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75340/new/

https://reviews.llvm.org/D75340



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75538: [clang-tidy] Updated language supported restrictions on some checks

2020-03-03 Thread Nathan James via Phabricator via cfe-commits
njames93 marked an inline comment as done.
njames93 added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/modernize-use-nullptr-basic.cpp:1
-// RUN: %check_clang_tidy -std=c++98 %s modernize-use-nullptr %t -- -- 
-Wno-non-literal-null-conversion
-//

alexfh wrote:
> IIRC, some of the modernize- checks were meant to be useful to make the 
> pre-C++11 code compile in C++11. This check is an example of this (maybe the 
> only one?). Limiting the check to C++11 and deleting this test is a bit too 
> radical.
I'm lost, this check is all about replacing assignment of pointer to 0 with 
`nullptr` a keyword which doesn't exist pre c++11, so this test case will just 
result in invalid code. Or am I missing the point?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75538/new/

https://reviews.llvm.org/D75538



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75441: [clang-tidy] Add helper base check classes that only run on specific language versions

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: aaron.ballman, gribozavr2, alexfh, lebedev.ri, 
Eugene.Zelenko.
Herald added subscribers: cfe-commits, xazax.hun.
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75441

Files:
  clang-tools-extra/clang-tidy/ClangTidyCheck.h


Index: clang-tools-extra/clang-tidy/ClangTidyCheck.h
===
--- clang-tools-extra/clang-tidy/ClangTidyCheck.h
+++ clang-tools-extra/clang-tidy/ClangTidyCheck.h
@@ -204,6 +204,39 @@
   const LangOptions () const { return Context->getLangOpts(); }
 };
 
+/// Helper class for clang-tidy checks that only register when in `Cc mode.
+class CClangTidyCheck : public ClangTidyCheck {
+  using ClangTidyCheck::ClangTidyCheck;
+  bool isLanguageVersionSupported(const LangOptions ) const final {
+return LangOpts.C99;
+  }
+};
+
+/// Helper class for clang-tidy checks that only register when in `c++` mode.
+class CppClangTidyCheck : public ClangTidyCheck {
+  using ClangTidyCheck::ClangTidyCheck;
+  bool isLanguageVersionSupported(const LangOptions ) const final {
+return LangOpts.CPlusPlus;
+  }
+};
+
+/// Helper class for clang-tidy checks that only register when in `c++11` mode.
+class Cpp11ClangTidyCheck : public ClangTidyCheck {
+  using ClangTidyCheck::ClangTidyCheck;
+  bool isLanguageVersionSupported(const LangOptions ) const final {
+return LangOpts.CPlusPlus11;
+  }
+};
+
+/// Helper class for clang-tidy checks that only register when in `Objective-c`
+/// mode.
+class ObjCClangTidyCheck : public ClangTidyCheck {
+  using ClangTidyCheck::ClangTidyCheck;
+  bool isLanguageVersionSupported(const LangOptions ) const final {
+return LangOpts.ObjC;
+  }
+};
+
 } // namespace tidy
 } // namespace clang
 


Index: clang-tools-extra/clang-tidy/ClangTidyCheck.h
===
--- clang-tools-extra/clang-tidy/ClangTidyCheck.h
+++ clang-tools-extra/clang-tidy/ClangTidyCheck.h
@@ -204,6 +204,39 @@
   const LangOptions () const { return Context->getLangOpts(); }
 };
 
+/// Helper class for clang-tidy checks that only register when in `Cc mode.
+class CClangTidyCheck : public ClangTidyCheck {
+  using ClangTidyCheck::ClangTidyCheck;
+  bool isLanguageVersionSupported(const LangOptions ) const final {
+return LangOpts.C99;
+  }
+};
+
+/// Helper class for clang-tidy checks that only register when in `c++` mode.
+class CppClangTidyCheck : public ClangTidyCheck {
+  using ClangTidyCheck::ClangTidyCheck;
+  bool isLanguageVersionSupported(const LangOptions ) const final {
+return LangOpts.CPlusPlus;
+  }
+};
+
+/// Helper class for clang-tidy checks that only register when in `c++11` mode.
+class Cpp11ClangTidyCheck : public ClangTidyCheck {
+  using ClangTidyCheck::ClangTidyCheck;
+  bool isLanguageVersionSupported(const LangOptions ) const final {
+return LangOpts.CPlusPlus11;
+  }
+};
+
+/// Helper class for clang-tidy checks that only register when in `Objective-c`
+/// mode.
+class ObjCClangTidyCheck : public ClangTidyCheck {
+  using ClangTidyCheck::ClangTidyCheck;
+  bool isLanguageVersionSupported(const LangOptions ) const final {
+return LangOpts.ObjC;
+  }
+};
+
 } // namespace tidy
 } // namespace clang
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75220: [clang-tidy] RenamerClangTidy now correctly renames decls

2020-02-26 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: aaron.ballman, gribozavr2, JonasToth, hokein, alexfh.
Herald added subscribers: cfe-commits, xazax.hun.
Herald added a project: clang.
njames93 updated this revision to Diff 246853.
njames93 added a comment.

- Remove unnecessary include


Fixes readability-identifier-naming doesn't rename using namespace correctly. 



Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75220

Files:
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
@@ -527,3 +527,8 @@
 // CHECK-FIXES: {{^}}int * const lc_PointerB = nullptr;{{$}}
 }
 
+using namespace FOO_NS;
+// CHECK-FIXES: {{^}}using namespace foo_ns;
+
+using namespace FOO_NS::InlineNamespace;
+// CHECK-FIXES: {{^}}using namespace foo_ns::inline_namespace;
Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
===
--- clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -272,6 +272,13 @@
   }
 
   if (const auto *Decl = Result.Nodes.getNodeAs("decl")) {
+
+// fix using namespace decls
+if (const auto *UsingNS = dyn_cast(Decl)) {
+  addUsage(NamingCheckFailures, UsingNS->getNominatedNamespaceAsWritten(),
+   UsingNS->getIdentLocation());
+}
+
 if (!Decl->getIdentifier() || Decl->getName().empty() || 
Decl->isImplicit())
   return;
 


Index: clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
@@ -527,3 +527,8 @@
 // CHECK-FIXES: {{^}}int * const lc_PointerB = nullptr;{{$}}
 }
 
+using namespace FOO_NS;
+// CHECK-FIXES: {{^}}using namespace foo_ns;
+
+using namespace FOO_NS::InlineNamespace;
+// CHECK-FIXES: {{^}}using namespace foo_ns::inline_namespace;
Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
===
--- clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -272,6 +272,13 @@
   }
 
   if (const auto *Decl = Result.Nodes.getNodeAs("decl")) {
+
+// fix using namespace decls
+if (const auto *UsingNS = dyn_cast(Decl)) {
+  addUsage(NamingCheckFailures, UsingNS->getNominatedNamespaceAsWritten(),
+   UsingNS->getIdentLocation());
+}
+
 if (!Decl->getIdentifier() || Decl->getName().empty() || Decl->isImplicit())
   return;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75220: [clang-tidy] RenamerClangTidy now correctly renames decls

2020-02-26 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246853.
njames93 added a comment.

- Remove unnecessary include


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75220/new/

https://reviews.llvm.org/D75220

Files:
  clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
@@ -527,3 +527,8 @@
 // CHECK-FIXES: {{^}}int * const lc_PointerB = nullptr;{{$}}
 }
 
+using namespace FOO_NS;
+// CHECK-FIXES: {{^}}using namespace foo_ns;
+
+using namespace FOO_NS::InlineNamespace;
+// CHECK-FIXES: {{^}}using namespace foo_ns::inline_namespace;
Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
===
--- clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -272,6 +272,13 @@
   }
 
   if (const auto *Decl = Result.Nodes.getNodeAs("decl")) {
+
+// fix using namespace decls
+if (const auto *UsingNS = dyn_cast(Decl)) {
+  addUsage(NamingCheckFailures, UsingNS->getNominatedNamespaceAsWritten(),
+   UsingNS->getIdentLocation());
+}
+
 if (!Decl->getIdentifier() || Decl->getName().empty() || 
Decl->isImplicit())
   return;
 


Index: clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp
@@ -527,3 +527,8 @@
 // CHECK-FIXES: {{^}}int * const lc_PointerB = nullptr;{{$}}
 }
 
+using namespace FOO_NS;
+// CHECK-FIXES: {{^}}using namespace foo_ns;
+
+using namespace FOO_NS::InlineNamespace;
+// CHECK-FIXES: {{^}}using namespace foo_ns::inline_namespace;
Index: clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
===
--- clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -272,6 +272,13 @@
   }
 
   if (const auto *Decl = Result.Nodes.getNodeAs("decl")) {
+
+// fix using namespace decls
+if (const auto *UsingNS = dyn_cast(Decl)) {
+  addUsage(NamingCheckFailures, UsingNS->getNominatedNamespaceAsWritten(),
+   UsingNS->getIdentLocation());
+}
+
 if (!Decl->getIdentifier() || Decl->getName().empty() || Decl->isImplicit())
   return;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75289: [clang-tidy] Added virtual isLanguageVersionSupported to ClangTidyCheck

2020-02-28 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 247230.
njames93 marked an inline comment as done.
njames93 added a comment.

- Moved isLanguageVersionSupported above register functions


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75289/new/

https://reviews.llvm.org/D75289

Files:
  clang-tools-extra/clang-tidy/ClangTidy.cpp
  clang-tools-extra/clang-tidy/ClangTidyCheck.h
  clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
  clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
  clang-tools-extra/clangd/ParsedAST.cpp
  clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h

Index: clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
===
--- clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
+++ clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
@@ -67,6 +67,8 @@
 // `getLangOpts()`).
 CheckFactory::createChecks(, Checks);
 for (auto  : Checks) {
+  if (!Check->isLanguageVersionSupported(Context.getLangOpts()))
+continue;
   Check->registerMatchers();
   Check->registerPPCallbacks(Compiler.getSourceManager(), PP, PP);
 }
Index: clang-tools-extra/clangd/ParsedAST.cpp
===
--- clang-tools-extra/clangd/ParsedAST.cpp
+++ clang-tools-extra/clangd/ParsedAST.cpp
@@ -301,6 +301,8 @@
 });
 Preprocessor *PP = >getPreprocessor();
 for (const auto  : CTChecks) {
+  if (!Check->isLanguageVersionSupported(CTContext->getLangOpts()))
+continue;
   // FIXME: the PP callbacks skip the entire preamble.
   // Checks that want to see #includes in the main file do not see them.
   Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
Index: clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
===
--- clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
+++ clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
@@ -41,7 +41,7 @@
   virtual SmartPtrTypeMatcher getSmartPointerTypeMatcher() const = 0;
 
   /// Returns whether the C++ version is compatible with current check.
-  virtual bool isLanguageVersionSupported(const LangOptions ) const;
+  bool isLanguageVersionSupported(const LangOptions ) const override;
 
   static const char PointerType[];
 
Index: clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
@@ -68,17 +68,12 @@
 void MakeSmartPtrCheck::registerPPCallbacks(const SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
-  if (isLanguageVersionSupported(getLangOpts())) {
 Inserter = std::make_unique(SM, getLangOpts(),
  IncludeStyle);
 PP->addPPCallbacks(Inserter->CreatePPCallbacks());
-  }
 }
 
 void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
-  if (!isLanguageVersionSupported(getLangOpts()))
-return;
-
   // Calling make_smart_ptr from within a member function of a type with a
   // private or protected constructor would be ill-formed.
   auto CanCallCtor = unless(has(ignoringImpCasts(
Index: clang-tools-extra/clang-tidy/ClangTidyCheck.h
===
--- clang-tools-extra/clang-tidy/ClangTidyCheck.h
+++ clang-tools-extra/clang-tidy/ClangTidyCheck.h
@@ -53,11 +53,24 @@
   /// constructor using the Options.get() methods below.
   ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
 
+  /// Override this to disable registering matchers and PP callbacks if an
+  /// invalid language version is being used.
+  ///
+  /// For example if a check is examining overloaded functions then this should
+  /// be overridden to return false when the CPlusPlus flag is not set in
+  /// \p LangOpts.
+  virtual bool isLanguageVersionSupported(const LangOptions ) const {
+return true;
+  }
+
   /// Override this to register ``PPCallbacks`` in the preprocessor.
   ///
   /// This should be used for clang-tidy checks that analyze preprocessor-
   /// dependent properties, e.g. include directives and macro definitions.
   ///
+  /// This will only be executed if the function isLanguageVersionSupported
+  /// returns true.
+  ///
   /// There are two Preprocessors to choose from that differ in how they handle
   /// modular #includes:
   ///  - PP is the real Preprocessor. It doesn't walk into modular #includes and
@@ -80,6 +93,9 @@
   /// "this" will be used as callback, but you can also specify other callback
   /// classes. Thereby, different matchers can trigger different callbacks.
   ///
+  /// This will only be 

[PATCH] D75289: [clang-tidy] Added virtual isLanguageVersionSupported to ClangTidyCheck

2020-02-28 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

In D75289#1896929 , @Eugene.Zelenko 
wrote:

> In D75289#1896925 , @njames93 wrote:
>
> > In D75289#1896902 , 
> > @Eugene.Zelenko wrote:
> >
> > > Language and/or its standard is checked in other places too. Should all 
> > > similar places be refactored?
> >
> >
> > They should but I feel they should be in follow up patches, the only reason 
> > MakeSmartPtrCheck is in here is because by coincidence it used the same 
> > name as what I planned and I got a compile warning about it. 
> >  I also don't know exactly where all occurrences are.
>
>
> Just grep for //getLangOpts()//.


Thanks for that tip, I've put the full implementation in a child revision.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75289/new/

https://reviews.llvm.org/D75289



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75289: [clang-tidy] Added virtual isLanguageVersionSupported to ClangTidyCheck

2020-02-28 Thread Nathan James via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG39c4246e1e5b: [clang-tidy] Added virtual 
isLanguageVersionSupported to ClangTidyCheck (authored by njames93).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75289/new/

https://reviews.llvm.org/D75289

Files:
  clang-tools-extra/clang-tidy/ClangTidy.cpp
  clang-tools-extra/clang-tidy/ClangTidyCheck.h
  clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
  clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
  clang-tools-extra/clangd/ParsedAST.cpp
  clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h

Index: clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
===
--- clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
+++ clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
@@ -67,6 +67,8 @@
 // `getLangOpts()`).
 CheckFactory::createChecks(, Checks);
 for (auto  : Checks) {
+  if (!Check->isLanguageVersionSupported(Context.getLangOpts()))
+continue;
   Check->registerMatchers();
   Check->registerPPCallbacks(Compiler.getSourceManager(), PP, PP);
 }
Index: clang-tools-extra/clangd/ParsedAST.cpp
===
--- clang-tools-extra/clangd/ParsedAST.cpp
+++ clang-tools-extra/clangd/ParsedAST.cpp
@@ -301,6 +301,8 @@
 });
 Preprocessor *PP = >getPreprocessor();
 for (const auto  : CTChecks) {
+  if (!Check->isLanguageVersionSupported(CTContext->getLangOpts()))
+continue;
   // FIXME: the PP callbacks skip the entire preamble.
   // Checks that want to see #includes in the main file do not see them.
   Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
Index: clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
===
--- clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
+++ clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
@@ -41,7 +41,7 @@
   virtual SmartPtrTypeMatcher getSmartPointerTypeMatcher() const = 0;
 
   /// Returns whether the C++ version is compatible with current check.
-  virtual bool isLanguageVersionSupported(const LangOptions ) const;
+  bool isLanguageVersionSupported(const LangOptions ) const override;
 
   static const char PointerType[];
 
Index: clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
@@ -68,17 +68,12 @@
 void MakeSmartPtrCheck::registerPPCallbacks(const SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
-  if (isLanguageVersionSupported(getLangOpts())) {
 Inserter = std::make_unique(SM, getLangOpts(),
  IncludeStyle);
 PP->addPPCallbacks(Inserter->CreatePPCallbacks());
-  }
 }
 
 void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
-  if (!isLanguageVersionSupported(getLangOpts()))
-return;
-
   // Calling make_smart_ptr from within a member function of a type with a
   // private or protected constructor would be ill-formed.
   auto CanCallCtor = unless(has(ignoringImpCasts(
Index: clang-tools-extra/clang-tidy/ClangTidyCheck.h
===
--- clang-tools-extra/clang-tidy/ClangTidyCheck.h
+++ clang-tools-extra/clang-tidy/ClangTidyCheck.h
@@ -53,11 +53,24 @@
   /// constructor using the Options.get() methods below.
   ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
 
+  /// Override this to disable registering matchers and PP callbacks if an
+  /// invalid language version is being used.
+  ///
+  /// For example if a check is examining overloaded functions then this should
+  /// be overridden to return false when the CPlusPlus flag is not set in
+  /// \p LangOpts.
+  virtual bool isLanguageVersionSupported(const LangOptions ) const {
+return true;
+  }
+
   /// Override this to register ``PPCallbacks`` in the preprocessor.
   ///
   /// This should be used for clang-tidy checks that analyze preprocessor-
   /// dependent properties, e.g. include directives and macro definitions.
   ///
+  /// This will only be executed if the function isLanguageVersionSupported
+  /// returns true.
+  ///
   /// There are two Preprocessors to choose from that differ in how they handle
   /// modular #includes:
   ///  - PP is the real Preprocessor. It doesn't walk into modular #includes and
@@ -80,6 +93,9 @@
   /// "this" will be used as callback, but you can also specify other callback
   /// classes. Thereby, different matchers can trigger different callbacks.
   ///
+ 

[PATCH] D75289: [clang-tidy] Added virtual isLanguageVersionSupported to ClangTidyCheck

2020-02-28 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 247226.
njames93 added a comment.

- Updated docs to include precondition


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75289/new/

https://reviews.llvm.org/D75289

Files:
  clang-tools-extra/clang-tidy/ClangTidy.cpp
  clang-tools-extra/clang-tidy/ClangTidyCheck.h
  clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
  clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
  clang-tools-extra/clangd/ParsedAST.cpp
  clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h

Index: clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
===
--- clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
+++ clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
@@ -67,6 +67,8 @@
 // `getLangOpts()`).
 CheckFactory::createChecks(, Checks);
 for (auto  : Checks) {
+  if (!Check->isLanguageVersionSupported(Context.getLangOpts()))
+continue;
   Check->registerMatchers();
   Check->registerPPCallbacks(Compiler.getSourceManager(), PP, PP);
 }
Index: clang-tools-extra/clangd/ParsedAST.cpp
===
--- clang-tools-extra/clangd/ParsedAST.cpp
+++ clang-tools-extra/clangd/ParsedAST.cpp
@@ -301,6 +301,8 @@
 });
 Preprocessor *PP = >getPreprocessor();
 for (const auto  : CTChecks) {
+  if (!Check->isLanguageVersionSupported(CTContext->getLangOpts()))
+continue;
   // FIXME: the PP callbacks skip the entire preamble.
   // Checks that want to see #includes in the main file do not see them.
   Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
Index: clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
===
--- clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
+++ clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
@@ -41,7 +41,7 @@
   virtual SmartPtrTypeMatcher getSmartPointerTypeMatcher() const = 0;
 
   /// Returns whether the C++ version is compatible with current check.
-  virtual bool isLanguageVersionSupported(const LangOptions ) const;
+  bool isLanguageVersionSupported(const LangOptions ) const override;
 
   static const char PointerType[];
 
Index: clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
@@ -68,17 +68,12 @@
 void MakeSmartPtrCheck::registerPPCallbacks(const SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
-  if (isLanguageVersionSupported(getLangOpts())) {
 Inserter = std::make_unique(SM, getLangOpts(),
  IncludeStyle);
 PP->addPPCallbacks(Inserter->CreatePPCallbacks());
-  }
 }
 
 void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
-  if (!isLanguageVersionSupported(getLangOpts()))
-return;
-
   // Calling make_smart_ptr from within a member function of a type with a
   // private or protected constructor would be ill-formed.
   auto CanCallCtor = unless(has(ignoringImpCasts(
Index: clang-tools-extra/clang-tidy/ClangTidyCheck.h
===
--- clang-tools-extra/clang-tidy/ClangTidyCheck.h
+++ clang-tools-extra/clang-tidy/ClangTidyCheck.h
@@ -58,6 +58,9 @@
   /// This should be used for clang-tidy checks that analyze preprocessor-
   /// dependent properties, e.g. include directives and macro definitions.
   ///
+  /// This will only be executed if the function isLanguageVersionSupported
+  /// returns true.
+  ///
   /// There are two Preprocessors to choose from that differ in how they handle
   /// modular #includes:
   ///  - PP is the real Preprocessor. It doesn't walk into modular #includes and
@@ -80,6 +83,9 @@
   /// "this" will be used as callback, but you can also specify other callback
   /// classes. Thereby, different matchers can trigger different callbacks.
   ///
+  /// This will only be executed if the function isLanguageVersionSupported
+  /// returns true.
+  ///
   /// If you need to merge information between the different matchers, you can
   /// store these as members of the derived class. However, note that all
   /// matches occur in the order of the AST traversal.
@@ -100,6 +106,16 @@
   /// whether it has the default value or it has been overridden.
   virtual void storeOptions(ClangTidyOptions::OptionMap ) {}
 
+  /// Override this to disable registering matchers and PP callbacks if an
+  /// invalid language version is being used.
+  ///
+  /// For example if a check is examining overloaded functions then this should
+  /// be overridden 

[PATCH] D75332: [clang-tidy] Add module for llvm-libc and restrict-system-libc-header-check.

2020-02-28 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

The test cases need fixing as they are causing the build to fail. Also would it 
be wise to add a .clang-tidy file to libc/ to enable this module for that 
subdirectory?




Comment at: clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt:17
+  
\ No newline at end of file


Not sure why this error is here but can it be resolved



Comment at: 
clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp:17
+
+class RestrictedIncludesPPCallbacks : public PPCallbacks {
+public:

Should put this in an anonymous namespace as it doesn't need external linkage



Comment at: 
clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.h:18
+
+/// FIXME: Write a short description.
+///

FIXME



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/llvmlibc-restrict-system-libc-headers.rst:6
+
+Finds includes of system libc headers within llvm-libc implementations.
+

Should explain the rationale for this check


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75332/new/

https://reviews.llvm.org/D75332



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75289: [clang-tidy] Added virtual isLanguageVersionSupported to ClangTidyCheck

2020-02-27 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: aaron.ballman, gribozavr2, Eugene.Zelenko, JonasToth, 
alexfh, hokein.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, 
xazax.hun.
Herald added a project: clang.

Motivated by Tune inspections to a specific C++ standard. 

Moves the isLanguageVersionSupported virtual function from `MakeSmartPtrCheck` 
to the base `ClangTidyCheck` class.
This will disable registering matchers or pp callbacks on unsupported language 
versions for a check.
Having it as a standalone function is cleaner than manually disabling the check 
in the register function and should hopefully
encourage check developers to actually restrict the check based on language 
version.
As an added bonus this could enable automatic detection of what language 
version a check runs on for the purpose of documentation generation


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75289

Files:
  clang-tools-extra/clang-tidy/ClangTidy.cpp
  clang-tools-extra/clang-tidy/ClangTidyCheck.h
  clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
  clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
  clang-tools-extra/clangd/ParsedAST.cpp
  clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h


Index: clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
===
--- clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
+++ clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
@@ -67,6 +67,8 @@
 // `getLangOpts()`).
 CheckFactory::createChecks(, Checks);
 for (auto  : Checks) {
+  if (!Check->isLanguageVersionSupported(Context.getLangOpts()))
+continue;
   Check->registerMatchers();
   Check->registerPPCallbacks(Compiler.getSourceManager(), PP, PP);
 }
Index: clang-tools-extra/clangd/ParsedAST.cpp
===
--- clang-tools-extra/clangd/ParsedAST.cpp
+++ clang-tools-extra/clangd/ParsedAST.cpp
@@ -301,6 +301,8 @@
 });
 Preprocessor *PP = >getPreprocessor();
 for (const auto  : CTChecks) {
+  if (!Check->isLanguageVersionSupported(CTContext->getLangOpts()))
+continue;
   // FIXME: the PP callbacks skip the entire preamble.
   // Checks that want to see #includes in the main file do not see them.
   Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
Index: clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
===
--- clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
+++ clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
@@ -41,7 +41,7 @@
   virtual SmartPtrTypeMatcher getSmartPointerTypeMatcher() const = 0;
 
   /// Returns whether the C++ version is compatible with current check.
-  virtual bool isLanguageVersionSupported(const LangOptions ) const;
+  bool isLanguageVersionSupported(const LangOptions ) const override;
 
   static const char PointerType[];
 
Index: clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
@@ -68,17 +68,12 @@
 void MakeSmartPtrCheck::registerPPCallbacks(const SourceManager ,
 Preprocessor *PP,
 Preprocessor *ModuleExpanderPP) {
-  if (isLanguageVersionSupported(getLangOpts())) {
 Inserter = std::make_unique(SM, getLangOpts(),
  IncludeStyle);
 PP->addPPCallbacks(Inserter->CreatePPCallbacks());
-  }
 }
 
 void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
-  if (!isLanguageVersionSupported(getLangOpts()))
-return;
-
   // Calling make_smart_ptr from within a member function of a type with a
   // private or protected constructor would be ill-formed.
   auto CanCallCtor = unless(has(ignoringImpCasts(
Index: clang-tools-extra/clang-tidy/ClangTidyCheck.h
===
--- clang-tools-extra/clang-tidy/ClangTidyCheck.h
+++ clang-tools-extra/clang-tidy/ClangTidyCheck.h
@@ -100,6 +100,16 @@
   /// whether it has the default value or it has been overridden.
   virtual void storeOptions(ClangTidyOptions::OptionMap ) {}
 
+  /// Override this to disable registering matchers and PP callbacks if an
+  /// invalid language version is being used.
+  ///
+  /// For example if a check is examining overloaded functions then this should
+  /// be overridden to return false when the CPlusPlus flag is not set in 
+  /// \p LangOpts.
+  virtual bool isLanguageVersionSupported(const LangOptions ) const {
+return true;
+  }
+
   /// Provides access to the 

[PATCH] D74669: [clang-tidy] New check: misc-no-include-cpp

2020-02-27 Thread Nathan James via Phabricator via cfe-commits
njames93 added inline comments.



Comment at: clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp:44
+  RawStringRecommendedExtensions(Options.getLocalOrGlobal(
+  "RecommendedExtensions", utils::defaultHeaderFileExtensions())) {
+  if (!utils::parseFileExtensions(RawStringSuspiciousExtensions,

Follow the convention of the other checks and use `HeaderFileExtensions` as the 
option name. Probably call the other option `ImplementationFileExtensions`



Comment at: clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.cpp:42
+StringRef Extension = Suffix.trim();
+for (StringRef::const_iterator it = Extension.begin();
+ it != Extension.end(); ++it) {

This could be changed to 
```
if (!llvm::all_of(Extension, isAlphanumeric))
  return false;
```



Comment at: clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h:38
+/// extensions.
+inline StringRef defaultHeaderFileExtensions() { return ",h,hh,hpp,hxx"; }
+

A lot of configuration options for clang tidy use semi-colon `;` seperated 
lists. Would it not be wise to carry on the convention and use semi colon here 
(and below) as well. It could break a few peoples configuration but that would 
be realised  fairly quickly and updated


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74669/new/

https://reviews.llvm.org/D74669



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75714: Add Optional overload to DiagnosticBuilder operator <

2020-03-05 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75714

Files:
  clang/include/clang/Basic/Diagnostic.h


Index: clang/include/clang/Basic/Diagnostic.h
===
--- clang/include/clang/Basic/Diagnostic.h
+++ clang/include/clang/Basic/Diagnostic.h
@@ -21,6 +21,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/iterator_range.h"
@@ -1311,6 +1312,15 @@
   return DB;
 }
 
+template 
+inline const DiagnosticBuilder <<(const DiagnosticBuilder ,
+   const llvm::Optional ) {
+  if (Opt) {
+DB << *Opt;
+  }
+  return DB;
+}
+
 inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
   return Report(SourceLocation(), DiagID);
 }


Index: clang/include/clang/Basic/Diagnostic.h
===
--- clang/include/clang/Basic/Diagnostic.h
+++ clang/include/clang/Basic/Diagnostic.h
@@ -21,6 +21,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/iterator_range.h"
@@ -1311,6 +1312,15 @@
   return DB;
 }
 
+template 
+inline const DiagnosticBuilder <<(const DiagnosticBuilder ,
+   const llvm::Optional ) {
+  if (Opt) {
+DB << *Opt;
+  }
+  return DB;
+}
+
 inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
   return Report(SourceLocation(), DiagID);
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75569: [clang-tidy] New check for methods marked __attribute__((unavailable)) that do not override a method from a superclass.

2020-03-05 Thread Nathan James via Phabricator via cfe-commits
njames93 added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/objc/MethodUnavailableNotOverrideCheck.cpp:47-49
+  auto Iter =
+  std::find(Macros.begin(), Macros.end(), Tok.getRawIdentifier().str());
+  return Iter != Macros.end();

`return llvm::is_contained(Macros, Tok.getRawIdentifier().str())`



Comment at: 
clang-tools-extra/clang-tidy/objc/MethodUnavailableNotOverrideCheck.cpp:52
+
+static FixItHint
+fixItRemovingUnavailableMethod(const ObjCMethodDecl *MD,

Should probably return an `llvm::Optional`



Comment at: 
clang-tools-extra/clang-tidy/objc/MethodUnavailableNotOverrideCheck.cpp:80
+void MethodUnavailableNotOverrideCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().ObjC)
+return;

This check is surplus to requirements now that there is the 
`isLanguageVersionSupported` check



Comment at: 
clang-tools-extra/clang-tidy/objc/MethodUnavailableNotOverrideCheck.cpp:84
+  Finder->addMatcher(
+  objcMethodDecl(allOf(hasAttr(clang::attr::Unavailable), 
isNotOverriding(),
+   hasDeclContext(objcInterfaceDecl(

`objcMethodDecl` is implicitly an `allOf` matcher, so there is no need to 
specify `allOf`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75569/new/

https://reviews.llvm.org/D75569



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75621: [clang-tidy] Use ; as separator for HeaderFileExtensions

2020-03-06 Thread Nathan James via Phabricator via cfe-commits
njames93 added inline comments.



Comment at: clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.cpp:43-45
+llvm::errs()
+<< "Using ',' as a file extension delimiter is deprecated. Please "
+   "switch your configuration to use ';'.\n";

lebedev.ri wrote:
> Can this spam be avoided?
> It's going to be really intrusive, and it is not always possible to
> just perform the migration (think: using more than one clang-tidy version.)
> The deprecation message should be in the docs/releasenotes.
That seems like a good idea. Would take a good many versions before the comma 
could safely be removed without fallout so people would get the warning too 
often and not be able to change it


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75621/new/

https://reviews.llvm.org/D75621



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75096: [ASTMatchers] Matcher macros with params move params instead of copying

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: aaron.ballman, gribozavr2.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Use move semantics instead of copying for AST Matchers with parameters


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75096

Files:
  clang/include/clang/ASTMatchers/ASTMatchersMacros.h

Index: clang/include/clang/ASTMatchers/ASTMatchersMacros.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ clang/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -134,9 +134,8 @@
   class matcher_##DefineMatcher##OverloadId##Matcher   \
   : public ::clang::ast_matchers::internal::MatcherInterface {   \
   public:  \
-explicit matcher_##DefineMatcher##OverloadId##Matcher( \
-ParamType const ##Param) \
-: Param(A##Param) {}   \
+explicit matcher_##DefineMatcher##OverloadId##Matcher(ParamType A##Param)  \
+: Param(std::move(A##Param)) {}\
 bool matches(const Type , \
  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,  \
  ::clang::ast_matchers::internal::BoundNodesTreeBuilder\
@@ -147,12 +146,13 @@
   };   \
   }\
   inline ::clang::ast_matchers::internal::Matcher DefineMatcher( \
-  ParamType const ) {\
+  ParamType Param) {   \
 return ::clang::ast_matchers::internal::makeMatcher(   \
-new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));\
+new internal::matcher_##DefineMatcher##OverloadId##Matcher(\
+std::move(Param)));\
   }\
-  typedef ::clang::ast_matchers::internal::Matcher(  \
-  ##_Type##OverloadId)(ParamType const );  \
+  typedef ::clang::ast_matchers::internal::Matcher ( \
+  ##_Type##OverloadId)(ParamType Param); \
   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
   const Type ,\
   ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
@@ -183,9 +183,9 @@
   class matcher_##DefineMatcher##OverloadId##Matcher   \
   : public ::clang::ast_matchers::internal::MatcherInterface {   \
   public:  \
-matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const ##Param1,  \
- ParamType2 const ##Param2)  \
-: Param1(A##Param1), Param2(A##Param2) {}  \
+matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 A##Param1, \
+ ParamType2 A##Param2) \
+: Param1(std::move(A##Param1)), Param2(std::move(A##Param2)) {}\
 bool matches(const Type , \
  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,  \
  ::clang::ast_matchers::internal::BoundNodesTreeBuilder\
@@ -197,14 +197,14 @@
   };   \
   }\
   inline ::clang::ast_matchers::internal::Matcher DefineMatcher( \
-  ParamType1 const , ParamType2 const ) {\
+  ParamType1 Param1, ParamType2 Param2) {  \
 return ::clang::ast_matchers::internal::makeMatcher(   \
-new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \
-   Param2));   \
+new internal::matcher_##DefineMatcher##OverloadId##Matcher(\
+std::move(Param1), std::move(Param2)));\
   }\
-  typedef ::clang::ast_matchers::internal::Matcher(  \
-  ##_Type##OverloadId)(ParamType1 const , \
- ParamType2 const );\
+  typedef 

[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6a0c066c6102: [ASTMatchers] Adds a matcher called 
`hasAnyOperatorName` (authored by njames93).

Changed prior to commit:
  https://reviews.llvm.org/D75040?vs=246335=246375#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/tools/dump_ast_matchers.py
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1123,6 +1123,19 @@
   EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
 }
 
+TEST(MatchBinaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher =
+  binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
+
+  EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
+  EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
+  // Ensure '+= isn't mistaken.
+  EXPECT_TRUE(notMatches("void x(int ) { I += 1; }", Matcher));
+}
+
 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
   StatementMatcher OperatorTrueFalse =
 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
@@ -1255,6 +1268,18 @@
   EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
 }
 
+TEST(MatchUnaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
+
+  EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { I++; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { ++I; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { I--; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { --I; }", Matcher));
+  EXPECT_TRUE(notMatches("int *x(int ) { return  }", Matcher));
+}
+
 TEST(MatchUnaryOperator, HasUnaryOperand) {
   StatementMatcher OperatorOnFalse =
 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -243,6 +243,7 @@
   REGISTER_MATCHER(hasAnyConstructorInitializer);
   REGISTER_MATCHER(hasAnyDeclaration);
   REGISTER_MATCHER(hasAnyName);
+  REGISTER_MATCHER(hasAnyOperatorName);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnyPlacementArg);
   REGISTER_MATCHER(hasAnySelector);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -375,6 +375,10 @@
   return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
 }
 
+HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef NameRefs) {
+  return HasOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
 HasNameMatcher::HasNameMatcher(std::vector N)
 : UseUnqualifiedMatch(llvm::all_of(
   N, [](StringRef Name) { return Name.find("::") == Name.npos; })),
@@ -849,6 +853,10 @@
 const internal::VariadicFunction, StringRef,
  internal::hasAnyNameFunc>
 hasAnyName = {};
+
+const internal::VariadicFunction
+hasAnyOperatorName = {};
 const internal::VariadicFunction, StringRef,
  internal::hasAnySelectorFunc>
 hasAnySelector = {};
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1858,6 +1858,47 @@
 llvm::Optional
 getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
const ASTContext );
+
+/// Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be std::vector>.
+template >
+class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface {
+  static_assert(std::is_same::value ||
+std::is_same::value,
+"Matcher only supports `BinaryOperator` and `UnaryOperator`");
+  static_assert(std::is_same>::value,
+  

[PATCH] D75096: [ASTMatchers] Matcher macros with params move params instead of copying

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG3e9a7b2ba470: [ASTMatchers] Matcher macros with params move 
params instead of copying (authored by njames93).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75096/new/

https://reviews.llvm.org/D75096

Files:
  clang/include/clang/ASTMatchers/ASTMatchersMacros.h

Index: clang/include/clang/ASTMatchers/ASTMatchersMacros.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ clang/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -134,9 +134,8 @@
   class matcher_##DefineMatcher##OverloadId##Matcher   \
   : public ::clang::ast_matchers::internal::MatcherInterface {   \
   public:  \
-explicit matcher_##DefineMatcher##OverloadId##Matcher( \
-ParamType const ##Param) \
-: Param(A##Param) {}   \
+explicit matcher_##DefineMatcher##OverloadId##Matcher(ParamType A##Param)  \
+: Param(std::move(A##Param)) {}\
 bool matches(const Type , \
  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,  \
  ::clang::ast_matchers::internal::BoundNodesTreeBuilder\
@@ -147,12 +146,13 @@
   };   \
   }\
   inline ::clang::ast_matchers::internal::Matcher DefineMatcher( \
-  ParamType const ) {\
+  ParamType Param) {   \
 return ::clang::ast_matchers::internal::makeMatcher(   \
-new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));\
+new internal::matcher_##DefineMatcher##OverloadId##Matcher(\
+std::move(Param)));\
   }\
-  typedef ::clang::ast_matchers::internal::Matcher(  \
-  ##_Type##OverloadId)(ParamType const );  \
+  typedef ::clang::ast_matchers::internal::Matcher ( \
+  ##_Type##OverloadId)(ParamType Param); \
   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
   const Type ,\
   ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
@@ -183,9 +183,9 @@
   class matcher_##DefineMatcher##OverloadId##Matcher   \
   : public ::clang::ast_matchers::internal::MatcherInterface {   \
   public:  \
-matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const ##Param1,  \
- ParamType2 const ##Param2)  \
-: Param1(A##Param1), Param2(A##Param2) {}  \
+matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 A##Param1, \
+ ParamType2 A##Param2) \
+: Param1(std::move(A##Param1)), Param2(std::move(A##Param2)) {}\
 bool matches(const Type , \
  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,  \
  ::clang::ast_matchers::internal::BoundNodesTreeBuilder\
@@ -197,14 +197,14 @@
   };   \
   }\
   inline ::clang::ast_matchers::internal::Matcher DefineMatcher( \
-  ParamType1 const , ParamType2 const ) {\
+  ParamType1 Param1, ParamType2 Param2) {  \
 return ::clang::ast_matchers::internal::makeMatcher(   \
-new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \
-   Param2));   \
+new internal::matcher_##DefineMatcher##OverloadId##Matcher(\
+std::move(Param1), std::move(Param2)));\
   }\
-  typedef ::clang::ast_matchers::internal::Matcher(  \
-  ##_Type##OverloadId)(ParamType1 const , \
- ParamType2 const );  

[PATCH] D75107: [clang-tidy] hicpp-signed-bitwise IgnorePositiveIntegerLiterals now partially recursive

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: aaron.ballman, gribozavr2, alexfh, hokein, JonasToth.
Herald added subscribers: cfe-commits, xazax.hun.
Herald added a project: clang.

Addresses hicpp-signed-bitwise.IgnorePositiveIntegerLiterals should be 
recursive. 
Only recursive for `|`, `^` and `&` operations and their assignment 
counterparts.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75107

Files:
  clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.cpp
  
clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-integer-literals.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-integer-literals.cpp
===
--- 
clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-integer-literals.cpp
+++ 
clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-integer-literals.cpp
@@ -21,6 +21,11 @@
   IResult = Int << 1;
   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand 
with a binary bitwise operator
   IResult = ~0; //Ok
+
+  IResult = 2 | 4 | 8;
+  IResult = 2 | 4 | 8 | 16;
+  IResult = 2 | 4 | 8 | 16 | -1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand 
with a binary bitwise operator
 }
 
 enum EnumConstruction {
Index: clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.cpp
===
--- clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.cpp
+++ clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.cpp
@@ -46,15 +46,24 @@
  "::std::ios_base::openmode"));
   const auto IsStdBitmask = 
ignoringImpCasts(declRefExpr(hasType(BitmaskType)));
 
+  const auto SignNoInterferenceOp =
+  hasAnyOperatorName("^", "^=", "|", "|=", "&", "&=");
+
+  const auto SignedIntegerOperandExtended =
+  (IgnorePositiveIntegerLiterals
+   ? expr(ignoringImpCasts(hasType(isSignedInteger())),
+  unless(anyOf(integerLiteral(),
+   binaryOperator(SignNoInterferenceOp
+   : expr(ignoringImpCasts(hasType(isSignedInteger()
+  .bind("signed-operand");
+
   // Match binary bitwise operations on signed integer arguments.
   Finder->addMatcher(
-  binaryOperator(anyOf(hasOperatorName("^"), hasOperatorName("|"),
-   hasOperatorName("&"), hasOperatorName("^="),
-   hasOperatorName("|="), hasOperatorName("&=")),
+  binaryOperator(SignNoInterferenceOp,
 
  unless(allOf(hasLHS(IsStdBitmask), hasRHS(IsStdBitmask))),
 
- hasEitherOperand(SignedIntegerOperand),
+ hasEitherOperand(SignedIntegerOperandExtended),
  hasLHS(hasType(isInteger())), 
hasRHS(hasType(isInteger(
   .bind("binary-no-sign-interference"),
   this);


Index: clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-integer-literals.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-integer-literals.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-integer-literals.cpp
@@ -21,6 +21,11 @@
   IResult = Int << 1;
   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
   IResult = ~0; //Ok
+
+  IResult = 2 | 4 | 8;
+  IResult = 2 | 4 | 8 | 16;
+  IResult = 2 | 4 | 8 | 16 | -1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
 }
 
 enum EnumConstruction {
Index: clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.cpp
===
--- clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.cpp
+++ clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.cpp
@@ -46,15 +46,24 @@
  "::std::ios_base::openmode"));
   const auto IsStdBitmask = ignoringImpCasts(declRefExpr(hasType(BitmaskType)));
 
+  const auto SignNoInterferenceOp =
+  hasAnyOperatorName("^", "^=", "|", "|=", "&", "&=");
+
+  const auto SignedIntegerOperandExtended =
+  (IgnorePositiveIntegerLiterals
+   ? expr(ignoringImpCasts(hasType(isSignedInteger())),
+  unless(anyOf(integerLiteral(),
+   binaryOperator(SignNoInterferenceOp
+   : expr(ignoringImpCasts(hasType(isSignedInteger()
+  .bind("signed-operand");
+
   // Match binary bitwise operations on signed integer arguments.
   Finder->addMatcher(
-  binaryOperator(anyOf(hasOperatorName("^"), hasOperatorName("|"),
-   hasOperatorName("&"), hasOperatorName("^="),
-   hasOperatorName("|="), hasOperatorName("&=")),
+  binaryOperator(SignNoInterferenceOp,
 
  

[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
njames93 edited the summary of this revision.
njames93 added reviewers: aaron.ballman, gribozavr2.

Acts on `BinaryOperator` and `UnaryOperator` and functions the same as 
`anyOf(hasOperatorName(...), hasOperatorName(...), ...)`

Documentation generation isn't perfect but I feel that the python doc script 
needs updating for that


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75040

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1123,6 +1123,19 @@
   EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
 }
 
+TEST(MatchBinaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher =
+  binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
+
+  EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
+  EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
+  // Ensure '+= isn't mistaken.
+  EXPECT_TRUE(notMatches("void x(int ) { I += 1; }", Matcher));
+}
+
 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
   StatementMatcher OperatorTrueFalse =
 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
@@ -1255,6 +1268,18 @@
   EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
 }
 
+TEST(MatchUnaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
+
+  EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { I++; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { ++I; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { I--; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { --I; }", Matcher));
+  EXPECT_TRUE(notMatches("int *x(int ) { return  }", Matcher));
+}
+
 TEST(MatchUnaryOperator, HasUnaryOperand) {
   StatementMatcher OperatorOnFalse =
 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -243,6 +243,7 @@
   REGISTER_MATCHER(hasAnyConstructorInitializer);
   REGISTER_MATCHER(hasAnyDeclaration);
   REGISTER_MATCHER(hasAnyName);
+  REGISTER_MATCHER(hasAnyOperatorName);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnyPlacementArg);
   REGISTER_MATCHER(hasAnySelector);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -380,6 +380,10 @@
   return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
 }
 
+HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef NameRefs) {
+  return HasOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
 HasNameMatcher::HasNameMatcher(std::vector N)
 : UseUnqualifiedMatch(std::all_of(
   N.begin(), N.end(),
@@ -854,6 +858,10 @@
 const internal::VariadicFunction, StringRef,
  internal::hasAnyNameFunc>
 hasAnyName = {};
+
+const internal::VariadicFunction
+hasAnyOperatorName = {};
 const internal::VariadicFunction, StringRef,
  internal::hasAnySelectorFunc>
 hasAnySelector = {};
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1858,6 +1858,50 @@
 llvm::Optional
 getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
const ASTContext );
+
+/// Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be StringRef.
+template 
+class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface {
+  static_assert(std::is_same::value ||
+std::is_same::value,
+"unsupported class for matcher");
+  static_assert(std::is_same>::value,
+"Unsupported 

[PATCH] D75113: [docs] dump-ast-matchers removes const from Matcher args and handles template functions slightly better

2020-02-25 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: aaron.ballman, gribozavr2, joerg.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75113

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/tools/dump_ast_matchers.py

Index: clang/docs/tools/dump_ast_matchers.py
===
--- clang/docs/tools/dump_ast_matchers.py
+++ clang/docs/tools/dump_ast_matchers.py
@@ -101,6 +101,8 @@
   args = re.sub(r'extern const\s+(.*)&', r'\1 ', args)
   args = re.sub(r'&', r' ', args)
   args = re.sub(r'(^|\s)M\d?(\s)', r'\1Matcher<*>\2', args)
+  args = re.sub(r'BindableMatcher', r'Matcher', args)
+  args = re.sub(r'const Matcher', r'Matcher', args)
   return args
 
 def unify_type(result_type):
@@ -125,7 +127,8 @@
 'id': matcher_id,
   }
   if is_dyncast:
-node_matchers[result_type + name] = matcher_html
+dict = node_matchers
+lookup = result_type + name
   # Use a heuristic to figure out whether a matcher is a narrowing or
   # traversal matcher. By default, matchers that take other matchers as
   # arguments (and are not node matchers) do traversal. We specifically
@@ -133,9 +136,14 @@
   # arguments.
   elif ('Matcher<' not in args or
 name in ['allOf', 'anyOf', 'anything', 'unless']):
-narrowing_matchers[result_type + name + esc(args)] = matcher_html
+dict = narrowing_matchers
+lookup = result_type + name + esc(args)
   else:
-traversal_matchers[result_type + name + esc(args)] = matcher_html
+dict = traversal_matchers
+lookup = result_type + name + esc(args)
+  
+  if dict.get(lookup) is None or len(dict.get(lookup)) < len(matcher_html):
+dict[lookup] = matcher_html
 
 def act_on_decl(declaration, comment, allowed_types):
   """Parse the matcher out of the given declaration and comment.
@@ -145,6 +153,9 @@
  definition.
   """
   if declaration.strip():
+
+if re.match(r'^\s?(#|namespace|using)', declaration): return
+
 # Node matchers are defined by writing:
 #   VariadicDynCastAllOfMatcher name;
 m = re.match(r""".*Variadic(?:DynCast)?AllOfMatcher\s*<
@@ -317,16 +328,27 @@
 
 # Parse free standing matcher functions, like:
 #   Matcher Name(Matcher InnerMatcher) {
-m = re.match(r"""^\s*(.*)\s+
+m = re.match(r"""^\s*(?:template\s+<\s*(?:class|typename)\s+(.+)\s*>\s+)?   
+ (.*)\s+
  ([^\s\(]+)\s*\(
  (.*)
  \)\s*{""", declaration, re.X)
 if m:
-  result, name, args = m.groups()
+  template_name, result, name, args = m.groups()
+  if template_name:
+matcherTemplateArgs = re.findall(r'Matcher<\s*(%s)\s*>' % template_name, args)
+templateArgs = re.findall(r'(?:^|[\s,<])(%s)(?:$|[\s,>])' % template_name, args)
+if len(matcherTemplateArgs) < len(templateArgs):
+  # The template name is used naked, so don't replace with `*`` later on
+  template_name = None
+else :
+  args = re.sub(r'(^|[\s,<])%s($|[\s,>])' % template_name, r'\1*\2', args)
   args = ', '.join(p.strip() for p in args.split(','))
-  m = re.match(r'.*\s+internal::(Bindable)?Matcher<([^>]+)>$', result)
+  m = re.match(r'(?:^|.*\s+)internal::(?:Bindable)?Matcher<([^>]+)>$', result)
   if m:
-result_types = [m.group(2)]
+result_types = [m.group(1)]
+if template_name and len(result_types) is 1 and result_types[0] == template_name:
+  result_types = ['*']
   else:
 result_types = extract_result_types(comment)
   if not result_types:
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -4669,6 +4669,22 @@
 
 
 
+Matcher*findAllMatcher*  Matcher
+Matches if the node or any descendant matches.
+
+Generates results for each match.
+
+For example, in:
+  class A { class B {}; class C {}; };
+The matcher:
+  cxxRecordDecl(hasName("::A"),
+findAll(cxxRecordDecl(isDefinition()).bind("m")))
+will generate results for A, B and C.
+
+Usable as: Any Matcher
+
+
+
 Matcher*forEachDescendantMatcher*
 Matches AST nodes that have descendant AST nodes that match the
 provided matcher.
@@ -4803,6 +4819,22 @@
 
 
 
+Matcher*traverseTraversalKind TK, Matcher*  InnerMatcher
+Causes all nested matchers to be matched with the specified traversal kind.
+
+Given
+  void foo()
+  {
+  int i = 3.0;
+  }
+The matcher
+  traverse(TK_IgnoreImplicitCastsAndParentheses,
+varDecl(hasInitializer(floatLiteral().bind("init")))
+  )
+matches the variable declaration with "init" bound to the "3.0".
+
+
+
 

[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 marked an inline comment as done.
njames93 added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1870
+std::is_same::value,
+"unsupported class for matcher");
+  static_assert(std::is_same>::value,

gribozavr2 wrote:
> Consider enhancing the message to say what the expected types are.
This is the reason c++17 removed the need for static_assert messages, the 
message isn't needed as you can figure the error from the predicate



Comment at: clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1880-1884
+for (const std::string  : Names) {
+  if (Name == OpName)
+return true;
+}
+return false;

aaron.ballman wrote:
> Can we use `llvm::find()` instead of a manual loop?
`llvm::is_contained` would be better, but they involve creating temporaries, 
`llvm::any_of` does it best I think


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246190.
njames93 marked an inline comment as done.
njames93 edited the summary of this revision.
njames93 added a comment.

- Address nits


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1123,6 +1123,19 @@
   EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
 }
 
+TEST(MatchBinaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher =
+  binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
+
+  EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
+  EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
+  // Ensure '+= isn't mistaken.
+  EXPECT_TRUE(notMatches("void x(int ) { I += 1; }", Matcher));
+}
+
 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
   StatementMatcher OperatorTrueFalse =
 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
@@ -1255,6 +1268,18 @@
   EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
 }
 
+TEST(MatchUnaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
+
+  EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { I++; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { ++I; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { I--; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { --I; }", Matcher));
+  EXPECT_TRUE(notMatches("int *x(int ) { return  }", Matcher));
+}
+
 TEST(MatchUnaryOperator, HasUnaryOperand) {
   StatementMatcher OperatorOnFalse =
 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -243,6 +243,7 @@
   REGISTER_MATCHER(hasAnyConstructorInitializer);
   REGISTER_MATCHER(hasAnyDeclaration);
   REGISTER_MATCHER(hasAnyName);
+  REGISTER_MATCHER(hasAnyOperatorName);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnyPlacementArg);
   REGISTER_MATCHER(hasAnySelector);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -380,6 +380,10 @@
   return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
 }
 
+HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef NameRefs) {
+  return HasOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
 HasNameMatcher::HasNameMatcher(std::vector N)
 : UseUnqualifiedMatch(std::all_of(
   N.begin(), N.end(),
@@ -854,6 +858,10 @@
 const internal::VariadicFunction, StringRef,
  internal::hasAnyNameFunc>
 hasAnyName = {};
+
+const internal::VariadicFunction
+hasAnyOperatorName = {};
 const internal::VariadicFunction, StringRef,
  internal::hasAnySelectorFunc>
 hasAnySelector = {};
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1858,6 +1858,47 @@
 llvm::Optional
 getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
const ASTContext );
+
+/// Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be std::vector>.
+template >
+class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface {
+  static_assert(std::is_same::value ||
+std::is_same::value,
+"Matcher only supports `BinaryOperator` and `UnaryOperator`");
+  static_assert(std::is_same>::value,
+"Matcher ArgT must be std::vector");
+
+public:
+  explicit HasAnyOperatorNameMatcher(std::vector Names)
+  : SingleNodeMatcherInterface(), Names(std::move(Names)) {}

[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 marked an inline comment as done.
njames93 added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:4772
+///
+/// FIXME: Tweak to improve docs generated
+extern const internal::VariadicFunction Any specific things you would like to improve? The fixme is rather vague.
This is what comes up in the ASTMatchersReference docs. 
```
Matcher hasAnyOperatorName  StringRef, ..., 
StringRef```
I would like it to have 
```
Matcher  hasAnyOperatorName StringRef, ..., StringRef
...
Matcher  hasAnyOperatorName  StringRef, ..., StringRef```
However how VariadicFunction is matched in the dumper won't support that yet. 
And If you want to support it properly regex wouldn't work, instead you'd need 
a parser


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75046: [docs] dump_ast_matchers strips internal::(Bindable)?Matcher from Result_type

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: joerg, gribozavr2, aaron.ballman.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Remove `internal::Matcher` and `internal::BindableMatcher` from Result Type 
when dumping AST Matchers


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75046

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/tools/dump_ast_matchers.py
  clang/include/clang/ASTMatchers/ASTMatchers.h

Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -307,7 +307,7 @@
 ///
 /// FIXME: Change to be a polymorphic matcher that works on any syntactic
 /// node. There's nothing `Stmt`-specific about it.
-AST_MATCHER_P(clang::Stmt, isExpandedFromMacro, llvm::StringRef, MacroName) {
+AST_MATCHER_P(Stmt, isExpandedFromMacro, llvm::StringRef, MacroName) {
   // Verifies that the statement' beginning and ending are both expanded from
   // the same instance of the given macro.
   auto& Context = Finder->getASTContext();
Index: clang/docs/tools/dump_ast_matchers.py
===
--- clang/docs/tools/dump_ast_matchers.py
+++ clang/docs/tools/dump_ast_matchers.py
@@ -103,6 +103,11 @@
   args = re.sub(r'(^|\s)M\d?(\s)', r'\1Matcher<*>\2', args)
   return args
 
+def unify_type(result_type):
+  """Gets rid of anything the user doesn't care about in the type name."""
+  result_type = re.sub(r'^internal::(Bindable)?Matcher<([a-zA-Z_][a-zA-Z0-9_]*)>$', r'\2', result_type)
+  return result_type
+
 def add_matcher(result_type, name, args, comment, is_dyncast=False):
   """Adds a matcher to one of our categories."""
   if name == 'id':
@@ -111,6 +116,7 @@
   matcher_id = '%s%d' % (name, ids[name])
   ids[name] += 1
   args = unify_arguments(args)
+  result_type = unify_type(result_type)
   matcher_html = TD_TEMPLATE % {
 'result': esc('Matcher<%s>' % result_type),
 'name': name,
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -2948,6 +2948,19 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Decl.html;>DeclisInstantiated
+Matches declarations that are template instantiations or are inside
+template instantiations.
+
+Given
+  templatetypename T void A(T t) { T i; }
+  A(0);
+  A(0U);
+functionDecl(isInstantiated())
+  matches 'A(int) {...};' and 'A(unsigned) {...}'.
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Decl.html;>DeclisPrivate
 Matches private C++ declarations.
 
@@ -3516,6 +3529,16 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html;>NamedDeclhasAnyNameStringRef, ..., StringRef
+Matches NamedDecl nodes that have any of the specified names.
+
+This matcher is only provided as a performance optimization of hasName.
+hasAnyName(a, b, c)
+ is equivalent to, but faster than
+anyOf(hasName(a), hasName(b), hasName(c))
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html;>NamedDeclhasExternalFormalLinkage
 Matches a declaration that has external formal linkage.
 
@@ -3679,6 +3702,17 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html;>ObjCMessageExprhasAnySelectorStringRef, ..., StringRef
+Matches when at least one of the supplied string equals to the
+Selector.getAsString()
+
+ matcher = objCMessageExpr(hasSelector("methodA:", "methodB:"));
+ matches both of the expressions below:
+[myObj methodA:argA];
+[myObj methodB:argB];
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html;>ObjCMessageExprhasKeywordSelector
 Matches when the selector is a keyword selector
 
@@ -4015,6 +4049,17 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtisExpandedFromMacrollvm::StringRef MacroName
+Matches statements that are (transitively) expanded from the named macro.
+Does not match if only part of the statement is expanded from that macro or
+if different parts of the the statement are expanded from different
+appearances of the macro.
+
+FIXME: Change to be a polymorphic matcher that works on any syntactic
+node. There's nothing `Stmt`-specific about it.
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtisExpansionInFileMatchingstd::string RegExp
 Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
@@ -4058,6 +4103,22 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtisInTemplateInstantiation
+Matches statements inside of a template instantiation.
+
+Given
+  int j;
+  templatetypename T void A(T t) { T i; j += 42;}
+  A(0);
+  A(0U);
+declStmt(isInTemplateInstantiation())
+  matches 'int i;' and 'unsigned i'.

[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 246203.
njames93 added a comment.

- Improved docs


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/tools/dump_ast_matchers.py
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1123,6 +1123,19 @@
   EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
 }
 
+TEST(MatchBinaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher =
+  binaryOperator(hasAnyOperatorName("+", "-", "*", "/"));
+
+  EXPECT_TRUE(matches("int x(int I) { return I + 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I - 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I * 2; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return I / 2; }", Matcher));
+  EXPECT_TRUE(notMatches("int x(int I) { return I % 2; }", Matcher));
+  // Ensure '+= isn't mistaken.
+  EXPECT_TRUE(notMatches("void x(int ) { I += 1; }", Matcher));
+}
+
 TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
   StatementMatcher OperatorTrueFalse =
 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
@@ -1255,6 +1268,18 @@
   EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
 }
 
+TEST(MatchUnaryOperator, HasAnyOperatorName) {
+  StatementMatcher Matcher = unaryOperator(hasAnyOperatorName("-", "*", "++"));
+
+  EXPECT_TRUE(matches("int x(int *I) { return *I; }", Matcher));
+  EXPECT_TRUE(matches("int x(int I) { return -I; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { I++; }", Matcher));
+  EXPECT_TRUE(matches("void x(int ) { ++I; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { I--; }", Matcher));
+  EXPECT_TRUE(notMatches("void x(int ) { --I; }", Matcher));
+  EXPECT_TRUE(notMatches("int *x(int ) { return  }", Matcher));
+}
+
 TEST(MatchUnaryOperator, HasUnaryOperand) {
   StatementMatcher OperatorOnFalse =
 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -243,6 +243,7 @@
   REGISTER_MATCHER(hasAnyConstructorInitializer);
   REGISTER_MATCHER(hasAnyDeclaration);
   REGISTER_MATCHER(hasAnyName);
+  REGISTER_MATCHER(hasAnyOperatorName);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnyPlacementArg);
   REGISTER_MATCHER(hasAnySelector);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -380,6 +380,10 @@
   return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
 }
 
+HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef NameRefs) {
+  return HasOpNameMatcher(vectorFromRefs(NameRefs));
+}
+
 HasNameMatcher::HasNameMatcher(std::vector N)
 : UseUnqualifiedMatch(std::all_of(
   N.begin(), N.end(),
@@ -854,6 +858,10 @@
 const internal::VariadicFunction, StringRef,
  internal::hasAnyNameFunc>
 hasAnyName = {};
+
+const internal::VariadicFunction
+hasAnyOperatorName = {};
 const internal::VariadicFunction, StringRef,
  internal::hasAnySelectorFunc>
 hasAnySelector = {};
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1858,6 +1858,47 @@
 llvm::Optional
 getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
const ASTContext );
+
+/// Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be std::vector>.
+template >
+class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface {
+  static_assert(std::is_same::value ||
+std::is_same::value,
+"Matcher only supports `BinaryOperator` and `UnaryOperator`");
+  static_assert(std::is_same>::value,
+"Matcher ArgT must be std::vector");
+
+public:
+  explicit HasAnyOperatorNameMatcher(std::vector Names)
+  : SingleNodeMatcherInterface(), Names(std::move(Names)) {}
+
+  bool matchesNode(const T ) const override {

[PATCH] D75040: [ASTMatchers] Adds a matcher called `hasAnyOperatorName`

2020-02-24 Thread Nathan James via Phabricator via cfe-commits
njames93 requested review of this revision.
njames93 marked 3 inline comments as done.
njames93 added a comment.

I have fixed up the docs to be more in line with other matchers


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75040/new/

https://reviews.llvm.org/D75040



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74669: [clang-tidy] New check: bugprone-suspicious-include

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

Adding the parent revision means you don't need to have those changes in this 
patch. It will cause issues down the line. best thing is to run a diff from 
this to the parent and just include those changes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74669/new/

https://reviews.llvm.org/D74669



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75429: [clangd] DefineOutline won't copy virtual specifiers on methods

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 247779.
njames93 added a comment.

- Addressed comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,80 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Virt specifiers.
+  {
+  R"cpp(
+struct A {
+  virtual void f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() ;
+};)cpp",
+  " void A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual virtual void virtual f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual virtual void virtual foo() ;
+};)cpp",
+  "  void  A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final override ;
+};)cpp",
+  "void B::foo()   {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2081,6 +2155,8 @@
   llvm::StringMap EditedFiles;
   ExtraFiles["Test.cpp"] = "";
   FileName = "Test.hpp";
+  ExtraArgs.push_back("-DVIRTUAL=virtual");
+  ExtraArgs.push_back("-DOVER=override");
 
   struct {
 llvm::StringRef Test;
@@ -2118,6 +2194,39 @@
   #define TARGET foo
   void TARGET();)cpp",
"void TARGET(){ return; }"},
+  {R"cpp(#define VIRT virtual
+  struct A {
+VIRT void f^oo() {}
+  };)cpp",
+   R"cpp(#define VIRT virtual
+  struct A {
+VIRT void foo() ;
+  };)cpp",
+" void A::foo() {}\n",},
+  {R"cpp(
+  struct A {
+VIRTUAL void f^oo() {}
+  };)cpp",
+   R"cpp(
+  struct A {
+VIRTUAL void foo() ;
+  };)cpp",
+" void A::foo() {}\n",},
+  {R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void fo^o() OVER {}
+  };)cpp",
+   R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void foo() OVER ;
+  };)cpp",
+"void B::foo()  {}\n",},
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2229,6 +2338,49 @@
 << Case.TestHeader;
   }
 }
+
+TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
+  FileName = "Test.hpp";
+  ExtraFiles["Test.cpp"] = "";
+  ExtraArgs.push_back("-DFINALOVER=final override");
+
+  std::pair Cases[] = {
+  {
+  R"cpp(
+  #define VIRT virtual void
+  struct A {
+VIRT fo^o() {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `virtual` specifier."},
+  {
+  R"cpp(
+  #define OVERFINAL final override
+  struct A {
+virtual void foo() {}
+  };
+  struct B : A {
+void fo^o() OVERFINAL {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `override` specifier.\ndefine outline: Can't move out of line "
+  "as function has a macro `final` specifier."},
+  {
+  R"cpp(
+  struct A {
+virtual void foo() {}
+  };
+  struct B : A {
+void fo^o() FINALOVER 

[PATCH] D75429: [clangd] DefineOutline won't copy virtual specifiers on methods

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 247766.
njames93 added a comment.

- Tweaked format


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,80 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Virt specifiers.
+  {
+  R"cpp(
+struct A {
+  virtual void f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() ;
+};)cpp",
+  " void A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual virtual void virtual f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual virtual void virtual foo() ;
+};)cpp",
+  "  void  A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final override ;
+};)cpp",
+  "void B::foo()   {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2081,6 +2155,8 @@
   llvm::StringMap EditedFiles;
   ExtraFiles["Test.cpp"] = "";
   FileName = "Test.hpp";
+  ExtraArgs.push_back("-DVIRTUAL=virtual");
+  ExtraArgs.push_back("-DOVER=override");
 
   struct {
 llvm::StringRef Test;
@@ -2118,6 +2194,39 @@
   #define TARGET foo
   void TARGET();)cpp",
"void TARGET(){ return; }"},
+  {R"cpp(#define VIRT virtual
+  struct A {
+VIRT void f^oo() {}
+  };)cpp",
+   R"cpp(#define VIRT virtual
+  struct A {
+VIRT void foo() ;
+  };)cpp",
+" void A::foo() {}\n",},
+  {R"cpp(
+  struct A {
+VIRTUAL void f^oo() {}
+  };)cpp",
+   R"cpp(
+  struct A {
+VIRTUAL void foo() ;
+  };)cpp",
+" void A::foo() {}\n",},
+  {R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void fo^o() OVER {}
+  };)cpp",
+   R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void foo() OVER ;
+  };)cpp",
+"void B::foo()  {}\n",},
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2229,6 +2338,49 @@
 << Case.TestHeader;
   }
 }
+
+TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
+  FileName = "Test.hpp";
+  ExtraFiles["Test.cpp"] = "";
+  ExtraArgs.push_back("-DFINALOVER=final override");
+
+  std::pair Cases[] = {
+  {
+  R"cpp(
+  #define VIRT virtual void
+  struct A {
+VIRT fo^o() {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `virtual` specifier."},
+  {
+  R"cpp(
+  #define OVERFINAL final override
+  struct A {
+virtual void foo() {}
+  };
+  struct B : A {
+void fo^o() OVERFINAL {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `override` specifier.\ndefine outline: Can't move out of line "
+  "as function has a macro `final` specifier."},
+  {
+  R"cpp(
+  struct A {
+virtual void foo() {}
+  };
+  struct B : A {
+void fo^o() FINALOVER {}
+  

[PATCH] D73649: [CodeComplete] Member completion for concept-constrained types.

2020-03-02 Thread Nathan James via Phabricator via cfe-commits
njames93 added inline comments.



Comment at: clang/lib/Sema/SemaCodeComplete.cpp:4860
+  return;
+if (auto *CSE = llvm::dyn_cast(E)) {
+  // If the concept is

nridge wrote:
> clang-tidy gives me an `'auto *CSE' can be declared as 'const auto *CSE'` 
> here, and several similar diagnostics below.
> 
> Not sure if that's something we want to obey, or alter our configuration to 
> silence it.
That warning will go away next time the bot updates the version of clang tidy 
it uses. It was decided to reduce the constraints on diagnosing that check 
inside llvm but that hasn't reached the pre merge bot. 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73649/new/

https://reviews.llvm.org/D73649



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75429: [clangd] DefineOutline won't copy virtual specifiers on methods

2020-03-03 Thread Nathan James via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb2666ccca027: [clangd] DefineOutline wont copy virtual 
specifiers on methods (authored by njames93).

Changed prior to commit:
  https://reviews.llvm.org/D75429?vs=247779=247828#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75429/new/

https://reviews.llvm.org/D75429

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2068,6 +2068,80 @@
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },
+  // Virt specifiers.
+  {
+  R"cpp(
+struct A {
+  virtual void f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() ;
+};)cpp",
+  " void A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual virtual void virtual f^oo() {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual virtual void virtual foo() ;
+};)cpp",
+  "  void  A::foo() {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() override ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final ;
+};)cpp",
+  "void B::foo()  {}\n",
+  },
+  {
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void fo^o() final override {}
+};)cpp",
+  R"cpp(
+struct A {
+  virtual void foo() = 0;
+};
+struct B : A {
+  void foo() final override ;
+};)cpp",
+  "void B::foo()   {}\n",
+  },
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2081,6 +2155,8 @@
   llvm::StringMap EditedFiles;
   ExtraFiles["Test.cpp"] = "";
   FileName = "Test.hpp";
+  ExtraArgs.push_back("-DVIRTUAL=virtual");
+  ExtraArgs.push_back("-DOVER=override");
 
   struct {
 llvm::StringRef Test;
@@ -2118,6 +2194,48 @@
   #define TARGET foo
   void TARGET();)cpp",
"void TARGET(){ return; }"},
+  {R"cpp(#define VIRT virtual
+  struct A {
+VIRT void f^oo() {}
+  };)cpp",
+   R"cpp(#define VIRT virtual
+  struct A {
+VIRT void foo() ;
+  };)cpp",
+   " void A::foo() {}\n"},
+  {R"cpp(
+  struct A {
+VIRTUAL void f^oo() {}
+  };)cpp",
+   R"cpp(
+  struct A {
+VIRTUAL void foo() ;
+  };)cpp",
+   " void A::foo() {}\n"},
+  {R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void fo^o() OVER {}
+  };)cpp",
+   R"cpp(
+  struct A {
+virtual void foo() = 0;
+  };
+  struct B : A {
+void foo() OVER ;
+  };)cpp",
+   "void B::foo()  {}\n"},
+  {R"cpp(#define STUPID_MACRO(X) virtual
+  struct A {
+STUPID_MACRO(sizeof sizeof int) void f^oo() {}
+  };)cpp",
+   R"cpp(#define STUPID_MACRO(X) virtual
+  struct A {
+STUPID_MACRO(sizeof sizeof int) void foo() ;
+  };)cpp",
+   " void A::foo() {}\n"},
   };
   for (const auto  : Cases) {
 SCOPED_TRACE(Case.Test);
@@ -2229,6 +2347,49 @@
 << Case.TestHeader;
   }
 }
+
+TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
+  FileName = "Test.hpp";
+  ExtraFiles["Test.cpp"] = "";
+  ExtraArgs.push_back("-DFINALOVER=final override");
+
+  std::pair Cases[] = {
+  {
+  R"cpp(
+  #define VIRT virtual void
+  struct A {
+VIRT fo^o() {}
+  };)cpp",
+  "fail: define outline: Can't move out of line as function has a "
+  "macro `virtual` specifier."},
+  {
+  R"cpp(
+  #define OVERFINAL final override
+  struct A {
+  

[PATCH] D75289: [clang-tidy] Added virtual isLanguageVersionSupported to ClangTidyCheck

2020-02-27 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

In D75289#1896902 , @Eugene.Zelenko 
wrote:

> Language and/or its standard is checked in other places too. Should all 
> similar places be refactored?


They should but I feel they should be in follow up patches, the only reason 
MakeSmartPtrCheck is in here is because by coincidence it used the same name as 
what I planned and I got a compile warning about it. 
I also don't know exactly where all occurrences are.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75289/new/

https://reviews.llvm.org/D75289



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73098: [clang-tidy] readability-identifier-naming disregards parameters restrictions on main like functions

2020-01-25 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 240400.
njames93 added a comment.

- Address nits


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73098/new/

https://reviews.llvm.org/D73098

Files:
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/docs/clang-tidy/checks/readability-identifier-naming.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp
@@ -0,0 +1,88 @@
+// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: readability-identifier-naming.ParameterCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.IgnoreMainLikeFunctions, value: 1} \
+// RUN:  ]}'
+
+int mainLike(int argc, char **argv);
+int mainLike(int argc, char **argv, const char **env);
+int mainLike(int argc, const char **argv);
+int mainLike(int argc, const char **argv, const char **env);
+int mainLike(int argc, char *argv[]);
+int mainLike(int argc, const char *argv[]);
+int mainLike(int argc, char *argv[], char *env[]);
+int mainLike(int argc, const char *argv[], const char *env[]);
+void notMain(int argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+void notMain(int argc, char **argv, char **env);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: warning: invalid case style for parameter 'env'
+int notMain(int argc, char **argv, char **env, int Extra);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: warning: invalid case style for parameter 'env'
+int notMain(int argc, char **argv, int Extra);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char *argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:29: warning: invalid case style for parameter 'argv'
+int notMain(unsigned argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:35: warning: invalid case style for parameter 'argv'
+int notMain(long argc, char *argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char16_t **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char argv[]);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: invalid case style for parameter 'argv'
+typedef char myFunChar;
+typedef int myFunInt;
+typedef char **myFunCharPtr;
+typedef long myFunLong;
+myFunInt mainLikeTypedef(myFunInt argc, myFunChar **argv);
+int mainLikeTypedef(int argc, myFunCharPtr argv);
+int notMainTypedef(myFunLong argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:43: warning: invalid case style for parameter 'argv'
+
+// Don't flag as name contains the word main
+int myMainFunction(int argc, char *argv[]);
+
+// This is fine, named with wmain and has wchar ptr.
+int wmainLike(int argc, wchar_t *argv[]);
+
+// Flag this as has signature of main, but named as wmain.
+int wmainLike(int argc, char *argv[]);
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+
+struct Foo {
+  Foo(int argc, char *argv[]) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: invalid case style for parameter 'argc'
+  // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: invalid case style for parameter 'argv'
+
+  int mainPub(int argc, char *argv[]);
+  static int mainPubStatic(int argc, char *argv[]);
+
+protected:
+  int mainProt(int argc, char *argv[]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: invalid case style for parameter 'argc'
+  // 

[PATCH] D72553: [clang-tidy] Add performance-prefer-preincrement check

2020-01-25 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 240402.
njames93 marked 5 inline comments as done.
njames93 added a comment.

- Address some nits, more test cases need adding though


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72553/new/

https://reviews.llvm.org/D72553

Files:
  clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp
  clang-tools-extra/clang-tidy/performance/CMakeLists.txt
  clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp
  clang-tools-extra/clang-tidy/performance/PreferPreIncrementCheck.cpp
  clang-tools-extra/clang-tidy/performance/PreferPreIncrementCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/llvm-prefer-pre-increment.rst
  clang-tools-extra/docs/clang-tidy/checks/performance-prefer-pre-increment.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-prefer-pre-increment/iterator.h
  
clang-tools-extra/test/clang-tidy/checkers/performance-prefer-pre-increment-disable-cpp-opcalls.cpp
  clang-tools-extra/test/clang-tidy/checkers/performance-prefer-pre-increment.c
  
clang-tools-extra/test/clang-tidy/checkers/performance-prefer-pre-increment.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/performance-prefer-pre-increment.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/performance-prefer-pre-increment.cpp
@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy %s performance-prefer-pre-increment %t -- -- \
+// RUN: -I%S/Inputs/performance-prefer-pre-increment
+
+#include "iterator.h"
+
+void foo() {
+  int Array[32];
+  Iterator It([0]);
+  It++;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use pre-increment instead of post-increment
+  // CHECK-FIXES: {{^}}  ++It;
+  It--;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use pre-decrement instead of post-decrement
+  // CHECK-FIXES: {{^}}  --It;
+  (*It)++;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use pre-increment instead of post-increment
+  // CHECK-FIXES: {{^}}  ++(*It);
+  (*It)--;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use pre-decrement instead of post-decrement
+  // CHECK-FIXES: {{^}}  --(*It);
+
+  *It++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use pre-increment instead of post-increment
+  *It--;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use pre-decrement instead of post-decrement
+
+  PostfixIterator PfIt([0]);
+  PfIt++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use pre-increment instead of post-increment
+  // CHECK-FIXES-NOT: {{^}}  ++PfIt;
+  PfIt--;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use pre-decrement instead of post-decrement
+  // CHECK-FIXES-NOT: {{^}}  --PfIt;
+  (*PfIt)++;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use pre-increment instead of post-increment
+  // CHECK-FIXES: {{^}}  ++(*PfIt);
+  (*PfIt)--;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Use pre-decrement instead of post-decrement
+  // CHECK-FIXES: {{^}}  --(*PfIt);
+
+  *PfIt++;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use pre-increment instead of post-increment
+  *PfIt--;
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use pre-decrement instead of post-decrement
+}
Index: clang-tools-extra/test/clang-tidy/checkers/performance-prefer-pre-increment.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/performance-prefer-pre-increment.c
@@ -0,0 +1,128 @@
+// RUN: %check_clang_tidy %s performance-prefer-pre-increment %t
+
+#define INC(X) X++
+#define DEC(X) X--
+
+void foo(int A) {
+  for (int I = 0; I < 10; I++) {
+// CHECK-MESSAGES: [[@LINE-1]]:27: warning: Use pre-increment instead of post-increment
+// CHECK-FIXES: {{^}}  for (int I = 0; I < 10; ++I) {
+  }
+  for (int I = 0; I < 10; ++I) {
+// CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use pre-increment instead of post-increment
+  }
+  for (int I = 0; I < 10; A = I++) {
+// CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use pre-increment instead of post-increment
+  }
+
+  for (int I = 10; I < 0; I--) {
+// CHECK-MESSAGES: [[@LINE-1]]:27: warning: Use pre-decrement instead of post-decrement
+// CHECK-FIXES: {{^}}  for (int I = 10; I < 0; --I) {
+  }
+  for (int I = 10; I < 0; --I) {
+// CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use pre-decrement instead of post-decrement
+  }
+  for (int I = 10; I < 0; A = I--) {
+// CHECK-MESSAGES-NOT: [[@LINE-1]]:{{\d*}}: warning: Use pre-decrement instead of post-decrement
+  }
+
+  for (int I = 0; I < 10; INC(I)) {
+// CHECK-MESSAGES: [[@LINE-1]]:31: warning: Use pre-increment instead of post-increment
+  }
+  for (int I = 0; I < 10; DEC(I)) {
+// CHECK-MESSAGES: [[@LINE-1]]:31: warning: Use pre-decrement instead of post-decrement
+  }
+  for (int I = 0; I < 10; A = INC(I)) {
+   

[PATCH] D72553: [clang-tidy] Add performance-prefer-preincrement check

2020-01-25 Thread Nathan James via Phabricator via cfe-commits
njames93 added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/performance/PreferPreIncrementCheck.cpp:63
+
+  if (!getLangOpts().CPlusPlus || !TransformCxxOpCalls)
+return;

JonasToth wrote:
> Why would you deactivate the check for c-code?
> I think the `for(int i = 0; i < 10; ++i)` could be a requirement in c-coding 
> styles, too. 
I only deactivate operator calls for c-code as they aren't a thing in c. The 
unary operation expr still runs in c-code



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/performance-prefer-pre-increment-disable-cpp-opcalls.cpp:44
+};
+
+void foo() {

JonasToth wrote:
> Test-cases that I would like to see:
> 
> - only the post-fix operator is overloaded for the class --> best-case this 
> is detected and a fix is not provided
> - iterator-inheritance: the base-class provides the operator-overloads --> 
> does matching work? There might be an implicit cast for example
> - the iterator-type is type-dependent --> maybe fixing should not be done or 
> even the warning should not be emitted, because there might be only a 
> post-fix available in some instantiations (see point 1). I do mean something 
> like this `template  void f() { T::iterator it; it++; }`
There are test cases for only post fix operator overloading. basically it 
doesn't warn or provided a fix it as that isn't valid. I feel like there could 
be a seperate check that detects classes that overload operator++(int) but not 
operator++() but thats not what this check is for.
I'll take a look at the other cases tomorrow


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72553/new/

https://reviews.llvm.org/D72553



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73203: [clang-tidy] Prevent a remove only fixit causing a conflict when enclosed by another fixit

2020-01-24 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 240163.
njames93 added a comment.

- Small edge case tweak


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73203/new/

https://reviews.llvm.org/D73203

Files:
  clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp

Index: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
===
--- clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -24,6 +24,8 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
 #include "clang/Tooling/Core/Diagnostic.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include 
@@ -589,8 +591,8 @@
 };
 
 Event(unsigned Begin, unsigned End, EventType Type, unsigned ErrorId,
-  unsigned ErrorSize)
-: Type(Type), ErrorId(ErrorId) {
+  unsigned ErrorSize, const tooling::Replacement )
+: Type(Type), ErrorId(ErrorId), Replacement() {
   // The events are going to be sorted by their position. In case of draw:
   //
   // * If an interval ends at the same position at which other interval
@@ -631,6 +633,8 @@
 // The index of the error to which the interval that generated this event
 // belongs.
 unsigned ErrorId;
+// The replacement this event relates to.
+const tooling::Replacement *Replacement;
 // The events will be sorted based on this field.
 std::tuple Priority;
   };
@@ -666,15 +670,18 @@
 if (Begin == End)
   continue;
 auto  = FileEvents[FilePath];
-Events.emplace_back(Begin, End, Event::ET_Begin, I, Sizes[I]);
-Events.emplace_back(Begin, End, Event::ET_End, I, Sizes[I]);
+Events.emplace_back(Begin, End, Event::ET_Begin, I, Sizes[I], Replace);
+Events.emplace_back(Begin, End, Event::ET_End, I, Sizes[I], Replace);
   }
 }
   }
 
   std::vector Apply(ErrorFixes.size(), true);
   for (auto  : FileEvents) {
+llvm::SmallSet RemoveOnlyEvents;
 std::vector  = FileAndEvents.second;
+using ReplacementPtrSet = llvm::SmallDenseSet;
+llvm::SmallDenseMap DiscardableReplacements;
 // Sweep.
 std::sort(Events.begin(), Events.end());
 int OpenIntervals = 0;
@@ -683,12 +690,66 @@
 --OpenIntervals;
   // This has to be checked after removing the interval from the count if it
   // is an end event, or before adding it if it is a begin event.
-  if (OpenIntervals != 0)
-Apply[Event.ErrorId] = false;
+  if (OpenIntervals != 0) {
+if (Event.Replacement->getReplacementText().empty()) {
+  if (Event.Type == Event::ET_Begin) {
+// Starting a removal only fix-it is OK inside another fix-it.
+// But need to discard this specific fix-it from its parent so it
+// wont get executed later and cause a conflict.
+RemoveOnlyEvents.insert();
+  } else if (Event.Type == Event::ET_End) {
+// End of a Remove only fix-it, Remove it from the set.
+bool Found = false;
+for (const auto *RemoveOnlyEvent : RemoveOnlyEvents) {
+  if (RemoveOnlyEvent->Replacement == Event.Replacement) {
+assert(!Found && "Event should only appear in set once");
+RemoveOnlyEvents.erase(RemoveOnlyEvent);
+Found = true;
+  }
+}
+DiscardableReplacements[Event.ErrorId].insert(Event.Replacement);
+assert(Found && "Event didn't appear in set");
+  }
+} else {
+  // This isnt a text removal only change, so must be a conflict.
+  Apply[Event.ErrorId] = false;
+}
+  } else {
+decltype(RemoveOnlyEvents)::size_type Size = RemoveOnlyEvents.size();
+assert(Size < 2 && "Once OpenIntervals is `0` this set should contain "
+   "no more than 1 event");
+if (Size) {
+  // The remove only fix-it is overlapping another even that we have
+  // already disabled. So no need to discard this fix-it
+  RemoveOnlyEvents.clear();
+}
+  }
   if (Event.Type == Event::ET_Begin)
 ++OpenIntervals;
 }
 assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
+for (const auto  : DiscardableReplacements) {
+  unsigned ErrorIndex = ErrorAndDiscarded.first;
+  const ReplacementPtrSet  = ErrorAndDiscarded.second;
+  if (!Apply[ErrorIndex])
+continue; // The whole error has already been discarded.
+  tooling::Replacements NewReplacements;
+  const tooling::Replacements  =
+  ErrorFixes[ErrorIndex].second->lookup(FileAndEvents.first);
+  for (const tooling::Replacement  : CurReplacements) {
+  

[PATCH] D73439: [ASTMatchers] Add cxxNoexceptExpr AST matcher

2020-01-26 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added a reviewer: aaron.ballman.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Adds a cxxNoexceptExpr matcher that matches the noexcept operator 
.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73439

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/lib/Analysis/ExprMutationAnalyzer.cpp
  clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -679,6 +679,14 @@
   cxxDeleteExpr()));
 }
 
+TEST(Matcher, NoexceptExpression) {
+  StatementMatcher NoExcept = cxxNoexceptExpr();
+  EXPECT_TRUE(matches("void foo(); bool bar = noexcept(foo());", NoExcept));
+  EXPECT_TRUE(
+  matches("void foo() noexcept; bool bar = noexcept(foo());", NoExcept));
+  EXPECT_TRUE(notMatches("void foo() noexcept;", NoExcept));
+}
+
 TEST(Matcher, DefaultArgument) {
   StatementMatcher Arg = cxxDefaultArgExpr();
 
Index: clang/lib/Analysis/ExprMutationAnalyzer.cpp
===
--- clang/lib/Analysis/ExprMutationAnalyzer.cpp
+++ clang/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -43,9 +43,6 @@
   return Node.isPotentiallyEvaluated();
 }
 
-const ast_matchers::internal::VariadicDynCastAllOfMatcher
-cxxNoexceptExpr;
-
 const ast_matchers::internal::VariadicDynCastAllOfMatcher
 genericSelectionExpr;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -183,6 +183,7 @@
   REGISTER_MATCHER(cxxMemberCallExpr);
   REGISTER_MATCHER(cxxMethodDecl);
   REGISTER_MATCHER(cxxNewExpr);
+  REGISTER_MATCHER(cxxNoexceptExpr);
   REGISTER_MATCHER(cxxNullPtrLiteralExpr);
   REGISTER_MATCHER(cxxOperatorCallExpr);
   REGISTER_MATCHER(cxxRecordDecl);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -730,6 +730,8 @@
 materializeTemporaryExpr;
 const internal::VariadicDynCastAllOfMatcher cxxNewExpr;
 const internal::VariadicDynCastAllOfMatcher cxxDeleteExpr;
+const internal::VariadicDynCastAllOfMatcher
+cxxNoexceptExpr;
 const internal::VariadicDynCastAllOfMatcher
 arraySubscriptExpr;
 const internal::VariadicDynCastAllOfMatcher
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -1824,6 +1824,20 @@
 extern const internal::VariadicDynCastAllOfMatcher
 cxxDeleteExpr;
 
+/// Matches noexcept expressions.
+///
+/// Given
+/// \code
+///   void nothrow() noexcpet;
+///   void throws();
+///   bool a = noexcept(nothrow())
+///   bool b = noexcept(throws())
+/// \endcode
+/// cxxNoexceptExpr()
+///   matches `noexcept(nothrow())` and noexcept(throws())
+extern const internal::VariadicDynCastAllOfMatcher
+cxxNoexceptExpr;
+
 /// Matches array subscript expressions.
 ///
 /// Given
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -1003,6 +1003,19 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxNoexceptExprMatcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXNoexceptExpr.html;>CXXNoexceptExpr...
+Matches noexcept expressions.
+
+Given
+  void nothrow() noexcpet;
+  void throws();
+  bool a = noexcept(nothrow())
+  bool b = noexcept(throws())
+cxxNoexceptExpr()
+  matches `noexcept(nothrow())` and noexcept(throws())
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxNullPtrLiteralExprMatcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXNullPtrLiteralExpr.html;>CXXNullPtrLiteralExpr...
 Matches nullptr literal.
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73441: [clang-tidy] Fix bugprone-use-after-move when move is in noexcept operator

2020-01-26 Thread Nathan James via Phabricator via cfe-commits
njames93 created this revision.
njames93 added reviewers: aaron.ballman, alexfh, JonasToth, hokein, gribozavr2.
Herald added subscribers: cfe-commits, xazax.hun.
Herald added a project: clang.

Fixes noexcept operator misinterpreted as being evaluated 
.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73441

Files:
  clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
@@ -1271,3 +1271,14 @@
   }
 };
 }
+
+namespace PR44667 {
+#define REQUIRE(expr) (void)(expr);
+struct S {};
+
+void foo() {
+  S s;
+  REQUIRE(noexcept(S{std::move(s)}));
+  S other{std::move(s)};
+}
+} // namespace PR44667
Index: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "UseAfterMoveCheck.h"
 
+#include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Lex/Lexer.h"
 
@@ -382,7 +383,8 @@
hasArgument(0, declRefExpr().bind("arg")),
anyOf(hasAncestor(lambdaExpr().bind("containing-lambda")),
  hasAncestor(functionDecl().bind("containing-func"))),
-   unless(inDecltypeOrTemplateArg()))
+   unless(inDecltypeOrTemplateArg()),
+   unless(hasAncestor(cxxNoexceptExpr(
   .bind("call-move");
 
   Finder->addMatcher(


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
@@ -1271,3 +1271,14 @@
   }
 };
 }
+
+namespace PR44667 {
+#define REQUIRE(expr) (void)(expr);
+struct S {};
+
+void foo() {
+  S s;
+  REQUIRE(noexcept(S{std::move(s)}));
+  S other{std::move(s)};
+}
+} // namespace PR44667
Index: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "UseAfterMoveCheck.h"
 
+#include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Lex/Lexer.h"
 
@@ -382,7 +383,8 @@
hasArgument(0, declRefExpr().bind("arg")),
anyOf(hasAncestor(lambdaExpr().bind("containing-lambda")),
  hasAncestor(functionDecl().bind("containing-func"))),
-   unless(inDecltypeOrTemplateArg()))
+   unless(inDecltypeOrTemplateArg()),
+   unless(hasAncestor(cxxNoexceptExpr(
   .bind("call-move");
 
   Finder->addMatcher(
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72448: [clang-tidy] readability-redundant-string-init now flags redundant initialisation in Field Decls and Constructor Initialisers

2020-01-26 Thread Nathan James via Phabricator via cfe-commits
njames93 marked 2 inline comments as done.
njames93 added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp:58
+  }
+  if (B.isInvalid() || E.isInvalid())
+return llvm::None;

aaron.ballman wrote:
> Should we be worried about macros here?
> 
> It looks a bit like we're ignoring macros entirely for this check, so maybe 
> that can be done as a separate patch instead. The situation I am worried 
> about is:
> ```
> #if SOMETHING
> #define INIT ""
> #else
> #define INIT "haha"
> #endif
> 
> std::string S = INIT;
> ```
I feel that everything in this check needs to check macros, but that's probably 
a follow up patch



Comment at: 
clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp:110
   namedDecl(
-  varDecl(
-  hasType(hasUnqualifiedDesugaredType(recordType(
-  hasDeclaration(cxxRecordDecl(hasStringTypeName),
-  hasInitializer(expr(ignoringImplicit(anyOf(
-  EmptyStringCtorExpr, EmptyStringCtorExprWithTemporaries)
-  .bind("vardecl"),
+  varDecl(StringType, hasInitializer(EmptyStringInit)).bind("vardecl"),
   unless(parmVarDecl())),

aaron.ballman wrote:
> Should this also match on something like `std::string foo{};` as a redundant 
> init? Similar question for the other cases. (Could be done in a follow-up 
> patch if desired.)
Probably should, however this is not what this patch is about


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72448/new/

https://reviews.llvm.org/D72448



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73439: [ASTMatchers] Add cxxNoexceptExpr AST matcher

2020-01-26 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 240461.
njames93 added a comment.

- Fix typo in documentation


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73439/new/

https://reviews.llvm.org/D73439

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/lib/Analysis/ExprMutationAnalyzer.cpp
  clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -679,6 +679,14 @@
   cxxDeleteExpr()));
 }
 
+TEST(Matcher, NoexceptExpression) {
+  StatementMatcher NoExcept = cxxNoexceptExpr();
+  EXPECT_TRUE(matches("void foo(); bool bar = noexcept(foo());", NoExcept));
+  EXPECT_TRUE(
+  matches("void foo() noexcept; bool bar = noexcept(foo());", NoExcept));
+  EXPECT_TRUE(notMatches("void foo() noexcept;", NoExcept));
+}
+
 TEST(Matcher, DefaultArgument) {
   StatementMatcher Arg = cxxDefaultArgExpr();
 
Index: clang/lib/Analysis/ExprMutationAnalyzer.cpp
===
--- clang/lib/Analysis/ExprMutationAnalyzer.cpp
+++ clang/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -43,9 +43,6 @@
   return Node.isPotentiallyEvaluated();
 }
 
-const ast_matchers::internal::VariadicDynCastAllOfMatcher
-cxxNoexceptExpr;
-
 const ast_matchers::internal::VariadicDynCastAllOfMatcher
 genericSelectionExpr;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -183,6 +183,7 @@
   REGISTER_MATCHER(cxxMemberCallExpr);
   REGISTER_MATCHER(cxxMethodDecl);
   REGISTER_MATCHER(cxxNewExpr);
+  REGISTER_MATCHER(cxxNoexceptExpr);
   REGISTER_MATCHER(cxxNullPtrLiteralExpr);
   REGISTER_MATCHER(cxxOperatorCallExpr);
   REGISTER_MATCHER(cxxRecordDecl);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -730,6 +730,8 @@
 materializeTemporaryExpr;
 const internal::VariadicDynCastAllOfMatcher cxxNewExpr;
 const internal::VariadicDynCastAllOfMatcher cxxDeleteExpr;
+const internal::VariadicDynCastAllOfMatcher
+cxxNoexceptExpr;
 const internal::VariadicDynCastAllOfMatcher
 arraySubscriptExpr;
 const internal::VariadicDynCastAllOfMatcher
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -1824,6 +1824,20 @@
 extern const internal::VariadicDynCastAllOfMatcher
 cxxDeleteExpr;
 
+/// Matches noexcept expressions.
+///
+/// Given
+/// \code
+///   void nothrow() noexcpet;
+///   void throws();
+///   bool a = noexcept(nothrow())
+///   bool b = noexcept(throws())
+/// \endcode
+/// cxxNoexceptExpr()
+///   matches `noexcept(nothrow())` and `noexcept(throws())`.
+extern const internal::VariadicDynCastAllOfMatcher
+cxxNoexceptExpr;
+
 /// Matches array subscript expressions.
 ///
 /// Given
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -1003,6 +1003,19 @@
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxNoexceptExprMatcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXNoexceptExpr.html;>CXXNoexceptExpr...
+Matches noexcept expressions.
+
+Given
+  void nothrow() noexcpet;
+  void throws();
+  bool a = noexcept(nothrow())
+  bool b = noexcept(throws())
+cxxNoexceptExpr()
+  matches `noexcept(nothrow())` and `noexcept(throws())`.
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxNullPtrLiteralExprMatcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXNullPtrLiteralExpr.html;>CXXNullPtrLiteralExpr...
 Matches nullptr literal.
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73098: [clang-tidy] readability-identifier-naming disregards parameters restrictions on main like functions

2020-01-23 Thread Nathan James via Phabricator via cfe-commits
njames93 added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp:383
+  } else {
+static llvm::Regex Matcher("(^((W[Mm])|(wm))ain([_A-Z]|$))|([a-z0-9_]W[Mm]"
+   "ain([_A-Z]|$))|(_wmain(_|$))",

Any thoughts on whether I should detect WMain or just Wmain. WMain looks more 
pleasing but using CamelCase rules it should likely be Wmain


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73098/new/

https://reviews.llvm.org/D73098



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73098: [clang-tidy] readability-identifier-naming disregards parameters restrictions on main like functions

2020-01-23 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 239825.
njames93 added a comment.

- use regex for func name matching


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73098/new/

https://reviews.llvm.org/D73098

Files:
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/docs/clang-tidy/checks/readability-identifier-naming.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: readability-identifier-naming.ParameterCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.IgnoreMainLikeFunctions, value: 1} \
+// RUN:  ]}'
+
+int mainLike(int argc, char **argv);
+int mainLike(int argc, char **argv, const char **env);
+int mainLike(int argc, const char **argv);
+int mainLike(int argc, const char **argv, const char **env);
+int mainLike(int argc, char *argv[]);
+int mainLike(int argc, const char *argv[]);
+int mainLike(int argc, char *argv[], char *env[]);
+int mainLike(int argc, const char *argv[], const char *env[]);
+void notMain(int argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+void notMain(int argc, char **argv, char **env);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: warning: invalid case style for parameter 'env'
+int notMain(int argc, char **argv, char **env, int Extra);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: warning: invalid case style for parameter 'env'
+int notMain(int argc, char **argv, int Extra);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char *argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:29: warning: invalid case style for parameter 'argv'
+int notMain(unsigned argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:35: warning: invalid case style for parameter 'argv'
+int notMain(long argc, char *argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char16_t **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char argv[]);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: invalid case style for parameter 'argv'
+typedef char myFunChar;
+typedef int myFunInt;
+typedef char **myFunCharPtr;
+typedef long myFunLong;
+myFunInt mainLikeTypedef(myFunInt argc, myFunChar **argv);
+int mainLikeTypedef(int argc, myFunCharPtr argv);
+int notMainTypedef(myFunLong argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:43: warning: invalid case style for parameter 'argv'
+
+// Don't flag as name contains the word main
+int myMainFunction(int argc, char *argv[]);
+
+// This is fine, named with wmain and has wchar ptr.
+int wmainLike(int argc, wchar_t *argv[]);
+
+// Flag this as has signature of main, but named as wmain.
+int wmainLike(int argc, char *argv[]);
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
Index: clang-tools-extra/docs/clang-tidy/checks/readability-identifier-naming.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/readability-identifier-naming.rst
+++ clang-tools-extra/docs/clang-tidy/checks/readability-identifier-naming.rst
@@ -55,6 +55,7 @@
  - :option:`GlobalFunctionCase`, :option:`GlobalFunctionPrefix`, :option:`GlobalFunctionSuffix`
  - 

[PATCH] D73098: [clang-tidy] readability-identifier-naming disregards parameters restrictions on main like functions

2020-01-23 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 239830.
njames93 added a comment.

- Dont trim func name before regex


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73098/new/

https://reviews.llvm.org/D73098

Files:
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/docs/clang-tidy/checks/readability-identifier-naming.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: readability-identifier-naming.ParameterCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.IgnoreMainLikeFunctions, value: 1} \
+// RUN:  ]}'
+
+int mainLike(int argc, char **argv);
+int mainLike(int argc, char **argv, const char **env);
+int mainLike(int argc, const char **argv);
+int mainLike(int argc, const char **argv, const char **env);
+int mainLike(int argc, char *argv[]);
+int mainLike(int argc, const char *argv[]);
+int mainLike(int argc, char *argv[], char *env[]);
+int mainLike(int argc, const char *argv[], const char *env[]);
+void notMain(int argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+void notMain(int argc, char **argv, char **env);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: warning: invalid case style for parameter 'env'
+int notMain(int argc, char **argv, char **env, int Extra);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: warning: invalid case style for parameter 'env'
+int notMain(int argc, char **argv, int Extra);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char *argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:29: warning: invalid case style for parameter 'argv'
+int notMain(unsigned argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:35: warning: invalid case style for parameter 'argv'
+int notMain(long argc, char *argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char16_t **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char argv[]);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: invalid case style for parameter 'argv'
+typedef char myFunChar;
+typedef int myFunInt;
+typedef char **myFunCharPtr;
+typedef long myFunLong;
+myFunInt mainLikeTypedef(myFunInt argc, myFunChar **argv);
+int mainLikeTypedef(int argc, myFunCharPtr argv);
+int notMainTypedef(myFunLong argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:43: warning: invalid case style for parameter 'argv'
+
+// Don't flag as name contains the word main
+int myMainFunction(int argc, char *argv[]);
+
+// This is fine, named with wmain and has wchar ptr.
+int wmainLike(int argc, wchar_t *argv[]);
+
+// Flag this as has signature of main, but named as wmain.
+int wmainLike(int argc, char *argv[]);
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
Index: clang-tools-extra/docs/clang-tidy/checks/readability-identifier-naming.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/readability-identifier-naming.rst
+++ clang-tools-extra/docs/clang-tidy/checks/readability-identifier-naming.rst
@@ -55,6 +55,7 @@
  - :option:`GlobalFunctionCase`, :option:`GlobalFunctionPrefix`, :option:`GlobalFunctionSuffix`
  - 

[PATCH] D73441: [clang-tidy] Fix bugprone-use-after-move when move is in noexcept operator

2020-01-27 Thread Nathan James via Phabricator via cfe-commits
njames93 marked 3 inline comments as done.
njames93 added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp:1276
+namespace PR44667 {
+#define REQUIRE(expr) (void)(expr);
+struct S {};

gribozavr2 wrote:
> njames93 wrote:
> > gribozavr2 wrote:
> > > Is the macro a necessary part of this test? If not, can it be removed?
> > I like to stick to the bug report as much as possible
> This is not generally the policy in LLVM and Clang. We prefer minimal 
> reproducers.
I've kept it minimal, the REQUIRE definition is just to suppress other warnings 
about unused expressions


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73441/new/

https://reviews.llvm.org/D73441



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73441: [clang-tidy] Fix bugprone-use-after-move when move is in noexcept operator

2020-01-27 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 240506.
njames93 added a comment.

- added more unevaluated context checks


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73441/new/

https://reviews.llvm.org/D73441

Files:
  clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
@@ -1271,3 +1271,28 @@
   }
 };
 }
+
+namespace PR44667 {
+#define REQUIRE(expr) (void)(expr);
+struct S {};
+
+void foo() {
+  S s;
+  REQUIRE(noexcept(S{std::move(s)}));
+  S other{std::move(s)};
+}
+void otherUnevaluated(){
+  S s;
+  REQUIRE(sizeof(S{std::move(s)}) > 8);
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wgnu-alignof-expression"
+  REQUIRE(alignof(S{std::move(s)}) > 8);
+#pragma clang diagnostic pop
+
+  // error: you need to include  before using the 'typeid' operator
+  // REQUIRE(typeid(S{std::move(s)}).name());
+
+  S other{std::move(s)};
+}
+} // namespace PR44667
Index: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -8,6 +8,10 @@
 
 #include "UseAfterMoveCheck.h"
 
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Lex/Lexer.h"
 
@@ -23,6 +27,22 @@
 
 namespace {
 
+AST_MATCHER(Expr, hasUnevaluatedContext){
+  if (isa(Node) || isa(Node)) return true;
+  if (const auto *UnaryExpr = dyn_cast()){
+switch (UnaryExpr->getKind()){
+  case UETT_SizeOf:
+  case UETT_AlignOf: return true;
+  default:
+  return false;
+}
+  }
+  if (const auto *TypeIDExpr = dyn_cast()){
+return !TypeIDExpr->isPotentiallyEvaluated();
+  }
+  return false;
+}
+
 /// Contains information about a use-after-move.
 struct UseAfterMove {
   // The DeclRefExpr that constituted the use of the object.
@@ -77,7 +97,8 @@
 static StatementMatcher inDecltypeOrTemplateArg() {
   return anyOf(hasAncestor(typeLoc()),
hasAncestor(declRefExpr(
-   
to(functionDecl(ast_matchers::isTemplateInstantiation());
+   to(functionDecl(ast_matchers::isTemplateInstantiation(),
+   hasAncestor(expr(hasUnevaluatedContext(;
 }
 
 UseAfterMoveFinder::UseAfterMoveFinder(ASTContext *TheContext)


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
@@ -1271,3 +1271,28 @@
   }
 };
 }
+
+namespace PR44667 {
+#define REQUIRE(expr) (void)(expr);
+struct S {};
+
+void foo() {
+  S s;
+  REQUIRE(noexcept(S{std::move(s)}));
+  S other{std::move(s)};
+}
+void otherUnevaluated(){
+  S s;
+  REQUIRE(sizeof(S{std::move(s)}) > 8);
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wgnu-alignof-expression"
+  REQUIRE(alignof(S{std::move(s)}) > 8);
+#pragma clang diagnostic pop
+
+  // error: you need to include  before using the 'typeid' operator
+  // REQUIRE(typeid(S{std::move(s)}).name());
+
+  S other{std::move(s)};
+}
+} // namespace PR44667
Index: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -8,6 +8,10 @@
 
 #include "UseAfterMoveCheck.h"
 
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Lex/Lexer.h"
 
@@ -23,6 +27,22 @@
 
 namespace {
 
+AST_MATCHER(Expr, hasUnevaluatedContext){
+  if (isa(Node) || isa(Node)) return true;
+  if (const auto *UnaryExpr = dyn_cast()){
+switch (UnaryExpr->getKind()){
+  case UETT_SizeOf:
+  case UETT_AlignOf: return true;
+  default:
+  return false;
+}
+  }
+  if (const auto *TypeIDExpr = dyn_cast()){
+return !TypeIDExpr->isPotentiallyEvaluated();
+  }
+  return false;
+}
+
 /// Contains information about a use-after-move.
 struct UseAfterMove {
   // The DeclRefExpr that constituted the use of the object.
@@ -77,7 +97,8 @@
 static StatementMatcher inDecltypeOrTemplateArg() {
   return anyOf(hasAncestor(typeLoc()),

[PATCH] D73441: [clang-tidy] Fix bugprone-use-after-move when move is in noexcept operator

2020-01-27 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 240507.
njames93 added a comment.

- Elide braces


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73441/new/

https://reviews.llvm.org/D73441

Files:
  clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
@@ -1271,3 +1271,28 @@
   }
 };
 }
+
+namespace PR44667 {
+#define REQUIRE(expr) (void)(expr);
+struct S {};
+
+void foo() {
+  S s;
+  REQUIRE(noexcept(S{std::move(s)}));
+  S other{std::move(s)};
+}
+void otherUnevaluated(){
+  S s;
+  REQUIRE(sizeof(S{std::move(s)}) > 8);
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wgnu-alignof-expression"
+  REQUIRE(alignof(S{std::move(s)}) > 8);
+#pragma clang diagnostic pop
+
+  // error: you need to include  before using the 'typeid' operator
+  // REQUIRE(typeid(S{std::move(s)}).name());
+
+  S other{std::move(s)};
+}
+} // namespace PR44667
Index: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -8,6 +8,10 @@
 
 #include "UseAfterMoveCheck.h"
 
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Lex/Lexer.h"
 
@@ -23,6 +27,21 @@
 
 namespace {
 
+AST_MATCHER(Expr, hasUnevaluatedContext){
+  if (isa(Node) || isa(Node)) return true;
+  if (const auto *UnaryExpr = dyn_cast()){
+switch (UnaryExpr->getKind()){
+  case UETT_SizeOf:
+  case UETT_AlignOf: return true;
+  default:
+  return false;
+}
+  }
+  if (const auto *TypeIDExpr = dyn_cast())
+return !TypeIDExpr->isPotentiallyEvaluated();
+  return false;
+}
+
 /// Contains information about a use-after-move.
 struct UseAfterMove {
   // The DeclRefExpr that constituted the use of the object.
@@ -77,7 +96,8 @@
 static StatementMatcher inDecltypeOrTemplateArg() {
   return anyOf(hasAncestor(typeLoc()),
hasAncestor(declRefExpr(
-   
to(functionDecl(ast_matchers::isTemplateInstantiation());
+   to(functionDecl(ast_matchers::isTemplateInstantiation(),
+   hasAncestor(expr(hasUnevaluatedContext(;
 }
 
 UseAfterMoveFinder::UseAfterMoveFinder(ASTContext *TheContext)


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
@@ -1271,3 +1271,28 @@
   }
 };
 }
+
+namespace PR44667 {
+#define REQUIRE(expr) (void)(expr);
+struct S {};
+
+void foo() {
+  S s;
+  REQUIRE(noexcept(S{std::move(s)}));
+  S other{std::move(s)};
+}
+void otherUnevaluated(){
+  S s;
+  REQUIRE(sizeof(S{std::move(s)}) > 8);
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wgnu-alignof-expression"
+  REQUIRE(alignof(S{std::move(s)}) > 8);
+#pragma clang diagnostic pop
+
+  // error: you need to include  before using the 'typeid' operator
+  // REQUIRE(typeid(S{std::move(s)}).name());
+
+  S other{std::move(s)};
+}
+} // namespace PR44667
Index: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -8,6 +8,10 @@
 
 #include "UseAfterMoveCheck.h"
 
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Lex/Lexer.h"
 
@@ -23,6 +27,21 @@
 
 namespace {
 
+AST_MATCHER(Expr, hasUnevaluatedContext){
+  if (isa(Node) || isa(Node)) return true;
+  if (const auto *UnaryExpr = dyn_cast()){
+switch (UnaryExpr->getKind()){
+  case UETT_SizeOf:
+  case UETT_AlignOf: return true;
+  default:
+  return false;
+}
+  }
+  if (const auto *TypeIDExpr = dyn_cast())
+return !TypeIDExpr->isPotentiallyEvaluated();
+  return false;
+}
+
 /// Contains information about a use-after-move.
 struct UseAfterMove {
   // The DeclRefExpr that constituted the use of the object.
@@ -77,7 +96,8 @@
 static StatementMatcher inDecltypeOrTemplateArg() {
   return anyOf(hasAncestor(typeLoc()),
hasAncestor(declRefExpr(
-   

[PATCH] D73441: [clang-tidy] Fix bugprone-use-after-move when move is in noexcept operator

2020-01-27 Thread Nathan James via Phabricator via cfe-commits
njames93 marked 2 inline comments as done.
njames93 added inline comments.



Comment at: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp:387
+   unless(inDecltypeOrTemplateArg()),
+   unless(hasAncestor(cxxNoexceptExpr(
   .bind("call-move");

gribozavr2 wrote:
> Quuxplusone wrote:
> > What about `sizeof`, `alignof`, `requires`, `typeid`, and other such 
> > unevaluated contexts? Shouldn't there be a common way to spell "this 
> > expression is unevaluated"? (I don't know if there is or not.)
> +1 to adding handling and tests for other unevaluated contexts.
I think i can write a matcher that will detect that



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp:1276
+namespace PR44667 {
+#define REQUIRE(expr) (void)(expr);
+struct S {};

gribozavr2 wrote:
> Is the macro a necessary part of this test? If not, can it be removed?
I like to stick to the bug report as much as possible


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73441/new/

https://reviews.llvm.org/D73441



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72448: [clang-tidy] readability-redundant-string-init now flags redundant initialisation in Field Decls and Constructor Initialisers

2020-01-23 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 239884.
njames93 added a comment.

- Small refactor


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72448/new/

https://reviews.llvm.org/D72448

Files:
  clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init.cpp
@@ -34,6 +34,12 @@
   std::string d(R"()");
   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
   // CHECK-FIXES: std::string d;
+  std::string e{""};
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES: std::string e;
+  std::string f = {""};
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES: std::string f;
 
   std::string u = "u";
   std::string w("w");
@@ -227,3 +233,53 @@
   other::wstring e = L"";
   other::wstring f(L"");
 }
+
+class Foo {
+  std::string A = "";
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES:  std::string A;
+  std::string B;
+  std::string C;
+  std::string D;
+  std::string E = "NotEmpty";
+
+public:
+  // Check redundant constructor where Field has a redundant initializer.
+  Foo() : A("") {}
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: redundant string initialization
+  // CHECK-FIXES:  Foo()  {}
+
+  // Check redundant constructor where Field has no initializer.
+  Foo(char) : B("") {}
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES:  Foo(char)  {}
+
+  // Check redundant constructor where Field has a valid initializer.
+  Foo(long) : E("") {}
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-FIXES:  Foo(long) : E() {}
+
+  // Check how it handles removing 1 initializer, and defaulting the other.
+  Foo(int) : B(""), E("") {}
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: redundant string initialization
+  // CHECK-MESSAGES: [[@LINE-2]]:21: warning: redundant string initialization
+  // CHECK-FIXES:  Foo(int) :  E() {}
+
+  Foo(short) : B{""} {}
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+  // CHECK-FIXES:  Foo(short)  {}
+
+  Foo(float) : A{""}, B{""} {}
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+  // CHECK-MESSAGES: [[@LINE-2]]:23: warning: redundant string initialization
+  // CHECK-FIXES:  Foo(float)  {}
+
+
+  // Check how it handles removing some redundant initializers while leaving
+  // valid initializers intact.
+  Foo(std::string Arg) : A(Arg), B(""), C("NonEmpty"), D(R"()"), E("") {}
+  // CHECK-MESSAGES: [[@LINE-1]]:34: warning: redundant string initialization
+  // CHECK-MESSAGES: [[@LINE-2]]:56: warning: redundant string initialization
+  // CHECK-MESSAGES: [[@LINE-3]]:66: warning: redundant string initialization
+  // CHECK-FIXES:  Foo(std::string Arg) : A(Arg),  C("NonEmpty"),  E() {}
+};
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -104,6 +104,11 @@
 Changes in existing checks
 ^^
 
+- Improved :doc:`readability-redundant-string-init
+  ` check now supports a
+  `StringNames` option enabling its application to custom string classes. The 
+  check now detects in class initializers and constructor initializers which 
+  are deemed to be redundant.
 
 Renamed checks
 ^^
Index: clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
@@ -20,6 +20,46 @@
 
 const char DefaultStringNames[] = "::std::basic_string";
 
+static ast_matchers::internal::Matcher
+hasAnyNameStdString(std::vector Names) {
+  return ast_matchers::internal::Matcher(
+  new ast_matchers::internal::HasNameMatcher(std::move(Names)));
+}
+
+static std::vector
+removeNamespaces(const std::vector ) {
+  std::vector Result;
+  Result.reserve(Names.size());
+  for (const std::string  : Names) {
+std::string::size_type ColonPos = Name.rfind(':');
+Result.push_back(
+Name.substr(ColonPos == std::string::npos ? 0 : ColonPos + 1));
+  }
+  return Result;
+}
+
+static const CXXConstructExpr *
+getConstructExpr(const CXXCtorInitializer ) {
+  const Expr *InitExpr = CtorInit.getInit();
+  if 

[PATCH] D73098: [clang-tidy] readability-identifier-naming disregards parameters restrictions on main like functions

2020-01-23 Thread Nathan James via Phabricator via cfe-commits
njames93 marked an inline comment as done.
njames93 added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp:383
+  } else {
+static llvm::Regex Matcher("(^((W[Mm])|(wm))ain([_A-Z]|$))|([a-z0-9_]W[Mm]"
+   "ain([_A-Z]|$))|(_wmain(_|$))",

aaron.ballman wrote:
> njames93 wrote:
> > Any thoughts on whether I should detect WMain or just Wmain. WMain looks 
> > more pleasing but using CamelCase rules it should likely be Wmain
> I think this needs to be controlled by an option if we want to keep it, 
> because you can still have names like `terminateMain(int exitCode, char 
> *msgs[]);` At the end of the day, no matter what regex we come up with, we 
> can probably pick an identifier that subverts the check. Also, the name 
> `main` might have different meanings if the function is a member function or 
> a member of a namespace (or, alternatively, it may actually relate to the 
> main entrypoint). Ultimately, this seems too much like guessing at user 
> intent, which is why I think it should be an option (and probably off by 
> default).
> 
> That said, if we're searching for main-like names, I think we need to find 
> names like wmain, Wmain, wMain, WMain optionally with a prefix or suffix 
> (perhaps with underscores). I am less certain how to treat member functions, 
> but suspect the reasonable thing to do is treat them as being potentially 
> main-like regardless of whether they're static or not, but the function still 
> needs to be publicly available rather than private or protected (those can't 
> be main-like, unless someone friends main... which is another twist).
Its current behaviour now is to just flag main, but there is an option 
IgnoreMainLikeFunctions(defaults to off) that if turned on will look for 
functions with the right sig that have the word main, Main, WMain, Wmain or 
wmain in there. I'll add in the public access though, that was an oversight


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73098/new/

https://reviews.llvm.org/D73098



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73098: [clang-tidy] readability-identifier-naming disregards parameters restrictions on main like functions

2020-01-23 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 239902.
njames93 added a comment.

- Added checks for access specifiers


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73098/new/

https://reviews.llvm.org/D73098

Files:
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp
  clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h
  clang-tools-extra/docs/clang-tidy/checks/readability-identifier-naming.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp
@@ -0,0 +1,88 @@
+// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \
+// RUN:   -config='{CheckOptions: [ \
+// RUN: {key: readability-identifier-naming.ParameterCase, value: CamelCase}, \
+// RUN: {key: readability-identifier-naming.IgnoreMainLikeFunctions, value: 1} \
+// RUN:  ]}'
+
+int mainLike(int argc, char **argv);
+int mainLike(int argc, char **argv, const char **env);
+int mainLike(int argc, const char **argv);
+int mainLike(int argc, const char **argv, const char **env);
+int mainLike(int argc, char *argv[]);
+int mainLike(int argc, const char *argv[]);
+int mainLike(int argc, char *argv[], char *env[]);
+int mainLike(int argc, const char *argv[], const char *env[]);
+void notMain(int argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+void notMain(int argc, char **argv, char **env);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+// CHECK-MESSAGES: :[[@LINE-3]]:44: warning: invalid case style for parameter 'env'
+int notMain(int argc, char **argv, char **env, int Extra);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+// CHECK-MESSAGES: :[[@LINE-3]]:43: warning: invalid case style for parameter 'env'
+int notMain(int argc, char **argv, int Extra);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char *argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:29: warning: invalid case style for parameter 'argv'
+int notMain(unsigned argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:35: warning: invalid case style for parameter 'argv'
+int notMain(long argc, char *argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char16_t **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: invalid case style for parameter 'argv'
+int notMain(int argc, char argv[]);
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: invalid case style for parameter 'argv'
+typedef char myFunChar;
+typedef int myFunInt;
+typedef char **myFunCharPtr;
+typedef long myFunLong;
+myFunInt mainLikeTypedef(myFunInt argc, myFunChar **argv);
+int mainLikeTypedef(int argc, myFunCharPtr argv);
+int notMainTypedef(myFunLong argc, char **argv);
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:43: warning: invalid case style for parameter 'argv'
+
+// Don't flag as name contains the word main
+int myMainFunction(int argc, char *argv[]);
+
+// This is fine, named with wmain and has wchar ptr.
+int wmainLike(int argc, wchar_t *argv[]);
+
+// Flag this as has signature of main, but named as wmain.
+int wmainLike(int argc, char *argv[]);
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: invalid case style for parameter 'argc'
+// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv'
+
+struct Foo {
+  Foo(int argc, char *argv[]) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: invalid case style for parameter 'argc'
+  // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: invalid case style for parameter 'argv'
+
+  int mainPub(int argc, char *argv[]);
+  static int mainPubStatic(int argc, char *argv[]);
+
+protected:
+  int mainProt(int argc, char *argv[]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: invalid case style for 

[PATCH] D73441: [clang-tidy] Fix bugprone-use-after-move when move is in noexcept operator

2020-01-27 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 240512.
njames93 added a comment.

- Fix formatting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73441/new/

https://reviews.llvm.org/D73441

Files:
  clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
@@ -1271,3 +1271,28 @@
   }
 };
 }
+
+namespace PR44667 {
+#define REQUIRE(expr) (void)(expr);
+struct S {};
+
+void foo() {
+  S s;
+  REQUIRE(noexcept(S{std::move(s)}));
+  S other{std::move(s)};
+}
+void otherUnevaluated(){
+  S s;
+  REQUIRE(sizeof(S{std::move(s)}) > 8);
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wgnu-alignof-expression"
+  REQUIRE(alignof(S{std::move(s)}) > 8);
+#pragma clang diagnostic pop
+
+  // error: you need to include  before using the 'typeid' operator
+  // REQUIRE(typeid(S{std::move(s)}).name());
+
+  S other{std::move(s)};
+}
+} // namespace PR44667
Index: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -8,6 +8,10 @@
 
 #include "UseAfterMoveCheck.h"
 
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Lex/Lexer.h"
 
@@ -23,6 +27,23 @@
 
 namespace {
 
+AST_MATCHER(Expr, hasUnevaluatedContext) {
+  if (isa(Node) || isa(Node))
+return true;
+  if (const auto *UnaryExpr = dyn_cast()) {
+switch (UnaryExpr->getKind()) {
+case UETT_SizeOf:
+case UETT_AlignOf:
+  return true;
+default:
+  return false;
+}
+  }
+  if (const auto *TypeIDExpr = dyn_cast())
+return !TypeIDExpr->isPotentiallyEvaluated();
+  return false;
+}
+
 /// Contains information about a use-after-move.
 struct UseAfterMove {
   // The DeclRefExpr that constituted the use of the object.
@@ -77,7 +98,8 @@
 static StatementMatcher inDecltypeOrTemplateArg() {
   return anyOf(hasAncestor(typeLoc()),
hasAncestor(declRefExpr(
-   
to(functionDecl(ast_matchers::isTemplateInstantiation());
+   to(functionDecl(ast_matchers::isTemplateInstantiation(),
+   hasAncestor(expr(hasUnevaluatedContext(;
 }
 
 UseAfterMoveFinder::UseAfterMoveFinder(ASTContext *TheContext)


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp
@@ -1271,3 +1271,28 @@
   }
 };
 }
+
+namespace PR44667 {
+#define REQUIRE(expr) (void)(expr);
+struct S {};
+
+void foo() {
+  S s;
+  REQUIRE(noexcept(S{std::move(s)}));
+  S other{std::move(s)};
+}
+void otherUnevaluated(){
+  S s;
+  REQUIRE(sizeof(S{std::move(s)}) > 8);
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wgnu-alignof-expression"
+  REQUIRE(alignof(S{std::move(s)}) > 8);
+#pragma clang diagnostic pop
+
+  // error: you need to include  before using the 'typeid' operator
+  // REQUIRE(typeid(S{std::move(s)}).name());
+
+  S other{std::move(s)};
+}
+} // namespace PR44667
Index: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -8,6 +8,10 @@
 
 #include "UseAfterMoveCheck.h"
 
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Lex/Lexer.h"
 
@@ -23,6 +27,23 @@
 
 namespace {
 
+AST_MATCHER(Expr, hasUnevaluatedContext) {
+  if (isa(Node) || isa(Node))
+return true;
+  if (const auto *UnaryExpr = dyn_cast()) {
+switch (UnaryExpr->getKind()) {
+case UETT_SizeOf:
+case UETT_AlignOf:
+  return true;
+default:
+  return false;
+}
+  }
+  if (const auto *TypeIDExpr = dyn_cast())
+return !TypeIDExpr->isPotentiallyEvaluated();
+  return false;
+}
+
 /// Contains information about a use-after-move.
 struct UseAfterMove {
   // The DeclRefExpr that constituted the use of the object.
@@ -77,7 +98,8 @@
 static StatementMatcher inDecltypeOrTemplateArg() {
   return anyOf(hasAncestor(typeLoc()),
hasAncestor(declRefExpr(
- 

[PATCH] D73413: [clang-tidy] Add check to detect external definitions with no header declaration

2020-01-27 Thread Nathan James via Phabricator via cfe-commits
njames93 marked 2 inline comments as done.
njames93 added a comment.

I'll work up those other test cases




Comment at: 
clang-tools-extra/clang-tidy/misc/MissingHeaderFileDeclarationCheck.cpp:29
+
+  bool isHeader() const {
+return llvm::StringSwitch(Extension)

gribozavr2 wrote:
> I think we should consider any file other than the main file to be a header 
> (anything brought in by `#include`). Projects have lots of different 
> convention -- for example, LLVM uses a `.inc` extension for some generated 
> files and x-macro files. The standard library does not have any extensions at 
> all (and I'm sure some projects imitate that) etc.
I agree in part, but there is one case that I didn't want to happen and that is 
when clang-tidy is ran as a text editor plugin. Often it will blindly treat the 
current open file as the main file which would lead to a lot of false 
positives, Would a better metric being matching on file extensions not 
corresponding to source files (c, cc, cxx, cpp)?



Comment at: 
clang-tools-extra/clang-tidy/misc/MissingHeaderFileDeclarationCheck.cpp:75
+  continue;
+if (AnyHeader || File->NamePart.equals_lower(ThisFile->NamePart))
+  return; // Found a good candidate for matching decl

gribozavr2 wrote:
> This heuristic should be a lot more complex. In practice people have more 
> complex naming conventions (for example, in Clang, Sema.h corresponds to many 
> files named SemaSomethingSomething.cpp).
> 
> I think there is a high chance that checking only a header with a matching 
> name will satisfy too few projects to be worth implementing.
> 
> On the other hand, if you could use C++ or Clang modules to narrow down the 
> list of headers where the declaration should appear, that would be a much 
> stronger signal.
That is the reason I added the CheckAnyHeader option. For small projects the 
matching name would be usually be enough, but for big complex projects there is 
no feasible check that would work. Falling back to making sure every external 
definition has a declaration in at least one header will always be a good 
warning


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73413/new/

https://reviews.llvm.org/D73413



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   4   5   6   7   8   9   >