[PATCH] D24841: [asan] Fix incorrect SEH symbol mangling on win64.

2016-09-22 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added reviewers: rnk, kcc.
etienneb added subscribers: cfe-commits, chrisha.

The ASAN unittests are failing (check-asan-dynamic) due to an incorrect symbol 
name:
```
LINK : error LNK2001: unresolved external symbol ___asan_seh_interceptor
```

On win64, the linker is not adding an extra underscore. This was correctly 
fixed in the same file for other uses.

After that patch, most of the unittests are passing, but some related to SEH 
needs to be fixed.
```
Failing Tests (4):
AddressSanitizer-x86_64-windows-dynamic :: 
TestCases/Windows/dll_intercept_memchr.cc
AddressSanitizer-x86_64-windows-dynamic :: 
TestCases/Windows/dll_intercept_memcpy_indirect.cc
AddressSanitizer-x86_64-windows-dynamic :: TestCases/Windows/dll_seh.cc
AddressSanitizer-x86_64-windows-dynamic :: TestCases/Windows/seh.cc

  Expected Passes: 339
  Passes With Retry  : 3
  Expected Failures  : 16
  Unsupported Tests  : 152
  Unexpected Failures: 4
```

https://reviews.llvm.org/D24841

Files:
  lib/Driver/Tools.cpp

Index: lib/Driver/Tools.cpp
===
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -10235,7 +10235,10 @@
 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
   // Make sure the dynamic runtime thunk is not optimized out at link time
   // to ensure proper SEH handling.
-  
CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor"));
+  CmdArgs.push_back(Args.MakeArgString(
+  TC.getArch() == llvm::Triple::x86
+  ? "-include:___asan_seh_interceptor"
+  : "-include:__asan_seh_interceptor"));
 } else if (DLL) {
   CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
 } else {


Index: lib/Driver/Tools.cpp
===
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -10235,7 +10235,10 @@
 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
   // Make sure the dynamic runtime thunk is not optimized out at link time
   // to ensure proper SEH handling.
-  CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor"));
+  CmdArgs.push_back(Args.MakeArgString(
+  TC.getArch() == llvm::Triple::x86
+  ? "-include:___asan_seh_interceptor"
+  : "-include:__asan_seh_interceptor"));
 } else if (DLL) {
   CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
 } else {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r282251 - [asan] Fix incorrect SEH symbol mangling on win64.

2016-09-23 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Fri Sep 23 09:07:47 2016
New Revision: 282251

URL: http://llvm.org/viewvc/llvm-project?rev=282251&view=rev
Log:
[asan] Fix incorrect SEH symbol mangling on win64.

Summary:
The ASAN unittests are failing (check-asan-dynamic) due to an incorrect symbol 
name:
```
LINK : error LNK2001: unresolved external symbol ___asan_seh_interceptor
```

On win64, the linker is not adding an extra underscore. This was correctly 
fixed in the same file for other uses.

After that patch, most of the unittests are passing, but some related to SEH 
needs to be fixed.
```
Failing Tests (4):
AddressSanitizer-x86_64-windows-dynamic :: 
TestCases/Windows/dll_intercept_memchr.cc
AddressSanitizer-x86_64-windows-dynamic :: 
TestCases/Windows/dll_intercept_memcpy_indirect.cc
AddressSanitizer-x86_64-windows-dynamic :: TestCases/Windows/dll_seh.cc
AddressSanitizer-x86_64-windows-dynamic :: TestCases/Windows/seh.cc

  Expected Passes: 339
  Passes With Retry  : 3
  Expected Failures  : 16
  Unsupported Tests  : 152
  Unexpected Failures: 4
```

Reviewers: rnk, kcc, majnemer

Subscribers: majnemer, chrisha, cfe-commits

Differential Revision: https://reviews.llvm.org/D24841

Modified:
cfe/trunk/lib/Driver/Tools.cpp

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=282251&r1=282250&r2=282251&view=diff
==
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Fri Sep 23 09:07:47 2016
@@ -10235,7 +10235,10 @@ void visualstudio::Linker::ConstructJob(
 CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
   // Make sure the dynamic runtime thunk is not optimized out at link time
   // to ensure proper SEH handling.
-  
CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor"));
+  CmdArgs.push_back(Args.MakeArgString(
+  TC.getArch() == llvm::Triple::x86
+  ? "-include:___asan_seh_interceptor"
+  : "-include:__asan_seh_interceptor"));
 } else if (DLL) {
   CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
 } else {


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


r280127 - typo + indentation [NFC]

2016-08-30 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Tue Aug 30 13:38:25 2016
New Revision: 280127

URL: http://llvm.org/viewvc/llvm-project?rev=280127&view=rev
Log:
typo + indentation [NFC]

Modified:
cfe/trunk/lib/Driver/MSVCToolChain.cpp
cfe/trunk/lib/Driver/ToolChains.h

Modified: cfe/trunk/lib/Driver/MSVCToolChain.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/MSVCToolChain.cpp?rev=280127&r1=280126&r2=280127&view=diff
==
--- cfe/trunk/lib/Driver/MSVCToolChain.cpp (original)
+++ cfe/trunk/lib/Driver/MSVCToolChain.cpp Tue Aug 30 13:38:25 2016
@@ -115,7 +115,7 @@ static bool readFullStringValue(HKEY hke
 std::wstring WideValue(reinterpret_cast(buffer.data()),
valueSize / sizeof(wchar_t));
 if (valueSize && WideValue.back() == L'\0') {
-WideValue.pop_back();
+  WideValue.pop_back();
 }
 // The destination buffer must be empty as an invariant of the conversion
 // function; but this function is sometimes called in a loop that passes in

Modified: cfe/trunk/lib/Driver/ToolChains.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=280127&r1=280126&r2=280127&view=diff
==
--- cfe/trunk/lib/Driver/ToolChains.h (original)
+++ cfe/trunk/lib/Driver/ToolChains.h Tue Aug 30 13:38:25 2016
@@ -190,7 +190,7 @@ protected:
 /// \brief Print information about the detected CUDA installation.
 void print(raw_ostream &OS) const;
 
-/// \brief Get the deteced Cuda install's version.
+/// \brief Get the detected Cuda install's version.
 CudaVersion version() const { return Version; }
 /// \brief Get the detected Cuda installation path.
 StringRef getInstallPath() const { return InstallPath; }


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


Re: [PATCH] D22507: Clang-tidy - Enum misuse check

2016-07-19 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

drive-by, some comments.
Thanks for the check



Comment at: clang-tidy/misc/EnumMisuseCheck.cpp:20
@@ +19,3 @@
+// Return the number of EnumConstantDecls in an EnumDecl.
+static int enumLen(const EnumDecl *EnumDec) {
+  int Counter = 0;

hokein wrote:
> You can use `std::distance(Enum->enumerator_begin(), Enum->enumerator_end())`.
We tend to keep name meaningful and avoid abbreviation.
enumLen -> enumLength


Comment at: clang-tidy/misc/EnumMisuseCheck.cpp:35
@@ +34,3 @@
+  ValueRange(const EnumDecl *EnumDec) {
+
+llvm::APSInt BeginVal = EnumDec->enumerator_begin()->getInitVal();

nit: remove empty line


Comment at: clang-tidy/misc/EnumMisuseCheck.cpp:55
@@ +54,3 @@
+
+bool hasCommonBit(const llvm::APSInt &Val1, const llvm::APSInt &Val2) {
+  return (Val1 & Val2).getExtValue();

nit: static


Comment at: clang-tidy/misc/EnumMisuseCheck.cpp:81
@@ +80,3 @@
+void EnumMisuseCheck::registerMatchers(MatchFinder *Finder) {
+
+  const auto enumExpr = [](StringRef RefName, StringRef DeclName) {

nit: remove empty line


Comment at: clang-tidy/misc/EnumMisuseCheck.cpp:117
@@ +116,3 @@
+// if there is only one not power-of-2 value in the enum unless it is
+static bool isPossiblyBitField(const int NonPowOfTwoCounter, const int EnumLen,
+   const ValueRange &VR, const EnumDecl *EnumDec) {

nit: const int x   --> int x   for all parameters


Comment at: clang-tidy/misc/EnumMisuseCheck.cpp:119
@@ +118,3 @@
+   const ValueRange &VR, const EnumDecl *EnumDec) {
+  return NonPowOfTwoCounter >= 1 && NonPowOfTwoCounter <= 2 && 
NonPowOfTwoCounter < enumLen(EnumDec) / 2 &&
+ (VR.MaxVal - VR.MinVal != EnumLen - 1) && !(NonPowOfTwoCounter == 1 
&& isMaxValAllBitSet(EnumDec));

nit: line too long


Comment at: clang-tidy/misc/EnumMisuseCheck.cpp:127
@@ +126,3 @@
+  // 1. case: The two enum values come from different types.
+  if (DiffEnumOp) {
+

A common pattern is:

```
if (const auto *DiffEnumOp = 
Result.Nodes.getNodeAs("diffEnumOp")) {
   [...]
}
```

This way the scope is smaller and there is less chance to use it by mistake.


Comment at: clang-tidy/misc/EnumMisuseCheck.cpp:128
@@ +127,3 @@
+  if (DiffEnumOp) {
+
+const auto *EnumDec = Result.Nodes.getNodeAs("enumDecl");

nit: no empty line


Comment at: clang-tidy/misc/EnumMisuseCheck.cpp:150
@@ +149,3 @@
+
+  if (EnumExpr) {
+if (!IsStrict)

ditto for th "if (var = ...)" pattern 


Comment at: clang-tidy/misc/EnumMisuseCheck.cpp:170
@@ +169,3 @@
+  "possibly contains misspelled "
+  "number(s) ");
+diag(EnumExpr->getExprLoc(), "Used here as a bitfield.",

nit: remove the space after (s)


Comment at: clang-tidy/misc/EnumMisuseCheck.cpp:177
@@ +176,3 @@
+  }
+  // 3. case
+  // | or + operator where both argument comes from the same enum type

To be consistent with your comments, add newline here.


Repository:
  rL LLVM

https://reviews.llvm.org/D22507



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


Re: [PATCH] D22507: Clang-tidy - Enum misuse check

2016-07-25 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

some nits



Comment at: docs/clang-tidy/checks/misc-enum-misuse.rst:37
@@ +36,3 @@
+unsigned flag;
+flag = A | H; //OK, disjoint value intervalls in the enum types > probably 
good use
+flag = B | F; //warning, have common values so they are probably misused

nit: space after //
here and below.


Comment at: docs/clang-tidy/checks/misc-enum-misuse.rst:37
@@ +36,3 @@
+unsigned flag;
+flag = A | H; //OK, disjoint value intervalls in the enum types > probably 
good use
+flag = B | F; //warning, have common values so they are probably misused

etienneb wrote:
> nit: space after //
> here and below.
nit: intervalls (typo)


Comment at: test/clang-tidy/misc-enum-misuse-weak.cpp:48
@@ +47,3 @@
+return 1;
+  // CHECK-MESSAGES: :[[@LINE-2]]:17: warning: enum values are from different 
enum types [misc-enum-misuse]
+  if (I | Y)

you can remove "[misc-enum-misuse]" from the following line.
Only the first occurrence is enough.


https://reviews.llvm.org/D22507



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


Re: [PATCH] D22220: [clang-tidy] Add check 'misc-move-forwarding-reference'

2016-07-25 Thread Etienne Bergeron via cfe-commits
etienneb added a subscriber: etienneb.
etienneb added a comment.

thx for the check



Comment at: clang-tidy/misc/MoveForwardingReferenceCheck.cpp:25
@@ +24,3 @@
+  const SourceManager &SM = Context->getSourceManager();
+  const LangOptions LangOpts = Context->getLangOpts();
+

nit: reference?


Comment at: clang-tidy/misc/MoveForwardingReferenceCheck.cpp:43-53
@@ +42,13 @@
+// another namespace).
+const StringRef OriginalText =
+Lexer::getSourceText(CallRange, SM, LangOpts);
+if (OriginalText == "::std::move") {
+  Diag << FixItHint::CreateReplacement(CallRange, "::std::" + ForwardName);
+  // If the original text was simply "move", we conservatively still put a
+  // "std::" in front of the "forward". Rationale: Even if the code
+  // apparently had a "using std::move;", that doesn't tell us whether it
+  // also had a "using std::forward;".
+} else if (OriginalText == "std::move" || OriginalText == "move") {
+  Diag << FixItHint::CreateReplacement(CallRange, "std::" + ForwardName);
+}
+  }

alexfh wrote:
> aaron.ballman wrote:
> > I'm not certain I understand the benefit to this. We know it's a call to 
> > std::move() from the standard namespace already, so why do we care about 
> > the original text? I think it's reasonable to replace any call to move() 
> > from the standard namespace with `::std::forward()`, so we should be able 
> > to remove the if statements and not have to go read the original source 
> > text from the source manager (which could involve, for instance, a query 
> > for that text over a slow network).
> I think, the value of this is to maintain consistency with the existing code 
> in terms of whether the `std` namespace should be globally qualified or not. 
> Changing `std::move` to `::std::forward` would sometimes be unwelcome, if the 
> code doesn't use `::std` otherwise.
I agree with alex, it's better to keep code consistency (programmer intend).
But, at the same time, the check should be bomb proof for ugly cases like:
```
  "std:: move"
   ":: std::move",
```

For the moment, the code seems to propose a fix only when it's a known case,
and a warning is emitted in every cases.


Comment at: clang-tidy/misc/MoveForwardingReferenceCheck.cpp:92
@@ +91,3 @@
+  Finder->addMatcher(
+  callExpr(callee(unresolvedLookupExpr().bind("lookup")),
+   argumentCountIs(1),

aaron.ballman wrote:
> It might be a bit more clear if you made `isStdMove()` into a local AST 
> matcher and called it from here.
+1 I agree with Aaron here.

The match will also be more precise.


https://reviews.llvm.org/D0



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


Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-25 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

In https://reviews.llvm.org/D22725#494167, @Prazek wrote:

> hmm It seems that I mislead you, I suck at C api - memmove source and 
> destination can overlap, but std::move can't. So I guess you have to remove 
> the memmove support. Sorry.


On windows (MSVC CRT), both function are the same : memmove.


https://reviews.llvm.org/D22725



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


Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-25 Thread Etienne Bergeron via cfe-commits
etienneb added inline comments.


Comment at: clang-tidy/modernize/UseAlgorithmCheck.cpp:73
@@ +72,3 @@
+  Finder->addMatcher(
+  callExpr(allOf(callee(functionDecl(matchesName("::memcpy"))),
+ argumentCountIs(3)))

It's more efficient to use  hasAnyName and merge the three following 
matcher.
That way, you won't need the function 'getCallExpr' to retrieve the CallExpr.


Comment at: clang-tidy/modernize/UseAlgorithmCheck.cpp:80
@@ +79,3 @@
+  Finder->addMatcher(
+  callExpr(allOf(callee(functionDecl(matchesName("::memmove"))),
+ argumentCountIs(3)))

allOf is not needed.


Comment at: clang-tidy/modernize/UseAlgorithmCheck.cpp:106
@@ +105,3 @@
+  const auto *MatchedExpr = getCallExpr(Result);
+  const auto MatchedName = MatchedExpr->getDirectCallee()->getNameAsString();
+  const auto ReplacedName = Replacements[MatchedName];

Instead of DirectCallee, you could add a "bind" to the Matcher : 
functionDecl(...).bind("callee")


Comment at: clang-tidy/modernize/UseAlgorithmCheck.cpp:107
@@ +106,3 @@
+  const auto MatchedName = MatchedExpr->getDirectCallee()->getNameAsString();
+  const auto ReplacedName = Replacements[MatchedName];
+

What is the name is not in the map?


https://reviews.llvm.org/D22725



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


[clang-tools-extra] r277539 - [clang-tidy] Fix missing dependency to static analyzer

2016-08-02 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Tue Aug  2 17:51:46 2016
New Revision: 277539

URL: http://llvm.org/viewvc/llvm-project?rev=277539&view=rev
Log:
[clang-tidy] Fix missing dependency to static analyzer

Summary:
This patch is fixing the build bot broken for a missing dependency.

The missing dependency is breaking "shared" build.

```
./mpi/TypeMismatchCheck.cpp:
  #include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h"
```

I'm not a fan of that fix. It's brining a strange dependency.

Reviewers: alexfh

Subscribers: llvm-commits, chrisha

Differential Revision: https://reviews.llvm.org/D23093

Modified:
clang-tools-extra/trunk/clang-tidy/mpi/CMakeLists.txt

Modified: clang-tools-extra/trunk/clang-tidy/mpi/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/mpi/CMakeLists.txt?rev=277539&r1=277538&r2=277539&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/mpi/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/mpi/CMakeLists.txt Tue Aug  2 17:51:46 
2016
@@ -12,4 +12,5 @@ add_clang_library(clangTidyMPIModule
   clangTidy
   clangTidyUtils
   clangTooling
+  clangStaticAnalyzerCheckers
   )


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


[PATCH] D23105: [clang/test] Fix a flaky unittest on windows

2016-08-02 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added a reviewer: rnk.
etienneb added subscribers: chrisha, cfe-commits.

The append operator on a shell command for quick command-line is
causing trouble on windows. [NFC]
The easiest way to fix them is to avoid using them.

This patch is an attempt to fix this broken build bot:
  clang-x86-win2008-selfhost

http://lab.llvm.org:8011/builders/clang-x86-win2008-selfhost/builds/9523

https://reviews.llvm.org/D23105

Files:
  test/Modules/no-stale-modtime.m

Index: test/Modules/no-stale-modtime.m
===
--- test/Modules/no-stale-modtime.m
+++ test/Modules/no-stale-modtime.m
@@ -7,18 +7,24 @@
 // RUN: echo '@import l; @import r;' > %t/b.h
 // RUN: echo '@import t; // fromt l' > %t/l.h
 // RUN: echo '@import t; // fromt r' > %t/r.h
-// RUN: echo '// top' > %t/t.h
-// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > 
%t/module.map
-// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' >> 
%t/module.map
+
+// RUN: echo '// top' > %t/t.h-1
+// RUN: cat %t/t.h-1 > %t/t.h
+
+// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > 
%t/module.map-1
+// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' > 
%t/module.map-2
+// RUN: cat %t/module.map-1 %t/module.map-2 > %t/module.map
 
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t 
-fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
 // RUN: | FileCheck -check-prefix=REBUILD-ALL %s
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t 
-fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build -verify
 
 // Add an identifier to ensure everything depending on t is out of date
-// RUN: echo 'extern int a;' >> %t/t.h
+// RUN: echo 'extern int a;' > %t/t.h-2
+// RUN: cat %t/t.h-1 %t/t.h-2 > %t/t.h
+
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t 
-fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
 // RUN: | FileCheck -check-prefix=REBUILD-ALL %s


Index: test/Modules/no-stale-modtime.m
===
--- test/Modules/no-stale-modtime.m
+++ test/Modules/no-stale-modtime.m
@@ -7,18 +7,24 @@
 // RUN: echo '@import l; @import r;' > %t/b.h
 // RUN: echo '@import t; // fromt l' > %t/l.h
 // RUN: echo '@import t; // fromt r' > %t/r.h
-// RUN: echo '// top' > %t/t.h
-// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > %t/module.map
-// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' >> %t/module.map
+
+// RUN: echo '// top' > %t/t.h-1
+// RUN: cat %t/t.h-1 > %t/t.h
+
+// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > %t/module.map-1
+// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' > %t/module.map-2
+// RUN: cat %t/module.map-1 %t/module.map-2 > %t/module.map
 
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
 // RUN: | FileCheck -check-prefix=REBUILD-ALL %s
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build -verify
 
 // Add an identifier to ensure everything depending on t is out of date
-// RUN: echo 'extern int a;' >> %t/t.h
+// RUN: echo 'extern int a;' > %t/t.h-2
+// RUN: cat %t/t.h-1 %t/t.h-2 > %t/t.h
+
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
 // RUN: | FileCheck -check-prefix=REBUILD-ALL %s
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r277576 - [clang/test] Fix a flaky unittest on windows

2016-08-02 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Wed Aug  3 01:10:15 2016
New Revision: 277576

URL: http://llvm.org/viewvc/llvm-project?rev=277576&view=rev
Log:
[clang/test] Fix a flaky unittest on windows

Summary:
The append operator on a shell command for quick command-line is
causing trouble on windows. [NFC]
The easiest way to fix them is to avoid using them.

This patch is an attempt to fix this broken build bot:
  clang-x86-win2008-selfhost

http://lab.llvm.org:8011/builders/clang-x86-win2008-selfhost/builds/9523

Reviewers: rnk

Subscribers: cfe-commits, chrisha

Differential Revision: https://reviews.llvm.org/D23105

Modified:
cfe/trunk/test/Modules/no-stale-modtime.m

Modified: cfe/trunk/test/Modules/no-stale-modtime.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/no-stale-modtime.m?rev=277576&r1=277575&r2=277576&view=diff
==
--- cfe/trunk/test/Modules/no-stale-modtime.m (original)
+++ cfe/trunk/test/Modules/no-stale-modtime.m Wed Aug  3 01:10:15 2016
@@ -7,9 +7,13 @@
 // RUN: echo '@import l; @import r;' > %t/b.h
 // RUN: echo '@import t; // fromt l' > %t/l.h
 // RUN: echo '@import t; // fromt r' > %t/r.h
-// RUN: echo '// top' > %t/t.h
-// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > 
%t/module.map
-// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' >> 
%t/module.map
+
+// RUN: echo '// top' > %t/t.h-1
+// RUN: cat %t/t.h-1 > %t/t.h
+
+// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > 
%t/module.map-1
+// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' > 
%t/module.map-2
+// RUN: cat %t/module.map-1 %t/module.map-2 > %t/module.map
 
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t 
-fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
@@ -18,7 +22,9 @@
 // RUN: -I %t -fsyntax-only %s -Rmodule-build -verify
 
 // Add an identifier to ensure everything depending on t is out of date
-// RUN: echo 'extern int a;' >> %t/t.h
+// RUN: echo 'extern int a;' > %t/t.h-2
+// RUN: cat %t/t.h-1 %t/t.h-2 > %t/t.h
+
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t 
-fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
 // RUN: | FileCheck -check-prefix=REBUILD-ALL %s


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


Re: [PATCH] D23105: [clang/test] Fix a flaky unittest on windows

2016-08-02 Thread Etienne Bergeron via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL277576: [clang/test] Fix a flaky unittest on windows 
(authored by etienneb).

Changed prior to commit:
  https://reviews.llvm.org/D23105?vs=66615&id=66616#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D23105

Files:
  cfe/trunk/test/Modules/no-stale-modtime.m

Index: cfe/trunk/test/Modules/no-stale-modtime.m
===
--- cfe/trunk/test/Modules/no-stale-modtime.m
+++ cfe/trunk/test/Modules/no-stale-modtime.m
@@ -7,18 +7,24 @@
 // RUN: echo '@import l; @import r;' > %t/b.h
 // RUN: echo '@import t; // fromt l' > %t/l.h
 // RUN: echo '@import t; // fromt r' > %t/r.h
-// RUN: echo '// top' > %t/t.h
-// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > 
%t/module.map
-// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' >> 
%t/module.map
+
+// RUN: echo '// top' > %t/t.h-1
+// RUN: cat %t/t.h-1 > %t/t.h
+
+// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > 
%t/module.map-1
+// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' > 
%t/module.map-2
+// RUN: cat %t/module.map-1 %t/module.map-2 > %t/module.map
 
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t 
-fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
 // RUN: | FileCheck -check-prefix=REBUILD-ALL %s
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t 
-fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build -verify
 
 // Add an identifier to ensure everything depending on t is out of date
-// RUN: echo 'extern int a;' >> %t/t.h
+// RUN: echo 'extern int a;' > %t/t.h-2
+// RUN: cat %t/t.h-1 %t/t.h-2 > %t/t.h
+
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t 
-fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
 // RUN: | FileCheck -check-prefix=REBUILD-ALL %s


Index: cfe/trunk/test/Modules/no-stale-modtime.m
===
--- cfe/trunk/test/Modules/no-stale-modtime.m
+++ cfe/trunk/test/Modules/no-stale-modtime.m
@@ -7,18 +7,24 @@
 // RUN: echo '@import l; @import r;' > %t/b.h
 // RUN: echo '@import t; // fromt l' > %t/l.h
 // RUN: echo '@import t; // fromt r' > %t/r.h
-// RUN: echo '// top' > %t/t.h
-// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > %t/module.map
-// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' >> %t/module.map
+
+// RUN: echo '// top' > %t/t.h-1
+// RUN: cat %t/t.h-1 > %t/t.h
+
+// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > %t/module.map-1
+// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' > %t/module.map-2
+// RUN: cat %t/module.map-1 %t/module.map-2 > %t/module.map
 
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
 // RUN: | FileCheck -check-prefix=REBUILD-ALL %s
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build -verify
 
 // Add an identifier to ensure everything depending on t is out of date
-// RUN: echo 'extern int a;' >> %t/t.h
+// RUN: echo 'extern int a;' > %t/t.h-2
+// RUN: cat %t/t.h-1 %t/t.h-2 > %t/t.h
+
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash \
 // RUN: -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
 // RUN: | FileCheck -check-prefix=REBUILD-ALL %s
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r277578 - [extra-tools] Fix extra tools build bot warnings due to incorrect doc

2016-08-03 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Wed Aug  3 01:59:46 2016
New Revision: 277578

URL: http://llvm.org/viewvc/llvm-project?rev=277578&view=rev
Log:
[extra-tools] Fix extra tools build bot warnings due to incorrect doc

/home/llvmbb/llvm-build-dir/clang-x86_64-debian-fast/llvm.src/tools/clang/tools/extra/clang-tidy/mpi/TypeMismatchCheck.cpp:172:12:
 warning: parameter 'Complex' not found in the function declaration 
[-Wdocumentation]
/home/llvmbb/llvm-build-dir/clang-x86_64-debian-fast/llvm.src/tools/clang/tools/extra/clang-tidy/mpi/TypeMismatchCheck.cpp:206:12:
 warning: parameter 'Complex' not fo


Modified:
clang-tools-extra/trunk/clang-tidy/mpi/TypeMismatchCheck.cpp

Modified: clang-tools-extra/trunk/clang-tidy/mpi/TypeMismatchCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/mpi/TypeMismatchCheck.cpp?rev=277578&r1=277577&r2=277578&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/mpi/TypeMismatchCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/mpi/TypeMismatchCheck.cpp Wed Aug  3 
01:59:46 2016
@@ -169,7 +169,7 @@ static bool isCComplexTypeMatching(const
 /// Check if a complex templated buffer type matches
 /// the MPI datatype.
 ///
-/// \param Complex buffer type
+/// \param Template buffer type
 /// \param BufferTypeName buffer type name, gets assigned
 /// \param MPIDatatype name of the MPI datatype
 /// \param LO language options
@@ -203,7 +203,7 @@ isCXXComplexTypeMatching(const TemplateS
 
 /// Check if a fixed size width buffer type matches the MPI datatype.
 ///
-/// \param Complex buffer type
+/// \param Typedef buffer type
 /// \param BufferTypeName buffer type name, gets assigned
 /// \param MPIDatatype name of the MPI datatype
 ///


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


Re: [PATCH] D19451: [clang-tidy] New checker for redundant expressions.

2016-04-26 Thread Etienne Bergeron via cfe-commits
etienneb added inline comments.


Comment at: clang-tidy/misc/RedundantExpressionCheck.cpp:21
@@ +20,3 @@
+
+static bool AreIdenticalExpr(const Expr *Left, const Expr *Right) {
+  if (!Left || !Right)

alexfh wrote:
> This is to some degree similar to comparing `llvm::FoldingSetNodeIDs` created 
> using `Stmt::Profile`. However it's only useful to check for identical 
> expressions and won't work, if you're going to extend this to equivalent 
> expressions.
Exact. There is plan to extend the notion of "equivalent".
I think we should lift this to "utils", and maybe we can also provide a 
"isIdenticalExpression" based on FoldingSet.


http://reviews.llvm.org/D19451



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


[PATCH] D19541: Fix generation of documentation for UndefinedBehaviorSanitizer.

2016-04-26 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added a reviewer: alexfh.
etienneb added a subscriber: cfe-commits.

The text is mis-aligned.

http://reviews.llvm.org/D19541

Files:
  docs/UndefinedBehaviorSanitizer.rst

Index: docs/UndefinedBehaviorSanitizer.rst
===
--- docs/UndefinedBehaviorSanitizer.rst
+++ docs/UndefinedBehaviorSanitizer.rst
@@ -93,13 +93,13 @@
   -  ``-fsanitize=null``: Use of a null pointer or creation of a null
  reference.
   -  ``-fsanitize=object-size``: An attempt to potentially use bytes which
-the optimizer can determine are not part of the object being accessed.
-This will also detect some types of undefined behavior that may not
-directly access memory, but are provably incorrect given the size of
-the objects involved, such as invalid downcasts and calling methods on
-invalid pointers. These checks are made in terms of
-``__builtin_object_size``, and consequently may be able to detect more
-problems at higher optimization levels.
+ the optimizer can determine are not part of the object being accessed.
+ This will also detect some types of undefined behavior that may not
+ directly access memory, but are provably incorrect given the size of
+ the objects involved, such as invalid downcasts and calling methods on
+ invalid pointers. These checks are made in terms of
+ ``__builtin_object_size``, and consequently may be able to detect more
+ problems at higher optimization levels.
   -  ``-fsanitize=return``: In C++, reaching the end of a
  value-returning function without returning a value.
   -  ``-fsanitize=returns-nonnull-attribute``: Returning null pointer


Index: docs/UndefinedBehaviorSanitizer.rst
===
--- docs/UndefinedBehaviorSanitizer.rst
+++ docs/UndefinedBehaviorSanitizer.rst
@@ -93,13 +93,13 @@
   -  ``-fsanitize=null``: Use of a null pointer or creation of a null
  reference.
   -  ``-fsanitize=object-size``: An attempt to potentially use bytes which
-the optimizer can determine are not part of the object being accessed.
-This will also detect some types of undefined behavior that may not
-directly access memory, but are provably incorrect given the size of
-the objects involved, such as invalid downcasts and calling methods on
-invalid pointers. These checks are made in terms of
-``__builtin_object_size``, and consequently may be able to detect more
-problems at higher optimization levels.
+ the optimizer can determine are not part of the object being accessed.
+ This will also detect some types of undefined behavior that may not
+ directly access memory, but are provably incorrect given the size of
+ the objects involved, such as invalid downcasts and calling methods on
+ invalid pointers. These checks are made in terms of
+ ``__builtin_object_size``, and consequently may be able to detect more
+ problems at higher optimization levels.
   -  ``-fsanitize=return``: In C++, reaching the end of a
  value-returning function without returning a value.
   -  ``-fsanitize=returns-nonnull-attribute``: Returning null pointer
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19541: Fix generation of documentation for UndefinedBehaviorSanitizer.

2016-04-26 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

This got fixed.
Abandoning this change.


http://reviews.llvm.org/D19541



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


[clang-tools-extra] r267574 - [clang-tidy] New checker for redundant expressions.

2016-04-26 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Tue Apr 26 12:30:30 2016
New Revision: 267574

URL: http://llvm.org/viewvc/llvm-project?rev=267574&view=rev
Log:
[clang-tidy] New checker for redundant expressions.

Summary:
This checker finds redundant expression on both side of a binary operator.

The current implementation provide a function to check whether expressions
are equivalent. This implementation is able to recognize the common
subset encounter in C++ program. Side-effects like "x++" are not considered
to be equivalent.

There are many False Positives related to macros and to floating point
computations (detecting NaN). The checker is ignoring these cases.

Example:
```
if( !dst || dst->depth != desired_depth ||
dst->nChannels != desired_num_channels ||
dst_size.width != src_size.width ||
dst_size.height != dst_size.height )<<--- bug
{
```

Reviewers: alexfh

Subscribers: danielmarjamaki, fahlgren, jordan_rose, zaks.anna, Eugene.Zelenko, 
cfe-commits

Differential Revision: http://reviews.llvm.org/D19451

Added:
clang-tools-extra/trunk/clang-tidy/misc/RedundantExpressionCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/RedundantExpressionCheck.h
clang-tools-extra/trunk/docs/clang-tidy/checks/misc-redundant-expression.rst
clang-tools-extra/trunk/test/clang-tidy/misc-redundant-expression.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp
clang-tools-extra/trunk/docs/ReleaseNotes.rst
clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt?rev=267574&r1=267573&r2=267574&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt Tue Apr 26 12:30:30 
2016
@@ -23,6 +23,7 @@ add_clang_library(clangTidyMiscModule
   NoexceptMoveConstructorCheck.cpp
   NonCopyableObjects.cpp
   PointerAndIntegralOperationCheck.cpp
+  RedundantExpressionCheck.cpp
   SizeofContainerCheck.cpp
   SizeofExpressionCheck.cpp
   StaticAssertCheck.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp?rev=267574&r1=267573&r2=267574&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp Tue Apr 26 
12:30:30 2016
@@ -31,6 +31,7 @@
 #include "NoexceptMoveConstructorCheck.h"
 #include "NonCopyableObjects.h"
 #include "PointerAndIntegralOperationCheck.h"
+#include "RedundantExpressionCheck.h"
 #include "SizeofContainerCheck.h"
 #include "SizeofExpressionCheck.h"
 #include "StaticAssertCheck.h"
@@ -98,6 +99,8 @@ public:
 "misc-non-copyable-objects");
 CheckFactories.registerCheck(
 "misc-pointer-and-integral-operation");
+CheckFactories.registerCheck(
+"misc-redundant-expression");
 
CheckFactories.registerCheck("misc-sizeof-container");
 CheckFactories.registerCheck(
 "misc-sizeof-expression");

Added: clang-tools-extra/trunk/clang-tidy/misc/RedundantExpressionCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/RedundantExpressionCheck.cpp?rev=267574&view=auto
==
--- clang-tools-extra/trunk/clang-tidy/misc/RedundantExpressionCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/RedundantExpressionCheck.cpp Tue 
Apr 26 12:30:30 2016
@@ -0,0 +1,133 @@
+//===--- RedundantExpressionCheck.cpp - 
clang-tidy-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "RedundantExpressionCheck.h"
+#include "../utils/Matchers.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+static bool AreIdenticalExpr(const Expr *Left, const Expr *Right) {
+  if (!Left || !Right)
+return !Left && !Right;
+
+  Left = Left->IgnoreParens();
+  Right = Right->IgnoreParens();
+
+  // Compare classes.
+  if (Left->getStmtClass() != Right->getStmtClass())
+return false;
+
+  // Compare children.
+  Expr::const_child_iterator LeftIter = Left->child_begin();
+  Expr::const_child_iterator RightIter = Right->child_begin();
+  while (LeftIter != Left->child_end() && RightIter != Right->child_end()) {

[PATCH] D19547: [clang-tidy] Add FixIt for swapping arguments in string-constructor-checker.

2016-04-26 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added a reviewer: alexfh.
etienneb added a subscriber: cfe-commits.

Arguments can be swapped using fixit when they are not in macros.
This is the same implementation than SwappedArguments. Some code 
got lifted to be reused.

Others checks are not safe to be fixed as they tend to be bugs or errors.
It is better to let the user manually review them.

http://reviews.llvm.org/D19547

Files:
  clang-tidy/misc/StringConstructorCheck.cpp
  clang-tidy/misc/SwappedArgumentsCheck.cpp
  clang-tidy/utils/FixItHintUtils.cpp
  clang-tidy/utils/FixItHintUtils.h
  test/clang-tidy/misc-string-constructor.cpp

Index: test/clang-tidy/misc-string-constructor.cpp
===
--- test/clang-tidy/misc-string-constructor.cpp
+++ test/clang-tidy/misc-string-constructor.cpp
@@ -22,8 +22,10 @@
 void Test() {
   std::string str('x', 4);
   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor parameters are probably swapped [misc-string-constructor]
+  // CHECK-FIXES: std::string str(4, 'x');  
   std::wstring wstr(L'x', 4);
   // CHECK-MESSAGES: [[@LINE-1]]:16: warning: constructor parameters are probably swapped
+  // CHECK-FIXES: std::wstring wstr(4, L'x');
   std::string s0(0, 'x');
   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
   std::string s1(-4, 'x');
Index: clang-tidy/utils/FixItHintUtils.h
===
--- clang-tidy/utils/FixItHintUtils.h
+++ clang-tidy/utils/FixItHintUtils.h
@@ -24,6 +24,9 @@
 /// \brief Creates fix to make VarDecl const qualified.
 FixItHint changeVarDeclToConst(const VarDecl &Var);
 
+/// \brief Get a StringRef representing a SourceRange.
+StringRef getSourceRangeAsString(const ASTContext &Context, SourceRange R);
+
 } // namespace create_fix_it
 } // utils
 } // namespace tidy
Index: clang-tidy/utils/FixItHintUtils.cpp
===
--- clang-tidy/utils/FixItHintUtils.cpp
+++ clang-tidy/utils/FixItHintUtils.cpp
@@ -30,6 +30,21 @@
   return FixItHint::CreateInsertion(Var.getTypeSpecStartLoc(), "const ");
 }
 
+StringRef getSourceRangeAsString(const ASTContext &Context, SourceRange R) {
+  const SourceManager &SM = Context.getSourceManager();
+  // Don't even try to resolve macro or include contraptions. Not worth emitting
+  // a fixit for.
+  if (R.getBegin().isMacroID() ||
+  !SM.isWrittenInSameFile(R.getBegin(), R.getEnd()))
+return StringRef();
+
+  const char *Begin = SM.getCharacterData(R.getBegin());
+  const char *End = SM.getCharacterData(
+  Lexer::getLocForEndOfToken(R.getEnd(), 0, SM, Context.getLangOpts()));
+
+  return StringRef(Begin, End - Begin);
+}
+
 } // namespace create_fix_it
 } // namespace utils
 } // namespace tidy
Index: clang-tidy/misc/SwappedArgumentsCheck.cpp
===
--- clang-tidy/misc/SwappedArgumentsCheck.cpp
+++ clang-tidy/misc/SwappedArgumentsCheck.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include "SwappedArgumentsCheck.h"
+#include "../utils/FixItHintUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -46,24 +47,8 @@
  Cast->getCastKind() == CK_PointerToBoolean;
 }
 
-/// \brief Get a StringRef representing a SourceRange.
-static StringRef getAsString(const MatchFinder::MatchResult &Result,
- SourceRange R) {
-  const SourceManager &SM = *Result.SourceManager;
-  // Don't even try to resolve macro or include contraptions. Not worth emitting
-  // a fixit for.
-  if (R.getBegin().isMacroID() ||
-  !SM.isWrittenInSameFile(R.getBegin(), R.getEnd()))
-return StringRef();
-
-  const char *Begin = SM.getCharacterData(R.getBegin());
-  const char *End = SM.getCharacterData(Lexer::getLocForEndOfToken(
-  R.getEnd(), 0, SM, Result.Context->getLangOpts()));
-
-  return StringRef(Begin, End - Begin);
-}
-
 void SwappedArgumentsCheck::check(const MatchFinder::MatchResult &Result) {
+  const ASTContext &Ctx = *Result.Context;
   auto *Call = Result.Nodes.getStmtAs("call");
 
   llvm::SmallPtrSet UsedArgs;
@@ -108,8 +93,10 @@
 << LHS->getType() << LHSFrom->getType() << RHS->getType()
 << RHSFrom->getType() << LHSRange << RHSRange;
 
-StringRef RHSString = getAsString(Result, RHSRange);
-StringRef LHSString = getAsString(Result, LHSRange);
+StringRef RHSString =
+utils::create_fix_it::getSourceRangeAsString(Ctx, RHSRange);
+StringRef LHSString =
+utils::create_fix_it::getSourceRangeAsString(Ctx, LHSRange);
 if (!LHSString.empty() && !RHSString.empty()) {
   D << FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(LHSRange), RHSString)
Index: clang-tidy/misc/StringConstructorCheck.cpp
==

[PATCH] D19577: [clang-tidy] Enhance misc-suspicious-string-compare by matching string.compare

2016-04-26 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added a reviewer: alexfh.
etienneb added a subscriber: cfe-commits.

This patch added the support for method "compare" on string-like classes.

The LLVM stringRef is supported. The checker assume that StringRef is returning 
-1, 0 or 1.
Which is not the case for other functions returning <0, 0 or >0.

http://reviews.llvm.org/D19577

Files:
  clang-tidy/misc/SuspiciousStringCompareCheck.cpp
  test/clang-tidy/misc-suspicious-string-compare.cpp

Index: test/clang-tidy/misc-suspicious-string-compare.cpp
===
--- test/clang-tidy/misc-suspicious-string-compare.cpp
+++ test/clang-tidy/misc-suspicious-string-compare.cpp
@@ -6,6 +6,34 @@
 
 typedef __SIZE_TYPE__ size;
 
+namespace std {
+template 
+class allocator {};
+template 
+class char_traits {};
+template 
+struct basic_string {
+  typedef basic_string _Type;
+  basic_string();
+  basic_string(const C *p, const A &a = A());
+
+  int compare(const C* s) const;
+};
+
+typedef basic_string, std::allocator > string;
+typedef basic_string, std::allocator > wstring;
+}
+
+namespace llvm {
+struct StringRef {
+  StringRef();
+  StringRef(const char*);
+  int compare(StringRef RHS);
+  int compare_lower(StringRef RHS);
+  int compare_numeric(StringRef RHS);
+};
+}
+
 struct locale_t {
   void* dummy;
 } locale;
@@ -335,3 +363,56 @@
 
   return 1;
 }
+
+int test_string_patterns() {
+  std::string str;
+  if (str.compare("a"))
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is called without explicitly comparing result
+  // CHECK-FIXES: if (str.compare("a") != 0)
+
+  if (str.compare("a") == 0 ||
+  str.compare("b"))
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is called without explicitly comparing result
+  // CHECK-FIXES: str.compare("b") != 0)
+
+  if (str.compare("a") == 1)
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is compared to a suspicious constant
+
+  if (str.compare("a") == 2)
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is compared to a suspicious constant
+}
+
+int test_llvm_patterns() {
+  llvm::StringRef str;
+  if (str.compare("a"))
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is called without explicitly comparing result
+  // CHECK-FIXES: if (str.compare("a") != 0)
+
+  if (str.compare_lower("a"))
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare_lower' is called without explicitly comparing result
+  // CHECK-FIXES: if (str.compare_lower("a") != 0)   
+
+  if (str.compare("a") == 0 ||
+  str.compare("b"))
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is called without explicitly comparing result
+  // CHECK-FIXES: str.compare("b") != 0)
+ 
+  if (str.compare("a") == 2)
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is compared to a suspicious constant
+
+  // The following calls are valid.
+  if (str.compare("a") == 1) return 0;
+  if (str.compare("a") != 1) return 0;
+  if (str.compare("a") == 0) return 0;
+  if (str.compare("a") != 0) return 0;
+  if (str.compare("a") == -1) return 0;
+  if (str.compare("a") != -1) return 0;
+}
Index: clang-tidy/misc/SuspiciousStringCompareCheck.cpp
===
--- clang-tidy/misc/SuspiciousStringCompareCheck.cpp
+++ clang-tidy/misc/SuspiciousStringCompareCheck.cpp
@@ -8,10 +8,10 @@
 //===--===//
 
 #include "SuspiciousStringCompareCheck.h"
+#include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
-#include "../utils/Matchers.h"
 
 using namespace clang::ast_matchers;
 
@@ -106,20 +106,37 @@
   ParseFunctionNames(KnownStringCompareFunctions, &FunctionNames);
   ParseFunctionNames(StringCompareLikeFunctions, &FunctionNames);
 
-  // Match a call to a string compare functions.
+  // Match a std::string::compare call.
+  const auto StdStringCompareCallExpr =
+  cxxMemberCallExpr(callee(cxxMethodDecl(ofClass(hasName("basic_string")),
+ hasName("compare"))
+   .bind("decl")))
+  .bind("call");
+
+  // Match llvm strings variants.
+  const auto LLVMStringCompareCallExpr =
+  cxxMemberCallExpr(
+  callee(cxxMethodDecl(hasAnyName("::llvm::StringRef::compare",
+  "::llvm::StringRef::compare_lower",
+  "::llvm::StringRef::compare_numeric"))
+ .bind("decl")))
+  .bind("call");
+
+  // Match a call to a string compare functions (i.e. strcmp).
   const auto FunctionCompareDecl =
   functionDecl(hasAnyName(std::vector(FunctionNames.begin(

Re: [PATCH] D19577: [clang-tidy] Enhance misc-suspicious-string-compare by matching string.compare

2016-04-27 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 55240.
etienneb marked an inline comment as done.
etienneb added a comment.

address alexfh comments, add a macro FP.


http://reviews.llvm.org/D19577

Files:
  clang-tidy/misc/SuspiciousStringCompareCheck.cpp
  test/clang-tidy/misc-suspicious-string-compare.cpp

Index: test/clang-tidy/misc-suspicious-string-compare.cpp
===
--- test/clang-tidy/misc-suspicious-string-compare.cpp
+++ test/clang-tidy/misc-suspicious-string-compare.cpp
@@ -6,6 +6,32 @@
 
 typedef __SIZE_TYPE__ size;
 
+namespace std {
+template 
+class allocator {};
+template 
+class char_traits {};
+template 
+struct basic_string {
+  typedef basic_string _Type;
+  basic_string();
+  basic_string(const C *p, const A &a = A());
+  int compare(const C* s) const;
+};
+
+typedef basic_string, std::allocator > string;
+}
+
+namespace llvm {
+struct StringRef {
+  StringRef();
+  StringRef(const char*);
+  int compare(StringRef RHS);
+  int compare_lower(StringRef RHS);
+  int compare_numeric(StringRef RHS);
+};
+}
+
 struct locale_t {
   void* dummy;
 } locale;
@@ -335,3 +361,82 @@
 
   return 1;
 }
+
+#define uprv_checkValidMemory(a, b) ((void)(a))
+#define uprv_strncmp(s1, s2, n) ( \
+uprv_checkValidMemory(s1, 1), \
+uprv_checkValidMemory(s2, 1), \
+strncmp(s1, s2, n))
+
+int strncmp_macro_uprv(const char* a, const char* b) {
+  if (uprv_strncmp(a, b, 4))
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncmp' is called without explicitly comparing result
+
+  if (uprv_strncmp(a, b, 4) == 2)
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncmp' is compared to a suspicious constant
+
+  if (uprv_strncmp(a, b, 4) <= .0)
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncmp' has suspicious implicit cast
+
+  if (uprv_strncmp(a, b, 4) + 0)
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: results of function 'strncmp' used by operator '+'
+
+  return 1;
+}
+
+int test_string_patterns() {
+  std::string str;
+  if (str.compare("a"))
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is called without explicitly comparing result
+  // CHECK-FIXES: if (str.compare("a") != 0)
+
+  if (str.compare("a") == 0 ||
+  str.compare("b"))
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is called without explicitly comparing result
+  // CHECK-FIXES: str.compare("b") != 0)
+
+  if (str.compare("a") == 1)
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is compared to a suspicious constant
+
+  if (str.compare("a") == 2)
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is compared to a suspicious constant
+}
+
+int test_llvm_patterns() {
+  llvm::StringRef str;
+  if (str.compare("a"))
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is called without explicitly comparing result
+  // CHECK-FIXES: if (str.compare("a") != 0)
+
+  if (str.compare_lower("a"))
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare_lower' is called without explicitly comparing result
+  // CHECK-FIXES: if (str.compare_lower("a") != 0)   
+
+  if (str.compare("a") == 0 ||
+  str.compare("b"))
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is called without explicitly comparing result
+  // CHECK-FIXES: str.compare("b") != 0)
+ 
+  if (str.compare("a") == 2)
+return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'compare' is compared to a suspicious constant
+
+  // The following calls are valid.
+  if (str.compare("a") == 1) return 0;
+  if (str.compare("a") != 1) return 0;
+  if (str.compare("a") == 0) return 0;
+  if (str.compare("a") != 0) return 0;
+  if (str.compare("a") == -1) return 0;
+  if (str.compare("a") != -1) return 0;
+}
Index: clang-tidy/misc/SuspiciousStringCompareCheck.cpp
===
--- clang-tidy/misc/SuspiciousStringCompareCheck.cpp
+++ clang-tidy/misc/SuspiciousStringCompareCheck.cpp
@@ -8,10 +8,10 @@
 //===--===//
 
 #include "SuspiciousStringCompareCheck.h"
+#include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
-#include "../utils/Matchers.h"
 
 using namespace clang::ast_matchers;
 
@@ -106,20 +106,43 @@
   ParseFunctionNames(KnownStringCompareFunctions, &FunctionNames);
   ParseFunctionNames(StringCompareLikeFunctions, &FunctionNames);
 
-  // Match a call to a string compare functions.
+  // Match a std::string::compare call.
+  const auto StdStringCompareCallExpr =
+  cxxMemberCallExpr(callee(cxxMethodDecl(ofClass(hasName("basic_string")),
+ hasName("compare"))
+ 

Re: [PATCH] D19577: [clang-tidy] Enhance misc-suspicious-string-compare by matching string.compare

2016-04-27 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

In http://reviews.llvm.org/D19577#413526, @alexfh wrote:

> I'm somewhat reluctant to add LLVM-specific checks to misc-. I would prefer 
> either to split the LLVM-specific part to a separate check in llvm/ (which 
> might derive from this check or somehow reuse the logic) or make the check 
> configurable enough so that these checks can be enabled for LLVM in the 
> config file.


How should we solve adding other code base to checkers.
It will be common to have these code base: chromium, llvm, boost, stl.

Should we use the local/global to configure them?


http://reviews.llvm.org/D19577



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


Re: [PATCH] D19547: [clang-tidy] Add FixIt for swapping arguments in string-constructor-checker.

2016-04-27 Thread Etienne Bergeron via cfe-commits
etienneb added inline comments.


Comment at: clang-tidy/misc/StringConstructorCheck.cpp:110
@@ -106,2 +109,3 @@
   if (Result.Nodes.getNodeAs("swapped-parameter")) {
-diag(Loc, "constructor parameters are probably swapped");
+assert(E->getNumArgs() == 2 && "Invalid number of arguments");
+auto D = diag(Loc, "constructor parameters are probably swapped");

alexfh wrote:
> Assertions should verify logical bugs in the code, not some properties of the 
> user input. The matcher doesn't seem to ensure that the argument count is 
> always 2, so it's possible to create code that will trigger this assertion. 
> Either add `argumentCountIs(2)` to the matcher or remove the assertion.
As I get it, it's not needed to add ' argumentCountIs(2)' because:

  hasArgument(0, hasType(CharPtrType)),
  hasArgument(1, hasType(isInteger())),

the code already validates that there is at least two parameters.
The assert would fail if there is more parameters, which can occur only on a 
incorrect definition of the constructor.

So, I'm i favor to just remove the assert.


http://reviews.llvm.org/D19547



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


Re: [PATCH] D19547: [clang-tidy] Add FixIt for swapping arguments in string-constructor-checker.

2016-04-27 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 55242.
etienneb added a comment.

address alexfh comments.


http://reviews.llvm.org/D19547

Files:
  clang-tidy/misc/StringConstructorCheck.cpp
  clang-tidy/misc/SwappedArgumentsCheck.cpp
  clang-tidy/utils/FixItHintUtils.cpp
  clang-tidy/utils/FixItHintUtils.h
  test/clang-tidy/misc-string-constructor.cpp

Index: test/clang-tidy/misc-string-constructor.cpp
===
--- test/clang-tidy/misc-string-constructor.cpp
+++ test/clang-tidy/misc-string-constructor.cpp
@@ -22,8 +22,10 @@
 void Test() {
   std::string str('x', 4);
   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor parameters are probably swapped [misc-string-constructor]
+  // CHECK-FIXES: std::string str(4, 'x');  
   std::wstring wstr(L'x', 4);
   // CHECK-MESSAGES: [[@LINE-1]]:16: warning: constructor parameters are probably swapped
+  // CHECK-FIXES: std::wstring wstr(4, L'x');
   std::string s0(0, 'x');
   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
   std::string s1(-4, 'x');
Index: clang-tidy/utils/FixItHintUtils.h
===
--- clang-tidy/utils/FixItHintUtils.h
+++ clang-tidy/utils/FixItHintUtils.h
@@ -24,6 +24,9 @@
 /// \brief Creates fix to make VarDecl const qualified.
 FixItHint changeVarDeclToConst(const VarDecl &Var);
 
+/// \brief Get a StringRef representing a SourceRange.
+StringRef getSourceRangeAsString(const ASTContext &Context, SourceRange R);
+
 } // namespace create_fix_it
 } // utils
 } // namespace tidy
Index: clang-tidy/utils/FixItHintUtils.cpp
===
--- clang-tidy/utils/FixItHintUtils.cpp
+++ clang-tidy/utils/FixItHintUtils.cpp
@@ -30,6 +30,21 @@
   return FixItHint::CreateInsertion(Var.getTypeSpecStartLoc(), "const ");
 }
 
+StringRef getSourceRangeAsString(const ASTContext &Context, SourceRange R) {
+  const SourceManager &SM = Context.getSourceManager();
+  // Don't even try to resolve macro or include contraptions. Not worth emitting
+  // a fixit for.
+  if (R.getBegin().isMacroID() ||
+  !SM.isWrittenInSameFile(R.getBegin(), R.getEnd()))
+return StringRef();
+
+  const char *Begin = SM.getCharacterData(R.getBegin());
+  const char *End = SM.getCharacterData(
+  Lexer::getLocForEndOfToken(R.getEnd(), 0, SM, Context.getLangOpts()));
+
+  return StringRef(Begin, End - Begin);
+}
+
 } // namespace create_fix_it
 } // namespace utils
 } // namespace tidy
Index: clang-tidy/misc/SwappedArgumentsCheck.cpp
===
--- clang-tidy/misc/SwappedArgumentsCheck.cpp
+++ clang-tidy/misc/SwappedArgumentsCheck.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include "SwappedArgumentsCheck.h"
+#include "../utils/FixItHintUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -46,24 +47,8 @@
  Cast->getCastKind() == CK_PointerToBoolean;
 }
 
-/// \brief Get a StringRef representing a SourceRange.
-static StringRef getAsString(const MatchFinder::MatchResult &Result,
- SourceRange R) {
-  const SourceManager &SM = *Result.SourceManager;
-  // Don't even try to resolve macro or include contraptions. Not worth emitting
-  // a fixit for.
-  if (R.getBegin().isMacroID() ||
-  !SM.isWrittenInSameFile(R.getBegin(), R.getEnd()))
-return StringRef();
-
-  const char *Begin = SM.getCharacterData(R.getBegin());
-  const char *End = SM.getCharacterData(Lexer::getLocForEndOfToken(
-  R.getEnd(), 0, SM, Result.Context->getLangOpts()));
-
-  return StringRef(Begin, End - Begin);
-}
-
 void SwappedArgumentsCheck::check(const MatchFinder::MatchResult &Result) {
+  const ASTContext &Ctx = *Result.Context;
   auto *Call = Result.Nodes.getStmtAs("call");
 
   llvm::SmallPtrSet UsedArgs;
@@ -108,8 +93,10 @@
 << LHS->getType() << LHSFrom->getType() << RHS->getType()
 << RHSFrom->getType() << LHSRange << RHSRange;
 
-StringRef RHSString = getAsString(Result, RHSRange);
-StringRef LHSString = getAsString(Result, LHSRange);
+StringRef RHSString =
+utils::create_fix_it::getSourceRangeAsString(Ctx, RHSRange);
+StringRef LHSString =
+utils::create_fix_it::getSourceRangeAsString(Ctx, LHSRange);
 if (!LHSString.empty() && !RHSString.empty()) {
   D << FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(LHSRange), RHSString)
Index: clang-tidy/misc/StringConstructorCheck.cpp
===
--- clang-tidy/misc/StringConstructorCheck.cpp
+++ clang-tidy/misc/StringConstructorCheck.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include "StringConstructorCheck.h"
+#include "../utils/FixItHint

[PATCH] D19703: [clang-tidy] Improve misc-redundant-expression and decrease false-positive

2016-04-28 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added a reviewer: alexfh.
etienneb added a subscriber: cfe-commits.

This patch is adding support for conditional expression and overloaded 
operators.

To decrease false-positive, this patch is adding a list of banned macro names 
that
has multiple variant with same integer value.

Also fixed support for template instantiation and added an unittest.

http://reviews.llvm.org/D19703

Files:
  clang-tidy/misc/RedundantExpressionCheck.cpp
  docs/clang-tidy/checks/misc-redundant-expression.rst
  test/clang-tidy/misc-redundant-expression.cpp

Index: test/clang-tidy/misc-redundant-expression.cpp
===
--- test/clang-tidy/misc-redundant-expression.cpp
+++ test/clang-tidy/misc-redundant-expression.cpp
@@ -68,14 +68,14 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both side of operator are equivalent
 
   if (foo(0) - 2 < foo(0) - 2) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent
   if (foo(bar(0)) < (foo(bar((0) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
 
   if (P1.x < P2.x && P1.x < P2.x) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
   if (P2.a[P1.x + 2] < P2.x && P2.a[(P1.x) + (2)] < (P2.x)) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent
 
   return 0;
 }
@@ -118,3 +118,22 @@
   if (F != F && F == F) return 1;
   return 0;
 }
+
+int TestBannedMacros() {
+#define EAGAIN 3
+#define NOT_EAGAIN 3
+  if (EAGAIN == 0 | EAGAIN == 0) return 0;
+  if (NOT_EAGAIN == 0 | NOT_EAGAIN == 0) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both side of operator are equivalent
+}
+
+struct MyClass {
+static const int Value = 42;
+};
+template 
+void TemplateCheck() {
+  static_assert(T::Value == U::Value, "should be identical");
+  static_assert(T::Value == T::Value, "should be identical");
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both side of operator are equivalent
+}
+void TestTemplate() { TemplateCheck(); }
Index: docs/clang-tidy/checks/misc-redundant-expression.rst
===
--- docs/clang-tidy/checks/misc-redundant-expression.rst
+++ docs/clang-tidy/checks/misc-redundant-expression.rst
@@ -12,6 +12,7 @@
   * always be a constant (zero or one)
 
 Example:
+
 .. code:: c++
 
   ((x+1) | (x+1)) // (x+1) is redundant
Index: clang-tidy/misc/RedundantExpressionCheck.cpp
===
--- clang-tidy/misc/RedundantExpressionCheck.cpp
+++ clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -11,14 +11,39 @@
 #include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
 
 using namespace clang::ast_matchers;
 
 namespace clang {
 namespace tidy {
 namespace misc {
 
-static bool AreIdenticalExpr(const Expr *Left, const Expr *Right) {
+static const char KnownBannedMacroNames[] =
+"EAGAIN;EWOULDBLOCK;SIGCLD;SIGCHLD;";
+
+static const char MacroNamesDelimiter[] = ";";
+
+static void ParseMacroNames(StringRef Option,
+std::vector *Result) {
+  SmallVector Names;
+  Option.split(Names, MacroNamesDelimiter);
+  for (StringRef &Name : Names) {
+Name = Name.trim();
+if (!Name.empty())
+  Result->push_back(Name);
+  }
+}
+
+static bool AreEquivalentNameSpecifier(const NestedNameSpecifier *Left,
+   NestedNameSpecifier *Right) {
+  llvm::FoldingSetNodeID LeftID, RightID;
+  Left->Profile(LeftID);
+  Right->Profile(RightID);
+  return LeftID == RightID;
+}
+
+static bool AreEquivalentExpr(const Expr *Left, const Expr *Right) {
   if (!Left || !Right)
 return !Left && !Right;
 
@@ -33,8 +58,8 @@
   Expr::const_child_iterator LeftIter = Left->child_begin();
   Expr::const_child_iterator RightIter = Right->child_begin();
   while (LeftIter != Left->child_end() && RightIter != Right->child_end()) {
-if (!AreIdenticalExpr(dyn_cast(*LeftIter),
-  dyn_cast(*RightIter)))
+if (!AreEquivalentExpr(dyn_cast(*LeftIter),
+   dyn_cast(*RightIter)))
   return false;
 ++LeftIter;
 ++RightIter;
@@ -53,15 +78,23 @@
   case Stmt::IntegerLiteralClass: {
 llvm::APInt LeftLit = cast(Left)->getValue();
 llvm::APInt RightLit = cast(Right)->getValue();
-return LeftLit.getBitWidth() == RightLit.getBitWidth() && LeftLit == RightLit;
+return LeftL

Re: [PATCH] D19703: [clang-tidy] Improve misc-redundant-expression and decrease false-positive

2016-04-28 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 55514.
etienneb added a comment.

nit


http://reviews.llvm.org/D19703

Files:
  clang-tidy/misc/RedundantExpressionCheck.cpp
  docs/clang-tidy/checks/misc-redundant-expression.rst
  test/clang-tidy/misc-redundant-expression.cpp

Index: test/clang-tidy/misc-redundant-expression.cpp
===
--- test/clang-tidy/misc-redundant-expression.cpp
+++ test/clang-tidy/misc-redundant-expression.cpp
@@ -68,14 +68,14 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both side of operator are equivalent
 
   if (foo(0) - 2 < foo(0) - 2) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent
   if (foo(bar(0)) < (foo(bar((0) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
 
   if (P1.x < P2.x && P1.x < P2.x) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
   if (P2.a[P1.x + 2] < P2.x && P2.a[(P1.x) + (2)] < (P2.x)) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent
 
   return 0;
 }
@@ -118,3 +118,22 @@
   if (F != F && F == F) return 1;
   return 0;
 }
+
+int TestBannedMacros() {
+#define EAGAIN 3
+#define NOT_EAGAIN 3
+  if (EAGAIN == 0 | EAGAIN == 0) return 0;
+  if (NOT_EAGAIN == 0 | NOT_EAGAIN == 0) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both side of operator are equivalent
+}
+
+struct MyClass {
+static const int Value = 42;
+};
+template 
+void TemplateCheck() {
+  static_assert(T::Value == U::Value, "should be identical");
+  static_assert(T::Value == T::Value, "should be identical");
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both side of operator are equivalent
+}
+void TestTemplate() { TemplateCheck(); }
Index: docs/clang-tidy/checks/misc-redundant-expression.rst
===
--- docs/clang-tidy/checks/misc-redundant-expression.rst
+++ docs/clang-tidy/checks/misc-redundant-expression.rst
@@ -12,6 +12,7 @@
   * always be a constant (zero or one)
 
 Example:
+
 .. code:: c++
 
   ((x+1) | (x+1)) // (x+1) is redundant
Index: clang-tidy/misc/RedundantExpressionCheck.cpp
===
--- clang-tidy/misc/RedundantExpressionCheck.cpp
+++ clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -11,14 +11,39 @@
 #include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
 
 using namespace clang::ast_matchers;
 
 namespace clang {
 namespace tidy {
 namespace misc {
 
-static bool AreIdenticalExpr(const Expr *Left, const Expr *Right) {
+static const char KnownBannedMacroNames[] =
+"EAGAIN;EWOULDBLOCK;SIGCLD;SIGCHLD;";
+
+static const char MacroNamesDelimiter[] = ";";
+
+static void ParseMacroNames(StringRef Option,
+std::vector *Result) {
+  SmallVector Names;
+  Option.split(Names, MacroNamesDelimiter);
+  for (StringRef &Name : Names) {
+Name = Name.trim();
+if (!Name.empty())
+  Result->push_back(Name);
+  }
+}
+
+static bool AreEquivalentNameSpecifier(const NestedNameSpecifier *Left,
+   const NestedNameSpecifier *Right) {
+  llvm::FoldingSetNodeID LeftID, RightID;
+  Left->Profile(LeftID);
+  Right->Profile(RightID);
+  return LeftID == RightID;
+}
+
+static bool AreEquivalentExpr(const Expr *Left, const Expr *Right) {
   if (!Left || !Right)
 return !Left && !Right;
 
@@ -33,8 +58,8 @@
   Expr::const_child_iterator LeftIter = Left->child_begin();
   Expr::const_child_iterator RightIter = Right->child_begin();
   while (LeftIter != Left->child_end() && RightIter != Right->child_end()) {
-if (!AreIdenticalExpr(dyn_cast(*LeftIter),
-  dyn_cast(*RightIter)))
+if (!AreEquivalentExpr(dyn_cast(*LeftIter),
+   dyn_cast(*RightIter)))
   return false;
 ++LeftIter;
 ++RightIter;
@@ -53,15 +78,23 @@
   case Stmt::IntegerLiteralClass: {
 llvm::APInt LeftLit = cast(Left)->getValue();
 llvm::APInt RightLit = cast(Right)->getValue();
-return LeftLit.getBitWidth() == RightLit.getBitWidth() && LeftLit == RightLit;
+return LeftLit.getBitWidth() == RightLit.getBitWidth() &&
+   LeftLit == RightLit;
   }
   case Stmt::FloatingLiteralClass:
 return cast(Left)->getValue().bitwiseIsEqual(
 cast(Right)->getValue());
   case Stmt::StringLiteralClass:
 return cast(Left)->getBytes() ==
cast(Right)->getByte

Re: [PATCH] D19703: [clang-tidy] Improve misc-redundant-expression and decrease false-positive

2016-04-28 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 55526.
etienneb added a comment.

adding unittests


http://reviews.llvm.org/D19703

Files:
  clang-tidy/misc/RedundantExpressionCheck.cpp
  docs/clang-tidy/checks/misc-redundant-expression.rst
  test/clang-tidy/misc-redundant-expression.cpp

Index: test/clang-tidy/misc-redundant-expression.cpp
===
--- test/clang-tidy/misc-redundant-expression.cpp
+++ test/clang-tidy/misc-redundant-expression.cpp
@@ -68,14 +68,14 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both side of operator are equivalent
 
   if (foo(0) - 2 < foo(0) - 2) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent
   if (foo(bar(0)) < (foo(bar((0) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
 
   if (P1.x < P2.x && P1.x < P2.x) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
   if (P2.a[P1.x + 2] < P2.x && P2.a[(P1.x) + (2)] < (P2.x)) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent
 
   return 0;
 }
@@ -100,13 +100,36 @@
   return 0;
 }
 
+int TestConditional(int x, int y) {
+  int k = 0;
+  k += (y < 0) ? x : x;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'true' and 'false' expression are equivalent
+  k += (y < 0) ? x + 1 : x + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'true' and 'false' expression are equivalent
+  return k;
+}
+
+struct MyStruct {
+  int x;
+} Q;
+bool operator==(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x == rhs.x; }
+bool TestOperator(const MyStruct& S) {
+  if (S == Q) return false;
+  return S == S;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: both side of overloaded operator are equivalent
+}
+
 #define LT(x, y) (void)((x) < (y))
+#define COND(x, y, z) ((x)?(y):(z))
+#define EQUALS(x, y) (x) == (y)
 
 int TestMacro(int X, int Y) {
   LT(0, 0);
   LT(1, 0);
   LT(X, X);
   LT(X+1, X + 1);
+  COND(X < Y, X, X);
+  EQUALS(Q, Q);
 }
 
 int TestFalsePositive(int* A, int X, float F) {
@@ -118,3 +141,22 @@
   if (F != F && F == F) return 1;
   return 0;
 }
+
+int TestBannedMacros() {
+#define EAGAIN 3
+#define NOT_EAGAIN 3
+  if (EAGAIN == 0 | EAGAIN == 0) return 0;
+  if (NOT_EAGAIN == 0 | NOT_EAGAIN == 0) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both side of operator are equivalent
+}
+
+struct MyClass {
+static const int Value = 42;
+};
+template 
+void TemplateCheck() {
+  static_assert(T::Value == U::Value, "should be identical");
+  static_assert(T::Value == T::Value, "should be identical");
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both side of overloaded operator are equivalent
+}
+void TestTemplate() { TemplateCheck(); }
Index: docs/clang-tidy/checks/misc-redundant-expression.rst
===
--- docs/clang-tidy/checks/misc-redundant-expression.rst
+++ docs/clang-tidy/checks/misc-redundant-expression.rst
@@ -12,6 +12,7 @@
   * always be a constant (zero or one)
 
 Example:
+
 .. code:: c++
 
   ((x+1) | (x+1)) // (x+1) is redundant
Index: clang-tidy/misc/RedundantExpressionCheck.cpp
===
--- clang-tidy/misc/RedundantExpressionCheck.cpp
+++ clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -11,14 +11,39 @@
 #include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
 
 using namespace clang::ast_matchers;
 
 namespace clang {
 namespace tidy {
 namespace misc {
 
-static bool AreIdenticalExpr(const Expr *Left, const Expr *Right) {
+static const char KnownBannedMacroNames[] =
+"EAGAIN;EWOULDBLOCK;SIGCLD;SIGCHLD;";
+
+static const char MacroNamesDelimiter[] = ";";
+
+static void ParseMacroNames(StringRef Option,
+std::vector *Result) {
+  SmallVector Names;
+  Option.split(Names, MacroNamesDelimiter);
+  for (StringRef &Name : Names) {
+Name = Name.trim();
+if (!Name.empty())
+  Result->push_back(Name);
+  }
+}
+
+static bool AreEquivalentNameSpecifier(const NestedNameSpecifier *Left,
+   const NestedNameSpecifier *Right) {
+  llvm::FoldingSetNodeID LeftID, RightID;
+  Left->Profile(LeftID);
+  Right->Profile(RightID);
+  return LeftID == RightID;
+}
+
+static bool AreEquivalentExpr(const Expr *Left, const Expr *Right) {
   if (!Left || !Right)
 return !Left && !Right;
 
@@ -33,8 +58,8 @@
   Expr::const_child_iterator LeftIter = Left->child_b

Re: [PATCH] D19586: Misleading Indentation check

2016-04-29 Thread Etienne Bergeron via cfe-commits
etienneb requested changes to this revision.
etienneb added a comment.
This revision now requires changes to proceed.

Could you lift some logics to the matcher instead of the check.



Comment at: clang-tidy/readability/MisleadingIndentationCheck.cpp:22
@@ +21,3 @@
+const MatchFinder::MatchResult &Result) {
+  auto *If = Result.Nodes.getNodeAs("if");
+  if (!If->getElse())

nit: const


Comment at: clang-tidy/readability/MisleadingIndentationCheck.cpp:40
@@ +39,3 @@
+const MatchFinder::MatchResult &Result) {
+  auto *CStmt = Result.Nodes.getNodeAs("stmt");
+  for (unsigned int i = 0; i < CStmt->size() - 1; i++) {

nit: const


Comment at: clang-tidy/readability/MisleadingIndentationCheck.cpp:67
@@ +66,3 @@
+  diag(NextLoc, "Wrong Indentation - statement is indented as a member "
+"of if statement");
+  }

of if statement  -> previous if statement


Comment at: clang-tidy/readability/MisleadingIndentationCheck.cpp:72
@@ +71,3 @@
+void MisleadingIndentationCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(ifStmt().bind("if"), this);
+  Finder->addMatcher(compoundStmt(has(ifStmt())).bind("stmt"), this);

instead of doing check at line 23:
```
   if (!If->getElse())
```

you should use 'hasElse' matcher here.

As I get it, you want to match something like:

```
anyOf(
  ifStatement(hasThen(stmt().bind("last")),
 hasElse(unless(compoundStmt())),
  ifStatement(hasThen(unless(compoundStmt())),
 unless(hasElse(stmt().bind("last")))
)
```

Then, by getting node named "last" you can retrieve the indentation of the last 
statement.




Comment at: clang-tidy/readability/MisleadingIndentationCheck.cpp:77
@@ +76,3 @@
+void MisleadingIndentationCheck::check(const MatchFinder::MatchResult &Result) 
{
+
+  if (Result.Nodes.getNodeAs("if"))

nit: remove empty line


Comment at: clang-tidy/readability/MisleadingIndentationCheck.h:30
@@ +29,3 @@
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void danglingElseCheck(const ast_matchers::MatchFinder::MatchResult &Result);
+  void missingBracesCheck(const ast_matchers::MatchFinder::MatchResult 
&Result);

nit: private


Comment at: docs/clang-tidy/checks/readability-misleading-indentation.rst:8
@@ +7,3 @@
+
+Correct indentation helps to understand code. Mismatch of the syntactical 
structure and the indentation of the code may reveal serious pr
+

could you fix these long lines.


Comment at: test/clang-tidy/readability-misleading-indentation.cpp:62
@@ +61,2 @@
+   return 0;
+}

I would like to see more tests with { }

```
if (xxx) {
} else {
}
```

```
if (xxx) {
}
else {
}
```

```
if (xxx)
{
}
else
{
}
```

```
if (xxx)
  {
  }
else
  {
  }
```


Comment at: test/clang-tidy/readability-misleading-indentation.cpp:62
@@ +61,2 @@
+   return 0;
+}

etienneb wrote:
> I would like to see more tests with { }
> 
> ```
> if (xxx) {
> } else {
> }
> ```
> 
> ```
> if (xxx) {
> }
> else {
> }
> ```
> 
> ```
> if (xxx)
> {
> }
> else
> {
> }
> ```
> 
> ```
> if (xxx)
>   {
>   }
> else
>   {
>   }
> ```
could you add test with macro:

```
#define BLOCK
  if (xxx)\
stm1();  \
stm2();
```


http://reviews.llvm.org/D19586



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


Re: [PATCH] D19586: Misleading Indentation check

2016-04-29 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

You should not limit the checker to "if".
The for-statement and while-statement are also wrong for the same reasons:

  while (x)
statement1();
statement2();



  for (...)
statement1();
statement2();

You should test your code over large code base.
You should catch these cases:
https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/frame/FrameView.cpp&q=setMediaType&sq=package:chromium&type=cs&l=1253

You will also find strange cases like:
https://code.google.com/p/chromium/codesearch#chromium/src/third_party/icu/source/i18n/usearch.cpp&q=initializepattern&sq=package:chromium&type=cs&l=438

The rule also apply for statements in a same compound:

  {
statement1();
statement2();
  statement3();

see: 
https://code.google.com/p/chromium/codesearch#chromium/src/third_party/icu/source/common/ushape.cpp&q=third_party/icu/source/common/ushape.cpp&sq=package:chromium&type=cs&l=784

But this can be a further improvement.


http://reviews.llvm.org/D19586



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


Re: [PATCH] D19586: Misleading Indentation check

2016-04-29 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

In http://reviews.llvm.org/D19586#417063, @xazax.hun wrote:

> In http://reviews.llvm.org/D19586#417053, @etienneb wrote:
>
> > The rule also apply for statements in a same compound:
> >
> >   {
> > statement1();
> > statement2();
> >   statement3();
> >
> >
> > But this can be a further improvement.
>
>
> I believe this might be an intentional omission, since this can not imply 
> semantic problems. But I agree that, this addition makes sense.


Fair enough. This checker is in 'readbility', so I don't see why not. 
But, feel free to postpone. Or let someone else take it.


http://reviews.llvm.org/D19586



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


Re: [PATCH] D19769: [clang-tidy] Add explicitly given array size heuristic to misc-suspicious-missing-comma check.

2016-04-30 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

If you are interested to a quick chat on this Checker, ping me. I know other 
cases that should be filtered and I'm lacking time to implement them. Here is a 
common one I would lie to see happening (base on comments):

  const char* A[] = {
// This is a entry
"entry1",
// This is the next entry
"entry2"
"entry2"
"entry2",
// This is the last entry
"entry2",
  };

Other common cases to append literals are:

  "Program version:"  VERSION 
  "Program version: %"  PRIu64 
  "Let add strange characters \xFF" "For nothing"  (you can't happend these two 
literals or the escaped char will be "\xFFF")



Comment at: clang-tidy/misc/SuspiciousMissingCommaCheck.cpp:92
@@ +91,3 @@
+  has(expr(ignoringImpCasts(ConcatenatedStringLiteral))),
+  hasParent(varDecl(allOf(hasType(arrayType()), isDefinition()))
+.bind("varDecl")));

The issue I see by matching the "hasParent" that way is that you are assuming 
that the matcher is only looking for initialisation-list attached to variable 
declaration (direct child).

Assume this case:
```
struct StrArray {
  int n;
  const char* list[5];
} A[2] = {
  {5, {"a", "b", "c", "d", "e" }},
  {5, {"a", "b", "c", "d", "e" }},
};
```

It is giving you this AST representation:
```
VarDecl 0x1e82738  line:6:3 A 'struct StrArray [2]' cinit
`-InitListExpr 0x1e82c38  'struct StrArray [2]'
  |-InitListExpr 0x1e82c88  'struct StrArray':'struct 
StrArray'
  | |-IntegerLiteral 0x1e827d8  'int' 5
  | `-InitListExpr 0x1e82cd8  'const char *[5]'
  |   |-ImplicitCastExpr 0x1e82d40  'const char *' 
  |   | `-StringLiteral 0x1e82878  'const char [2]' lvalue "a"
  |   |-ImplicitCastExpr 0x1e82d58  'const char *' 
  |   | `-StringLiteral 0x1e828a8  'const char [2]' lvalue "b"
  |   |-ImplicitCastExpr 0x1e82d70  'const char *' 
  |   | `-StringLiteral 0x1e828d8  'const char [2]' lvalue "c"
  |   |-ImplicitCastExpr 0x1e82d88  'const char *' 
  |   | `-StringLiteral 0x1e82908  'const char [2]' lvalue "d"
  |   `-ImplicitCastExpr 0x1e82da0  'const char *' 
  | `-StringLiteral 0x1e82938  'const char [2]' lvalue "e"
  `-InitListExpr 0x1e82db8  'struct StrArray':'struct 
StrArray'
|-IntegerLiteral 0x1e82a20  'int' 5
`-InitListExpr 0x1e82e08  'const char *[5]'
  |-ImplicitCastExpr 0x1e82e70  'const char *' 
  | `-StringLiteral 0x1e82a40  'const char [2]' lvalue "a"
  |-ImplicitCastExpr 0x1e82e88  'const char *' 
  | `-StringLiteral 0x1e82a70  'const char [2]' lvalue "b"
  |-ImplicitCastExpr 0x1e82ea0  'const char *' 
  | `-StringLiteral 0x1e82aa0  'const char [2]' lvalue "c"
  |-ImplicitCastExpr 0x1e82eb8  'const char *' 
  | `-StringLiteral 0x1e82ad0  'const char [2]' lvalue "d"
  `-ImplicitCastExpr 0x1e82ed0  'const char *' 
`-StringLiteral 0x1e82b00  'const char [2]' lvalue "e"
```

I believe this can be solved with something like:
  hasParent(anyOf(varDecl(allOf(hasType(arrayType()), isDefinition()),
  anything()))  <<-- to accept all other cases.

That way, you are adding an heuristic to filter some incorrect warnings.

I believe it's possible to match the example above as the size is part of the 
type.

If I try this example:

```
{5, {"a", "b", "c", "d"}},// only four string literal
```

I'm getting the following AST:
```
 `-InitListExpr 0x28ffd50  'struct StrArray':'struct StrArray'
|-IntegerLiteral 0x28ff9e8  'int' 5
`-InitListExpr 0x28ffda0  'const char *[5]'
  |-array filler
  | `-ImplicitValueInitExpr 0x28ffe78 <> 'const char *'
  |-ImplicitCastExpr 0x28ffde0  'const char *' 
  | `-StringLiteral 0x28ffa08  'const char [2]' lvalue "a"
  |-ImplicitCastExpr 0x28ffe00  'const char *' 
  | `-StringLiteral 0x28ffa38  'const char [2]' lvalue "b"
  |-ImplicitCastExpr 0x28ffe28  'const char *' 
  | `-StringLiteral 0x28ffa68  'const char [2]' lvalue "c"
  `-ImplicitCastExpr 0x28ffe60  'const char *' 
`-StringLiteral 0x28ffa98  'const char [2]' lvalue "d"
```

For the direct case:
```
const char* list[5] = { "a", "b"};
```

It has the following AST-representation:

```
VarDecl 0x2c67f00  col:13 list 'const char *[5]' cinit
`-InitListExpr 0x2c68010  'const char *[5]'
  |-array filler
  | `-ImplicitValueInitExpr 0x2c68098 <> 'const char *'
  |-ImplicitCastExpr 0x2c68050  'const char *' 
  | `-StringLiteral 0x2c67f60  'const char [2]' lvalue "a"
  `-ImplicitCastExpr 0x2c68070  'const char *' 
`-StringLiteral 0x2c67f90  'const char [2]' lvalue "b"
```
So, it seems the length could be taken from the type instead of the 
declaration?!
Or, look at what is the "Array Filler" (I still don't know). This may be an 
more straight forward way.




http://reviews.llvm.org/D19769



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


Re: [PATCH] D19769: [clang-tidy] Add explicitly given array size heuristic to misc-suspicious-missing-comma check.

2016-05-01 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

this is cool :)
It's a simple and precise rule to avoid using the probabilistic heuristic.



Comment at: clang-tidy/misc/SuspiciousMissingCommaCheck.cpp:94
@@ -93,3 +93,3 @@
   Finder->addMatcher(StringsInitializerList.bind("list"), this);
 }
 

If it's working as-is,... this is neat  :)


Comment at: clang-tidy/misc/SuspiciousMissingCommaCheck.cpp:106
@@ +105,3 @@
+  if (InitializerList->hasArrayFiller()) {
+  diag(InitializerList->getExprLoc(),
+   "wrong string array initialization: "

The error should still be reported to the missing comma (concatenated token):
  ConcatenatedLiteral->getLocStart(),

We could add a NOTE to point to the array, stating that the size mismatch.

What do you think?


Comment at: test/clang-tidy/misc-suspicious-missing-comma.cpp:84
@@ +83,3 @@
+
+// Missing comma or wrong explicit array size.
+const char* TheThreeMusketeers[4] = {

Could you add the more complicated example I sent you.
More tests is always welcome.

Currently, there is no tests for initialisation list in initialisation list.


http://reviews.llvm.org/D19769



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


[PATCH] D19811: [clang-tidy] Cleaning namespaces to be more consistant across checkers.

2016-05-02 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added a reviewer: alexfh.
etienneb added a subscriber: cfe-commits.

The goal of the patch is to bring checkers in their appropriate namespace.
This path doesn't change any behavior.

http://reviews.llvm.org/D19811

Files:
  clang-tidy/cert/CERTTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
  clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
  clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h
  clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h
  clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h
  clang-tidy/misc/AssertSideEffectCheck.cpp
  clang-tidy/misc/AssertSideEffectCheck.h
  clang-tidy/misc/BoolPointerImplicitConversionCheck.cpp
  clang-tidy/misc/IncorrectRoundings.cpp
  clang-tidy/misc/MacroParenthesesCheck.cpp
  clang-tidy/misc/MacroParenthesesCheck.h
  clang-tidy/misc/MoveConstantArgumentCheck.cpp
  clang-tidy/misc/MoveConstructorInitCheck.cpp
  clang-tidy/misc/MoveConstructorInitCheck.h
  clang-tidy/misc/NewDeleteOverloadsCheck.cpp
  clang-tidy/misc/NoexceptMoveConstructorCheck.cpp
  clang-tidy/misc/NoexceptMoveConstructorCheck.h
  clang-tidy/misc/NonCopyableObjects.cpp
  clang-tidy/misc/NonCopyableObjects.h
  clang-tidy/misc/SizeofContainerCheck.cpp
  clang-tidy/misc/SizeofContainerCheck.h
  clang-tidy/misc/StaticAssertCheck.cpp
  clang-tidy/misc/StaticAssertCheck.h
  clang-tidy/misc/StringIntegerAssignmentCheck.cpp
  clang-tidy/misc/StringIntegerAssignmentCheck.h
  clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
  clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h
  clang-tidy/misc/UndelegatedConstructor.cpp
  clang-tidy/misc/UnusedAliasDeclsCheck.cpp
  clang-tidy/misc/UnusedAliasDeclsCheck.h
  clang-tidy/misc/UnusedParametersCheck.cpp
  clang-tidy/misc/UnusedParametersCheck.h
  clang-tidy/misc/UnusedRAIICheck.cpp
  clang-tidy/modernize/RawStringLiteralCheck.h
  clang-tidy/modernize/RedundantVoidArgCheck.cpp
  clang-tidy/performance/ForRangeCopyCheck.cpp
  clang-tidy/performance/ImplicitCastInLoopCheck.cpp
  clang-tidy/readability/ImplicitBoolCastCheck.cpp
  clang-tidy/readability/ImplicitBoolCastCheck.h
  clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp
  clang-tidy/readability/RedundantStringCStrCheck.cpp
  clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp
  clang-tidy/readability/UniqueptrDeleteReleaseCheck.h

Index: clang-tidy/readability/UniqueptrDeleteReleaseCheck.h
===
--- clang-tidy/readability/UniqueptrDeleteReleaseCheck.h
+++ clang-tidy/readability/UniqueptrDeleteReleaseCheck.h
@@ -14,6 +14,7 @@
 
 namespace clang {
 namespace tidy {
+namespace readability {
 
 /// Flag statements of the form: delete .release()
 /// and replace them with:  = nullptr
@@ -28,6 +29,7 @@
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
 
+} // namespace readability
 } // namespace tidy
 } // namespace clang
 
Index: clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp
===
--- clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp
+++ clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp
@@ -16,6 +16,7 @@
 
 namespace clang {
 namespace tidy {
+namespace readability {
 
 void UniqueptrDeleteReleaseCheck::registerMatchers(MatchFinder *Finder) {
   auto IsSusbstituted = qualType(anyOf(
@@ -64,6 +65,7 @@
  " = nullptr");
 }
 
+} // namespace readability
 } // namespace tidy
 } // namespace clang
 
Index: clang-tidy/readability/RedundantStringCStrCheck.cpp
===
--- clang-tidy/readability/RedundantStringCStrCheck.cpp
+++ clang-tidy/readability/RedundantStringCStrCheck.cpp
@@ -14,9 +14,11 @@
 #include "RedundantStringCStrCheck.h"
 #include "clang/Lex/Lexer.h"
 
-namespace clang {
+using namespace clang::ast_matchers;
 
-using namespace ast_matchers;
+namespace clang {
+namespace tidy {
+namespace readability {
 
 namespace {
 
@@ -67,9 +69,6 @@
 
 } // end namespace
 
-namespace tidy {
-namespace readability {
-
 void RedundantStringCStrCheck::registerMatcher

[clang-tools-extra] r268264 - [clang-tidy] Cleaning namespaces to be more consistant across checkers.

2016-05-02 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Mon May  2 13:00:29 2016
New Revision: 268264

URL: http://llvm.org/viewvc/llvm-project?rev=268264&view=rev
Log:
[clang-tidy] Cleaning namespaces to be more consistant across checkers.

Summary:
The goal of the patch is to bring checkers in their appropriate namespace.
This path doesn't change any behavior.

Reviewers: alexfh

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D19811

Modified:
clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h
clang-tools-extra/trunk/clang-tidy/misc/AssertSideEffectCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/AssertSideEffectCheck.h

clang-tools-extra/trunk/clang-tidy/misc/BoolPointerImplicitConversionCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/IncorrectRoundings.cpp
clang-tools-extra/trunk/clang-tidy/misc/MacroParenthesesCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/MacroParenthesesCheck.h
clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/MoveConstructorInitCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/MoveConstructorInitCheck.h
clang-tools-extra/trunk/clang-tidy/misc/NewDeleteOverloadsCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/NoexceptMoveConstructorCheck.h
clang-tools-extra/trunk/clang-tidy/misc/NonCopyableObjects.cpp
clang-tools-extra/trunk/clang-tidy/misc/NonCopyableObjects.h
clang-tools-extra/trunk/clang-tidy/misc/SizeofContainerCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/SizeofContainerCheck.h
clang-tools-extra/trunk/clang-tidy/misc/StaticAssertCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/StaticAssertCheck.h
clang-tools-extra/trunk/clang-tidy/misc/StringIntegerAssignmentCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/StringIntegerAssignmentCheck.h

clang-tools-extra/trunk/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h
clang-tools-extra/trunk/clang-tidy/misc/UndelegatedConstructor.cpp
clang-tools-extra/trunk/clang-tidy/misc/UnusedAliasDeclsCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/UnusedAliasDeclsCheck.h
clang-tools-extra/trunk/clang-tidy/misc/UnusedParametersCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/UnusedParametersCheck.h
clang-tools-extra/trunk/clang-tidy/misc/UnusedRAIICheck.cpp
clang-tools-extra/trunk/clang-tidy/modernize/RawStringLiteralCheck.h
clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp
clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp
clang-tools-extra/trunk/clang-tidy/performance/ImplicitCastInLoopCheck.cpp
clang-tools-extra/trunk/clang-tidy/readability/ImplicitBoolCastCheck.cpp
clang-tools-extra/trunk/clang-tidy/readability/ImplicitBoolCastCheck.h

clang-tools-extra/trunk/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp
clang-tools-extra/trunk/clang-tidy/readability/RedundantStringCStrCheck.cpp

clang-tools-extra/trunk/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp
clang-tools-extra/trunk/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h

Modified: clang-tools-extra/trunk/clang-tidy/cert/CERTTidyModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-

[PATCH] D19819: [clang-tidy] Cleanup namespace in utils folder.

2016-05-02 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added a reviewer: alexfh.
etienneb added a subscriber: cfe-commits.

This is a step forward cleaning up the namespaces in clang-tidy/utils.
There is no behavior change.

http://reviews.llvm.org/D19819

Files:
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
  clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
  clang-tidy/llvm/HeaderGuardCheck.h
  clang-tidy/misc/MoveConstructorInitCheck.cpp
  clang-tidy/misc/MoveConstructorInitCheck.h
  clang-tidy/misc/SuspiciousSemicolonCheck.cpp
  clang-tidy/modernize/PassByValueCheck.cpp
  clang-tidy/modernize/PassByValueCheck.h
  clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
  clang-tidy/modernize/ReplaceAutoPtrCheck.h
  clang-tidy/performance/ForRangeCopyCheck.cpp
  clang-tidy/performance/UnnecessaryCopyInitialization.cpp
  clang-tidy/performance/UnnecessaryValueParamCheck.cpp
  clang-tidy/utils/DeclRefExprUtils.cpp
  clang-tidy/utils/DeclRefExprUtils.h
  clang-tidy/utils/FixItHintUtils.cpp
  clang-tidy/utils/FixItHintUtils.h
  clang-tidy/utils/HeaderGuard.cpp
  clang-tidy/utils/HeaderGuard.h
  clang-tidy/utils/IncludeInserter.cpp
  clang-tidy/utils/IncludeInserter.h
  clang-tidy/utils/IncludeSorter.cpp
  clang-tidy/utils/IncludeSorter.h
  clang-tidy/utils/LexerUtils.cpp
  clang-tidy/utils/LexerUtils.h

Index: clang-tidy/utils/LexerUtils.h
===
--- clang-tidy/utils/LexerUtils.h
+++ clang-tidy/utils/LexerUtils.h
@@ -15,14 +15,16 @@
 
 namespace clang {
 namespace tidy {
-namespace lexer_utils {
+namespace utils {
+namespace lexer {
 
 // Returns previous non-comment token skipping over any comment text or
 // tok::unknown if not found.
 Token getPreviousNonCommentToken(const ASTContext &Context,
  SourceLocation Location);
 
-} // namespace lexer_utils
+} // namespace lexer
+} // namespace utils
 } // namespace tidy
 } // namespace clang
 
Index: clang-tidy/utils/LexerUtils.cpp
===
--- clang-tidy/utils/LexerUtils.cpp
+++ clang-tidy/utils/LexerUtils.cpp
@@ -11,7 +11,8 @@
 
 namespace clang {
 namespace tidy {
-namespace lexer_utils {
+namespace utils {
+namespace lexer {
 
 Token getPreviousNonCommentToken(const ASTContext &Context,
  SourceLocation Location) {
@@ -34,6 +35,7 @@
   return Token;
 }
 
-} // namespace lexer_utils
+} // namespace lexer
+} // namespace utils
 } // namespace tidy
 } // namespace clang
Index: clang-tidy/utils/IncludeSorter.h
===
--- clang-tidy/utils/IncludeSorter.h
+++ clang-tidy/utils/IncludeSorter.h
@@ -15,6 +15,7 @@
 
 namespace clang {
 namespace tidy {
+namespace utils {  
 
 // Class used by IncludeSorterCallback and IncludeInserterCallback to record the
 // names of the inclusions in a given source file being processed and generate
@@ -83,6 +84,7 @@
   SmallVector IncludeBucket[IK_InvalidInclude];
 };
 
+} // namespace utils
 } // namespace tidy
 } // namespace clang
 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDESORTER_H
Index: clang-tidy/utils/IncludeSorter.cpp
===
--- clang-tidy/utils/IncludeSorter.cpp
+++ clang-tidy/utils/IncludeSorter.cpp
@@ -12,6 +12,7 @@
 
 namespace clang {
 namespace tidy {
+namespace utils {  
 
 namespace {
 
@@ -291,5 +292,6 @@
   return Style == IS_LLVM ? "llvm" : "google";
 }
 
+} // namespace utils
 } // namespace tidy
 } // namespace clang
Index: clang-tidy/utils/IncludeInserter.h
===
--- clang-tidy/utils/IncludeInserter.h
+++ clang-tidy/utils/IncludeInserter.h
@@ -20,6 +20,7 @@
 
 namespace clang {
 namespace tidy {
+namespace utils {
 
 // IncludeInserter can be used by ClangTidyChecks in the following fashion:
 // class MyCheck : public ClangTidyCheck {
@@ -70,6 +71,7 @@
   friend class IncludeInserterCallback;
 };
 
+} // namespace utils
 } // namespace tidy
 } // namespace clang
 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDEINSERTER_H
Index: clang-tidy/utils/IncludeInserter.cpp
===
--- clang-tidy/utils/IncludeInserter.cpp
+++ clang-tidy/utils/IncludeInserter.cpp
@@ -12,6 +12,7 @@
 
 namespace clang {
 namespace tidy {
+namespace utils {
 
 class IncludeInserterCallback : public PPCallbacks {
 public:
@@ -80,5 +81,6 @@
   end_location);
 }
 
+} // namespace utils
 } // namespace tidy
 } // namespace clang
Index: clang-tidy/utils/HeaderGuard.h
===
--- clang-tidy/utils/HeaderGuard.h
+++ clang-tidy/utils/HeaderGuard.h
@@ -14,6 +14,7 @@
 
 namespace clang {
 namespace tidy {
+namespace utils {
 
 /// Finds and fixes header 

Re: [PATCH] D19819: [clang-tidy] Cleanup namespace in utils folder.

2016-05-02 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 55858.
etienneb added a comment.

add missing case


http://reviews.llvm.org/D19819

Files:
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
  clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
  clang-tidy/llvm/HeaderGuardCheck.h
  clang-tidy/misc/MoveConstructorInitCheck.cpp
  clang-tidy/misc/MoveConstructorInitCheck.h
  clang-tidy/misc/SuspiciousSemicolonCheck.cpp
  clang-tidy/modernize/PassByValueCheck.cpp
  clang-tidy/modernize/PassByValueCheck.h
  clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
  clang-tidy/modernize/ReplaceAutoPtrCheck.h
  clang-tidy/performance/ForRangeCopyCheck.cpp
  clang-tidy/performance/UnnecessaryCopyInitialization.cpp
  clang-tidy/performance/UnnecessaryValueParamCheck.cpp
  clang-tidy/utils/DeclRefExprUtils.cpp
  clang-tidy/utils/DeclRefExprUtils.h
  clang-tidy/utils/FixItHintUtils.cpp
  clang-tidy/utils/FixItHintUtils.h
  clang-tidy/utils/HeaderGuard.cpp
  clang-tidy/utils/HeaderGuard.h
  clang-tidy/utils/IncludeInserter.cpp
  clang-tidy/utils/IncludeInserter.h
  clang-tidy/utils/IncludeSorter.cpp
  clang-tidy/utils/IncludeSorter.h
  clang-tidy/utils/LexerUtils.cpp
  clang-tidy/utils/LexerUtils.h
  clang-tidy/utils/Matchers.h
  clang-tidy/utils/TypeTraits.cpp
  clang-tidy/utils/TypeTraits.h

Index: clang-tidy/utils/TypeTraits.h
===
--- clang-tidy/utils/TypeTraits.h
+++ clang-tidy/utils/TypeTraits.h
@@ -15,6 +15,7 @@
 
 namespace clang {
 namespace tidy {
+namespace utils {
 namespace type_traits {
 
 // \brief Returns true If \c Type is expensive to copy.
@@ -28,6 +29,7 @@
const ASTContext &Context);
 
 } // type_traits
+} // namespace utils
 } // namespace tidy
 } // namespace clang
 
Index: clang-tidy/utils/TypeTraits.cpp
===
--- clang-tidy/utils/TypeTraits.cpp
+++ clang-tidy/utils/TypeTraits.cpp
@@ -13,6 +13,7 @@
 
 namespace clang {
 namespace tidy {
+namespace utils {
 namespace type_traits {
 
 namespace {
@@ -106,6 +107,7 @@
   return false;
 }
 
-} // type_traits
+} // namespace type_traits
+} // namespace utils
 } // namespace tidy
 } // namespace clang
Index: clang-tidy/utils/Matchers.h
===
--- clang-tidy/utils/Matchers.h
+++ clang-tidy/utils/Matchers.h
@@ -31,12 +31,12 @@
 
 AST_MATCHER(QualType, isExpensiveToCopy) {
   llvm::Optional IsExpensive =
-  type_traits::isExpensiveToCopy(Node, Finder->getASTContext());
+  utils::type_traits::isExpensiveToCopy(Node, Finder->getASTContext());
   return IsExpensive && *IsExpensive;
 }
 
 AST_MATCHER(RecordDecl, isTriviallyDefaultConstructible) {
-  return type_traits::recordIsTriviallyDefaultConstructible(
+  return utils::type_traits::recordIsTriviallyDefaultConstructible(
   Node, Finder->getASTContext());
 }
 
Index: clang-tidy/utils/LexerUtils.h
===
--- clang-tidy/utils/LexerUtils.h
+++ clang-tidy/utils/LexerUtils.h
@@ -15,14 +15,16 @@
 
 namespace clang {
 namespace tidy {
-namespace lexer_utils {
+namespace utils {
+namespace lexer {
 
 // Returns previous non-comment token skipping over any comment text or
 // tok::unknown if not found.
 Token getPreviousNonCommentToken(const ASTContext &Context,
  SourceLocation Location);
 
-} // namespace lexer_utils
+} // namespace lexer
+} // namespace utils
 } // namespace tidy
 } // namespace clang
 
Index: clang-tidy/utils/LexerUtils.cpp
===
--- clang-tidy/utils/LexerUtils.cpp
+++ clang-tidy/utils/LexerUtils.cpp
@@ -11,7 +11,8 @@
 
 namespace clang {
 namespace tidy {
-namespace lexer_utils {
+namespace utils {
+namespace lexer {
 
 Token getPreviousNonCommentToken(const ASTContext &Context,
  SourceLocation Location) {
@@ -34,6 +35,7 @@
   return Token;
 }
 
-} // namespace lexer_utils
+} // namespace lexer
+} // namespace utils
 } // namespace tidy
 } // namespace clang
Index: clang-tidy/utils/IncludeSorter.h
===
--- clang-tidy/utils/IncludeSorter.h
+++ clang-tidy/utils/IncludeSorter.h
@@ -15,6 +15,7 @@
 
 namespace clang {
 namespace tidy {
+namespace utils {  
 
 // Class used by IncludeSorterCallback and IncludeInserterCallback to record the
 // names of the inclusions in a given source file being processed and generate
@@ -83,6 +84,7 @@
   SmallVector IncludeBucket[IK_InvalidInclude];
 };
 
+} // namespace utils
 } // namespace tidy
 } // namespace clang
 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDESORTER_H
Index: clang-tidy/utils/IncludeSorter.cpp
===
--- clang-tidy/utils/Include

Re: [PATCH] D19819: [clang-tidy] Cleanup namespace in utils folder.

2016-05-02 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 55876.
etienneb added a comment.

fix unittests


http://reviews.llvm.org/D19819

Files:
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
  clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
  clang-tidy/llvm/HeaderGuardCheck.h
  clang-tidy/misc/MoveConstructorInitCheck.cpp
  clang-tidy/misc/MoveConstructorInitCheck.h
  clang-tidy/misc/SuspiciousSemicolonCheck.cpp
  clang-tidy/modernize/PassByValueCheck.cpp
  clang-tidy/modernize/PassByValueCheck.h
  clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
  clang-tidy/modernize/ReplaceAutoPtrCheck.h
  clang-tidy/performance/ForRangeCopyCheck.cpp
  clang-tidy/performance/UnnecessaryCopyInitialization.cpp
  clang-tidy/performance/UnnecessaryValueParamCheck.cpp
  clang-tidy/utils/DeclRefExprUtils.cpp
  clang-tidy/utils/DeclRefExprUtils.h
  clang-tidy/utils/FixItHintUtils.cpp
  clang-tidy/utils/FixItHintUtils.h
  clang-tidy/utils/HeaderGuard.cpp
  clang-tidy/utils/HeaderGuard.h
  clang-tidy/utils/IncludeInserter.cpp
  clang-tidy/utils/IncludeInserter.h
  clang-tidy/utils/IncludeSorter.cpp
  clang-tidy/utils/IncludeSorter.h
  clang-tidy/utils/LexerUtils.cpp
  clang-tidy/utils/LexerUtils.h
  clang-tidy/utils/Matchers.h
  clang-tidy/utils/TypeTraits.cpp
  clang-tidy/utils/TypeTraits.h
  unittests/clang-tidy/IncludeInserterTest.cpp

Index: unittests/clang-tidy/IncludeInserterTest.cpp
===
--- unittests/clang-tidy/IncludeInserterTest.cpp
+++ unittests/clang-tidy/IncludeInserterTest.cpp
@@ -33,9 +33,10 @@
   : ClangTidyCheck(CheckName, Context) {}
 
   void registerPPCallbacks(CompilerInstance &Compiler) override {
-Inserter.reset(new IncludeInserter(Compiler.getSourceManager(),
-   Compiler.getLangOpts(),
-   IncludeSorter::IS_Google));
+Inserter.reset(new utils::IncludeInserter(
+Compiler.getSourceManager(),
+Compiler.getLangOpts(),
+utils::IncludeSorter::IS_Google));
 Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
   }
 
@@ -58,7 +59,7 @@
   virtual std::vector HeadersToInclude() const = 0;
   virtual bool IsAngledInclude() const = 0;
 
-  std::unique_ptr Inserter;
+  std::unique_ptr Inserter;
 };
 
 class NonSystemHeaderInserterCheck : public IncludeInserterCheckBase {
Index: clang-tidy/utils/TypeTraits.h
===
--- clang-tidy/utils/TypeTraits.h
+++ clang-tidy/utils/TypeTraits.h
@@ -15,6 +15,7 @@
 
 namespace clang {
 namespace tidy {
+namespace utils {
 namespace type_traits {
 
 // \brief Returns true If \c Type is expensive to copy.
@@ -28,6 +29,7 @@
const ASTContext &Context);
 
 } // type_traits
+} // namespace utils
 } // namespace tidy
 } // namespace clang
 
Index: clang-tidy/utils/TypeTraits.cpp
===
--- clang-tidy/utils/TypeTraits.cpp
+++ clang-tidy/utils/TypeTraits.cpp
@@ -13,6 +13,7 @@
 
 namespace clang {
 namespace tidy {
+namespace utils {
 namespace type_traits {
 
 namespace {
@@ -106,6 +107,7 @@
   return false;
 }
 
-} // type_traits
+} // namespace type_traits
+} // namespace utils
 } // namespace tidy
 } // namespace clang
Index: clang-tidy/utils/Matchers.h
===
--- clang-tidy/utils/Matchers.h
+++ clang-tidy/utils/Matchers.h
@@ -31,12 +31,12 @@
 
 AST_MATCHER(QualType, isExpensiveToCopy) {
   llvm::Optional IsExpensive =
-  type_traits::isExpensiveToCopy(Node, Finder->getASTContext());
+  utils::type_traits::isExpensiveToCopy(Node, Finder->getASTContext());
   return IsExpensive && *IsExpensive;
 }
 
 AST_MATCHER(RecordDecl, isTriviallyDefaultConstructible) {
-  return type_traits::recordIsTriviallyDefaultConstructible(
+  return utils::type_traits::recordIsTriviallyDefaultConstructible(
   Node, Finder->getASTContext());
 }
 
Index: clang-tidy/utils/LexerUtils.h
===
--- clang-tidy/utils/LexerUtils.h
+++ clang-tidy/utils/LexerUtils.h
@@ -15,14 +15,16 @@
 
 namespace clang {
 namespace tidy {
-namespace lexer_utils {
+namespace utils {
+namespace lexer {
 
 // Returns previous non-comment token skipping over any comment text or
 // tok::unknown if not found.
 Token getPreviousNonCommentToken(const ASTContext &Context,
  SourceLocation Location);
 
-} // namespace lexer_utils
+} // namespace lexer
+} // namespace utils
 } // namespace tidy
 } // namespace clang
 
Index: clang-tidy/utils/LexerUtils.cpp
===
--- clang-tidy/utils/LexerUtils.cpp
+++ clang-tidy/utils/LexerUtils.cpp
@@ -11,7 +11,8 @@
 
 namespace clang {
 namespace tidy {
-n

[PATCH] D19841: [clang-tidy] Lift common matchers to utils namespace

2016-05-02 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added a reviewer: alexfh.
etienneb added a subscriber: cfe-commits.

This patch is lifting matchers used by more than one checkers
to the common namespace.

http://reviews.llvm.org/D19841

Files:
  clang-tidy/misc/BoolPointerImplicitConversionCheck.cpp
  clang-tidy/modernize/UseNullptrCheck.cpp
  clang-tidy/performance/FasterStringFindCheck.cpp
  clang-tidy/readability/ImplicitBoolCastCheck.cpp
  clang-tidy/readability/RedundantStringInitCheck.cpp
  clang-tidy/utils/Matchers.h

Index: clang-tidy/utils/Matchers.h
===
--- clang-tidy/utils/Matchers.h
+++ clang-tidy/utils/Matchers.h
@@ -17,6 +17,19 @@
 namespace tidy {
 namespace matchers {
 
+AST_MATCHER_P(StringLiteral, lengthIs, unsigned, N) {
+  return Node.getLength() == N;
+}
+
+AST_MATCHER_P(Expr, ignoringImplicit,
+  ast_matchers::internal::Matcher, InnerMatcher) {
+  return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
+}
+
+AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
+  return Node.getCastKind() == Kind;
+}
+
 AST_MATCHER(BinaryOperator, isRelationalOperator) {
   return Node.isRelationalOp();
 }
Index: clang-tidy/readability/RedundantStringInitCheck.cpp
===
--- clang-tidy/readability/RedundantStringInitCheck.cpp
+++ clang-tidy/readability/RedundantStringInitCheck.cpp
@@ -8,25 +8,16 @@
 //===--===//
 
 #include "RedundantStringInitCheck.h"
+#include "../utils/Matchers.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 
 using namespace clang::ast_matchers;
+using namespace clang::tidy::matchers;
 
 namespace clang {
 namespace tidy {
 namespace readability {
 
-namespace {
-
-AST_MATCHER(StringLiteral, lengthIsZero) { return Node.getLength() == 0; }
-
-AST_MATCHER_P(Expr, ignoringImplicit,
-  ast_matchers::internal::Matcher, InnerMatcher) {
-  return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
-}
-
-} // namespace
-
 void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
   if (!getLangOpts().CPlusPlus)
 return;
@@ -45,7 +36,7 @@
   const auto EmptyStringCtorExpr =
   cxxConstructExpr(StringConstructorExpr,
   hasArgument(0, ignoringParenImpCasts(
- stringLiteral(lengthIsZero();
+ stringLiteral(lengthIs(0);
 
   const auto EmptyStringCtorExprWithTemporaries =
   expr(ignoringImplicit(
Index: clang-tidy/readability/ImplicitBoolCastCheck.cpp
===
--- clang-tidy/readability/ImplicitBoolCastCheck.cpp
+++ clang-tidy/readability/ImplicitBoolCastCheck.cpp
@@ -8,22 +8,20 @@
 //===--===//
 
 #include "ImplicitBoolCastCheck.h"
+#include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
 
 using namespace clang::ast_matchers;
+using namespace clang::tidy::matchers;
 
 namespace clang {
 namespace tidy {
 namespace readability {
 
 namespace {
 
-AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
-  return Node.getCastKind() == Kind;
-}
-
 AST_MATCHER(Stmt, isMacroExpansion) {
   SourceManager &SM = Finder->getASTContext().getSourceManager();
   SourceLocation Loc = Node.getLocStart();
Index: clang-tidy/performance/FasterStringFindCheck.cpp
===
--- clang-tidy/performance/FasterStringFindCheck.cpp
+++ clang-tidy/performance/FasterStringFindCheck.cpp
@@ -8,12 +8,14 @@
 //===--===//
 
 #include "FasterStringFindCheck.h"
+#include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang::ast_matchers;
+using namespace clang::tidy::matchers;
 
 namespace clang {
 namespace tidy {
@@ -51,8 +53,6 @@
   return Result;
 }
 
-AST_MATCHER(StringLiteral, lengthIsOne) { return Node.getLength() == 1; }
-
 AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher,
  hasSubstitutedType) {
   return hasType(qualType(anyOf(substTemplateTypeParmType(),
@@ -79,7 +79,7 @@
 return;
 
   const auto SingleChar =
-  expr(ignoringParenCasts(stringLiteral(lengthIsOne()).bind("literal")));
+  expr(ignoringParenCasts(stringLiteral(lengthIs(1)).bind("literal")));
 
   const auto StringFindFunctions =
   anyOf(hasName("find"), hasName("rfind"), hasName("find_first_of"),
Index: clang-tidy/modernize/UseNullptrCheck.cpp
===
--- clang-tidy/modernize/UseNullptrCheck.cpp
+++ clang-tidy/modernize/UseNullptrCheck.cpp
@@ -8,13

[PATCH] D19846: [clang-tidy] Lift parsing of sequence of names functions to utils.

2016-05-02 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added a reviewer: alexfh.
etienneb added a subscriber: cfe-commits.

Lift some common code used by multiple checkers.

This function is also used by checkers that are coming.
It is quite common for a checker to parse a list of names.

http://reviews.llvm.org/D19846

Files:
  clang-tidy/misc/DanglingHandleCheck.cpp
  clang-tidy/misc/SuspiciousStringCompareCheck.cpp
  clang-tidy/performance/FasterStringFindCheck.cpp
  clang-tidy/utils/CMakeLists.txt
  clang-tidy/utils/OptionUtils.cpp
  clang-tidy/utils/OptionUtils.h

Index: clang-tidy/utils/OptionUtils.h
===
--- /dev/null
+++ clang-tidy/utils/OptionUtils.h
@@ -0,0 +1,31 @@
+//===--- DanglingHandleCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+namespace option {
+
+/// \brief Parse a list of names separated by ";" character.
+std::vector parseNames(StringRef Option);
+
+/// \brief Serialize a sequence of names that can be parse by parseNames.
+std::string serializeNames(const std::vector &Names);
+
+} // namespace option
+} // namespace utils
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
Index: clang-tidy/utils/OptionUtils.cpp
===
--- /dev/null
+++ clang-tidy/utils/OptionUtils.cpp
@@ -0,0 +1,38 @@
+//===--- DanglingHandleCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "OptionUtils.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+namespace option {
+
+static const char NamesDelimiter[] = ";";
+
+std::vector parseNames(StringRef Option) {
+  SmallVector Names;
+  Option.split(Names, NamesDelimiter);
+  std::vector Result;
+  for (StringRef &Name : Names) {
+Name = Name.trim();
+if (!Name.empty())
+  Result.push_back(Name);
+  }
+  return Result;
+}
+
+std::string serializeNames(const std::vector &Names) {
+  return llvm::join(Names.begin(), Names.end(), NamesDelimiter);
+}
+
+} // namespace option
+} // namespace utils
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/utils/CMakeLists.txt
===
--- clang-tidy/utils/CMakeLists.txt
+++ clang-tidy/utils/CMakeLists.txt
@@ -3,11 +3,12 @@
 add_clang_library(clangTidyUtils
   DeclRefExprUtils.cpp
   FixItHintUtils.cpp
-  HeaderGuard.cpp
   HeaderFileExtensionsUtils.cpp
+  HeaderGuard.cpp
   IncludeInserter.cpp
   IncludeSorter.cpp
   LexerUtils.cpp
+  OptionUtils.cpp
   TypeTraits.cpp
 
   LINK_LIBS
Index: clang-tidy/performance/FasterStringFindCheck.cpp
===
--- clang-tidy/performance/FasterStringFindCheck.cpp
+++ clang-tidy/performance/FasterStringFindCheck.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include "FasterStringFindCheck.h"
+#include "../utils/OptionUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "llvm/ADT/Optional.h"
@@ -21,20 +22,6 @@
 
 namespace {
 
-static const char StringLikeClassesDelimiter[] = ";";
-
-std::vector ParseClasses(StringRef Option) {
-  SmallVector Classes;
-  Option.split(Classes, StringLikeClassesDelimiter);
-  std::vector Result;
-  for (StringRef &Class : Classes) {
-Class = Class.trim();
-if (!Class.empty())
-  Result.push_back(Class);
-  }
-  return Result;
-}
-
 llvm::Optional MakeCharacterLiteral(const StringLiteral *Literal) {
   std::string Result;
   {
@@ -64,14 +51,13 @@
 FasterStringFindCheck::FasterStringFindCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
-  StringLikeClasses(
-  ParseClasses(Options.get("StringLikeClasses", "std::basic_string"))) {
+  StringLikeClasses(utils::option::parseNames(
+  Options.get("StringLikeClasses", "std::basic_string"))) {
 }
 
 void FasterStringFindCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "StringLikeClasses",
-llvm::join(StringLikeClasses.begin(), StringLikeClasses.end(),
-   S

[clang-tools-extra] r268356 - [clang-tidy] Cleanup namespace in utils folder.

2016-05-02 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Mon May  2 21:54:05 2016
New Revision: 268356

URL: http://llvm.org/viewvc/llvm-project?rev=268356&view=rev
Log:
[clang-tidy] Cleanup namespace in utils folder.

Summary:
This is a step forward cleaning up the namespaces in clang-tidy/utils.
There is no behavior change.

Reviewers: alexfh

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D19819

Modified:

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
clang-tools-extra/trunk/clang-tidy/llvm/HeaderGuardCheck.h
clang-tools-extra/trunk/clang-tidy/misc/MoveConstructorInitCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/MoveConstructorInitCheck.h
clang-tools-extra/trunk/clang-tidy/misc/SuspiciousSemicolonCheck.cpp
clang-tools-extra/trunk/clang-tidy/modernize/PassByValueCheck.cpp
clang-tools-extra/trunk/clang-tidy/modernize/PassByValueCheck.h
clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.h
clang-tools-extra/trunk/clang-tidy/performance/ForRangeCopyCheck.cpp

clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryCopyInitialization.cpp

clang-tools-extra/trunk/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
clang-tools-extra/trunk/clang-tidy/utils/DeclRefExprUtils.cpp
clang-tools-extra/trunk/clang-tidy/utils/DeclRefExprUtils.h
clang-tools-extra/trunk/clang-tidy/utils/FixItHintUtils.cpp
clang-tools-extra/trunk/clang-tidy/utils/FixItHintUtils.h
clang-tools-extra/trunk/clang-tidy/utils/HeaderGuard.cpp
clang-tools-extra/trunk/clang-tidy/utils/HeaderGuard.h
clang-tools-extra/trunk/clang-tidy/utils/IncludeInserter.cpp
clang-tools-extra/trunk/clang-tidy/utils/IncludeInserter.h
clang-tools-extra/trunk/clang-tidy/utils/IncludeSorter.cpp
clang-tools-extra/trunk/clang-tidy/utils/IncludeSorter.h
clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.cpp
clang-tools-extra/trunk/clang-tidy/utils/LexerUtils.h
clang-tools-extra/trunk/clang-tidy/utils/Matchers.h
clang-tools-extra/trunk/clang-tidy/utils/TypeTraits.cpp
clang-tools-extra/trunk/clang-tidy/utils/TypeTraits.h
clang-tools-extra/trunk/unittests/clang-tidy/IncludeInserterTest.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp?rev=268356&r1=268355&r2=268356&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
 (original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
 Mon May  2 21:54:05 2016
@@ -22,7 +22,7 @@ namespace cppcoreguidelines {
 ProBoundsConstantArrayIndexCheck::ProBoundsConstantArrayIndexCheck(
 StringRef Name, ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context), GslHeader(Options.get("GslHeader", "")),
-  IncludeStyle(IncludeSorter::parseIncludeStyle(
+  IncludeStyle(utils::IncludeSorter::parseIncludeStyle(
   Options.get("IncludeStyle", "llvm"))) {}
 
 void ProBoundsConstantArrayIndexCheck::storeOptions(
@@ -36,8 +36,8 @@ void ProBoundsConstantArrayIndexCheck::r
   if (!getLangOpts().CPlusPlus)
 return;
 
-  Inserter.reset(new IncludeInserter(Compiler.getSourceManager(),
- Compiler.getLangOpts(), IncludeStyle));
+  Inserter.reset(new utils::IncludeInserter(
+  Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle));
   Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
 }
 

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h?rev=268356&r1=268355&r2=268356&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
 (original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
 Mon May  2 21:54:05 2016
@@ -24,8 +24,8 @@ namespace cppcoreguidelines {
 /// 
http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.html
 class ProBoundsConstantArrayIndexCheck : public ClangTidyCheck {
   const std::string GslHeader;
-  const IncludeSorter::IncludeStyle IncludeStyle;
-  std::unique_ptr Inserter;
+  const utils::IncludeSorter::IncludeStyle IncludeStyle;
+  std::unique_ptr Inserter;
 
 public:
   ProBoundsCo

Re: [PATCH] D19841: [clang-tidy] Lift common matchers to utils namespace

2016-05-02 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

Who is the owner of ASTMatcher?

If he is willing to receive these matchers in ASTMatcher, I'll lift them.
Otherwise, we should at least lift them within clang-tidy.


http://reviews.llvm.org/D19841



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


[PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-03 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added reviewers: alexfh, sbenza, klimek.
etienneb added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

This AST matcher will match a given CastExpr kind.
It's an narrowing matcher on CastExpr.

http://reviews.llvm.org/D19871

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3475,6 +3475,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -75,6 +75,7 @@
   // TODO: Here is the list of the missing matchers, grouped by reason.
   //
   // Need Variant/Parser fixes:
+  // hasCastKind
   // ofKind
   //
   // Polymorphic + argument overload:
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3548,6 +3548,17 @@
   InnerMatcher.matches(*SubExpression, Finder, Builder));
 }
 
+/// \brief Matches casts that has a given cast kind.
+///
+/// Example: matches the implicit cast around \c 0
+/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
+/// \code
+///   int *p = 0;
+/// \endcode
+AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
+  return Node.getCastKind() == Kind;
+}
+
 /// \brief Matches casts whose destination type matches a given matcher.
 ///
 /// (Note: Clang's AST refers to other conversions as "casts" too, and calls


Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3475,6 +3475,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -75,6 +75,7 @@
   // TODO: Here is the list of the missing matchers, grouped by reason.
   //
   // Need Variant/Parser fixes:
+  // hasCastKind
   // ofKind
   //
   // Polymorphic + argument overload:
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3548,6 +3548,17 @@
   InnerMatcher.matches(*SubExpression, Finder, Builder));
 }
 
+/// \brief Matches casts that has a given cast kind.
+///
+/// Example: matches the implicit cast around \c 0
+/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
+/// \code
+///   int *p = 0;
+/// \endcode
+AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
+  return Node.getCastKind() == Kind;
+}
+
 /// \brief Matches casts whose destination type matches a given matcher.
 ///
 /// (Note: Clang's AST refers to other conversions as "casts" too, and calls
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-03 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

In http://reviews.llvm.org/D19871#419947, @aaron.ballman wrote:

> Is this required for some purpose?


It's used in clang-tidy checkers.

  see http://reviews.llvm.org/D19841
   

> I'm not keen on adding new AST matchers that we cannot expose via the dynamic 
> API, so I would prefer to solve that problem if we want to add this matcher.

> 

> Also, be sure to regenerate the documentation from dump_ast_matchers.py


Ah, this is the way to generate the doc. Thanks :)


http://reviews.llvm.org/D19871



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


Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-03 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

> It's good to have that context in a review for functionality that isn't part 
> of the proposed patch. :-) Looking at the other patch, I would prefer to keep 
> this matcher narrowed to just clang-tidy unless you can also solve how to 
> expose it via the dynamic registry so that it can be used by tools like 
> clang-query.


That was my original idea.

In http://reviews.llvm.org/D19871#419998, @sbenza wrote:

> In http://reviews.llvm.org/D19871#419985, @aaron.ballman wrote:
>
> > In http://reviews.llvm.org/D19871#419954, @etienneb wrote:
> >
> > > In http://reviews.llvm.org/D19871#419947, @aaron.ballman wrote:
> > >
> > > > Is this required for some purpose?
> > >
> > >
> > > It's used in clang-tidy checkers.
> > >
> > >   see http://reviews.llvm.org/D19841
> >
> >
> > It's good to have that context in a review for functionality that isn't 
> > part of the proposed patch. :-) Looking at the other patch, I would prefer 
> > to keep this matcher narrowed to just clang-tidy unless you can also solve 
> > how to expose it via the dynamic registry so that it can be used by tools 
> > like clang-query.
>
>
> What we have done in the past with enum-arg matchers is to use string->enum 
> conversion in the dynamic bindings.
>  See the specialization `ArgTypeTraits` in `Marshallers.h`.
>  We could add one for `CastKind` too.


I think I got the idea, I'll give a try to see the results. Thanks Samuel.


http://reviews.llvm.org/D19871



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


Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-03 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.



> I agree that when possible, matchers should be available via the dynamic 
> matchers API. It doesn't seem overly complicated to add this support here. As 
> far as I understand, we just need to register the matcher in 
> lib/ASTMatchers/Dynamic/Registry.cpp and add support for `CastKind` argument 
> type (by adding a corresponding `ArgTypeTraits` instantiation). Etienne, can 
> you try this?




1. The parameter is passed as a string (which is not the case for the 
hasCastKind matcher): hasAttr("attr::CUDADevice").

2. There is no easy way to list every cast kind. Which means we need to 
hardcode them (or iterate over the domain) [both solution sounds terrible to 
me].

  static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
return llvm::StringSwitch(AttrKind)
  .Case("CK_Dependent", CK_Dependent)
 [...]<<-- list every cast kind here.
  .Default(clang::CastKind(-1));
  }

So even if the above solution is working, we still need to call it that way (as 
a string):
clang-query> match castExpr(hasCastKind("CK_Dependent"))


http://reviews.llvm.org/D19871



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


Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-03 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

> though I would love if someday we could expose actual enumerations somehow 
> instead of string literals


I would like too. Ditto for "equals" which is missing :)


http://reviews.llvm.org/D19871



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


Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-03 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56022.
etienneb added a comment.

add dynamic parsing


http://reviews.llvm.org/D19871

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

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3475,6 +3475,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -209,6 +209,7 @@
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasCaseConstant);
+  REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDecayedType);
Index: lib/ASTMatchers/Dynamic/Marshallers.h
===
--- lib/ASTMatchers/Dynamic/Marshallers.h
+++ lib/ASTMatchers/Dynamic/Marshallers.h
@@ -95,6 +95,85 @@
 return ArgKind(ArgKind::AK_String);
   }
 };
+///
+template <> struct ArgTypeTraits {
+private:
+  static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
+return llvm::StringSwitch(AttrKind)
+  .Case("CK_Dependent", CK_Dependent)
+  .Case("CK_BitCast", CK_BitCast)
+  .Case("CK_LValueBitCast", CK_LValueBitCast)
+  .Case("CK_LValueToRValue", CK_LValueToRValue)
+  .Case("CK_NoOp", CK_NoOp)
+  .Case("CK_BaseToDerived", CK_BaseToDerived)
+  .Case("CK_DerivedToBase", CK_DerivedToBase)
+  .Case("CK_UncheckedDerivedToBase", CK_UncheckedDerivedToBase)
+  .Case("CK_Dynamic", CK_Dynamic)
+  .Case("CK_ToUnion", CK_ToUnion)
+  .Case("CK_ArrayToPointerDecay", CK_ArrayToPointerDecay)
+  .Case("CK_FunctionToPointerDecay", CK_FunctionToPointerDecay)
+  .Case("CK_NullToMemberPointer", CK_NullToMemberPointer)
+  .Case("CK_NullToPointer", CK_NullToPointer)
+  .Case("CK_BaseToDerivedMemberPointer", CK_BaseToDerivedMemberPointer)
+  .Case("CK_DerivedToBaseMemberPointer", CK_DerivedToBaseMemberPointer)
+  .Case("CK_ReinterpretMemberPointer", CK_ReinterpretMemberPointer)
+  .Case("CK_UserDefinedConversion", CK_UserDefinedConversion)
+  .Case("CK_ConstructorConversion", CK_ConstructorConversion)
+  .Case("CK_IntegralToPointer", CK_IntegralToPointer)
+  .Case("CK_PointerToIntegral", CK_PointerToIntegral)
+  .Case("CK_PointerToBoolean", CK_PointerToBoolean)
+  .Case("CK_ToVoid", CK_ToVoid)
+  .Case("CK_VectorSplat", CK_VectorSplat)
+  .Case("CK_IntegralCast", CK_IntegralCast)
+  .Case("CK_BooleanToSignedIntegral", CK_BooleanToSignedIntegral)
+  .Case("CK_IntegralToBoolean", CK_IntegralToBoolean)
+  .Case("CK_IntegralToFloating", CK_IntegralToFloating)
+  .Case("CK_FloatingToIntegral", CK_FloatingToIntegral)
+  .Case("CK_FloatingCast", CK_FloatingCast)
+  .Case("CK_FloatingToBoolean", CK_FloatingToBoolean)
+  .Case("CK_MemberPointerToBoolean", CK_MemberPointerToBoolean)
+  .Case("CK_CPointerToObjCPointerCast", CK_CPointerToObjCPointerCast)
+  .Case("CK_BlockPointerToObjCPointerCast",
+ CK_BlockPointerToObjCPointerCast)
+  .Case("CK_AnyPointerToBlockPointerCast", CK_AnyPointerToBlockPointerCast)
+  .Case("CK_ObjCObjectLValueCast", CK_ObjCObjectLValueCast)
+  .Case("CK_FloatingRealToComplex", CK_FloatingRealToComplex)
+  .Case("CK_FloatingComplexToReal", CK_FloatingComplexToReal)
+  .Case("CK_FloatingComplexToBoolean", CK_FloatingComplexToBoolean)
+  .Case("CK_FloatingComplexCast", CK_FloatingComplexCast)
+  .Case("CK_FloatingComplexToIntegralComplex",
+ CK_FloatingComplexToIntegralComplex)
+  .Case("CK_IntegralRealToComplex", CK_IntegralRealToComplex)
+  .Case("CK_IntegralComplexToReal", CK_IntegralComplexToReal)
+  .Case("CK_IntegralComplexToBoolean", CK_IntegralComplexToBoolean)
+  .Case("CK_IntegralComplexCast", CK_IntegralComplexCast)
+  .Case("CK_IntegralComplexToFloatingComplex",
+CK_IntegralComplexToFloatingComplex)
+  .Case("CK_ARCConsumeObject", CK_ARCConsumeObject)
+  .Case("CK_ARCProduceObject", CK_ARCProduceObject)
+  .Case("CK_ARCReclaimReturnedObjec

Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-03 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56023.
etienneb added a comment.

nit


http://reviews.llvm.org/D19871

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

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3475,6 +3475,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -209,6 +209,7 @@
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasCaseConstant);
+  REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDecayedType);
Index: lib/ASTMatchers/Dynamic/Marshallers.h
===
--- lib/ASTMatchers/Dynamic/Marshallers.h
+++ lib/ASTMatchers/Dynamic/Marshallers.h
@@ -96,6 +96,85 @@
   }
 };
 
+template <> struct ArgTypeTraits {
+private:
+  static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
+return llvm::StringSwitch(AttrKind)
+  .Case("CK_Dependent", CK_Dependent)
+  .Case("CK_BitCast", CK_BitCast)
+  .Case("CK_LValueBitCast", CK_LValueBitCast)
+  .Case("CK_LValueToRValue", CK_LValueToRValue)
+  .Case("CK_NoOp", CK_NoOp)
+  .Case("CK_BaseToDerived", CK_BaseToDerived)
+  .Case("CK_DerivedToBase", CK_DerivedToBase)
+  .Case("CK_UncheckedDerivedToBase", CK_UncheckedDerivedToBase)
+  .Case("CK_Dynamic", CK_Dynamic)
+  .Case("CK_ToUnion", CK_ToUnion)
+  .Case("CK_ArrayToPointerDecay", CK_ArrayToPointerDecay)
+  .Case("CK_FunctionToPointerDecay", CK_FunctionToPointerDecay)
+  .Case("CK_NullToMemberPointer", CK_NullToMemberPointer)
+  .Case("CK_NullToPointer", CK_NullToPointer)
+  .Case("CK_BaseToDerivedMemberPointer", CK_BaseToDerivedMemberPointer)
+  .Case("CK_DerivedToBaseMemberPointer", CK_DerivedToBaseMemberPointer)
+  .Case("CK_ReinterpretMemberPointer", CK_ReinterpretMemberPointer)
+  .Case("CK_UserDefinedConversion", CK_UserDefinedConversion)
+  .Case("CK_ConstructorConversion", CK_ConstructorConversion)
+  .Case("CK_IntegralToPointer", CK_IntegralToPointer)
+  .Case("CK_PointerToIntegral", CK_PointerToIntegral)
+  .Case("CK_PointerToBoolean", CK_PointerToBoolean)
+  .Case("CK_ToVoid", CK_ToVoid)
+  .Case("CK_VectorSplat", CK_VectorSplat)
+  .Case("CK_IntegralCast", CK_IntegralCast)
+  .Case("CK_BooleanToSignedIntegral", CK_BooleanToSignedIntegral)
+  .Case("CK_IntegralToBoolean", CK_IntegralToBoolean)
+  .Case("CK_IntegralToFloating", CK_IntegralToFloating)
+  .Case("CK_FloatingToIntegral", CK_FloatingToIntegral)
+  .Case("CK_FloatingCast", CK_FloatingCast)
+  .Case("CK_FloatingToBoolean", CK_FloatingToBoolean)
+  .Case("CK_MemberPointerToBoolean", CK_MemberPointerToBoolean)
+  .Case("CK_CPointerToObjCPointerCast", CK_CPointerToObjCPointerCast)
+  .Case("CK_BlockPointerToObjCPointerCast",
+ CK_BlockPointerToObjCPointerCast)
+  .Case("CK_AnyPointerToBlockPointerCast", CK_AnyPointerToBlockPointerCast)
+  .Case("CK_ObjCObjectLValueCast", CK_ObjCObjectLValueCast)
+  .Case("CK_FloatingRealToComplex", CK_FloatingRealToComplex)
+  .Case("CK_FloatingComplexToReal", CK_FloatingComplexToReal)
+  .Case("CK_FloatingComplexToBoolean", CK_FloatingComplexToBoolean)
+  .Case("CK_FloatingComplexCast", CK_FloatingComplexCast)
+  .Case("CK_FloatingComplexToIntegralComplex",
+ CK_FloatingComplexToIntegralComplex)
+  .Case("CK_IntegralRealToComplex", CK_IntegralRealToComplex)
+  .Case("CK_IntegralComplexToReal", CK_IntegralComplexToReal)
+  .Case("CK_IntegralComplexToBoolean", CK_IntegralComplexToBoolean)
+  .Case("CK_IntegralComplexCast", CK_IntegralComplexCast)
+  .Case("CK_IntegralComplexToFloatingComplex",
+CK_IntegralComplexToFloatingComplex)
+  .Case("CK_ARCConsumeObject", CK_ARCConsumeObject)
+  .Case("CK_ARCProduceObject", CK_ARCProduceObject)
+  .Case("CK_ARCReclaimReturnedObject", CK_ARCReclaimReturnedObject)
+  .Case("CK_ARCExtendBlockObject", CK_ARCExtendBlockObject)
+  .Ca

[PATCH] D19876: Add an AST matcher for string-literal length

2016-05-03 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added reviewers: alexfh, sbenza, aaron.ballman, klimek.
etienneb added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

This patch is adding support for a matcher to check string literal length.

This matcher is used in clang-tidy checkers and is part of this refactoring:
  see: http://reviews.llvm.org/D19841

http://reviews.llvm.org/D19876

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

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -2536,6 +2536,17 @@
   EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
 }
 
+TEST(StringLiteral, LengthIs) {
+  StatementMatcher Literal = stringLiteral(lengthIs(4));
+  EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
+  // wide string
+  EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
+  // with escaped characters
+  EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
+  // no matching, too small
+  EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
+}
+
 TEST(Matcher, CharacterLiterals) {
   StatementMatcher CharLiteral = characterLiteral();
   EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -323,6 +323,7 @@
   REGISTER_MATCHER(labelDecl);
   REGISTER_MATCHER(labelStmt);
   REGISTER_MATCHER(lambdaExpr);
+  REGISTER_MATCHER(lengthIs);
   REGISTER_MATCHER(lValueReferenceType);
   REGISTER_MATCHER(matchesName);
   REGISTER_MATCHER(matchesSelector);
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -1560,12 +1560,23 @@
 ///
 /// Example matches "abcd", L"abcd"
 /// \code
-///   char *s = "abcd"; wchar_t *ws = L"abcd"
+///   char *s = "abcd"; wchar_t *ws = L"abcd";
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   StringLiteral> stringLiteral;
 
+/// \brief Matches string length for a given string literal node.
+///
+/// Example matches "abcd", L"abcd"
+/// \code
+///   char *s = "abcd"; wchar_t *ws = L"abcd";
+///   char *t = "a";
+/// \endcode
+AST_MATCHER_P(StringLiteral, lengthIs, unsigned, N) {
+  return Node.getLength() == N;
+}
+
 /// \brief Matches character literals (also matches wchar_t).
 ///
 /// Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral),
Index: docs/LibASTMatchersReference.html
===
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -410,7 +410,7 @@
 
 Given
   typedef int X;
-   using Y = int;
+  using Y = int;
 typeAliasDecl()
   matches "using Y = int", but not "typedef int X"
 
@@ -421,7 +421,7 @@
 
 Given
   typedef int X;
-   using Y = int;
+  using Y = int;
 typedefDecl()
   matches "typedef int X", but not "using Y = int"
 
@@ -432,7 +432,7 @@
 
 Given
   typedef int X;
-   using Y = int;
+  using Y = int;
 typedefNameDecl()
   matches "typedef int X" and "using Y = int"
 
@@ -1217,7 +1217,7 @@
 Matches string literals (also matches wide string literals).
 
 Example matches "abcd", L"abcd"
-  char *s = "abcd"; wchar_t *ws = L"abcd"
+  char *s = "abcd"; wchar_t *ws = L"abcd";
 
 
 
@@ -2941,6 +2941,15 @@
 
 
 
+MatcherStringLiteral>lengthIsunsigned N
+Matches string length for a given string literal node.
+
+Example matches "abcd", L"abcd"
+  char *s = "abcd"; wchar_t *ws = L"abcd";
+  char *t = "a";
+
+
+
 MatcherTagDecl>isDefinition
 Matches if a declaration has a body attached.
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19876: Add an AST matcher for string-literal length

2016-05-03 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56025.
etienneb added a comment.

fix doc


http://reviews.llvm.org/D19876

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

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -2536,6 +2536,17 @@
   EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
 }
 
+TEST(StringLiteral, LengthIs) {
+  StatementMatcher Literal = stringLiteral(lengthIs(4));
+  EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
+  // wide string
+  EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
+  // with escaped characters
+  EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
+  // no matching, too small
+  EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
+}
+
 TEST(Matcher, CharacterLiterals) {
   StatementMatcher CharLiteral = characterLiteral();
   EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -323,6 +323,7 @@
   REGISTER_MATCHER(labelDecl);
   REGISTER_MATCHER(labelStmt);
   REGISTER_MATCHER(lambdaExpr);
+  REGISTER_MATCHER(lengthIs);
   REGISTER_MATCHER(lValueReferenceType);
   REGISTER_MATCHER(matchesName);
   REGISTER_MATCHER(matchesSelector);
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -1560,12 +1560,25 @@
 ///
 /// Example matches "abcd", L"abcd"
 /// \code
-///   char *s = "abcd"; wchar_t *ws = L"abcd"
+///   char *s = "abcd"; wchar_t *ws = L"abcd";
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   StringLiteral> stringLiteral;
 
+/// \brief Matches string length for a given string literal node.
+///
+/// Example:
+///   stringLiteral(lengthIs(4))
+/// matches "abcd", L"abcd"
+/// \code
+///   char *s = "abcd"; wchar_t *ws = L"abcd";
+///   char *t = "a";
+/// \endcode
+AST_MATCHER_P(StringLiteral, lengthIs, unsigned, N) {
+  return Node.getLength() == N;
+}
+
 /// \brief Matches character literals (also matches wchar_t).
 ///
 /// Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral),
Index: docs/LibASTMatchersReference.html
===
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -410,7 +410,7 @@
 
 Given
   typedef int X;
-   using Y = int;
+  using Y = int;
 typeAliasDecl()
   matches "using Y = int", but not "typedef int X"
 
@@ -421,7 +421,7 @@
 
 Given
   typedef int X;
-   using Y = int;
+  using Y = int;
 typedefDecl()
   matches "typedef int X", but not "using Y = int"
 
@@ -432,7 +432,7 @@
 
 Given
   typedef int X;
-   using Y = int;
+  using Y = int;
 typedefNameDecl()
   matches "typedef int X" and "using Y = int"
 
@@ -1217,7 +1217,7 @@
 Matches string literals (also matches wide string literals).
 
 Example matches "abcd", L"abcd"
-  char *s = "abcd"; wchar_t *ws = L"abcd"
+  char *s = "abcd"; wchar_t *ws = L"abcd";
 
 
 
@@ -2941,6 +2941,17 @@
 
 
 
+MatcherStringLiteral>lengthIsunsigned N
+Matches string length for a given string literal node.
+
+Example:
+  stringLiteral(lengthIs(4))
+matches "abcd", L"abcd"
+  char *s = "abcd"; wchar_t *ws = L"abcd";
+  char *t = "a";
+
+
+
 MatcherTagDecl>isDefinition
 Matches if a declaration has a body attached.
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19876: Add an AST matcher for string-literal length

2016-05-03 Thread Etienne Bergeron via cfe-commits
etienneb added inline comments.


Comment at: include/clang/ASTMatchers/ASTMatchers.h:1578
@@ +1577,3 @@
+/// \endcode
+AST_MATCHER_P(StringLiteral, lengthIs, unsigned, N) {
+  return Node.getLength() == N;

aaron.ballman wrote:
> Perhaps we can adjust the `hasSize()` matcher instead? It currently works 
> with ConstantArrayType, but it seems reasonable for it to also work with 
> StringLiteral.
I didn't like the term "size" as it typically refer to the size in bytes.
Which is not the same for a wide-string.

Now, there is two different convention for naming matchers:
  hasLength   and  lengthIs  ?

Any toughs on that?




http://reviews.llvm.org/D19876



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


Re: [PATCH] D19846: [clang-tidy] Lift parsing of sequence of names functions to utils.

2016-05-04 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56173.
etienneb marked 4 inline comments as done.
etienneb added a comment.

address alexfh comments


http://reviews.llvm.org/D19846

Files:
  clang-tidy/misc/DanglingHandleCheck.cpp
  clang-tidy/misc/SuspiciousStringCompareCheck.cpp
  clang-tidy/performance/FasterStringFindCheck.cpp
  clang-tidy/utils/CMakeLists.txt
  clang-tidy/utils/OptionsUtils.cpp
  clang-tidy/utils/OptionsUtils.h

Index: clang-tidy/utils/OptionsUtils.h
===
--- /dev/null
+++ clang-tidy/utils/OptionsUtils.h
@@ -0,0 +1,31 @@
+//===--- DanglingHandleCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+namespace options {
+
+/// \brief Parse a semicolon separated list of strings.
+std::vector parseStrings(StringRef Option);
+
+/// \brief Serialize a sequence of names that can be parsed by 'parseStrings'.
+std::string serializeStrings(ArrayRef Strings);
+
+} // namespace options
+} // namespace utils
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
Index: clang-tidy/utils/OptionsUtils.cpp
===
--- /dev/null
+++ clang-tidy/utils/OptionsUtils.cpp
@@ -0,0 +1,38 @@
+//===--- DanglingHandleCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "OptionsUtils.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+namespace options {
+
+static const char StringsDelimiter[] = ";";
+
+std::vector parseStrings(StringRef Option) {
+  SmallVector Names;
+  Option.split(Names, StringsDelimiter);
+  std::vector Result;
+  for (StringRef &Name : Names) {
+Name = Name.trim();
+if (!Name.empty())
+  Result.push_back(Name);
+  }
+  return Result;
+}
+
+std::string serializeStrings(ArrayRef Strings) {
+  return llvm::join(Strings.begin(), Strings.end(), StringsDelimiter);
+}
+
+} // namespace options
+} // namespace utils
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/utils/CMakeLists.txt
===
--- clang-tidy/utils/CMakeLists.txt
+++ clang-tidy/utils/CMakeLists.txt
@@ -3,11 +3,12 @@
 add_clang_library(clangTidyUtils
   DeclRefExprUtils.cpp
   FixItHintUtils.cpp
-  HeaderGuard.cpp
   HeaderFileExtensionsUtils.cpp
+  HeaderGuard.cpp
   IncludeInserter.cpp
   IncludeSorter.cpp
   LexerUtils.cpp
+  OptionsUtils.cpp
   TypeTraits.cpp
 
   LINK_LIBS
Index: clang-tidy/performance/FasterStringFindCheck.cpp
===
--- clang-tidy/performance/FasterStringFindCheck.cpp
+++ clang-tidy/performance/FasterStringFindCheck.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include "FasterStringFindCheck.h"
+#include "../utils/OptionsUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "llvm/ADT/Optional.h"
@@ -21,20 +22,6 @@
 
 namespace {
 
-static const char StringLikeClassesDelimiter[] = ";";
-
-std::vector ParseClasses(StringRef Option) {
-  SmallVector Classes;
-  Option.split(Classes, StringLikeClassesDelimiter);
-  std::vector Result;
-  for (StringRef &Class : Classes) {
-Class = Class.trim();
-if (!Class.empty())
-  Result.push_back(Class);
-  }
-  return Result;
-}
-
 llvm::Optional MakeCharacterLiteral(const StringLiteral *Literal) {
   std::string Result;
   {
@@ -64,14 +51,13 @@
 FasterStringFindCheck::FasterStringFindCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
-  StringLikeClasses(
-  ParseClasses(Options.get("StringLikeClasses", "std::basic_string"))) {
+  StringLikeClasses(utils::options::parseStrings(
+  Options.get("StringLikeClasses", "std::basic_string"))) {
 }
 
 void FasterStringFindCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "StringLikeClasses",
-llvm::join(StringLikeClasses.begin(), StringLikeClasses.end(),
-   StringLikeClassesDelimiter));
+utils::options::serializeStrings(StringLikeClasses));
 }
 
 void Faste

Re: [PATCH] D19876: Add an AST matcher for string-literal length

2016-05-04 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

Aaron? could you comment on it?



Comment at: include/clang/ASTMatchers/ASTMatchers.h:1575
@@ +1574,3 @@
+/// \code
+///   char *s = "abcd"; wchar_t *ws = L"abcd";
+///   char *t = "a";

aaron.ballman wrote:
> Split these onto two lines?
If I look around, it seems to be more consistent to keep it on the same line 
(line 1563)

```
///   char *s = "abcd"; wchar_t *ws = L"abcd";
```

```
///   int array[4] = {1}; vector int myvec = (vector int)(1, 2);
```

```
///   char ch = 'a'; wchar_t chw = L'a';
``


Comment at: include/clang/ASTMatchers/ASTMatchers.h:1578
@@ +1577,3 @@
+/// \endcode
+AST_MATCHER_P(StringLiteral, lengthIs, unsigned, N) {
+  return Node.getLength() == N;

etienneb wrote:
> aaron.ballman wrote:
> > Perhaps we can adjust the `hasSize()` matcher instead? It currently works 
> > with ConstantArrayType, but it seems reasonable for it to also work with 
> > StringLiteral.
> I didn't like the term "size" as it typically refer to the size in bytes.
> Which is not the same for a wide-string.
> 
> Now, there is two different convention for naming matchers:
>   hasLength   and  lengthIs  ?
> 
> Any toughs on that?
> 
> 
Here is the matcher for hasSize
```
AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
  return Node.getSize() == N;
}
```

It's getting the getSize attribute. I believe we should stick with the name of 
the attribute.
But, I'm not sure if we should use hasLength, or lengthIs.


http://reviews.llvm.org/D19876



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


Re: [PATCH] D19876: Add an AST matcher for string-literal length

2016-05-04 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

Other opinions?
I'll proceed to the cleanup if no one else has comments.



Comment at: include/clang/ASTMatchers/ASTMatchers.h:1575
@@ +1574,3 @@
+/// \code
+///   char *s = "abcd"; wchar_t *ws = L"abcd";
+///   char *t = "a";

aaron.ballman wrote:
> etienneb wrote:
> > aaron.ballman wrote:
> > > Split these onto two lines?
> > If I look around, it seems to be more consistent to keep it on the same 
> > line (line 1563)
> > 
> > ```
> > ///   char *s = "abcd"; wchar_t *ws = L"abcd";
> > ```
> > 
> > ```
> > ///   int array[4] = {1}; vector int myvec = (vector int)(1, 2);
> > ```
> > 
> > ```
> > ///   char ch = 'a'; wchar_t chw = L'a';
> > ``
> I don't have a strong opinion on it; however, since these get turned into 
> examples that are on the website, I would weakly prefer the examples not be 
> hideous. :-P
Ditto. No strong opinion.
But, I like consistency. I'm willing to fix all other instances too.


Comment at: include/clang/ASTMatchers/ASTMatchers.h:1578
@@ +1577,3 @@
+/// \endcode
+AST_MATCHER_P(StringLiteral, lengthIs, unsigned, N) {
+  return Node.getLength() == N;

aaron.ballman wrote:
> etienneb wrote:
> > etienneb wrote:
> > > aaron.ballman wrote:
> > > > Perhaps we can adjust the `hasSize()` matcher instead? It currently 
> > > > works with ConstantArrayType, but it seems reasonable for it to also 
> > > > work with StringLiteral.
> > > I didn't like the term "size" as it typically refer to the size in bytes.
> > > Which is not the same for a wide-string.
> > > 
> > > Now, there is two different convention for naming matchers:
> > >   hasLength   and  lengthIs  ?
> > > 
> > > Any toughs on that?
> > > 
> > > 
> > Here is the matcher for hasSize
> > ```
> > AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
> >   return Node.getSize() == N;
> > }
> > ```
> > 
> > It's getting the getSize attribute. I believe we should stick with the name 
> > of the attribute.
> > But, I'm not sure if we should use hasLength, or lengthIs.
> I'm not too worried about size vs length (for instance, std::string has 
> both). I would imagine this being implemented the same way we do other things 
> with variance in API but not concept. See GetBodyMatcher in 
> ASTMatchersInternal.h (and others near there) as an example.
> 
> I prefer hasSize because the two concepts are quite similar. For instance, a 
> string literal's type is of a constant array type already.
I do not have strong opinion too on the naming. I'm curious if others also has 
opinion on it?
Then, I'll proceed.


http://reviews.llvm.org/D19876



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


Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-04 Thread Etienne Bergeron via cfe-commits
etienneb added inline comments.


Comment at: lib/ASTMatchers/Dynamic/Marshallers.h:102
@@ +101,3 @@
+  static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
+return llvm::StringSwitch(AttrKind)
+  .Case("CK_Dependent", CK_Dependent)

aaron.ballman wrote:
> This might be an awful idea, but let's explore it.
> 
> What if we moved the CastKind enumerator names into a .def (or .inc) file and 
> use macros to generate the enumeration as well as this monster switch 
> statement? We do this in other places where it makes sense to do so, such as 
> in Expr.h:
> ```
>   enum AtomicOp {
> #define BUILTIN(ID, TYPE, ATTRS)
> #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) AO ## ID,
> #include "clang/Basic/Builtins.def"
> // Avoid trailing comma
> BI_First = 0
>   };
> ```
Does the dynamic matching is used somewhere else than clang-query?
I wonder the impact of refactoring to support them if it's barely used.
It can't be worse than before as it wasn't supported at all (the matcher didn't 
exists).

I believe there is a larger cleanup to do to support correctly dynamic matcher 
like "equals".
And, this case is one among others.

I'm not a fan of this huge switch that may just get out-of-sync with the 
original enum.

I'm still in favor of adding this matcher to the unsupported list until we push 
the more complicated fix.
[which may fall in my plate anyway]

Any toughs?


http://reviews.llvm.org/D19871



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


Re: [PATCH] D19769: [clang-tidy] Add explicitly given array size heuristic to misc-suspicious-missing-comma check.

2016-05-04 Thread Etienne Bergeron via cfe-commits
etienneb requested changes to this revision.
etienneb added a comment.
This revision now requires changes to proceed.

If the 'original' size is available, the checkers should by-pass the heuristic.
Can you check if there is a way to get the original size.



Comment at: clang-tidy/misc/SuspiciousMissingCommaCheck.cpp:106
@@ +105,3 @@
+  if (InitializerList->hasArrayFiller()) {
+  diag(InitializerList->getExprLoc(),
+   "wrong string array initialization: "

szdominik wrote:
> etienneb wrote:
> > The error should still be reported to the missing comma (concatenated 
> > token):
> >   ConcatenatedLiteral->getLocStart(),
> > 
> > We could add a NOTE to point to the array, stating that the size mismatch.
> > 
> > What do you think?
> Interesting question (the first idea was that we can't decide that the comma 
> is missing or the size is wrong, so report to the array, that's a more secure 
> solution), but I agree that the note could be more effective.
> And... it's still a suspicious-missing-comma checker, not a 
> wrong-string-array-size checker :)
How can you be sure the size was provided by the user? And not inferred by the 
type system?

For the following examples:
```
const char* listA[] = {"a", "b" };
const char* listB[5] = {"a", "b" };
```

We've got this:
```
VarDecl 0x5e9d840  col:13 
listA 'const char *[2]' cinit
`-InitListExpr 0x5e9d950  'const char *[2]'
  |-ImplicitCastExpr 0x5e9d978  'const char *' 
  | `-StringLiteral 0x5e9d8d8  'const char [2]' lvalue "a"
  `-ImplicitCastExpr 0x5e9d988  'const char *' 
`-StringLiteral 0x5e9d8fc  'const char [2]' lvalue "b"
```

```
VarDecl 0x5e9d840  col:13 
listA 'const char *[2]' cinit
`-InitListExpr 0x5e9d950  'const char *[2]'
  |-ImplicitCastExpr 0x5e9d978  'const char *' 
  | `-StringLiteral 0x5e9d8d8  'const char [2]' lvalue "a"
  `-ImplicitCastExpr 0x5e9d988  'const char *' 
`-StringLiteral 0x5e9d8fc  'const char [2]' lvalue "b"
```

How can I tell the "size" was written by the user?
How can you get the "5" and not the "2".



http://reviews.llvm.org/D19769



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


Re: [PATCH] D19769: [clang-tidy] Add explicitly given array size heuristic to misc-suspicious-missing-comma check.

2016-05-05 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

In http://reviews.llvm.org/D19769#422317, @szdominik wrote:

> The original size is available - but from the decleration, not from the 
> initListExpr.


Let do the copy paste (correctly):

  clang-query> match namedDecl(hasName("listA"))
  
  Match #1:
  
  Binding for "root":
  VarDecl 0x1a06370  col:13 listA 'const char *[2]' cinit
  `-InitListExpr 0x1a06538  'const char *[2]'
|-ImplicitCastExpr 0x1a06578  'const char *' 
| `-StringLiteral 0x1a06488  'const char [2]' lvalue "a"
`-ImplicitCastExpr 0x1a06598  'const char *' 
  `-StringLiteral 0x1a064b8  'const char [2]' lvalue "b"
  
  1 match.
  clang-query> match namedDecl(hasName("listB"))
  
  Match #1:
  
  Binding for "root":
  VarDecl 0x1a06678  col:13 listB 'const char *[5]' cinit
  `-InitListExpr 0x1a06788  'const char *[5]'
|-array filler
| `-ImplicitValueInitExpr 0x1a06810 <> 'const char *'
|-ImplicitCastExpr 0x1a067c8  'const char *' 
| `-StringLiteral 0x1a066d8  'const char [2]' lvalue "a"
`-ImplicitCastExpr 0x1a067e8  'const char *' 
  `-StringLiteral 0x1a06708  'const char [2]' lvalue "b"

Now, if you are telling me there is a way to handle correctly this example:

const char* A[2] = {"a" "b");

Even using "hasParent" and going to the declaration to get the original 
size this worth implementing it.
Just be sure your matcher won't remove actually supported cases. You first 
proposal was breaking initialization list in initialization list.

So, the plan is:
If the parent is a declaration, and has a size, and the size match skip the 
heuristic even if there is concatenated string literals.

wdyt?


http://reviews.llvm.org/D19769



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


Re: [PATCH] D19876: Add an AST matcher for string-literal length

2016-05-06 Thread Etienne Bergeron via cfe-commits
etienneb added inline comments.


Comment at: include/clang/ASTMatchers/ASTMatchers.h:1578
@@ +1577,3 @@
+/// \endcode
+AST_MATCHER_P(StringLiteral, lengthIs, unsigned, N) {
+  return Node.getLength() == N;

etienneb wrote:
> aaron.ballman wrote:
> > etienneb wrote:
> > > etienneb wrote:
> > > > aaron.ballman wrote:
> > > > > Perhaps we can adjust the `hasSize()` matcher instead? It currently 
> > > > > works with ConstantArrayType, but it seems reasonable for it to also 
> > > > > work with StringLiteral.
> > > > I didn't like the term "size" as it typically refer to the size in 
> > > > bytes.
> > > > Which is not the same for a wide-string.
> > > > 
> > > > Now, there is two different convention for naming matchers:
> > > >   hasLength   and  lengthIs  ?
> > > > 
> > > > Any toughs on that?
> > > > 
> > > > 
> > > Here is the matcher for hasSize
> > > ```
> > > AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
> > >   return Node.getSize() == N;
> > > }
> > > ```
> > > 
> > > It's getting the getSize attribute. I believe we should stick with the 
> > > name of the attribute.
> > > But, I'm not sure if we should use hasLength, or lengthIs.
> > I'm not too worried about size vs length (for instance, std::string has 
> > both). I would imagine this being implemented the same way we do other 
> > things with variance in API but not concept. See GetBodyMatcher in 
> > ASTMatchersInternal.h (and others near there) as an example.
> > 
> > I prefer hasSize because the two concepts are quite similar. For instance, 
> > a string literal's type is of a constant array type already.
> I do not have strong opinion too on the naming. I'm curious if others also 
> has opinion on it?
> Then, I'll proceed.
>  For instance, a string literal's type

stringLiteral is matching an expression and not a type.
And, hasSize is currently applied on types.
Do we want this?


http://reviews.llvm.org/D19876



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


Re: [PATCH] D19876: Add an AST matcher for string-literal length

2016-05-06 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56423.
etienneb added a comment.

merging hasSize


http://reviews.llvm.org/D19876

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  include/clang/ASTMatchers/ASTMatchersInternal.h
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -2536,6 +2536,17 @@
   EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
 }
 
+TEST(StringLiteral, LengthIs) {
+  StatementMatcher Literal = stringLiteral(lengthIs(4));
+  EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
+  // wide string
+  EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
+  // with escaped characters
+  EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
+  // no matching, too small
+  EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
+}
+
 TEST(Matcher, CharacterLiterals) {
   StatementMatcher CharLiteral = characterLiteral();
   EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1651,6 +1651,19 @@
 }
 
 template 
+struct HasSizeMatcher {
+  static bool hasSize(const Ty &Node, unsigned int N) {
+return Node.getSize() == N;
+  }
+};
+
+template <>
+inline bool HasSizeMatcher::hasSize(
+const StringLiteral &Node, unsigned int N) {
+  return Node.getLength() == N;
+}
+
+template 
 struct GetSourceExpressionMatcher {
   static const Expr *get(const Ty &Node) {
 return Node.getSubExpr();
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -1560,7 +1560,8 @@
 ///
 /// Example matches "abcd", L"abcd"
 /// \code
-///   char *s = "abcd"; wchar_t *ws = L"abcd"
+///   char *s = "abcd";
+///   wchar_t *ws = L"abcd";
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -1573,7 +1574,8 @@
 ///
 /// Example matches 'a', L'a'
 /// \code
-///   char ch = 'a'; wchar_t chw = L'a';
+///   char ch = 'a';
+///   wchar_t chw = L'a';
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -1609,7 +1611,8 @@
 ///
 /// Example match: {1}, (1, 2)
 /// \code
-///   int array[4] = {1}; vector int myvec = (vector int)(1, 2);
+///   int array[4] = {1};
+///   vector int myvec = (vector int)(1, 2);
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -4228,18 +4231,26 @@
 ///   matches "int a[2]"
 AST_TYPE_MATCHER(ConstantArrayType, constantArrayType);
 
-/// \brief Matches \c ConstantArrayType nodes that have the specified size.
+/// \brief Matches nodes that have the specified size.
 ///
 /// Given
 /// \code
 ///   int a[42];
 ///   int b[2 * 21];
 ///   int c[41], d[43];
+///   char *s = "abcd";
+///   wchar_t *ws = L"abcd";
+///   char *w = "a";
 /// \endcode
 /// constantArrayType(hasSize(42))
 ///   matches "int a[42]" and "int b[2 * 21]"
-AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
-  return Node.getSize() == N;
+/// stringLiteral(lengthIs(4))
+///   matches "abcd", L"abcd"
+AST_POLYMORPHIC_MATCHER_P(hasSize,
+  AST_POLYMORPHIC_SUPPORTED_TYPES(ConstantArrayType,
+  StringLiteral),
+  unsigned, N) {
+  return internal::HasSizeMatcher::hasSize(Node, N);
 }
 
 /// \brief Matches C++ arrays whose size is a value-dependent expression.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19876: Add an AST matcher for string-literal length

2016-05-06 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56425.
etienneb added a comment.

fix unittests


http://reviews.llvm.org/D19876

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  include/clang/ASTMatchers/ASTMatchersInternal.h
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -51,7 +51,6 @@
 
   // Do not accept non-toplevel matchers.
   EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), nullptr));
-  EXPECT_FALSE(Finder.addDynamicMatcher(hasSize(2), nullptr));
   EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr));
 }
 
@@ -2536,6 +2535,17 @@
   EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
 }
 
+TEST(StringLiteral, HasSize) {
+  StatementMatcher Literal = stringLiteral(hasSize(4));
+  EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
+  // wide string
+  EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
+  // with escaped characters
+  EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
+  // no matching, too small
+  EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
+}
+
 TEST(Matcher, CharacterLiterals) {
   StatementMatcher CharLiteral = characterLiteral();
   EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1651,6 +1651,19 @@
 }
 
 template 
+struct HasSizeMatcher {
+  static bool hasSize(const Ty &Node, unsigned int N) {
+return Node.getSize() == N;
+  }
+};
+
+template <>
+inline bool HasSizeMatcher::hasSize(
+const StringLiteral &Node, unsigned int N) {
+  return Node.getLength() == N;
+}
+
+template 
 struct GetSourceExpressionMatcher {
   static const Expr *get(const Ty &Node) {
 return Node.getSubExpr();
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -1560,7 +1560,8 @@
 ///
 /// Example matches "abcd", L"abcd"
 /// \code
-///   char *s = "abcd"; wchar_t *ws = L"abcd"
+///   char *s = "abcd";
+///   wchar_t *ws = L"abcd";
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -1573,7 +1574,8 @@
 ///
 /// Example matches 'a', L'a'
 /// \code
-///   char ch = 'a'; wchar_t chw = L'a';
+///   char ch = 'a';
+///   wchar_t chw = L'a';
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -1609,7 +1611,8 @@
 ///
 /// Example match: {1}, (1, 2)
 /// \code
-///   int array[4] = {1}; vector int myvec = (vector int)(1, 2);
+///   int array[4] = {1};
+///   vector int myvec = (vector int)(1, 2);
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -4228,18 +4231,26 @@
 ///   matches "int a[2]"
 AST_TYPE_MATCHER(ConstantArrayType, constantArrayType);
 
-/// \brief Matches \c ConstantArrayType nodes that have the specified size.
+/// \brief Matches nodes that have the specified size.
 ///
 /// Given
 /// \code
 ///   int a[42];
 ///   int b[2 * 21];
 ///   int c[41], d[43];
+///   char *s = "abcd";
+///   wchar_t *ws = L"abcd";
+///   char *w = "a";
 /// \endcode
 /// constantArrayType(hasSize(42))
 ///   matches "int a[42]" and "int b[2 * 21]"
-AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
-  return Node.getSize() == N;
+/// stringLiteral(hasSize(4))
+///   matches "abcd", L"abcd"
+AST_POLYMORPHIC_MATCHER_P(hasSize,
+  AST_POLYMORPHIC_SUPPORTED_TYPES(ConstantArrayType,
+  StringLiteral),
+  unsigned, N) {
+  return internal::HasSizeMatcher::hasSize(Node, N);
 }
 
 /// \brief Matches C++ arrays whose size is a value-dependent expression.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19876: Add an AST matcher for string-literal length

2016-05-06 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

Aaron? minus re-generation of the doc.
Is that what you want to see?

note: returned types for both getLength are not the same (APInt vs unsigned 
int).
I took the 'hasSize'-Matcher approach to let overloaded operators do the job 
for dispatching types.

note: there is a unittest for top-level node that is no longer valid because 
stringLiteral can be a top-level node now.


http://reviews.llvm.org/D19876



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


Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-06 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56427.
etienneb added a comment.

revert to previous solution


http://reviews.llvm.org/D19871

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3475,6 +3475,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -75,6 +75,7 @@
   // TODO: Here is the list of the missing matchers, grouped by reason.
   //
   // Need Variant/Parser fixes:
+  // hasCastKind  
   // ofKind
   //
   // Polymorphic + argument overload:
@@ -210,6 +211,7 @@
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasCaseConstant);
+  REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDecayedType);
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3548,6 +3548,17 @@
   InnerMatcher.matches(*SubExpression, Finder, Builder));
 }
 
+/// \brief Matches casts that has a given cast kind.
+///
+/// Example: matches the implicit cast around \c 0
+/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
+/// \code
+///   int *p = 0;
+/// \endcode
+AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
+  return Node.getCastKind() == Kind;
+}
+
 /// \brief Matches casts whose destination type matches a given matcher.
 ///
 /// (Note: Clang's AST refers to other conversions as "casts" too, and calls


Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3475,6 +3475,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -75,6 +75,7 @@
   // TODO: Here is the list of the missing matchers, grouped by reason.
   //
   // Need Variant/Parser fixes:
+  // hasCastKind  
   // ofKind
   //
   // Polymorphic + argument overload:
@@ -210,6 +211,7 @@
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasCaseConstant);
+  REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDecayedType);
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3548,6 +3548,17 @@
   InnerMatcher.matches(*SubExpression, Finder, Builder));
 }
 
+/// \brief Matches casts that has a given cast kind.
+///
+/// Example: matches the implicit cast around \c 0
+/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
+/// \code
+///   int *p = 0;
+/// \endcode
+AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
+  return Node.getCastKind() == Kind;
+}
+
 /// \brief Matches casts whose destination type matches a given matcher.
 ///
 /// (Note: Clang's AST refers to other conversions as "casts" too, and calls
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-06 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56428.
etienneb added a comment.

fix unittests


http://reviews.llvm.org/D19871

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

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3475,6 +3475,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -75,6 +75,7 @@
   // TODO: Here is the list of the missing matchers, grouped by reason.
   //
   // Need Variant/Parser fixes:
+  // hasCastKind  
   // ofKind
   //
   // Polymorphic + argument overload:
@@ -210,6 +211,7 @@
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasCaseConstant);
+  REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDecayedType);
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3548,6 +3548,17 @@
   InnerMatcher.matches(*SubExpression, Finder, Builder));
 }
 
+/// \brief Matches casts that has a given cast kind.
+///
+/// Example: matches the implicit cast around \c 0
+/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
+/// \code
+///   int *p = 0;
+/// \endcode
+AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
+  return Node.getCastKind() == Kind;
+}
+
 /// \brief Matches casts whose destination type matches a given matcher.
 ///
 /// (Note: Clang's AST refers to other conversions as "casts" too, and calls
Index: docs/LibASTMatchersReference.html
===
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -2156,6 +2156,15 @@
 
 
 
+MatcherCastExpr>hasCastKindCastKind Kind
+Matches casts that has 
a given cast kind.
+
+Example: matches the implicit cast around 0
+(matcher = castExpr(hasCastKind(CK_NullToPointer)))
+  int *p = 0;
+
+
+
 MatcherCharacterLiteral>equalsValueT  Value
 Matches literals that are 
equal to the given value.
 


Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3475,6 +3475,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -75,6 +75,7 @@
   // TODO: Here is the list of the missing matchers, grouped by reason.
   //
   // Need Variant/Parser fixes:
+  // hasCastKind  
   // ofKind
   //
   // Polymorphic + argument overload:
@@ -210,6 +211,7 @@
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasCaseConstant);
+  REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDecayedType);
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3548,6 +3548,17 @@
   InnerMatcher.matches(*SubExpression, Finder, Builder));
 }
 
+/// \brief Matches casts that has a given cast kind.
+///
+/// Example: matches the implicit cast around \c 0
+/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
+/// \code
+///   int *p = 0;
+/// \endcode
+AST_MATCHER_P(CastExpr, hasCastKind, C

Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-06 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

Get back to this solution.
comments?


http://reviews.llvm.org/D19871



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


Re: [PATCH] D19846: [clang-tidy] Lift parsing of sequence of names functions to utils.

2016-05-10 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56723.
etienneb added a comment.

fix alexfh comments (renaming)


http://reviews.llvm.org/D19846

Files:
  clang-tidy/misc/DanglingHandleCheck.cpp
  clang-tidy/misc/SuspiciousStringCompareCheck.cpp
  clang-tidy/performance/FasterStringFindCheck.cpp
  clang-tidy/utils/CMakeLists.txt
  clang-tidy/utils/OptionsUtils.cpp
  clang-tidy/utils/OptionsUtils.h

Index: clang-tidy/utils/OptionsUtils.h
===
--- /dev/null
+++ clang-tidy/utils/OptionsUtils.h
@@ -0,0 +1,32 @@
+//===--- DanglingHandleCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+namespace options {
+
+/// \brief Parse a semicolon separated list of strings.
+std::vector parseStringList(StringRef Option);
+
+/// \brief Serialize a sequence of names that can be parsed by
+/// 'parseStringList'.
+std::string serializeStringList(ArrayRef Strings);
+
+} // namespace options
+} // namespace utils
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_OPTIONUTILS_H
Index: clang-tidy/utils/OptionsUtils.cpp
===
--- /dev/null
+++ clang-tidy/utils/OptionsUtils.cpp
@@ -0,0 +1,38 @@
+//===--- DanglingHandleCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "OptionsUtils.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+namespace options {
+
+static const char StringsDelimiter[] = ";";
+
+std::vector parseStringList(StringRef Option) {
+  SmallVector Names;
+  Option.split(Names, StringsDelimiter);
+  std::vector Result;
+  for (StringRef &Name : Names) {
+Name = Name.trim();
+if (!Name.empty())
+  Result.push_back(Name);
+  }
+  return Result;
+}
+
+std::string serializeStringList(ArrayRef Strings) {
+  return llvm::join(Strings.begin(), Strings.end(), StringsDelimiter);
+}
+
+} // namespace options
+} // namespace utils
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/utils/CMakeLists.txt
===
--- clang-tidy/utils/CMakeLists.txt
+++ clang-tidy/utils/CMakeLists.txt
@@ -3,11 +3,12 @@
 add_clang_library(clangTidyUtils
   DeclRefExprUtils.cpp
   FixItHintUtils.cpp
-  HeaderGuard.cpp
   HeaderFileExtensionsUtils.cpp
+  HeaderGuard.cpp
   IncludeInserter.cpp
   IncludeSorter.cpp
   LexerUtils.cpp
+  OptionsUtils.cpp
   TypeTraits.cpp
 
   LINK_LIBS
Index: clang-tidy/performance/FasterStringFindCheck.cpp
===
--- clang-tidy/performance/FasterStringFindCheck.cpp
+++ clang-tidy/performance/FasterStringFindCheck.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include "FasterStringFindCheck.h"
+#include "../utils/OptionsUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "llvm/ADT/Optional.h"
@@ -21,20 +22,6 @@
 
 namespace {
 
-static const char StringLikeClassesDelimiter[] = ";";
-
-std::vector ParseClasses(StringRef Option) {
-  SmallVector Classes;
-  Option.split(Classes, StringLikeClassesDelimiter);
-  std::vector Result;
-  for (StringRef &Class : Classes) {
-Class = Class.trim();
-if (!Class.empty())
-  Result.push_back(Class);
-  }
-  return Result;
-}
-
 llvm::Optional MakeCharacterLiteral(const StringLiteral *Literal) {
   std::string Result;
   {
@@ -64,14 +51,13 @@
 FasterStringFindCheck::FasterStringFindCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
-  StringLikeClasses(
-  ParseClasses(Options.get("StringLikeClasses", "std::basic_string"))) {
+  StringLikeClasses(utils::options::parseStringList(
+  Options.get("StringLikeClasses", "std::basic_string"))) {
 }
 
 void FasterStringFindCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "StringLikeClasses",
-llvm::join(StringLikeClasses.begin(), StringLikeClasses.end(),
-   StringLikeClassesDelimiter));
+utils::options::serializeStringList(StringLikeClasses));
 }
 
 void FasterStringFin

Re: [PATCH] D19846: [clang-tidy] Lift parsing of sequence of names functions to utils.

2016-05-10 Thread Etienne Bergeron via cfe-commits
etienneb marked an inline comment as done.
etienneb added a comment.

renaming done, landing.


http://reviews.llvm.org/D19846



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


[clang-tools-extra] r269065 - [clang-tidy] Lift parsing of sequence of names functions to utils.

2016-05-10 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Tue May 10 10:31:15 2016
New Revision: 269065

URL: http://llvm.org/viewvc/llvm-project?rev=269065&view=rev
Log:
[clang-tidy] Lift parsing of sequence of names functions to utils.

Summary:
Lift some common code used by multiple checkers.

This function is also used by checkers that are coming.
It is quite common for a checker to parse a list of names.

Reviewers: alexfh

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D19846

Added:
clang-tools-extra/trunk/clang-tidy/utils/OptionsUtils.cpp
clang-tools-extra/trunk/clang-tidy/utils/OptionsUtils.h
Modified:
clang-tools-extra/trunk/clang-tidy/misc/DanglingHandleCheck.cpp
clang-tools-extra/trunk/clang-tidy/misc/SuspiciousStringCompareCheck.cpp
clang-tools-extra/trunk/clang-tidy/performance/FasterStringFindCheck.cpp
clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt

Modified: clang-tools-extra/trunk/clang-tidy/misc/DanglingHandleCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/DanglingHandleCheck.cpp?rev=269065&r1=269064&r2=269065&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/misc/DanglingHandleCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/DanglingHandleCheck.cpp Tue May 10 
10:31:15 2016
@@ -8,6 +8,7 @@
 
//===--===//
 
 #include "DanglingHandleCheck.h"
+#include "../utils/OptionsUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 
@@ -19,20 +20,6 @@ namespace misc {
 
 namespace {
 
-static const char HandleClassesDelimiter[] = ";";
-
-std::vector parseClasses(StringRef Option) {
-  SmallVector Classes;
-  Option.split(Classes, HandleClassesDelimiter);
-  std::vector Result;
-  for (StringRef &Class : Classes) {
-Class = Class.trim();
-if (!Class.empty())
-  Result.push_back(Class);
-  }
-  return Result;
-}
-
 ast_matchers::internal::BindableMatcher
 handleFrom(ast_matchers::internal::Matcher IsAHandle,
ast_matchers::internal::Matcher Arg) {
@@ -97,7 +84,7 @@ makeContainerMatcher(ast_matchers::inter
 DanglingHandleCheck::DanglingHandleCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
-  HandleClasses(parseClasses(Options.get(
+  HandleClasses(utils::options::parseStringList(Options.get(
   "HandleClasses",
   "std::basic_string_view;std::experimental::basic_string_view"))),
   IsAHandle(cxxRecordDecl(hasAnyName(std::vector(
@@ -106,8 +93,7 @@ DanglingHandleCheck::DanglingHandleCheck
 
 void DanglingHandleCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "HandleClasses",
-llvm::join(HandleClasses.begin(), HandleClasses.end(),
-   HandleClassesDelimiter));
+utils::options::serializeStringList(HandleClasses));
 }
 
 void DanglingHandleCheck::registerMatchersForVariables(MatchFinder *Finder) {

Modified: 
clang-tools-extra/trunk/clang-tidy/misc/SuspiciousStringCompareCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/SuspiciousStringCompareCheck.cpp?rev=269065&r1=269064&r2=269065&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/misc/SuspiciousStringCompareCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/misc/SuspiciousStringCompareCheck.cpp 
Tue May 10 10:31:15 2016
@@ -8,10 +8,11 @@
 
//===--===//
 
 #include "SuspiciousStringCompareCheck.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
-#include "../utils/Matchers.h"
 
 using namespace clang::ast_matchers;
 
@@ -19,6 +20,9 @@ namespace clang {
 namespace tidy {
 namespace misc {
 
+
+// Semicolon separated list of known string compare-like functions. The list
+// must ends with a semicolon.
 static const char KnownStringCompareFunctions[] = "__builtin_memcmp;"
   "__builtin_strcasecmp;"
   "__builtin_strcmp;"
@@ -64,19 +68,6 @@ static const char KnownStringCompareFunc
   "wcsnicmp;"
   "wmemcmp;";
 
-static const char StringCompareLikeFunctionsDelimiter[] = ";";
-
-static void ParseFunctionNames(StringRef Option,
-   std::vector *Result) {
-  SmallVector Functions;
-  Option.split(Functions, StringCompareLikeFunctionsDelimiter);
-  for (StringRef &Function : Functions) {
-Function = Function.trim();
-if (!Function.empty())

Re: [PATCH] D19941: [clang-tidy] FixItHint Tooling refactoring

2016-05-10 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56781.
etienneb marked 3 inline comments as done.
etienneb added a comment.

add unittests


http://reviews.llvm.org/D19941

Files:
  include/clang/Tooling/Fixit.h
  lib/Tooling/CMakeLists.txt
  lib/Tooling/Fixit.cpp
  unittests/Tooling/CMakeLists.txt
  unittests/Tooling/FixitTest.cpp

Index: unittests/Tooling/FixitTest.cpp
===
--- /dev/null
+++ unittests/Tooling/FixitTest.cpp
@@ -0,0 +1,163 @@
+//===- unittest/Tooling/FixitTest.cpp ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "TestVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Tooling/Fixit.h"
+
+using namespace clang;
+
+namespace {
+
+struct CallsVisitor : TestVisitor {
+  bool VisitCallExpr(CallExpr *Expr) {
+OnCall(Expr, Context);
+return true;
+  }
+
+  std::function OnCall;
+};
+
+std::string LocationToString(SourceLocation Loc, ASTContext *Context) {
+  return Loc.printToString(Context->getSourceManager());
+}
+
+TEST(FixitTest, getText) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("foo(x, y)", tooling::fixit::getText(*CE, *Context));
+EXPECT_EQ("foo(x, y)",
+  tooling::fixit::getText(CE->getSourceRange(), *Context));
+
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("x", tooling::fixit::getText(*P0, *Context));
+EXPECT_EQ("y", tooling::fixit::getText(*P1, *Context));
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("APPLY(foo, x, y)", tooling::fixit::getText(*CE, *Context));
+  };
+  Visitor.runOver("#define APPLY(f, x, y) f(x, y)\n"
+  "void foo(int x, int y) { APPLY(foo, x, y); }");
+}
+
+TEST(FixitTest, createRemoval) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = tooling::fixit::createRemoval(*CE);
+EXPECT_EQ("foo(x, y)",
+  tooling::fixit::getText(Hint.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint.CodeToInsert.empty());
+
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = tooling::fixit::createRemoval(*P0);
+EXPECT_EQ(
+"x", tooling::fixit::getText(Hint0.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint0.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint0.CodeToInsert.empty());
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = tooling::fixit::createRemoval(*P1);
+EXPECT_EQ(
+"y", tooling::fixit::getText(Hint1.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint1.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint1.CodeToInsert.empty());
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+}
+
+TEST(FixitTest, createRemovalWithMacro) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = tooling::fixit::createRemoval(*CE);
+EXPECT_EQ("FOO",
+  tooling::fixit::getText(Hint.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint.CodeToInsert.empty());
+
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = tooling::fixit::createRemoval(*P0);
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToString(Hint0.RemoveRange.getBegin(), Context));
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToString(Hint0.RemoveRange.getEnd(), Context));
+EXPECT_TRUE(Hint0.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint0.CodeToInsert.empty());
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = tooling::fixit::createRemoval(*P1);
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToString(Hint1.RemoveRange.getBegin(), Context));
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToString(Hint1.RemoveRange.getEnd(), Context));
+EXPECT_TRUE(Hint1.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint1.CodeToInsert.empty());
+  };
+  Visitor.runOver("#define FOO foo(1, 1)\n"
+  "void foo(int x, int y) { FOO; }");
+}
+
+TEST(FixitTest, createReplacement) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+FixItHint Hint0 = tooling::fixit::createReplacement(*P0, *P1, *Context);
+FixItHint Hint1 = tooling::fixit::createReplacement(*P1, *P0, *Context);
+
+// Validate Hint0 fields.
+EXPECT_EQ(
+"x", tooling::fixit::getText(Hint0.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint0.InsertFromRange.isInvalid());
+EXPECT_EQ(Hint0.CodeToInser

Re: [PATCH] D19941: [tooling] FixItHint Tooling refactoring

2016-05-10 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56790.
etienneb added a comment.

more unittests


http://reviews.llvm.org/D19941

Files:
  include/clang/Tooling/Fixit.h
  lib/Tooling/CMakeLists.txt
  lib/Tooling/Fixit.cpp
  unittests/Tooling/CMakeLists.txt
  unittests/Tooling/FixitTest.cpp

Index: unittests/Tooling/FixitTest.cpp
===
--- /dev/null
+++ unittests/Tooling/FixitTest.cpp
@@ -0,0 +1,214 @@
+//===- unittest/Tooling/FixitTest.cpp ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "TestVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Tooling/Fixit.h"
+
+using namespace clang;
+
+namespace {
+
+struct CallsVisitor : TestVisitor {
+  bool VisitCallExpr(CallExpr *Expr) {
+OnCall(Expr, Context);
+return true;
+  }
+
+  std::function OnCall;
+};
+
+std::string LocationToString(SourceLocation Loc, ASTContext *Context) {
+  return Loc.printToString(Context->getSourceManager());
+}
+
+TEST(FixitTest, getText) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("foo(x, y)", tooling::fixit::getText(*CE, *Context));
+EXPECT_EQ("foo(x, y)",
+  tooling::fixit::getText(CE->getSourceRange(), *Context));
+
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("x", tooling::fixit::getText(*P0, *Context));
+EXPECT_EQ("y", tooling::fixit::getText(*P1, *Context));
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("APPLY(foo, x, y)", tooling::fixit::getText(*CE, *Context));
+  };
+  Visitor.runOver("#define APPLY(f, x, y) f(x, y)\n"
+  "void foo(int x, int y) { APPLY(foo, x, y); }");
+}
+
+TEST(FixitTest, getTextWithMacro) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("F OO", tooling::fixit::getText(*CE, *Context));
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("", tooling::fixit::getText(*P0, *Context));
+EXPECT_EQ("", tooling::fixit::getText(*P1, *Context));
+  };
+  Visitor.runOver("#define F foo(\n"
+  "#define OO x, y)\n"
+  "void foo(int x, int y) { F OO ; }");
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("", tooling::fixit::getText(*CE, *Context));
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("x", tooling::fixit::getText(*P0, *Context));
+EXPECT_EQ("y", tooling::fixit::getText(*P1, *Context));
+  };
+  Visitor.runOver("#define FOO(x, y) (void)x; (void)y; foo(x, y);\n"
+  "void foo(int x, int y) { FOO(x,y) }");
+}
+
+TEST(FixitTest, createRemoval) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = tooling::fixit::createRemoval(*CE);
+EXPECT_EQ("foo(x, y)",
+  tooling::fixit::getText(Hint.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint.CodeToInsert.empty());
+
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = tooling::fixit::createRemoval(*P0);
+EXPECT_EQ(
+"x", tooling::fixit::getText(Hint0.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint0.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint0.CodeToInsert.empty());
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = tooling::fixit::createRemoval(*P1);
+EXPECT_EQ(
+"y", tooling::fixit::getText(Hint1.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint1.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint1.CodeToInsert.empty());
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+}
+
+TEST(FixitTest, createRemovalWithMacro) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = tooling::fixit::createRemoval(*CE);
+EXPECT_EQ("FOO",
+  tooling::fixit::getText(Hint.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint.CodeToInsert.empty());
+
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = tooling::fixit::createRemoval(*P0);
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToString(Hint0.RemoveRange.getBegin(), Context));
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToString(Hint0.RemoveRange.getEnd(), Context));
+EXPECT_TRUE(Hint0.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint0.CodeToInsert.empty());
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = tooling::fixit::createRemoval(*P1);
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToStrin

Re: [PATCH] D19941: [tooling] FixItHint Tooling refactoring

2016-05-10 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56825.
etienneb marked 5 inline comments as done.
etienneb added a comment.

address alexfh comments


http://reviews.llvm.org/D19941

Files:
  include/clang/Tooling/FixIt.h
  lib/Tooling/CMakeLists.txt
  lib/Tooling/FixIt.cpp
  unittests/Tooling/CMakeLists.txt
  unittests/Tooling/FixItTest.cpp

Index: unittests/Tooling/FixItTest.cpp
===
--- /dev/null
+++ unittests/Tooling/FixItTest.cpp
@@ -0,0 +1,238 @@
+//===- unittest/Tooling/FixitTest.cpp ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "TestVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang;
+
+namespace {
+
+struct CallsVisitor : TestVisitor {
+  bool VisitCallExpr(CallExpr *Expr) {
+OnCall(Expr, Context);
+return true;
+  }
+
+  std::function OnCall;
+};
+
+std::string LocationToString(SourceLocation Loc, ASTContext *Context) {
+  return Loc.printToString(Context->getSourceManager());
+}
+
+TEST(FixitTest, getText) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("foo(x, y)", tooling::fixit::getText(*CE, *Context));
+EXPECT_EQ("foo(x, y)",
+  tooling::fixit::getText(CE->getSourceRange(), *Context));
+
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("x", tooling::fixit::getText(*P0, *Context));
+EXPECT_EQ("y", tooling::fixit::getText(*P1, *Context));
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+
+  Visitor.OnCall = [&](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("APPLY(foo, x, y)", tooling::fixit::getText(*CE, *Context));
+  };
+  Visitor.runOver("#define APPLY(f, x, y) f(x, y)\n"
+  "void foo(int x, int y) { APPLY(foo, x, y); }");
+}
+
+TEST(FixitTest, getTextWithMacro) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("F OO", tooling::fixit::getText(*CE, *Context));
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("", tooling::fixit::getText(*P0, *Context));
+EXPECT_EQ("", tooling::fixit::getText(*P1, *Context));
+  };
+  Visitor.runOver("#define F foo(\n"
+  "#define OO x, y)\n"
+  "void foo(int x, int y) { F OO ; }");
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("", tooling::fixit::getText(*CE, *Context));
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("x", tooling::fixit::getText(*P0, *Context));
+EXPECT_EQ("y", tooling::fixit::getText(*P1, *Context));
+  };
+  Visitor.runOver("#define FOO(x, y) (void)x; (void)y; foo(x, y);\n"
+  "void foo(int x, int y) { FOO(x,y) }");
+}
+
+TEST(FixitTest, createRemoval) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = tooling::fixit::createRemoval(*CE);
+EXPECT_EQ("foo(x, y)",
+  tooling::fixit::getText(Hint.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint.CodeToInsert.empty());
+
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = tooling::fixit::createRemoval(*P0);
+EXPECT_EQ(
+"x", tooling::fixit::getText(Hint0.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint0.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint0.CodeToInsert.empty());
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = tooling::fixit::createRemoval(*P1);
+EXPECT_EQ(
+"y", tooling::fixit::getText(Hint1.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint1.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint1.CodeToInsert.empty());
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = tooling::fixit::createRemoval(*P0);
+EXPECT_EQ("x + y", tooling::fixit::getText(Hint0.RemoveRange.getAsRange(),
+   *Context));
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = tooling::fixit::createRemoval(*P1);
+EXPECT_EQ("y + x", tooling::fixit::getText(Hint1.RemoveRange.getAsRange(),
+   *Context));
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x + y, y + x); }");
+}
+
+TEST(FixitTest, createRemovalWithMacro) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = tooling::fixit::createRemoval(*CE);
+EXPECT_EQ("FOO",
+  tooling::fixit::getText(Hint.RemoveRange.getAsRange(), *Context));
+E

Re: [PATCH] D19941: [tooling] FixItHint Tooling refactoring

2016-05-10 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56826.
etienneb added a comment.

nits


http://reviews.llvm.org/D19941

Files:
  include/clang/Tooling/FixIt.h
  lib/Tooling/CMakeLists.txt
  lib/Tooling/FixIt.cpp
  unittests/Tooling/CMakeLists.txt
  unittests/Tooling/FixItTest.cpp

Index: unittests/Tooling/FixItTest.cpp
===
--- /dev/null
+++ unittests/Tooling/FixItTest.cpp
@@ -0,0 +1,238 @@
+//===- unittest/Tooling/FixitTest.cpp ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "TestVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang;
+
+namespace {
+
+struct CallsVisitor : TestVisitor {
+  bool VisitCallExpr(CallExpr *Expr) {
+OnCall(Expr, Context);
+return true;
+  }
+
+  std::function OnCall;
+};
+
+std::string LocationToString(SourceLocation Loc, ASTContext *Context) {
+  return Loc.printToString(Context->getSourceManager());
+}
+
+TEST(FixItTest, getText) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("foo(x, y)", tooling::fixit::getText(*CE, *Context));
+EXPECT_EQ("foo(x, y)",
+  tooling::fixit::getText(CE->getSourceRange(), *Context));
+
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("x", tooling::fixit::getText(*P0, *Context));
+EXPECT_EQ("y", tooling::fixit::getText(*P1, *Context));
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("APPLY(foo, x, y)", tooling::fixit::getText(*CE, *Context));
+  };
+  Visitor.runOver("#define APPLY(f, x, y) f(x, y)\n"
+  "void foo(int x, int y) { APPLY(foo, x, y); }");
+}
+
+TEST(FixItTest, getTextWithMacro) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("F OO", tooling::fixit::getText(*CE, *Context));
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("", tooling::fixit::getText(*P0, *Context));
+EXPECT_EQ("", tooling::fixit::getText(*P1, *Context));
+  };
+  Visitor.runOver("#define F foo(\n"
+  "#define OO x, y)\n"
+  "void foo(int x, int y) { F OO ; }");
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("", tooling::fixit::getText(*CE, *Context));
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("x", tooling::fixit::getText(*P0, *Context));
+EXPECT_EQ("y", tooling::fixit::getText(*P1, *Context));
+  };
+  Visitor.runOver("#define FOO(x, y) (void)x; (void)y; foo(x, y);\n"
+  "void foo(int x, int y) { FOO(x,y) }");
+}
+
+TEST(FixItTest, createRemoval) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = tooling::fixit::createRemoval(*CE);
+EXPECT_EQ("foo(x, y)",
+  tooling::fixit::getText(Hint.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint.CodeToInsert.empty());
+
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = tooling::fixit::createRemoval(*P0);
+EXPECT_EQ(
+"x", tooling::fixit::getText(Hint0.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint0.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint0.CodeToInsert.empty());
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = tooling::fixit::createRemoval(*P1);
+EXPECT_EQ(
+"y", tooling::fixit::getText(Hint1.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint1.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint1.CodeToInsert.empty());
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = tooling::fixit::createRemoval(*P0);
+EXPECT_EQ("x + y", tooling::fixit::getText(Hint0.RemoveRange.getAsRange(),
+   *Context));
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = tooling::fixit::createRemoval(*P1);
+EXPECT_EQ("y + x", tooling::fixit::getText(Hint1.RemoveRange.getAsRange(),
+   *Context));
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x + y, y + x); }");
+}
+
+TEST(FixItTest, createRemovalWithMacro) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = tooling::fixit::createRemoval(*CE);
+EXPECT_EQ("FOO",
+  tooling::fixit::getText(Hint.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint.InsertFromRange.isInvalid());
+EXPECT_TRUE(H

Re: [PATCH] D19941: [tooling] FixItHint Tooling refactoring

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56907.
etienneb marked an inline comment as done.
etienneb added a comment.

fix nits


http://reviews.llvm.org/D19941

Files:
  include/clang/Tooling/FixIt.h
  lib/Tooling/CMakeLists.txt
  lib/Tooling/FixIt.cpp
  unittests/Tooling/CMakeLists.txt
  unittests/Tooling/FixItTest.cpp

Index: unittests/Tooling/FixItTest.cpp
===
--- /dev/null
+++ unittests/Tooling/FixItTest.cpp
@@ -0,0 +1,232 @@
+//===- unittest/Tooling/FixitTest.cpp ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "TestVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang;
+
+using tooling::fixit::getText;
+using tooling::fixit::createRemoval;
+using tooling::fixit::createReplacement;
+
+namespace {
+
+struct CallsVisitor : TestVisitor {
+  bool VisitCallExpr(CallExpr *Expr) {
+OnCall(Expr, Context);
+return true;
+  }
+
+  std::function OnCall;
+};
+
+std::string LocationToString(SourceLocation Loc, ASTContext *Context) {
+  return Loc.printToString(Context->getSourceManager());
+}
+
+TEST(FixItTest, getText) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("foo(x, y)", getText(*CE, *Context));
+EXPECT_EQ("foo(x, y)", getText(CE->getSourceRange(), *Context));
+
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("x", getText(*P0, *Context));
+EXPECT_EQ("y", getText(*P1, *Context));
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("APPLY(foo, x, y)", getText(*CE, *Context));
+  };
+  Visitor.runOver("#define APPLY(f, x, y) f(x, y)\n"
+  "void foo(int x, int y) { APPLY(foo, x, y); }");
+}
+
+TEST(FixItTest, getTextWithMacro) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("F OO", getText(*CE, *Context));
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("", getText(*P0, *Context));
+EXPECT_EQ("", getText(*P1, *Context));
+  };
+  Visitor.runOver("#define F foo(\n"
+  "#define OO x, y)\n"
+  "void foo(int x, int y) { F OO ; }");
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("", getText(*CE, *Context));
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("x", getText(*P0, *Context));
+EXPECT_EQ("y", getText(*P1, *Context));
+  };
+  Visitor.runOver("#define FOO(x, y) (void)x; (void)y; foo(x, y);\n"
+  "void foo(int x, int y) { FOO(x,y) }");
+}
+
+TEST(FixItTest, createRemoval) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = createRemoval(*CE);
+EXPECT_EQ("foo(x, y)", getText(Hint.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint.CodeToInsert.empty());
+
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = createRemoval(*P0);
+EXPECT_EQ("x", getText(Hint0.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint0.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint0.CodeToInsert.empty());
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = createRemoval(*P1);
+EXPECT_EQ("y", getText(Hint1.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint1.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint1.CodeToInsert.empty());
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = createRemoval(*P0);
+EXPECT_EQ("x + y", getText(Hint0.RemoveRange.getAsRange(), *Context));
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = createRemoval(*P1);
+EXPECT_EQ("y + x", getText(Hint1.RemoveRange.getAsRange(), *Context));
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x + y, y + x); }");
+}
+
+TEST(FixItTest, createRemovalWithMacro) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = createRemoval(*CE);
+EXPECT_EQ("FOO", getText(Hint.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint.CodeToInsert.empty());
+
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = createRemoval(*P0);
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToString(Hint0.RemoveRange.getBegin(), Context));
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToString(Hint0.RemoveRange.getEnd(), Context));
+EXPECT_TRUE(Hint0.InsertFromRange.isInvalid());
+ 

Re: [PATCH] D19941: [tooling] FixItHint Tooling refactoring

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

I added the "using statements".
landing.



Comment at: include/clang/Tooling/Fixit.h:35
@@ +34,3 @@
+///used by the following template abstractions.
+inline SourceRange getSourceRange(const SourceRange &Range) { return Range; }
+

alexfh wrote:
> Do we want to expose `getSourceRange` as an API? If no, it should also be in 
> the `namespace internal`.
Good question.
I moved it into the internal namespace.

If it's become needed, we can re-expose it.


Comment at: include/clang/Tooling/Fixit.h:55
@@ +54,3 @@
+// \brief Returns a FixItHint to remove \p Node.
+template  FixItHint createRemoval(const T &Node) {
+  return FixItHint::CreateRemoval(getSourceRange(Node));

alexfh wrote:
> I wonder whether we should later extend this to remove comments attached to 
> nodes like Stmt and FunctionDecl? It's out of this patches scope, but maybe 
> add a FIXME to sketch the further development plans.
I like the idea. I didn't think about comments and other syntactical elements 
that may be related to a Node. 
But, I believe we will have a other set of functions for Node and comments.

An other concept that I believe it's missing is to provide helper to append 
expression (operators) and stay semantically correct with operator precedence. 
Some cases needed to add parentheses.




Comment at: unittests/Tooling/FixitTest.cpp:53
@@ +52,3 @@
+
+TEST(FixitTest, getTextWithMacro) {
+  CallsVisitor Visitor;

alexfh wrote:
> Could you add a test where getText returns an empty string?
see line 68, already there!


Comment at: unittests/Tooling/FixitTest.cpp:119
@@ +118,3 @@
+  LocationToString(Hint0.RemoveRange.getBegin(), Context));
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToString(Hint0.RemoveRange.getEnd(), Context));

alexfh wrote:
> One character range is boring. Can you make the parameter longer and also 
> verify whether the range is a token range or a character range?
In this case, it's not one character... it's one token.
As it's a "token range", the whole token is used.

But, I can use an expression too.
Not a bad idea: added but in 'createRemoval'

There is already a reand at line 138:
  EXPECT_EQ("input.cc:2:26 ",
  EXPECT_EQ("input.cc:2:26 ",


http://reviews.llvm.org/D19941



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


Re: [PATCH] D19703: [clang-tidy] Improve misc-redundant-expression and decrease false-positive

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56911.
etienneb marked an inline comment as done.
etienneb added a comment.
Herald added a subscriber: klimek.

use new API


http://reviews.llvm.org/D19703

Files:
  include/clang/Tooling/FixIt.h
  lib/Tooling/CMakeLists.txt
  lib/Tooling/FixIt.cpp
  unittests/Tooling/CMakeLists.txt
  unittests/Tooling/FixItTest.cpp

Index: unittests/Tooling/FixItTest.cpp
===
--- /dev/null
+++ unittests/Tooling/FixItTest.cpp
@@ -0,0 +1,232 @@
+//===- unittest/Tooling/FixitTest.cpp ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "TestVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang;
+
+using tooling::fixit::getText;
+using tooling::fixit::createRemoval;
+using tooling::fixit::createReplacement;
+
+namespace {
+
+struct CallsVisitor : TestVisitor {
+  bool VisitCallExpr(CallExpr *Expr) {
+OnCall(Expr, Context);
+return true;
+  }
+
+  std::function OnCall;
+};
+
+std::string LocationToString(SourceLocation Loc, ASTContext *Context) {
+  return Loc.printToString(Context->getSourceManager());
+}
+
+TEST(FixItTest, getText) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("foo(x, y)", getText(*CE, *Context));
+EXPECT_EQ("foo(x, y)", getText(CE->getSourceRange(), *Context));
+
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("x", getText(*P0, *Context));
+EXPECT_EQ("y", getText(*P1, *Context));
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("APPLY(foo, x, y)", getText(*CE, *Context));
+  };
+  Visitor.runOver("#define APPLY(f, x, y) f(x, y)\n"
+  "void foo(int x, int y) { APPLY(foo, x, y); }");
+}
+
+TEST(FixItTest, getTextWithMacro) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("F OO", getText(*CE, *Context));
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("", getText(*P0, *Context));
+EXPECT_EQ("", getText(*P1, *Context));
+  };
+  Visitor.runOver("#define F foo(\n"
+  "#define OO x, y)\n"
+  "void foo(int x, int y) { F OO ; }");
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+EXPECT_EQ("", getText(*CE, *Context));
+Expr *P0 = CE->getArg(0);
+Expr *P1 = CE->getArg(1);
+EXPECT_EQ("x", getText(*P0, *Context));
+EXPECT_EQ("y", getText(*P1, *Context));
+  };
+  Visitor.runOver("#define FOO(x, y) (void)x; (void)y; foo(x, y);\n"
+  "void foo(int x, int y) { FOO(x,y) }");
+}
+
+TEST(FixItTest, createRemoval) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = createRemoval(*CE);
+EXPECT_EQ("foo(x, y)", getText(Hint.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint.CodeToInsert.empty());
+
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = createRemoval(*P0);
+EXPECT_EQ("x", getText(Hint0.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint0.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint0.CodeToInsert.empty());
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = createRemoval(*P1);
+EXPECT_EQ("y", getText(Hint1.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint1.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint1.CodeToInsert.empty());
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = createRemoval(*P0);
+EXPECT_EQ("x + y", getText(Hint0.RemoveRange.getAsRange(), *Context));
+
+Expr *P1 = CE->getArg(1);
+FixItHint Hint1 = createRemoval(*P1);
+EXPECT_EQ("y + x", getText(Hint1.RemoveRange.getAsRange(), *Context));
+  };
+  Visitor.runOver("void foo(int x, int y) { foo(x + y, y + x); }");
+}
+
+TEST(FixItTest, createRemovalWithMacro) {
+  CallsVisitor Visitor;
+
+  Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+FixItHint Hint = createRemoval(*CE);
+EXPECT_EQ("FOO", getText(Hint.RemoveRange.getAsRange(), *Context));
+EXPECT_TRUE(Hint.InsertFromRange.isInvalid());
+EXPECT_TRUE(Hint.CodeToInsert.empty());
+
+Expr *P0 = CE->getArg(0);
+FixItHint Hint0 = createRemoval(*P0);
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToString(Hint0.RemoveRange.getBegin(), Context));
+EXPECT_EQ("input.cc:2:26 ",
+  LocationToString(Hint0.RemoveRange.getEnd(), Context));
+EXPECT_TRUE(

Re: [PATCH] D19703: [clang-tidy] Improve misc-redundant-expression and decrease false-positive

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56912.
etienneb added a comment.

fix bad upload


http://reviews.llvm.org/D19703

Files:
  clang-tidy/misc/RedundantExpressionCheck.cpp
  docs/clang-tidy/checks/misc-redundant-expression.rst
  test/clang-tidy/misc-redundant-expression.cpp

Index: test/clang-tidy/misc-redundant-expression.cpp
===
--- test/clang-tidy/misc-redundant-expression.cpp
+++ test/clang-tidy/misc-redundant-expression.cpp
@@ -68,14 +68,14 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both side of operator are equivalent
 
   if (foo(0) - 2 < foo(0) - 2) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent
   if (foo(bar(0)) < (foo(bar((0) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
 
   if (P1.x < P2.x && P1.x < P2.x) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
   if (P2.a[P1.x + 2] < P2.x && P2.a[(P1.x) + (2)] < (P2.x)) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent
 
   return 0;
 }
@@ -100,13 +100,36 @@
   return 0;
 }
 
+int TestConditional(int x, int y) {
+  int k = 0;
+  k += (y < 0) ? x : x;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'true' and 'false' expression are equivalent
+  k += (y < 0) ? x + 1 : x + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'true' and 'false' expression are equivalent
+  return k;
+}
+
+struct MyStruct {
+  int x;
+} Q;
+bool operator==(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x == rhs.x; }
+bool TestOperator(const MyStruct& S) {
+  if (S == Q) return false;
+  return S == S;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: both side of overloaded operator are equivalent
+}
+
 #define LT(x, y) (void)((x) < (y))
+#define COND(x, y, z) ((x)?(y):(z))
+#define EQUALS(x, y) (x) == (y)
 
 int TestMacro(int X, int Y) {
   LT(0, 0);
   LT(1, 0);
   LT(X, X);
   LT(X+1, X + 1);
+  COND(X < Y, X, X);
+  EQUALS(Q, Q);
 }
 
 int TestFalsePositive(int* A, int X, float F) {
@@ -118,3 +141,22 @@
   if (F != F && F == F) return 1;
   return 0;
 }
+
+int TestBannedMacros() {
+#define EAGAIN 3
+#define NOT_EAGAIN 3
+  if (EAGAIN == 0 | EAGAIN == 0) return 0;
+  if (NOT_EAGAIN == 0 | NOT_EAGAIN == 0) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both side of operator are equivalent
+}
+
+struct MyClass {
+static const int Value = 42;
+};
+template 
+void TemplateCheck() {
+  static_assert(T::Value == U::Value, "should be identical");
+  static_assert(T::Value == T::Value, "should be identical");
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both side of overloaded operator are equivalent
+}
+void TestTemplate() { TemplateCheck(); }
Index: docs/clang-tidy/checks/misc-redundant-expression.rst
===
--- docs/clang-tidy/checks/misc-redundant-expression.rst
+++ docs/clang-tidy/checks/misc-redundant-expression.rst
@@ -12,6 +12,7 @@
   * always be a constant (zero or one)
 
 Example:
+
 .. code:: c++
 
   ((x+1) | (x+1)) // (x+1) is redundant
Index: clang-tidy/misc/RedundantExpressionCheck.cpp
===
--- clang-tidy/misc/RedundantExpressionCheck.cpp
+++ clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -9,16 +9,30 @@
 
 #include "RedundantExpressionCheck.h"
 #include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
 
 using namespace clang::ast_matchers;
 
 namespace clang {
 namespace tidy {
 namespace misc {
 
-static bool AreIdenticalExpr(const Expr *Left, const Expr *Right) {
+static const char KnownBannedMacroNames[] =
+"EAGAIN;EWOULDBLOCK;SIGCLD;SIGCHLD;";
+
+
+static bool AreEquivalentNameSpecifier(const NestedNameSpecifier *Left,
+   const NestedNameSpecifier *Right) {
+  llvm::FoldingSetNodeID LeftID, RightID;
+  Left->Profile(LeftID);
+  Right->Profile(RightID);
+  return LeftID == RightID;
+}
+
+static bool AreEquivalentExpr(const Expr *Left, const Expr *Right) {
   if (!Left || !Right)
 return !Left && !Right;
 
@@ -33,8 +47,8 @@
   Expr::const_child_iterator LeftIter = Left->child_begin();
   Expr::const_child_iterator RightIter = Right->child_begin();
   while (LeftIter != Left->child_end() && RightIter != Right->child_end()) {
-if (!AreIdenticalExpr(dyn_cast(*LeftIter),
-  dyn_cast(*RightIter)))
+if (!AreEquiva

r269188 - [tooling] FixItHint Tooling refactoring

2016-05-11 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Wed May 11 09:31:39 2016
New Revision: 269188

URL: http://llvm.org/viewvc/llvm-project?rev=269188&view=rev
Log:
[tooling] FixItHint Tooling refactoring

Summary:
This is the refactoring to lift some FixItHint into tooling.
used by: http://reviews.llvm.org/D19807

Reviewers: klimek, alexfh

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D19941

Added:
cfe/trunk/include/clang/Tooling/FixIt.h
cfe/trunk/lib/Tooling/FixIt.cpp
cfe/trunk/unittests/Tooling/FixItTest.cpp
Modified:
cfe/trunk/lib/Tooling/CMakeLists.txt
cfe/trunk/unittests/Tooling/CMakeLists.txt

Added: cfe/trunk/include/clang/Tooling/FixIt.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/FixIt.h?rev=269188&view=auto
==
--- cfe/trunk/include/clang/Tooling/FixIt.h (added)
+++ cfe/trunk/include/clang/Tooling/FixIt.h Wed May 11 09:31:39 2016
@@ -0,0 +1,72 @@
+//===--- FixIt.h - FixIt Hint utilities -*- C++ 
-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+//  This file implements functions to ease source rewriting from AST-nodes.
+//
+//  Example swapping A and B expressions:
+//
+//Expr *A, *B;
+//tooling::fixit::createReplacement(*A, *B);
+//tooling::fixit::createReplacement(*B, *A);
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLING_FIXIT_H
+#define LLVM_CLANG_TOOLING_FIXIT_H
+
+#include "clang/AST/ASTContext.h"
+
+namespace clang {
+namespace tooling {
+namespace fixit {
+
+namespace internal {
+StringRef getText(SourceRange Range, const ASTContext &Context);
+
+/// \brief Returns the SourceRange of a SourceRange. This identity function is
+///used by the following template abstractions.
+inline SourceRange getSourceRange(const SourceRange &Range) { return Range; }
+
+/// \brief Returns the SourceRange of the token at Location \p Loc.
+inline SourceRange getSourceRange(const SourceLocation &Loc) {
+  return SourceRange(Loc);
+}
+
+/// \brief Returns the SourceRange of an given Node. \p Node is typically a
+///'Stmt', 'Expr' or a 'Decl'.
+template  SourceRange getSourceRange(const T &Node) {
+  return Node.getSourceRange();
+}
+} // end namespace internal
+
+// \brief Returns a textual representation of \p Node.
+template 
+StringRef getText(const T &Node, const ASTContext &Context) {
+  return internal::getText(internal::getSourceRange(Node), Context);
+}
+
+// \brief Returns a FixItHint to remove \p Node.
+// TODO: Add support for related syntactical elements (i.e. comments, ...).
+template  FixItHint createRemoval(const T &Node) {
+  return FixItHint::CreateRemoval(internal::getSourceRange(Node));
+}
+
+// \brief Returns a FixItHint to replace \p Destination by \p Source.
+template 
+FixItHint createReplacement(const D &Destination, const S &Source,
+const ASTContext &Context) {
+  return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
+  getText(Source, Context));
+}
+
+} // end namespace fixit
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_FIXINT_H

Modified: cfe/trunk/lib/Tooling/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/CMakeLists.txt?rev=269188&r1=269187&r2=269188&view=diff
==
--- cfe/trunk/lib/Tooling/CMakeLists.txt (original)
+++ cfe/trunk/lib/Tooling/CMakeLists.txt Wed May 11 09:31:39 2016
@@ -7,6 +7,7 @@ add_clang_library(clangTooling
   CommonOptionsParser.cpp
   CompilationDatabase.cpp
   FileMatchTrie.cpp
+  FixIt.cpp
   JSONCompilationDatabase.cpp
   Refactoring.cpp
   RefactoringCallbacks.cpp

Added: cfe/trunk/lib/Tooling/FixIt.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/FixIt.cpp?rev=269188&view=auto
==
--- cfe/trunk/lib/Tooling/FixIt.cpp (added)
+++ cfe/trunk/lib/Tooling/FixIt.cpp Wed May 11 09:31:39 2016
@@ -0,0 +1,31 @@
+//===--- FixIt.cpp - FixIt Hint utilities ---*- C++ 
-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// This file contains implementations of utitilies to ease source code 
rewriting
+// by providing helper functions related to FixItHint.
+//
+//===--===//
+

Re: [PATCH] D19547: [clang-tidy] Add FixIt for swapping arguments in string-constructor-checker.

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56919.
etienneb marked an inline comment as done.
etienneb added a comment.

use new API. code simplification


http://reviews.llvm.org/D19547

Files:
  clang-tidy/misc/StringConstructorCheck.cpp
  test/clang-tidy/misc-string-constructor.cpp

Index: test/clang-tidy/misc-string-constructor.cpp
===
--- test/clang-tidy/misc-string-constructor.cpp
+++ test/clang-tidy/misc-string-constructor.cpp
@@ -21,9 +21,11 @@
 
 void Test() {
   std::string str('x', 4);
-  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor parameters are 
probably swapped [misc-string-constructor]
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: string constructor parameters 
are probably swapped; expecting string(count, character) 
[misc-string-constructor]
+  // CHECK-FIXES: std::string str(4, 'x');  
   std::wstring wstr(L'x', 4);
-  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: constructor parameters are 
probably swapped
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: string constructor parameters 
are probably swapped
+  // CHECK-FIXES: std::wstring wstr(4, L'x');
   std::string s0(0, 'x');
   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty 
string
   std::string s1(-4, 'x');
Index: clang-tidy/misc/StringConstructorCheck.cpp
===
--- clang-tidy/misc/StringConstructorCheck.cpp
+++ clang-tidy/misc/StringConstructorCheck.cpp
@@ -10,6 +10,7 @@
 #include "StringConstructorCheck.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
 
 using namespace clang::ast_matchers;
 
@@ -54,7 +55,7 @@
   isDefinition(),
   hasType(pointerType(pointee(isAnyCharacter(), isConstQualified(,
   hasInitializer(ignoringParenImpCasts(BoundStringLiteral)));
-  auto ConstStrLiteral = expr(ignoringParenImpCasts(anyOf(
+  const auto ConstStrLiteral = expr(ignoringParenImpCasts(anyOf(
   BoundStringLiteral, declRefExpr(hasDeclaration(anyOf(
   ConstPtrStrLiteralDecl, 
ConstStrLiteralDecl));
 
@@ -88,7 +89,7 @@
   // Detect the expression: string("...", 0);
   hasArgument(1, ZeroExpr.bind("empty-string")),
   // Detect the expression: string("...", -4);
-  hasArgument(1, NegativeExpr.bind("negative-length")),
  
+  hasArgument(1, NegativeExpr.bind("negative-length")),
   // Detect the expression: string("lit", 0x1234567);
   hasArgument(1, LargeLengthExpr.bind("large-length")),
   // Detect the expression: string("lit", 5)
@@ -100,11 +101,18 @@
 }
 
 void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) {
-  const auto *E = Result.Nodes.getNodeAs("constructor");
+  const ASTContext &Ctx = *Result.Context;
+  const auto *E = Result.Nodes.getNodeAs("constructor");
+  assert(E && "missing constructor expression");
   SourceLocation Loc = E->getLocStart();
 
   if (Result.Nodes.getNodeAs("swapped-parameter")) {
-diag(Loc, "constructor parameters are probably swapped");
+const Expr* P0 = E->getArg(0);
+const Expr* P1 = E->getArg(1);
+diag(Loc, "string constructor parameters are probably swapped;"
+  " expecting string(count, character)")
+<< tooling::fixit::createReplacement(*P0, *P1, Ctx)
+<< tooling::fixit::createReplacement(*P1, *P0, Ctx);
   } else if (Result.Nodes.getNodeAs("empty-string")) {
 diag(Loc, "constructor creating an empty string");
   } else if (Result.Nodes.getNodeAs("negative-length")) {


Index: test/clang-tidy/misc-string-constructor.cpp
===
--- test/clang-tidy/misc-string-constructor.cpp
+++ test/clang-tidy/misc-string-constructor.cpp
@@ -21,9 +21,11 @@
 
 void Test() {
   std::string str('x', 4);
-  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor parameters are probably swapped [misc-string-constructor]
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: string constructor parameters are probably swapped; expecting string(count, character) [misc-string-constructor]
+  // CHECK-FIXES: std::string str(4, 'x');  
   std::wstring wstr(L'x', 4);
-  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: constructor parameters are probably swapped
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: string constructor parameters are probably swapped
+  // CHECK-FIXES: std::wstring wstr(4, L'x');
   std::string s0(0, 'x');
   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
   std::string s1(-4, 'x');
Index: clang-tidy/misc/StringConstructorCheck.cpp
===
--- clang-tidy/misc/StringConstructorCheck.cpp
+++ clang-tidy/misc/StringConstructorCheck.cpp
@@ -10,6 +10,7 @@
 #include "StringConstructorCheck.h"
 #include "clang/AST/ASTCo

Re: [PATCH] D19703: [clang-tidy] Improve misc-redundant-expression and decrease false-positive

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.



> We should add a hasAnyOverloadedOperatorName matcher at some point.


I proposed it to sbenza@ and he told me that the reason he did HasAnyName was 
for speed issue.
I can't tell if that one has speed issue too.

But, otherwise, I agree... for code readability... we should do it.


http://reviews.llvm.org/D19703



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


Re: [PATCH] D19703: [clang-tidy] Improve misc-redundant-expression and decrease false-positive

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56935.
etienneb marked an inline comment as done.
etienneb added a comment.

remove useless set creation


http://reviews.llvm.org/D19703

Files:
  clang-tidy/misc/RedundantExpressionCheck.cpp
  docs/clang-tidy/checks/misc-redundant-expression.rst
  test/clang-tidy/misc-redundant-expression.cpp

Index: test/clang-tidy/misc-redundant-expression.cpp
===
--- test/clang-tidy/misc-redundant-expression.cpp
+++ test/clang-tidy/misc-redundant-expression.cpp
@@ -68,14 +68,14 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both side of operator are equivalent
 
   if (foo(0) - 2 < foo(0) - 2) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent
   if (foo(bar(0)) < (foo(bar((0) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
 
   if (P1.x < P2.x && P1.x < P2.x) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
   if (P2.a[P1.x + 2] < P2.x && P2.a[(P1.x) + (2)] < (P2.x)) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent
 
   return 0;
 }
@@ -100,13 +100,36 @@
   return 0;
 }
 
+int TestConditional(int x, int y) {
+  int k = 0;
+  k += (y < 0) ? x : x;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'true' and 'false' expression are equivalent
+  k += (y < 0) ? x + 1 : x + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'true' and 'false' expression are equivalent
+  return k;
+}
+
+struct MyStruct {
+  int x;
+} Q;
+bool operator==(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x == rhs.x; }
+bool TestOperator(const MyStruct& S) {
+  if (S == Q) return false;
+  return S == S;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: both side of overloaded operator are equivalent
+}
+
 #define LT(x, y) (void)((x) < (y))
+#define COND(x, y, z) ((x)?(y):(z))
+#define EQUALS(x, y) (x) == (y)
 
 int TestMacro(int X, int Y) {
   LT(0, 0);
   LT(1, 0);
   LT(X, X);
   LT(X+1, X + 1);
+  COND(X < Y, X, X);
+  EQUALS(Q, Q);
 }
 
 int TestFalsePositive(int* A, int X, float F) {
@@ -118,3 +141,22 @@
   if (F != F && F == F) return 1;
   return 0;
 }
+
+int TestBannedMacros() {
+#define EAGAIN 3
+#define NOT_EAGAIN 3
+  if (EAGAIN == 0 | EAGAIN == 0) return 0;
+  if (NOT_EAGAIN == 0 | NOT_EAGAIN == 0) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both side of operator are equivalent
+}
+
+struct MyClass {
+static const int Value = 42;
+};
+template 
+void TemplateCheck() {
+  static_assert(T::Value == U::Value, "should be identical");
+  static_assert(T::Value == T::Value, "should be identical");
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both side of overloaded operator are equivalent
+}
+void TestTemplate() { TemplateCheck(); }
Index: docs/clang-tidy/checks/misc-redundant-expression.rst
===
--- docs/clang-tidy/checks/misc-redundant-expression.rst
+++ docs/clang-tidy/checks/misc-redundant-expression.rst
@@ -12,6 +12,7 @@
   * always be a constant (zero or one)
 
 Example:
+
 .. code:: c++
 
   ((x+1) | (x+1)) // (x+1) is redundant
Index: clang-tidy/misc/RedundantExpressionCheck.cpp
===
--- clang-tidy/misc/RedundantExpressionCheck.cpp
+++ clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -9,16 +9,29 @@
 
 #include "RedundantExpressionCheck.h"
 #include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
 
 using namespace clang::ast_matchers;
 
 namespace clang {
 namespace tidy {
 namespace misc {
 
-static bool AreIdenticalExpr(const Expr *Left, const Expr *Right) {
+static const char KnownBannedMacroNames[] =
+"EAGAIN;EWOULDBLOCK;SIGCLD;SIGCHLD;";
+
+static bool AreEquivalentNameSpecifier(const NestedNameSpecifier *Left,
+   const NestedNameSpecifier *Right) {
+  llvm::FoldingSetNodeID LeftID, RightID;
+  Left->Profile(LeftID);
+  Right->Profile(RightID);
+  return LeftID == RightID;
+}
+
+static bool AreEquivalentExpr(const Expr *Left, const Expr *Right) {
   if (!Left || !Right)
 return !Left && !Right;
 
@@ -33,8 +46,8 @@
   Expr::const_child_iterator LeftIter = Left->child_begin();
   Expr::const_child_iterator RightIter = Right->child_begin();
   while (LeftIter != Left->child_end() && RightIter != Right->child_end()) {
-if (!AreIdenticalExpr(dyn_cast(*LeftIter),
-  

Re: [PATCH] D19703: [clang-tidy] Improve misc-redundant-expression and decrease false-positive

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56937.
etienneb added a comment.

fix naming nits


http://reviews.llvm.org/D19703

Files:
  clang-tidy/misc/RedundantExpressionCheck.cpp
  docs/clang-tidy/checks/misc-redundant-expression.rst
  test/clang-tidy/misc-redundant-expression.cpp

Index: test/clang-tidy/misc-redundant-expression.cpp
===
--- test/clang-tidy/misc-redundant-expression.cpp
+++ test/clang-tidy/misc-redundant-expression.cpp
@@ -68,14 +68,14 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both side of operator are equivalent
 
   if (foo(0) - 2 < foo(0) - 2) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both side of operator are equivalent
   if (foo(bar(0)) < (foo(bar((0) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
 
   if (P1.x < P2.x && P1.x < P2.x) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both side of operator are equivalent
   if (P2.a[P1.x + 2] < P2.x && P2.a[(P1.x) + (2)] < (P2.x)) return 1;
-  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent  
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both side of operator are equivalent
 
   return 0;
 }
@@ -100,13 +100,36 @@
   return 0;
 }
 
+int TestConditional(int x, int y) {
+  int k = 0;
+  k += (y < 0) ? x : x;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'true' and 'false' expression are equivalent
+  k += (y < 0) ? x + 1 : x + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'true' and 'false' expression are equivalent
+  return k;
+}
+
+struct MyStruct {
+  int x;
+} Q;
+bool operator==(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x == rhs.x; }
+bool TestOperator(const MyStruct& S) {
+  if (S == Q) return false;
+  return S == S;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: both side of overloaded operator are equivalent
+}
+
 #define LT(x, y) (void)((x) < (y))
+#define COND(x, y, z) ((x)?(y):(z))
+#define EQUALS(x, y) (x) == (y)
 
 int TestMacro(int X, int Y) {
   LT(0, 0);
   LT(1, 0);
   LT(X, X);
   LT(X+1, X + 1);
+  COND(X < Y, X, X);
+  EQUALS(Q, Q);
 }
 
 int TestFalsePositive(int* A, int X, float F) {
@@ -118,3 +141,22 @@
   if (F != F && F == F) return 1;
   return 0;
 }
+
+int TestBannedMacros() {
+#define EAGAIN 3
+#define NOT_EAGAIN 3
+  if (EAGAIN == 0 | EAGAIN == 0) return 0;
+  if (NOT_EAGAIN == 0 | NOT_EAGAIN == 0) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both side of operator are equivalent
+}
+
+struct MyClass {
+static const int Value = 42;
+};
+template 
+void TemplateCheck() {
+  static_assert(T::Value == U::Value, "should be identical");
+  static_assert(T::Value == T::Value, "should be identical");
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both side of overloaded operator are equivalent
+}
+void TestTemplate() { TemplateCheck(); }
Index: docs/clang-tidy/checks/misc-redundant-expression.rst
===
--- docs/clang-tidy/checks/misc-redundant-expression.rst
+++ docs/clang-tidy/checks/misc-redundant-expression.rst
@@ -12,6 +12,7 @@
   * always be a constant (zero or one)
 
 Example:
+
 .. code:: c++
 
   ((x+1) | (x+1)) // (x+1) is redundant
Index: clang-tidy/misc/RedundantExpressionCheck.cpp
===
--- clang-tidy/misc/RedundantExpressionCheck.cpp
+++ clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -9,16 +9,29 @@
 
 #include "RedundantExpressionCheck.h"
 #include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
 
 using namespace clang::ast_matchers;
 
 namespace clang {
 namespace tidy {
 namespace misc {
 
-static bool AreIdenticalExpr(const Expr *Left, const Expr *Right) {
+static const char KnownBannedMacroNames[] =
+"EAGAIN;EWOULDBLOCK;SIGCLD;SIGCHLD;";
+
+static bool areEquivalentNameSpecifier(const NestedNameSpecifier *Left,
+   const NestedNameSpecifier *Right) {
+  llvm::FoldingSetNodeID LeftID, RightID;
+  Left->Profile(LeftID);
+  Right->Profile(RightID);
+  return LeftID == RightID;
+}
+
+static bool areEquivalentExpr(const Expr *Left, const Expr *Right) {
   if (!Left || !Right)
 return !Left && !Right;
 
@@ -33,8 +46,8 @@
   Expr::const_child_iterator LeftIter = Left->child_begin();
   Expr::const_child_iterator RightIter = Right->child_begin();
   while (LeftIter != Left->child_end() && RightIter != Right->child_end()) {
-if (!AreIdenticalExpr(dyn_cast(*LeftIter),
-  dyn_cast(*RightIter)))
+if (!areEquival

Re: [PATCH] D19703: [clang-tidy] Improve misc-redundant-expression and decrease false-positive

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

+ Removed copy of a vector to a set
+ Fixed some minor coding-style issues



Comment at: clang-tidy/misc/RedundantExpressionCheck.cpp:140
@@ +139,3 @@
+  const LangOptions &LO = Finder->getASTContext().getLangOpts();
+  std::set Names(NameRefs.begin(), NameRefs.end());
+  SourceLocation Loc = Node.getExprLoc();

alexfh wrote:
> Is there a way to not create a set on each call to the matcher? There also 
> might be a more suitable container in llvm/ADT.
Some ideas:
1) We may assume the vector is small and do the lookup.
2) We may assume a sorted vector and do a binary search.
3) The matcher could receive a set instead of a vector and lifting out the copy.

Implemented 3)


http://reviews.llvm.org/D19703



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


[clang-tools-extra] r269208 - [clang-tidy] Add FixIt for swapping arguments in string-constructor-checker.

2016-05-11 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Wed May 11 12:32:12 2016
New Revision: 269208

URL: http://llvm.org/viewvc/llvm-project?rev=269208&view=rev
Log:
[clang-tidy] Add FixIt for swapping arguments in string-constructor-checker.

Summary:
Arguments can be swapped using fixit when they are not in macros.
This is the same implementation than SwappedArguments. Some code 
got lifted to be reused.

Others checks are not safe to be fixed as they tend to be bugs or errors.
It is better to let the user manually review them.

Reviewers: alexfh

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D19547

Modified:
clang-tools-extra/trunk/clang-tidy/misc/StringConstructorCheck.cpp
clang-tools-extra/trunk/test/clang-tidy/misc-string-constructor.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/StringConstructorCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/StringConstructorCheck.cpp?rev=269208&r1=269207&r2=269208&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/misc/StringConstructorCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/misc/StringConstructorCheck.cpp Wed May 
11 12:32:12 2016
@@ -10,6 +10,7 @@
 #include "StringConstructorCheck.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
 
 using namespace clang::ast_matchers;
 
@@ -54,7 +55,7 @@ void StringConstructorCheck::registerMat
   isDefinition(),
   hasType(pointerType(pointee(isAnyCharacter(), isConstQualified(,
   hasInitializer(ignoringParenImpCasts(BoundStringLiteral)));
-  auto ConstStrLiteral = expr(ignoringParenImpCasts(anyOf(
+  const auto ConstStrLiteral = expr(ignoringParenImpCasts(anyOf(
   BoundStringLiteral, declRefExpr(hasDeclaration(anyOf(
   ConstPtrStrLiteralDecl, 
ConstStrLiteralDecl));
 
@@ -88,7 +89,7 @@ void StringConstructorCheck::registerMat
   // Detect the expression: string("...", 0);
   hasArgument(1, ZeroExpr.bind("empty-string")),
   // Detect the expression: string("...", -4);
-  hasArgument(1, NegativeExpr.bind("negative-length")),
  
+  hasArgument(1, NegativeExpr.bind("negative-length")),
   // Detect the expression: string("lit", 0x1234567);
   hasArgument(1, LargeLengthExpr.bind("large-length")),
   // Detect the expression: string("lit", 5)
@@ -100,11 +101,18 @@ void StringConstructorCheck::registerMat
 }
 
 void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) {
-  const auto *E = Result.Nodes.getNodeAs("constructor");
+  const ASTContext &Ctx = *Result.Context;
+  const auto *E = Result.Nodes.getNodeAs("constructor");
+  assert(E && "missing constructor expression");
   SourceLocation Loc = E->getLocStart();
 
   if (Result.Nodes.getNodeAs("swapped-parameter")) {
-diag(Loc, "constructor parameters are probably swapped");
+const Expr *P0 = E->getArg(0);
+const Expr *P1 = E->getArg(1);
+diag(Loc, "string constructor parameters are probably swapped;"
+  " expecting string(count, character)")
+<< tooling::fixit::createReplacement(*P0, *P1, Ctx)
+<< tooling::fixit::createReplacement(*P1, *P0, Ctx);
   } else if (Result.Nodes.getNodeAs("empty-string")) {
 diag(Loc, "constructor creating an empty string");
   } else if (Result.Nodes.getNodeAs("negative-length")) {

Modified: clang-tools-extra/trunk/test/clang-tidy/misc-string-constructor.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-string-constructor.cpp?rev=269208&r1=269207&r2=269208&view=diff
==
--- clang-tools-extra/trunk/test/clang-tidy/misc-string-constructor.cpp 
(original)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-string-constructor.cpp Wed May 
11 12:32:12 2016
@@ -21,9 +21,11 @@ extern const char kText3[];
 
 void Test() {
   std::string str('x', 4);
-  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor parameters are 
probably swapped [misc-string-constructor]
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: string constructor parameters 
are probably swapped; expecting string(count, character) 
[misc-string-constructor]
+  // CHECK-FIXES: std::string str(4, 'x');  
   std::wstring wstr(L'x', 4);
-  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: constructor parameters are 
probably swapped
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: string constructor parameters 
are probably swapped
+  // CHECK-FIXES: std::wstring wstr(4, L'x');
   std::string s0(0, 'x');
   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty 
string
   std::string s1(-4, 'x');


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi

[clang-tools-extra] r269210 - [clang-tidy] Refactoring of FixHintUtils

2016-05-11 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Wed May 11 12:38:22 2016
New Revision: 269210

URL: http://llvm.org/viewvc/llvm-project?rev=269210&view=rev
Log:
[clang-tidy] Refactoring of FixHintUtils

Summary:
Refactor some checkers to use the tooling re-writing API.
see: http://reviews.llvm.org/D19941

Reviewers: klimek, alexfh

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D19807

Modified:
clang-tools-extra/trunk/clang-tidy/misc/SwappedArgumentsCheck.cpp
clang-tools-extra/trunk/clang-tidy/readability/ElseAfterReturnCheck.cpp
clang-tools-extra/trunk/test/clang-tidy/misc-swapped-arguments.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/SwappedArgumentsCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/SwappedArgumentsCheck.cpp?rev=269210&r1=269209&r2=269210&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/misc/SwappedArgumentsCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/SwappedArgumentsCheck.cpp Wed May 
11 12:38:22 2016
@@ -10,6 +10,7 @@
 #include "SwappedArgumentsCheck.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
 #include "llvm/ADT/SmallPtrSet.h"
 
 using namespace clang::ast_matchers;
@@ -46,25 +47,9 @@ static bool isImplicitCastCandidate(cons
  Cast->getCastKind() == CK_PointerToBoolean;
 }
 
-/// \brief Get a StringRef representing a SourceRange.
-static StringRef getAsString(const MatchFinder::MatchResult &Result,
- SourceRange R) {
-  const SourceManager &SM = *Result.SourceManager;
-  // Don't even try to resolve macro or include contraptions. Not worth 
emitting
-  // a fixit for.
-  if (R.getBegin().isMacroID() ||
-  !SM.isWrittenInSameFile(R.getBegin(), R.getEnd()))
-return StringRef();
-
-  const char *Begin = SM.getCharacterData(R.getBegin());
-  const char *End = SM.getCharacterData(Lexer::getLocForEndOfToken(
-  R.getEnd(), 0, SM, Result.Context->getLangOpts()));
-
-  return StringRef(Begin, End - Begin);
-}
-
 void SwappedArgumentsCheck::check(const MatchFinder::MatchResult &Result) {
-  auto *Call = Result.Nodes.getStmtAs("call");
+  const ASTContext &Ctx = *Result.Context;
+  const auto *Call = Result.Nodes.getStmtAs("call");
 
   llvm::SmallPtrSet UsedArgs;
   for (unsigned I = 1, E = Call->getNumArgs(); I < E; ++I) {
@@ -99,24 +84,14 @@ void SwappedArgumentsCheck::check(const
   continue;
 
 // Emit a warning and fix-its that swap the arguments.
-SourceRange LHSRange = LHS->getSourceRange(),
-RHSRange = RHS->getSourceRange();
-auto D =
-diag(Call->getLocStart(), "argument with implicit conversion from %0 "
-  "to %1 followed by argument converted from "
-  "%2 to %3, potentially swapped arguments.")
+diag(Call->getLocStart(), "argument with implicit conversion from %0 "
+  "to %1 followed by argument converted from "
+  "%2 to %3, potentially swapped arguments.")
 << LHS->getType() << LHSFrom->getType() << RHS->getType()
-<< RHSFrom->getType() << LHSRange << RHSRange;
-
-StringRef RHSString = getAsString(Result, RHSRange);
-StringRef LHSString = getAsString(Result, LHSRange);
-if (!LHSString.empty() && !RHSString.empty()) {
-  D << FixItHint::CreateReplacement(
-   CharSourceRange::getTokenRange(LHSRange), RHSString)
-<< FixItHint::CreateReplacement(
-   CharSourceRange::getTokenRange(RHSRange), LHSString);
-}
-
+<< RHSFrom->getType()
+<< tooling::fixit::createReplacement(*LHS, *RHS, Ctx)
+<< tooling::fixit::createReplacement(*RHS, *LHS, Ctx);
+
 // Remember that we emitted a warning for this argument.
 UsedArgs.insert(RHSCast);
   }

Modified: 
clang-tools-extra/trunk/clang-tidy/readability/ElseAfterReturnCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/ElseAfterReturnCheck.cpp?rev=269210&r1=269209&r2=269210&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/readability/ElseAfterReturnCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/readability/ElseAfterReturnCheck.cpp Wed 
May 11 12:38:22 2016
@@ -10,6 +10,7 @@
 #include "ElseAfterReturnCheck.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
 
 using namespace clang::ast_matchers;
 
@@ -28,20 +29,17 @@ void ElseAfterReturnCheck::registerMatch
   this);
 }
 
-static FixItHint removeToken(SourceLocation Loc) {
-  return FixItHint::CreateRemoval(CharSourceRange::getTokenRange(Loc, Loc));
-}
-
 void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *If = Result.Nodes.ge

Re: [PATCH] D19876: Add an AST matcher for string-literal length

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 56942.
etienneb added a comment.

re-generating doc


http://reviews.llvm.org/D19876

Files:
  docs/LibASTMatchersReference.html
  include/clang/ASTMatchers/ASTMatchers.h
  include/clang/ASTMatchers/ASTMatchersInternal.h
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -51,7 +51,6 @@
 
   // Do not accept non-toplevel matchers.
   EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), nullptr));
-  EXPECT_FALSE(Finder.addDynamicMatcher(hasSize(2), nullptr));
   EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr));
 }
 
@@ -2536,6 +2535,17 @@
   EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
 }
 
+TEST(StringLiteral, HasSize) {
+  StatementMatcher Literal = stringLiteral(hasSize(4));
+  EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
+  // wide string
+  EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
+  // with escaped characters
+  EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
+  // no matching, too small
+  EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
+}
+
 TEST(Matcher, CharacterLiterals) {
   StatementMatcher CharLiteral = characterLiteral();
   EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1651,6 +1651,19 @@
 }
 
 template 
+struct HasSizeMatcher {
+  static bool hasSize(const Ty &Node, unsigned int N) {
+return Node.getSize() == N;
+  }
+};
+
+template <>
+inline bool HasSizeMatcher::hasSize(
+const StringLiteral &Node, unsigned int N) {
+  return Node.getLength() == N;
+}
+
+template 
 struct GetSourceExpressionMatcher {
   static const Expr *get(const Ty &Node) {
 return Node.getSubExpr();
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -1560,7 +1560,8 @@
 ///
 /// Example matches "abcd", L"abcd"
 /// \code
-///   char *s = "abcd"; wchar_t *ws = L"abcd"
+///   char *s = "abcd";
+///   wchar_t *ws = L"abcd";
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -1573,7 +1574,8 @@
 ///
 /// Example matches 'a', L'a'
 /// \code
-///   char ch = 'a'; wchar_t chw = L'a';
+///   char ch = 'a';
+///   wchar_t chw = L'a';
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -1609,7 +1611,8 @@
 ///
 /// Example match: {1}, (1, 2)
 /// \code
-///   int array[4] = {1}; vector int myvec = (vector int)(1, 2);
+///   int array[4] = {1};
+///   vector int myvec = (vector int)(1, 2);
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -4228,18 +4231,26 @@
 ///   matches "int a[2]"
 AST_TYPE_MATCHER(ConstantArrayType, constantArrayType);
 
-/// \brief Matches \c ConstantArrayType nodes that have the specified size.
+/// \brief Matches nodes that have the specified size.
 ///
 /// Given
 /// \code
 ///   int a[42];
 ///   int b[2 * 21];
 ///   int c[41], d[43];
+///   char *s = "abcd";
+///   wchar_t *ws = L"abcd";
+///   char *w = "a";
 /// \endcode
 /// constantArrayType(hasSize(42))
 ///   matches "int a[42]" and "int b[2 * 21]"
-AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
-  return Node.getSize() == N;
+/// stringLiteral(hasSize(4))
+///   matches "abcd", L"abcd"
+AST_POLYMORPHIC_MATCHER_P(hasSize,
+  AST_POLYMORPHIC_SUPPORTED_TYPES(ConstantArrayType,
+  StringLiteral),
+  unsigned, N) {
+  return internal::HasSizeMatcher::hasSize(Node, N);
 }
 
 /// \brief Matches C++ arrays whose size is a value-dependent expression.
Index: docs/LibASTMatchersReference.html
===
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -644,15 +644,17 @@
 though.
 
 Example matches 'a', L'a'
-  char ch = 'a'; wchar_t chw = L'a';
+  char ch = 'a';
+  wchar_t chw = L'a';
 
 
 
 MatcherStmt>compoundLiteralExprMatcherCompoundLiteralExpr>...
 Matches compound (i.e. non-scalar) literals
 
 Example match: {1}, (1, 2)
-  int array[4] = {1}; vector int myvec = (vector int)(1, 2);
+  int array[4] = {1};
+  vector int myvec = (vector int)(1, 2);
 
 
 
@@ -1217,7 +1219,8 @@
 Matches string literals (also matches wide string literals).
 
 Example matches "abcd", L"abcd"
-  char *s = "abcd"; wchar_t *ws = L"abcd"
+  char *s = "

[PATCH] D20180: [tooling] Fix missing inline keyworkd, breaking build bot.

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added a reviewer: rnk.
etienneb added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

The missing keyword "inline" is causing some buildbot to fail.
The symbol is not available.

see: 
http://lab.llvm.org:8011/builders/clang-ppc64be-linux-multistage/builds/2281/

http://reviews.llvm.org/D20180

Files:
  include/clang/Tooling/FixIt.h

Index: include/clang/Tooling/FixIt.h
===
--- include/clang/Tooling/FixIt.h
+++ include/clang/Tooling/FixIt.h
@@ -40,27 +40,27 @@
 
 /// \brief Returns the SourceRange of an given Node. \p Node is typically a
 ///'Stmt', 'Expr' or a 'Decl'.
-template  SourceRange getSourceRange(const T &Node) {
+template  inline SourceRange getSourceRange(const T &Node) {
   return Node.getSourceRange();
 }
 } // end namespace internal
 
 // \brief Returns a textual representation of \p Node.
 template 
-StringRef getText(const T &Node, const ASTContext &Context) {
+inline StringRef getText(const T &Node, const ASTContext &Context) {
   return internal::getText(internal::getSourceRange(Node), Context);
 }
 
 // \brief Returns a FixItHint to remove \p Node.
 // TODO: Add support for related syntactical elements (i.e. comments, ...).
-template  FixItHint createRemoval(const T &Node) {
+template  inline FixItHint createRemoval(const T &Node) {
   return FixItHint::CreateRemoval(internal::getSourceRange(Node));
 }
 
 // \brief Returns a FixItHint to replace \p Destination by \p Source.
 template 
-FixItHint createReplacement(const D &Destination, const S &Source,
-const ASTContext &Context) {
+inline FixItHint createReplacement(const D &Destination, const S &Source,
+   const ASTContext &Context) {
   return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
   getText(Source, Context));
 }


Index: include/clang/Tooling/FixIt.h
===
--- include/clang/Tooling/FixIt.h
+++ include/clang/Tooling/FixIt.h
@@ -40,27 +40,27 @@
 
 /// \brief Returns the SourceRange of an given Node. \p Node is typically a
 ///'Stmt', 'Expr' or a 'Decl'.
-template  SourceRange getSourceRange(const T &Node) {
+template  inline SourceRange getSourceRange(const T &Node) {
   return Node.getSourceRange();
 }
 } // end namespace internal
 
 // \brief Returns a textual representation of \p Node.
 template 
-StringRef getText(const T &Node, const ASTContext &Context) {
+inline StringRef getText(const T &Node, const ASTContext &Context) {
   return internal::getText(internal::getSourceRange(Node), Context);
 }
 
 // \brief Returns a FixItHint to remove \p Node.
 // TODO: Add support for related syntactical elements (i.e. comments, ...).
-template  FixItHint createRemoval(const T &Node) {
+template  inline FixItHint createRemoval(const T &Node) {
   return FixItHint::CreateRemoval(internal::getSourceRange(Node));
 }
 
 // \brief Returns a FixItHint to replace \p Destination by \p Source.
 template 
-FixItHint createReplacement(const D &Destination, const S &Source,
-const ASTContext &Context) {
+inline FixItHint createReplacement(const D &Destination, const S &Source,
+   const ASTContext &Context) {
   return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
   getText(Source, Context));
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r269224 - [tooling] Fix missing inline keyworkd, breaking build bot.

2016-05-11 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Wed May 11 15:09:17 2016
New Revision: 269224

URL: http://llvm.org/viewvc/llvm-project?rev=269224&view=rev
Log:
[tooling] Fix missing inline keyworkd, breaking build bot.

Summary:
The missing keyword "inline" is causing some buildbot to fail.
The symbol is not available.

see: 
http://lab.llvm.org:8011/builders/clang-ppc64be-linux-multistage/builds/2281/

Reviewers: rnk

Subscribers: cfe-commits, klimek

Differential Revision: http://reviews.llvm.org/D20180

Modified:
cfe/trunk/include/clang/Tooling/FixIt.h

Modified: cfe/trunk/include/clang/Tooling/FixIt.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/FixIt.h?rev=269224&r1=269223&r2=269224&view=diff
==
--- cfe/trunk/include/clang/Tooling/FixIt.h (original)
+++ cfe/trunk/include/clang/Tooling/FixIt.h Wed May 11 15:09:17 2016
@@ -40,27 +40,27 @@ inline SourceRange getSourceRange(const
 
 /// \brief Returns the SourceRange of an given Node. \p Node is typically a
 ///'Stmt', 'Expr' or a 'Decl'.
-template  SourceRange getSourceRange(const T &Node) {
+template  inline SourceRange getSourceRange(const T &Node) {
   return Node.getSourceRange();
 }
 } // end namespace internal
 
 // \brief Returns a textual representation of \p Node.
 template 
-StringRef getText(const T &Node, const ASTContext &Context) {
+inline StringRef getText(const T &Node, const ASTContext &Context) {
   return internal::getText(internal::getSourceRange(Node), Context);
 }
 
 // \brief Returns a FixItHint to remove \p Node.
 // TODO: Add support for related syntactical elements (i.e. comments, ...).
-template  FixItHint createRemoval(const T &Node) {
+template  inline FixItHint createRemoval(const T &Node) {
   return FixItHint::CreateRemoval(internal::getSourceRange(Node));
 }
 
 // \brief Returns a FixItHint to replace \p Destination by \p Source.
 template 
-FixItHint createReplacement(const D &Destination, const S &Source,
-const ASTContext &Context) {
+inline FixItHint createReplacement(const D &Destination, const S &Source,
+   const ASTContext &Context) {
   return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
   getText(Source, Context));
 }


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


Re: [PATCH] D20180: [tooling] Fix missing inline keyworkd, breaking build bot.

2016-05-11 Thread Etienne Bergeron via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL269224: [tooling] Fix missing inline keyworkd, breaking 
build bot. (authored by etienneb).

Changed prior to commit:
  http://reviews.llvm.org/D20180?vs=56949&id=56954#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D20180

Files:
  cfe/trunk/include/clang/Tooling/FixIt.h

Index: cfe/trunk/include/clang/Tooling/FixIt.h
===
--- cfe/trunk/include/clang/Tooling/FixIt.h
+++ cfe/trunk/include/clang/Tooling/FixIt.h
@@ -40,27 +40,27 @@
 
 /// \brief Returns the SourceRange of an given Node. \p Node is typically a
 ///'Stmt', 'Expr' or a 'Decl'.
-template  SourceRange getSourceRange(const T &Node) {
+template  inline SourceRange getSourceRange(const T &Node) {
   return Node.getSourceRange();
 }
 } // end namespace internal
 
 // \brief Returns a textual representation of \p Node.
 template 
-StringRef getText(const T &Node, const ASTContext &Context) {
+inline StringRef getText(const T &Node, const ASTContext &Context) {
   return internal::getText(internal::getSourceRange(Node), Context);
 }
 
 // \brief Returns a FixItHint to remove \p Node.
 // TODO: Add support for related syntactical elements (i.e. comments, ...).
-template  FixItHint createRemoval(const T &Node) {
+template  inline FixItHint createRemoval(const T &Node) {
   return FixItHint::CreateRemoval(internal::getSourceRange(Node));
 }
 
 // \brief Returns a FixItHint to replace \p Destination by \p Source.
 template 
-FixItHint createReplacement(const D &Destination, const S &Source,
-const ASTContext &Context) {
+inline FixItHint createReplacement(const D &Destination, const S &Source,
+   const ASTContext &Context) {
   return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
   getText(Source, Context));
 }


Index: cfe/trunk/include/clang/Tooling/FixIt.h
===
--- cfe/trunk/include/clang/Tooling/FixIt.h
+++ cfe/trunk/include/clang/Tooling/FixIt.h
@@ -40,27 +40,27 @@
 
 /// \brief Returns the SourceRange of an given Node. \p Node is typically a
 ///'Stmt', 'Expr' or a 'Decl'.
-template  SourceRange getSourceRange(const T &Node) {
+template  inline SourceRange getSourceRange(const T &Node) {
   return Node.getSourceRange();
 }
 } // end namespace internal
 
 // \brief Returns a textual representation of \p Node.
 template 
-StringRef getText(const T &Node, const ASTContext &Context) {
+inline StringRef getText(const T &Node, const ASTContext &Context) {
   return internal::getText(internal::getSourceRange(Node), Context);
 }
 
 // \brief Returns a FixItHint to remove \p Node.
 // TODO: Add support for related syntactical elements (i.e. comments, ...).
-template  FixItHint createRemoval(const T &Node) {
+template  inline FixItHint createRemoval(const T &Node) {
   return FixItHint::CreateRemoval(internal::getSourceRange(Node));
 }
 
 // \brief Returns a FixItHint to replace \p Destination by \p Source.
 template 
-FixItHint createReplacement(const D &Destination, const S &Source,
-const ASTContext &Context) {
+inline FixItHint createReplacement(const D &Destination, const S &Source,
+   const ASTContext &Context) {
   return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
   getText(Source, Context));
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D20182: [clang-tidy] Add missing dependency of libtooling to misc module

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added reviewers: alexfh, rnk.
etienneb added a subscriber: cfe-commits.

The new API for fixit is in libtooling and the library misc in clang-tidy
didn't had the appropriate dependency.

This commit was breaking some build bots:
http://reviews.llvm.org/D19547

This commit tried (but failed) to fix it:
http://reviews.llvm.org/D20180

To repro, you can make a build with these flags:
```
cmake -DBUILD_SHARED_LIBS=ON
```

Thanks rnk@ for helping figuring out.

http://reviews.llvm.org/D20182

Files:
  clang-tidy/misc/CMakeLists.txt

Index: clang-tidy/misc/CMakeLists.txt
===
--- clang-tidy/misc/CMakeLists.txt
+++ clang-tidy/misc/CMakeLists.txt
@@ -50,4 +50,5 @@
   clangLex
   clangTidy
   clangTidyUtils
+  clangTooling
   )


Index: clang-tidy/misc/CMakeLists.txt
===
--- clang-tidy/misc/CMakeLists.txt
+++ clang-tidy/misc/CMakeLists.txt
@@ -50,4 +50,5 @@
   clangLex
   clangTidy
   clangTidyUtils
+  clangTooling
   )
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20182: [clang-tidy] Add missing dependency of libtooling to misc module

2016-05-11 Thread Etienne Bergeron via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL269240: [clang-tidy] Add missing dependency of libtooling to 
misc module (authored by etienneb).

Changed prior to commit:
  http://reviews.llvm.org/D20182?vs=56963&id=56966#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D20182

Files:
  clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt

Index: clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
===
--- clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
+++ clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
@@ -50,4 +50,5 @@
   clangLex
   clangTidy
   clangTidyUtils
+  clangTooling
   )


Index: clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
===
--- clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
+++ clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
@@ -50,4 +50,5 @@
   clangLex
   clangTidy
   clangTidyUtils
+  clangTooling
   )
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r269240 - [clang-tidy] Add missing dependency of libtooling to misc module

2016-05-11 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Wed May 11 16:32:29 2016
New Revision: 269240

URL: http://llvm.org/viewvc/llvm-project?rev=269240&view=rev
Log:
[clang-tidy] Add missing dependency of libtooling to misc module

Summary:
The new API for fixit is in libtooling and the library misc in clang-tidy
didn't had the appropriate dependency.

This commit was breaking some build bots:
http://reviews.llvm.org/D19547

This commit tried (but failed) to fix it:
http://reviews.llvm.org/D20180

To repro, you can make a build with these flags:
```
cmake -DBUILD_SHARED_LIBS=ON
```

Thanks rnk@ for helping figuring out.

Reviewers: alexfh, rnk

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D20182

Modified:
clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt

Modified: clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt?rev=269240&r1=269239&r2=269240&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt Wed May 11 16:32:29 
2016
@@ -50,4 +50,5 @@ add_clang_library(clangTidyMiscModule
   clangLex
   clangTidy
   clangTidyUtils
+  clangTooling
   )


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


Re: [PATCH] D20180: [tooling] Fix missing inline keyworkd, breaking build bot.

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

I'm sure you're right: they are redundant keywords.
I'm preparing the revert patch, and I'm running tests over multiple build types.


Repository:
  rL LLVM

http://reviews.llvm.org/D20180



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


[PATCH] D20189: [tooling] Remove redundant inline keyword

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added a reviewer: alexfh.
etienneb added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

The inline keywords are redundant.
Introduce by this commit to try to fix broken build bots:
  http://reviews.llvm.org/D20180

Tested on Debug and Release build [linux].
Tested on Release + Shared (-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON) 
[linux]
Tested on Release [windows]

http://reviews.llvm.org/D20189

Files:
  include/clang/Tooling/FixIt.h

Index: include/clang/Tooling/FixIt.h
===
--- include/clang/Tooling/FixIt.h
+++ include/clang/Tooling/FixIt.h
@@ -40,26 +40,26 @@
 
 /// \brief Returns the SourceRange of an given Node. \p Node is typically a
 ///'Stmt', 'Expr' or a 'Decl'.
-template  inline SourceRange getSourceRange(const T &Node) {
+template  SourceRange getSourceRange(const T &Node) {
   return Node.getSourceRange();
 }
 } // end namespace internal
 
 // \brief Returns a textual representation of \p Node.
 template 
-inline StringRef getText(const T &Node, const ASTContext &Context) {
+StringRef getText(const T &Node, const ASTContext &Context) {
   return internal::getText(internal::getSourceRange(Node), Context);
 }
 
 // \brief Returns a FixItHint to remove \p Node.
 // TODO: Add support for related syntactical elements (i.e. comments, ...).
-template  inline FixItHint createRemoval(const T &Node) {
+template  FixItHint createRemoval(const T &Node) {
   return FixItHint::CreateRemoval(internal::getSourceRange(Node));
 }
 
 // \brief Returns a FixItHint to replace \p Destination by \p Source.
 template 
-inline FixItHint createReplacement(const D &Destination, const S &Source,
+FixItHint createReplacement(const D &Destination, const S &Source,
const ASTContext &Context) {
   return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
   getText(Source, Context));


Index: include/clang/Tooling/FixIt.h
===
--- include/clang/Tooling/FixIt.h
+++ include/clang/Tooling/FixIt.h
@@ -40,26 +40,26 @@
 
 /// \brief Returns the SourceRange of an given Node. \p Node is typically a
 ///'Stmt', 'Expr' or a 'Decl'.
-template  inline SourceRange getSourceRange(const T &Node) {
+template  SourceRange getSourceRange(const T &Node) {
   return Node.getSourceRange();
 }
 } // end namespace internal
 
 // \brief Returns a textual representation of \p Node.
 template 
-inline StringRef getText(const T &Node, const ASTContext &Context) {
+StringRef getText(const T &Node, const ASTContext &Context) {
   return internal::getText(internal::getSourceRange(Node), Context);
 }
 
 // \brief Returns a FixItHint to remove \p Node.
 // TODO: Add support for related syntactical elements (i.e. comments, ...).
-template  inline FixItHint createRemoval(const T &Node) {
+template  FixItHint createRemoval(const T &Node) {
   return FixItHint::CreateRemoval(internal::getSourceRange(Node));
 }
 
 // \brief Returns a FixItHint to replace \p Destination by \p Source.
 template 
-inline FixItHint createReplacement(const D &Destination, const S &Source,
+FixItHint createReplacement(const D &Destination, const S &Source,
const ASTContext &Context) {
   return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
   getText(Source, Context));
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20180: [tooling] Fix missing inline keyworkd, breaking build bot.

2016-05-11 Thread Etienne Bergeron via cfe-commits
etienneb added a comment.

In http://reviews.llvm.org/D20180#427893, @rnk wrote:

> In http://reviews.llvm.org/D20180#427840, @alexfh wrote:
>
> > `inline` seems to be completely redundant here. Can you try removing it and 
> > running whatever build configurations were failing without 
> > http://reviews.llvm.org/D20182?
>
>
> My bad, it's explicit function template specializations that need to be 
> marked inline when in headers.


Hmm, it's my bad! I tried it to solve broken bot.
 I try it that way because it is implemented with "inline" in 
ASTMatcherInternal:

Example:

  template <>
  inline const Stmt *GetBodyMatcher::get(const FunctionDecl 
&Node) {
return Node.doesThisDeclarationHaveABody() ? Node.getBody() : nullptr;
  }

But, it's "explicit template specialisation" in the above case.

Revert patch is ready: http://reviews.llvm.org/D20189

Still thanks Reid for helping finding the repro case.


Repository:
  rL LLVM

http://reviews.llvm.org/D20180



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


r269257 - [tooling] Remove redundant inline keyword

2016-05-11 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Wed May 11 19:22:28 2016
New Revision: 269257

URL: http://llvm.org/viewvc/llvm-project?rev=269257&view=rev
Log:
[tooling] Remove redundant inline keyword

Summary:
The inline keywords are redundant.
Introduce by this commit to try to fix broken build bots:
  http://reviews.llvm.org/D20180

Tested on Debug and Release build [linux].
Tested on Release + Shared (-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON) 
[linux]
Tested on Release [windows]

Reviewers: alexfh

Subscribers: cfe-commits, klimek

Differential Revision: http://reviews.llvm.org/D20189

Modified:
cfe/trunk/include/clang/Tooling/FixIt.h

Modified: cfe/trunk/include/clang/Tooling/FixIt.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/FixIt.h?rev=269257&r1=269256&r2=269257&view=diff
==
--- cfe/trunk/include/clang/Tooling/FixIt.h (original)
+++ cfe/trunk/include/clang/Tooling/FixIt.h Wed May 11 19:22:28 2016
@@ -40,26 +40,26 @@ inline SourceRange getSourceRange(const
 
 /// \brief Returns the SourceRange of an given Node. \p Node is typically a
 ///'Stmt', 'Expr' or a 'Decl'.
-template  inline SourceRange getSourceRange(const T &Node) {
+template  SourceRange getSourceRange(const T &Node) {
   return Node.getSourceRange();
 }
 } // end namespace internal
 
 // \brief Returns a textual representation of \p Node.
 template 
-inline StringRef getText(const T &Node, const ASTContext &Context) {
+StringRef getText(const T &Node, const ASTContext &Context) {
   return internal::getText(internal::getSourceRange(Node), Context);
 }
 
 // \brief Returns a FixItHint to remove \p Node.
 // TODO: Add support for related syntactical elements (i.e. comments, ...).
-template  inline FixItHint createRemoval(const T &Node) {
+template  FixItHint createRemoval(const T &Node) {
   return FixItHint::CreateRemoval(internal::getSourceRange(Node));
 }
 
 // \brief Returns a FixItHint to replace \p Destination by \p Source.
 template 
-inline FixItHint createReplacement(const D &Destination, const S &Source,
+FixItHint createReplacement(const D &Destination, const S &Source,
const ASTContext &Context) {
   return FixItHint::CreateReplacement(internal::getSourceRange(Destination),
   getText(Source, Context));


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


r269274 - Add an AST matcher for string-literal length

2016-05-11 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Wed May 11 23:20:04 2016
New Revision: 269274

URL: http://llvm.org/viewvc/llvm-project?rev=269274&view=rev
Log:
Add an AST matcher for string-literal length

Summary:
This patch is adding support for a matcher to check string literal length.

This matcher is used in clang-tidy checkers and is part of this refactoring:
  see: http://reviews.llvm.org/D19841

Reviewers: sbenza, klimek, aaron.ballman

Subscribers: alexfh, klimek, cfe-commits

Differential Revision: http://reviews.llvm.org/D19876

Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=269274&r1=269273&r2=269274&view=diff
==
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Wed May 11 23:20:04 2016
@@ -644,7 +644,8 @@ Not matching Hex-encoded chars (e.g. 0x1
 though.
 
 Example matches 'a', L'a'
-  char ch = 'a'; wchar_t chw = L'a';
+  char ch = 'a';
+  wchar_t chw = L'a';
 
 
 
@@ -652,7 +653,8 @@ Example matches 'a', L'a'
 Matches 
compound (i.e. non-scalar) literals
 
 Example match: {1}, (1, 2)
-  int array[4] = {1}; vector int myvec = (vector int)(1, 2);
+  int array[4] = {1};
+  vector int myvec = (vector int)(1, 2);
 
 
 
@@ -1217,7 +1219,8 @@ Example match: ({ int X = 4; X; })
 Matches string 
literals (also matches wide string literals).
 
 Example matches "abcd", L"abcd"
-  char *s = "abcd"; wchar_t *ws = L"abcd"
+  char *s = "abcd";
+  wchar_t *ws = L"abcd";
 
 
 
@@ -2191,14 +2194,19 @@ compoundStmt(statementCountIs(0)))
 
 
 MatcherConstantArrayType>hasSizeunsigned N
-Matches ConstantArrayType 
nodes that have the specified size.
+Matches nodes that have the 
specified size.
 
 Given
   int a[42];
   int b[2 * 21];
   int c[41], d[43];
+  char *s = "abcd";
+  wchar_t *ws = L"abcd";
+  char *w = "a";
 constantArrayType(hasSize(42))
   matches "int a[42]" and "int b[2 * 21]"
+stringLiteral(hasSize(4))
+  matches "abcd", L"abcd"
 
 
 
@@ -2955,6 +2963,23 @@ Usable as: MatcherStringLiteral>hasSizeunsigned N
+Matches nodes that have the 
specified size.
+
+Given
+  int a[42];
+  int b[2 * 21];
+  int c[41], d[43];
+  char *s = "abcd";
+  wchar_t *ws = L"abcd";
+  char *w = "a";
+constantArrayType(hasSize(42))
+  matches "int a[42]" and "int b[2 * 21]"
+stringLiteral(hasSize(4))
+  matches "abcd", L"abcd"
+
+
+
 MatcherTagDecl>isDefinition
 Matches if a 
declaration has a body attached.
 

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=269274&r1=269273&r2=269274&view=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Wed May 11 23:20:04 2016
@@ -1560,7 +1560,8 @@ const internal::VariadicDynCastAllOfMatc
 ///
 /// Example matches "abcd", L"abcd"
 /// \code
-///   char *s = "abcd"; wchar_t *ws = L"abcd"
+///   char *s = "abcd";
+///   wchar_t *ws = L"abcd";
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -1573,7 +1574,8 @@ const internal::VariadicDynCastAllOfMatc
 ///
 /// Example matches 'a', L'a'
 /// \code
-///   char ch = 'a'; wchar_t chw = L'a';
+///   char ch = 'a';
+///   wchar_t chw = L'a';
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -1609,7 +1611,8 @@ const internal::VariadicDynCastAllOfMatc
 ///
 /// Example match: {1}, (1, 2)
 /// \code
-///   int array[4] = {1}; vector int myvec = (vector int)(1, 2);
+///   int array[4] = {1};
+///   vector int myvec = (vector int)(1, 2);
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
@@ -4228,18 +4231,26 @@ AST_TYPELOC_TRAVERSE_MATCHER(hasElementT
 ///   matches "int a[2]"
 AST_TYPE_MATCHER(ConstantArrayType, constantArrayType);
 
-/// \brief Matches \c ConstantArrayType nodes that have the specified size.
+/// \brief Matches nodes that have the specified size.
 ///
 /// Given
 /// \code
 ///   int a[42];
 ///   int b[2 * 21];
 ///   int c[41], d[43];
+///   char *s = "abcd";
+///   wchar_t *ws = L"abcd";
+///   char *w = "a";
 /// \endcode
 /// constantArrayType(hasSize(42))
 ///   matches "int a[42]" and "int b[2 * 21]"
-AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
-  return Node.getSize() == N;
+/// stringLiteral(hasSize(4))
+///   matches "abcd", L"abcd"
+AST_POLYMO

[clang-tools-extra] r269275 - [clang-tidy] Improve misc-redundant-expression and decrease false-positive

2016-05-11 Thread Etienne Bergeron via cfe-commits
Author: etienneb
Date: Wed May 11 23:32:47 2016
New Revision: 269275

URL: http://llvm.org/viewvc/llvm-project?rev=269275&view=rev
Log:
[clang-tidy] Improve misc-redundant-expression and decrease false-positive

Summary:
This patch is adding support for conditional expression and overloaded 
operators.

To decrease false-positive, this patch is adding a list of banned macro names 
that
has multiple variant with same integer value.

Also fixed support for template instantiation and added an unittest.

Reviewers: alexfh

Subscribers: klimek, Sarcasm, cfe-commits

Differential Revision: http://reviews.llvm.org/D19703

Modified:
clang-tools-extra/trunk/clang-tidy/misc/RedundantExpressionCheck.cpp
clang-tools-extra/trunk/docs/clang-tidy/checks/misc-redundant-expression.rst
clang-tools-extra/trunk/test/clang-tidy/misc-redundant-expression.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/RedundantExpressionCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/RedundantExpressionCheck.cpp?rev=269275&r1=269274&r2=269275&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/misc/RedundantExpressionCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/misc/RedundantExpressionCheck.cpp Wed 
May 11 23:32:47 2016
@@ -9,8 +9,10 @@
 
 #include "RedundantExpressionCheck.h"
 #include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
 
 using namespace clang::ast_matchers;
 
@@ -18,7 +20,18 @@ namespace clang {
 namespace tidy {
 namespace misc {
 
-static bool AreIdenticalExpr(const Expr *Left, const Expr *Right) {
+static const char KnownBannedMacroNames[] =
+"EAGAIN;EWOULDBLOCK;SIGCLD;SIGCHLD;";
+
+static bool areEquivalentNameSpecifier(const NestedNameSpecifier *Left,
+   const NestedNameSpecifier *Right) {
+  llvm::FoldingSetNodeID LeftID, RightID;
+  Left->Profile(LeftID);
+  Right->Profile(RightID);
+  return LeftID == RightID;
+}
+
+static bool areEquivalentExpr(const Expr *Left, const Expr *Right) {
   if (!Left || !Right)
 return !Left && !Right;
 
@@ -33,8 +46,8 @@ static bool AreIdenticalExpr(const Expr
   Expr::const_child_iterator LeftIter = Left->child_begin();
   Expr::const_child_iterator RightIter = Right->child_begin();
   while (LeftIter != Left->child_end() && RightIter != Right->child_end()) {
-if (!AreIdenticalExpr(dyn_cast(*LeftIter),
-  dyn_cast(*RightIter)))
+if (!areEquivalentExpr(dyn_cast(*LeftIter),
+   dyn_cast(*RightIter)))
   return false;
 ++LeftIter;
 ++RightIter;
@@ -53,7 +66,8 @@ static bool AreIdenticalExpr(const Expr
   case Stmt::IntegerLiteralClass: {
 llvm::APInt LeftLit = cast(Left)->getValue();
 llvm::APInt RightLit = cast(Right)->getValue();
-return LeftLit.getBitWidth() == RightLit.getBitWidth() && LeftLit == 
RightLit;
+return LeftLit.getBitWidth() == RightLit.getBitWidth() &&
+   LeftLit == RightLit;
   }
   case Stmt::FloatingLiteralClass:
 return cast(Left)->getValue().bitwiseIsEqual(
@@ -62,6 +76,13 @@ static bool AreIdenticalExpr(const Expr
 return cast(Left)->getBytes() ==
cast(Right)->getBytes();
 
+  case Stmt::DependentScopeDeclRefExprClass:
+if (cast(Left)->getDeclName() !=
+cast(Right)->getDeclName())
+  return false;
+return areEquivalentNameSpecifier(
+cast(Left)->getQualifier(),
+cast(Right)->getQualifier());
   case Stmt::DeclRefExprClass:
 return cast(Left)->getDecl() ==
cast(Right)->getDecl();
@@ -89,22 +110,52 @@ static bool AreIdenticalExpr(const Expr
   }
 }
 
-AST_MATCHER(BinaryOperator, OperandsAreEquivalent) {
-  return AreIdenticalExpr(Node.getLHS(), Node.getRHS());
+AST_MATCHER(BinaryOperator, operandsAreEquivalent) {
+  return areEquivalentExpr(Node.getLHS(), Node.getRHS());
+}
+
+AST_MATCHER(ConditionalOperator, expressionsAreEquivalent) {
+  return areEquivalentExpr(Node.getTrueExpr(), Node.getFalseExpr());
+}
+
+AST_MATCHER(CallExpr, parametersAreEquivalent) {
+  return Node.getNumArgs() == 2 &&
+ areEquivalentExpr(Node.getArg(0), Node.getArg(1));
 }
 
-AST_MATCHER(BinaryOperator, isInMacro) {
+AST_MATCHER(BinaryOperator, binaryOperatorIsInMacro) {
   return Node.getOperatorLoc().isMacroID();
 }
 
-AST_MATCHER(Expr, isInstantiationDependent) {
-  return Node.isInstantiationDependent();
+AST_MATCHER(ConditionalOperator, conditionalOperatorIsInMacro) {
+  return Node.getQuestionLoc().isMacroID() || Node.getColonLoc().isMacroID();
+}
+
+AST_MATCHER(Expr, isMacro) { return Node.getExprLoc().isMacroID(); }
+
+AST_MATCHER_P(Expr, expandedByMacro, std::set, Names) {
+  const SourceManager &SM = Finder->getASTContext().getSourceManager();
+  const LangOptions &LO = Finder->getASTContext().getLan

[PATCH] D20207: [AST] Move operations enum to a definition file.

2016-05-12 Thread Etienne Bergeron via cfe-commits
etienneb created this revision.
etienneb added reviewers: klimek, aaron.ballman.
etienneb added subscribers: cfe-commits, alexfh, sbenza.

This patch moves the enum definitions to a definition (.def) file.

These modifications provide way to list enumerator of a given type.

As an example, this allow parsing of "kinds" in the dynamic matchers.
see: http://reviews.llvm.org/D19871
The dynamic matcher "ofKind" also required this patch to be fixed.

http://reviews.llvm.org/D20207

Files:
  include/clang/AST/OperationKinds.def
  include/clang/AST/OperationKinds.h
  include/clang/module.modulemap
  lib/AST/Expr.cpp

Index: lib/AST/Expr.cpp
===
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -1084,20 +1084,8 @@
 /// corresponds to, e.g. "sizeof" or "[pre]++".
 StringRef UnaryOperator::getOpcodeStr(Opcode Op) {
   switch (Op) {
-  case UO_PostInc: return "++";
-  case UO_PostDec: return "--";
-  case UO_PreInc:  return "++";
-  case UO_PreDec:  return "--";
-  case UO_AddrOf:  return "&";
-  case UO_Deref:   return "*";
-  case UO_Plus:return "+";
-  case UO_Minus:   return "-";
-  case UO_Not: return "~";
-  case UO_LNot:return "!";
-  case UO_Real:return "__real";
-  case UO_Imag:return "__imag";
-  case UO_Extension: return "__extension__";
-  case UO_Coawait: return "co_await";
+#define UNARY_OPERATION(Name, Spelling) case UO_##Name: return Spelling;
+#include "clang/AST/OperationKinds.def"
   }
   llvm_unreachable("Unknown unary operator");
 }
@@ -1608,120 +1596,9 @@
 
 const char *CastExpr::getCastKindName() const {
   switch (getCastKind()) {
-  case CK_Dependent:
-return "Dependent";
-  case CK_BitCast:
-return "BitCast";
-  case CK_LValueBitCast:
-return "LValueBitCast";
-  case CK_LValueToRValue:
-return "LValueToRValue";
-  case CK_NoOp:
-return "NoOp";
-  case CK_BaseToDerived:
-return "BaseToDerived";
-  case CK_DerivedToBase:
-return "DerivedToBase";
-  case CK_UncheckedDerivedToBase:
-return "UncheckedDerivedToBase";
-  case CK_Dynamic:
-return "Dynamic";
-  case CK_ToUnion:
-return "ToUnion";
-  case CK_ArrayToPointerDecay:
-return "ArrayToPointerDecay";
-  case CK_FunctionToPointerDecay:
-return "FunctionToPointerDecay";
-  case CK_NullToMemberPointer:
-return "NullToMemberPointer";
-  case CK_NullToPointer:
-return "NullToPointer";
-  case CK_BaseToDerivedMemberPointer:
-return "BaseToDerivedMemberPointer";
-  case CK_DerivedToBaseMemberPointer:
-return "DerivedToBaseMemberPointer";
-  case CK_ReinterpretMemberPointer:
-return "ReinterpretMemberPointer";
-  case CK_UserDefinedConversion:
-return "UserDefinedConversion";
-  case CK_ConstructorConversion:
-return "ConstructorConversion";
-  case CK_IntegralToPointer:
-return "IntegralToPointer";
-  case CK_PointerToIntegral:
-return "PointerToIntegral";
-  case CK_PointerToBoolean:
-return "PointerToBoolean";
-  case CK_ToVoid:
-return "ToVoid";
-  case CK_VectorSplat:
-return "VectorSplat";
-  case CK_IntegralCast:
-return "IntegralCast";
-  case CK_BooleanToSignedIntegral:
-return "BooleanToSignedIntegral";
-  case CK_IntegralToBoolean:
-return "IntegralToBoolean";
-  case CK_IntegralToFloating:
-return "IntegralToFloating";
-  case CK_FloatingToIntegral:
-return "FloatingToIntegral";
-  case CK_FloatingCast:
-return "FloatingCast";
-  case CK_FloatingToBoolean:
-return "FloatingToBoolean";
-  case CK_MemberPointerToBoolean:
-return "MemberPointerToBoolean";
-  case CK_CPointerToObjCPointerCast:
-return "CPointerToObjCPointerCast";
-  case CK_BlockPointerToObjCPointerCast:
-return "BlockPointerToObjCPointerCast";
-  case CK_AnyPointerToBlockPointerCast:
-return "AnyPointerToBlockPointerCast";
-  case CK_ObjCObjectLValueCast:
-return "ObjCObjectLValueCast";
-  case CK_FloatingRealToComplex:
-return "FloatingRealToComplex";
-  case CK_FloatingComplexToReal:
-return "FloatingComplexToReal";
-  case CK_FloatingComplexToBoolean:
-return "FloatingComplexToBoolean";
-  case CK_FloatingComplexCast:
-return "FloatingComplexCast";
-  case CK_FloatingComplexToIntegralComplex:
-return "FloatingComplexToIntegralComplex";
-  case CK_IntegralRealToComplex:
-return "IntegralRealToComplex";
-  case CK_IntegralComplexToReal:
-return "IntegralComplexToReal";
-  case CK_IntegralComplexToBoolean:
-return "IntegralComplexToBoolean";
-  case CK_IntegralComplexCast:
-return "IntegralComplexCast";
-  case CK_IntegralComplexToFloatingComplex:
-return "IntegralComplexToFloatingComplex";
-  case CK_ARCConsumeObject:
-return "ARCConsumeObject";
-  case CK_ARCProduceObject:
-return "ARCProduceObject";
-  case CK_ARCReclaimReturnedObject:
-return "ARCReclaimReturnedObject";
-  case CK_ARCExtendBlockObject:
-return "ARCExtendBlockObject";
-  case CK_AtomicToNonAtomic:
-return "AtomicToNonAtomic";
-

Re: [PATCH] D20207: [AST] Move operations enum to a definition file.

2016-05-12 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 57043.
etienneb added a comment.
Herald added a subscriber: klimek.

rebase over AST modifications


http://reviews.llvm.org/D20207

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  lib/ASTMatchers/Dynamic/Marshallers.h
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3485,6 +3485,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -210,6 +210,7 @@
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasCaseConstant);
+  REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDecayedType);
Index: lib/ASTMatchers/Dynamic/Marshallers.h
===
--- lib/ASTMatchers/Dynamic/Marshallers.h
+++ lib/ASTMatchers/Dynamic/Marshallers.h
@@ -96,6 +96,28 @@
   }
 };
 
+template <> struct ArgTypeTraits {
+private:
+  static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
+return llvm::StringSwitch(AttrKind)
+#define CAST_OPERATION(Name) .Case( #Name, CK_##Name)
+#include "clang/AST/OperationKinds.def"
+.Default(CK_Invalid);
+  }
+
+public:
+  static bool is(const VariantValue &Value) {
+return Value.isString() &&  
+  getCastKind(Value.getString()) != CK_Invalid;
+  }
+  static clang::CastKind get(const VariantValue &Value) {
+return getCastKind(Value.getString());
+  }
+  static ArgKind getKind() {
+return ArgKind(ArgKind::AK_String);
+  }
+};
+
 /// \brief Matcher descriptor interface.
 ///
 /// Provides a \c create() method that constructs the matcher from the provided
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3551,6 +3551,17 @@
   InnerMatcher.matches(*SubExpression, Finder, Builder));
 }
 
+/// \brief Matches casts that has a given cast kind.
+///
+/// Example: matches the implicit cast around \c 0
+/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
+/// \code
+///   int *p = 0;
+/// \endcode
+AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
+  return Node.getCastKind() == Kind;
+}
+
 /// \brief Matches casts whose destination type matches a given matcher.
 ///
 /// (Note: Clang's AST refers to other conversions as "casts" too, and calls


Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3485,6 +3485,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -210,6 +210,7 @@
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasCaseConstant);
+  REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDecayedType);
Index: lib/ASTMatchers/Dynamic/Marshallers.h
===
--- lib/ASTMatchers/Dynamic/Marshallers.h
+++ lib/ASTMatchers/Dynamic/Marshallers.h
@@ -96,6 +96,28 @@
   }
 };
 
+template <> struct ArgTypeTraits {
+private:
+  static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
+return llvm::StringSwitch(AttrKind)
+#define CAST_OPERATION(Name) .Case( #Name, CK_##Name)
+#include "clang/AST/OperationKinds.def"
+.Default(CK_Invalid);
+  }
+
+public:
+  static bool is(const VariantValue &Value) {
+return 

Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-12 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 57044.
etienneb marked an inline comment as done.
etienneb added a comment.

rebase over AST modifications


http://reviews.llvm.org/D19871

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  lib/ASTMatchers/Dynamic/Marshallers.h
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3485,6 +3485,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -210,6 +210,7 @@
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasCaseConstant);
+  REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDecayedType);
Index: lib/ASTMatchers/Dynamic/Marshallers.h
===
--- lib/ASTMatchers/Dynamic/Marshallers.h
+++ lib/ASTMatchers/Dynamic/Marshallers.h
@@ -96,6 +96,28 @@
   }
 };
 
+template <> struct ArgTypeTraits {
+private:
+  static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
+return llvm::StringSwitch(AttrKind)
+#define CAST_OPERATION(Name) .Case( #Name, CK_##Name)
+#include "clang/AST/OperationKinds.def"
+.Default(CK_Invalid);
+  }
+
+public:
+  static bool is(const VariantValue &Value) {
+return Value.isString() &&  
+  getCastKind(Value.getString()) != CK_Invalid;
+  }
+  static clang::CastKind get(const VariantValue &Value) {
+return getCastKind(Value.getString());
+  }
+  static ArgKind getKind() {
+return ArgKind(ArgKind::AK_String);
+  }
+};
+
 /// \brief Matcher descriptor interface.
 ///
 /// Provides a \c create() method that constructs the matcher from the provided
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3551,6 +3551,17 @@
   InnerMatcher.matches(*SubExpression, Finder, Builder));
 }
 
+/// \brief Matches casts that has a given cast kind.
+///
+/// Example: matches the implicit cast around \c 0
+/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
+/// \code
+///   int *p = 0;
+/// \endcode
+AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
+  return Node.getCastKind() == Kind;
+}
+
 /// \brief Matches casts whose destination type matches a given matcher.
 ///
 /// (Note: Clang's AST refers to other conversions as "casts" too, and calls


Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -3485,6 +3485,13 @@
   EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
 }
 
+TEST(CastExpression, HasCastKind) {
+  EXPECT_TRUE(matches("char *p = 0;",
+  castExpr(hasCastKind(CK_NullToPointer;
+  EXPECT_TRUE(notMatches("char *p = 0;",
+  castExpr(hasCastKind(CK_DerivedToBase;
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);",
   cxxReinterpretCastExpr()));
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -210,6 +210,7 @@
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasCaseConstant);
+  REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDecayedType);
Index: lib/ASTMatchers/Dynamic/Marshallers.h
===
--- lib/ASTMatchers/Dynamic/Marshallers.h
+++ lib/ASTMatchers/Dynamic/Marshallers.h
@@ -96,6 +96,28 @@
   }
 };
 
+template <> struct ArgTypeTraits {
+private:
+  static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
+return llvm::StringSwitch(AttrKind)
+#define CAST_OPERATION(Name) .Case( #Name, CK_##Name)
+#include "clang/AST/OperationKinds.def"
+.Default(CK_Invalid);
+  }
+
+public:
+  static bool is(const VariantValue &Value) {
+   

Re: [PATCH] D20207: [AST] Move operations enum to a definition file.

2016-05-12 Thread Etienne Bergeron via cfe-commits
etienneb updated this revision to Diff 57045.
etienneb added a comment.

remove incorrect patch upload (sorry)


http://reviews.llvm.org/D20207

Files:
  include/clang/AST/OperationKinds.def
  include/clang/AST/OperationKinds.h
  include/clang/module.modulemap
  lib/AST/Expr.cpp

Index: lib/AST/Expr.cpp
===
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -1084,20 +1084,8 @@
 /// corresponds to, e.g. "sizeof" or "[pre]++".
 StringRef UnaryOperator::getOpcodeStr(Opcode Op) {
   switch (Op) {
-  case UO_PostInc: return "++";
-  case UO_PostDec: return "--";
-  case UO_PreInc:  return "++";
-  case UO_PreDec:  return "--";
-  case UO_AddrOf:  return "&";
-  case UO_Deref:   return "*";
-  case UO_Plus:return "+";
-  case UO_Minus:   return "-";
-  case UO_Not: return "~";
-  case UO_LNot:return "!";
-  case UO_Real:return "__real";
-  case UO_Imag:return "__imag";
-  case UO_Extension: return "__extension__";
-  case UO_Coawait: return "co_await";
+#define UNARY_OPERATION(Name, Spelling) case UO_##Name: return Spelling;
+#include "clang/AST/OperationKinds.def"
   }
   llvm_unreachable("Unknown unary operator");
 }
@@ -1608,120 +1596,9 @@
 
 const char *CastExpr::getCastKindName() const {
   switch (getCastKind()) {
-  case CK_Dependent:
-return "Dependent";
-  case CK_BitCast:
-return "BitCast";
-  case CK_LValueBitCast:
-return "LValueBitCast";
-  case CK_LValueToRValue:
-return "LValueToRValue";
-  case CK_NoOp:
-return "NoOp";
-  case CK_BaseToDerived:
-return "BaseToDerived";
-  case CK_DerivedToBase:
-return "DerivedToBase";
-  case CK_UncheckedDerivedToBase:
-return "UncheckedDerivedToBase";
-  case CK_Dynamic:
-return "Dynamic";
-  case CK_ToUnion:
-return "ToUnion";
-  case CK_ArrayToPointerDecay:
-return "ArrayToPointerDecay";
-  case CK_FunctionToPointerDecay:
-return "FunctionToPointerDecay";
-  case CK_NullToMemberPointer:
-return "NullToMemberPointer";
-  case CK_NullToPointer:
-return "NullToPointer";
-  case CK_BaseToDerivedMemberPointer:
-return "BaseToDerivedMemberPointer";
-  case CK_DerivedToBaseMemberPointer:
-return "DerivedToBaseMemberPointer";
-  case CK_ReinterpretMemberPointer:
-return "ReinterpretMemberPointer";
-  case CK_UserDefinedConversion:
-return "UserDefinedConversion";
-  case CK_ConstructorConversion:
-return "ConstructorConversion";
-  case CK_IntegralToPointer:
-return "IntegralToPointer";
-  case CK_PointerToIntegral:
-return "PointerToIntegral";
-  case CK_PointerToBoolean:
-return "PointerToBoolean";
-  case CK_ToVoid:
-return "ToVoid";
-  case CK_VectorSplat:
-return "VectorSplat";
-  case CK_IntegralCast:
-return "IntegralCast";
-  case CK_BooleanToSignedIntegral:
-return "BooleanToSignedIntegral";
-  case CK_IntegralToBoolean:
-return "IntegralToBoolean";
-  case CK_IntegralToFloating:
-return "IntegralToFloating";
-  case CK_FloatingToIntegral:
-return "FloatingToIntegral";
-  case CK_FloatingCast:
-return "FloatingCast";
-  case CK_FloatingToBoolean:
-return "FloatingToBoolean";
-  case CK_MemberPointerToBoolean:
-return "MemberPointerToBoolean";
-  case CK_CPointerToObjCPointerCast:
-return "CPointerToObjCPointerCast";
-  case CK_BlockPointerToObjCPointerCast:
-return "BlockPointerToObjCPointerCast";
-  case CK_AnyPointerToBlockPointerCast:
-return "AnyPointerToBlockPointerCast";
-  case CK_ObjCObjectLValueCast:
-return "ObjCObjectLValueCast";
-  case CK_FloatingRealToComplex:
-return "FloatingRealToComplex";
-  case CK_FloatingComplexToReal:
-return "FloatingComplexToReal";
-  case CK_FloatingComplexToBoolean:
-return "FloatingComplexToBoolean";
-  case CK_FloatingComplexCast:
-return "FloatingComplexCast";
-  case CK_FloatingComplexToIntegralComplex:
-return "FloatingComplexToIntegralComplex";
-  case CK_IntegralRealToComplex:
-return "IntegralRealToComplex";
-  case CK_IntegralComplexToReal:
-return "IntegralComplexToReal";
-  case CK_IntegralComplexToBoolean:
-return "IntegralComplexToBoolean";
-  case CK_IntegralComplexCast:
-return "IntegralComplexCast";
-  case CK_IntegralComplexToFloatingComplex:
-return "IntegralComplexToFloatingComplex";
-  case CK_ARCConsumeObject:
-return "ARCConsumeObject";
-  case CK_ARCProduceObject:
-return "ARCProduceObject";
-  case CK_ARCReclaimReturnedObject:
-return "ARCReclaimReturnedObject";
-  case CK_ARCExtendBlockObject:
-return "ARCExtendBlockObject";
-  case CK_AtomicToNonAtomic:
-return "AtomicToNonAtomic";
-  case CK_NonAtomicToAtomic:
-return "NonAtomicToAtomic";
-  case CK_CopyAndAutoreleaseBlockObject:
-return "CopyAndAutoreleaseBlockObject";
-  case CK_BuiltinFnToFnPtr:
-return "BuiltinFnToFnPtr";
-  case CK_ZeroToOCLEvent:
-return "ZeroToOCLEvent";
-  case CK_AddressSpaceConversion:
-return "AddressSpaceConversion

Re: [PATCH] D19871: Add an AST matcher for CastExpr kind

2016-05-12 Thread Etienne Bergeron via cfe-commits
etienneb marked 3 inline comments as done.
etienneb added a comment.

This patch has been modified to support dynamic matchers.
It rely on : http://reviews.llvm.org/D20207

Comments?



Comment at: lib/ASTMatchers/Dynamic/Marshallers.h:102
@@ +101,3 @@
+  static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
+return llvm::StringSwitch(AttrKind)
+#define CAST_OPERATION(Name) .Case( #Name, CK_##Name)

moved to that solution. (let try it)


Comment at: lib/ASTMatchers/Dynamic/Registry.cpp:78
@@ -77,2 +77,3 @@
   // Need Variant/Parser fixes:
+  // hasCastKind  
   // ofKind

sbenza wrote:
> Is it registered or not?
> You add this comment, but also add the matcher in the registry below.
bad revert.
I'm making a patch to allow dynamic matcher, and I'll come back fixing this CL.


http://reviews.llvm.org/D19871



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


  1   2   3   4   >