[PATCH] D94873: [clang] [driver] Remove obsolete unistd.h include

2021-01-16 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder created this revision.
tbaeder added reviewers: rsmith, aaron.ballman, dlj.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This was needed for a call to `getuid()`, but that call is gone these days, so 
remove the include as well.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D94873

Files:
  clang/lib/Driver/ToolChains/Clang.cpp


Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -45,10 +45,6 @@
 #include "llvm/Support/TargetParser.h"
 #include "llvm/Support/YAMLParser.h"
 
-#ifdef LLVM_ON_UNIX
-#include  // For getuid().
-#endif
-
 using namespace clang::driver;
 using namespace clang::driver::tools;
 using namespace clang;


Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -45,10 +45,6 @@
 #include "llvm/Support/TargetParser.h"
 #include "llvm/Support/YAMLParser.h"
 
-#ifdef LLVM_ON_UNIX
-#include  // For getuid().
-#endif
-
 using namespace clang::driver;
 using namespace clang::driver::tools;
 using namespace clang;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D94854: [Clang] Fix SwiftCallingConv's aggregate lowering for _Atomic(_Bool).

2021-01-16 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

Clang is trying to avoid using non-byte-multiple integer types for memory 
accesses in LLVM IR, whereas Swift isn't.  If you take your test case and make 
the field non-atomic, you'll see that: Clang is accessing the field as an `i8` 
and Swift is accessing it as an `i1`.  So there's a deeper mismatch here which 
in practice works out because there's no actual difference in memory access 
width between those types.

The most correct thing for Swift to do is probably to follow Clang's lead in 
access widths when accessing a C type.  In general, I'm not sure there's any 
compelling reason for Swift to be doing its own IR type layout on Clang's 
struct types instead of asking Clang IRGen for the lowering, field indexes, and 
so on.  So in the abstract, I think the best fixes would be for Swift to use 
Clang's IR type and to access this field in memory as an `i8`, whether it's 
atomic or not; and if we did that, Swift would have to have `mapIntoNative` / 
`mapFromNative` potentially truncate / extend to match the CC schema, even for 
fields Swift imported as `Bool`.  That would be a more invasive change; 
probably right now it'd be better to just add that logic to match schemas so 
that `_Atomic(_Bool)` works.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D94854

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


[libunwind] 3cbd476 - [VE] Support VE in libunwind

2021-01-16 Thread Kazushi Marukawa via cfe-commits

Author: Kazushi (Jam) Marukawa
Date: 2021-01-17T15:35:02+09:00
New Revision: 3cbd476c54886e8ebac64b4145d4517732a71023

URL: 
https://github.com/llvm/llvm-project/commit/3cbd476c54886e8ebac64b4145d4517732a71023
DIFF: 
https://github.com/llvm/llvm-project/commit/3cbd476c54886e8ebac64b4145d4517732a71023.diff

LOG: [VE] Support VE in libunwind

Modify libunwind to support SjLj exception handling routines for VE.
In order to do that, we need to implement not only SjLj exception
handling routines but also a Registers_ve class.  This implementation
of Registers_ve is incomplete.  We will work on it later when we need
backtrace in libunwind.

Reviewed By: #libunwind, compnerd

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

Added: 


Modified: 
libunwind/include/__libunwind_config.h
libunwind/include/libunwind.h
libunwind/src/Registers.hpp
libunwind/src/Unwind-sjlj.c
libunwind/src/libunwind.cpp

Removed: 




diff  --git a/libunwind/include/__libunwind_config.h 
b/libunwind/include/__libunwind_config.h
index 80be357496c4..34ac6f717d6e 100644
--- a/libunwind/include/__libunwind_config.h
+++ b/libunwind/include/__libunwind_config.h
@@ -25,6 +25,7 @@
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC 31
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON   34
 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64
+#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE143
 
 #if defined(_LIBUNWIND_IS_NATIVE_ONLY)
 # if defined(__linux__)
@@ -138,6 +139,11 @@
 #error "Unsupported RISC-V ABI"
 #  endif
 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 
_LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV
+# elif defined(__ve__)
+#  define _LIBUNWIND_TARGET_VE 1
+#  define _LIBUNWIND_CONTEXT_SIZE 67
+#  define _LIBUNWIND_CURSOR_SIZE 79
+#  define _LIBUNWIND_HIGHEST_DWARF_REGISTER 
_LIBUNWIND_HIGHEST_DWARF_REGISTER_VE
 # else
 #  error "Unsupported architecture."
 # endif
@@ -154,6 +160,7 @@
 # define _LIBUNWIND_TARGET_SPARC 1
 # define _LIBUNWIND_TARGET_HEXAGON 1
 # define _LIBUNWIND_TARGET_RISCV 1
+# define _LIBUNWIND_TARGET_VE 1
 # define _LIBUNWIND_CONTEXT_SIZE 167
 # define _LIBUNWIND_CURSOR_SIZE 179
 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287

diff  --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h
index 6ec649a460b8..5bae8d02f799 100644
--- a/libunwind/include/libunwind.h
+++ b/libunwind/include/libunwind.h
@@ -947,4 +947,156 @@ enum {
   UNW_RISCV_F31 = 63,
 };
 
+// VE register numbers
+enum {
+  UNW_VE_S0   = 0,
+  UNW_VE_S1   = 1,
+  UNW_VE_S2   = 2,
+  UNW_VE_S3   = 3,
+  UNW_VE_S4   = 4,
+  UNW_VE_S5   = 5,
+  UNW_VE_S6   = 6,
+  UNW_VE_S7   = 7,
+  UNW_VE_S8   = 8,
+  UNW_VE_S9   = 9,
+  UNW_VE_S10  = 10,
+  UNW_VE_S11  = 11,
+  UNW_VE_S12  = 12,
+  UNW_VE_S13  = 13,
+  UNW_VE_S14  = 14,
+  UNW_VE_S15  = 15,
+  UNW_VE_S16  = 16,
+  UNW_VE_S17  = 17,
+  UNW_VE_S18  = 18,
+  UNW_VE_S19  = 19,
+  UNW_VE_S20  = 20,
+  UNW_VE_S21  = 21,
+  UNW_VE_S22  = 22,
+  UNW_VE_S23  = 23,
+  UNW_VE_S24  = 24,
+  UNW_VE_S25  = 25,
+  UNW_VE_S26  = 26,
+  UNW_VE_S27  = 27,
+  UNW_VE_S28  = 28,
+  UNW_VE_S29  = 29,
+  UNW_VE_S30  = 30,
+  UNW_VE_S31  = 31,
+  UNW_VE_S32  = 32,
+  UNW_VE_S33  = 33,
+  UNW_VE_S34  = 34,
+  UNW_VE_S35  = 35,
+  UNW_VE_S36  = 36,
+  UNW_VE_S37  = 37,
+  UNW_VE_S38  = 38,
+  UNW_VE_S39  = 39,
+  UNW_VE_S40  = 40,
+  UNW_VE_S41  = 41,
+  UNW_VE_S42  = 42,
+  UNW_VE_S43  = 43,
+  UNW_VE_S44  = 44,
+  UNW_VE_S45  = 45,
+  UNW_VE_S46  = 46,
+  UNW_VE_S47  = 47,
+  UNW_VE_S48  = 48,
+  UNW_VE_S49  = 49,
+  UNW_VE_S50  = 50,
+  UNW_VE_S51  = 51,
+  UNW_VE_S52  = 52,
+  UNW_VE_S53  = 53,
+  UNW_VE_S54  = 54,
+  UNW_VE_S55  = 55,
+  UNW_VE_S56  = 56,
+  UNW_VE_S57  = 57,
+  UNW_VE_S58  = 58,
+  UNW_VE_S59  = 59,
+  UNW_VE_S60  = 60,
+  UNW_VE_S61  = 61,
+  UNW_VE_S62  = 62,
+  UNW_VE_S63  = 63,
+  UNW_VE_V0   = 64 + 0,
+  UNW_VE_V1   = 64 + 1,
+  UNW_VE_V2   = 64 + 2,
+  UNW_VE_V3   = 64 + 3,
+  UNW_VE_V4   = 64 + 4,
+  UNW_VE_V5   = 64 + 5,
+  UNW_VE_V6   = 64 + 6,
+  UNW_VE_V7   = 64 + 7,
+  UNW_VE_V8   = 64 + 8,
+  UNW_VE_V9   = 64 + 9,
+  UNW_VE_V10  = 64 + 10,
+  UNW_VE_V11  = 64 + 11,
+  UNW_VE_V12  = 64 + 12,
+  UNW_VE_V13  = 64 + 13,
+  UNW_VE_V14  = 64 + 14,
+  UNW_VE_V15  = 64 + 15,
+  UNW_VE_V16  = 64 + 16,
+  UNW_VE_V17  = 64 + 17,
+  UNW_VE_V18  = 64 + 18,
+  UNW_VE_V19  = 64 + 19,
+  UNW_VE_V20  = 64 + 20,
+  UNW_VE_V21  = 64 + 21,
+  UNW_VE_V22  = 64 + 22,
+  UNW_VE_V23  = 64 + 23,
+  UNW_VE_V24  = 64 + 24,
+  UNW_VE_V25  = 64 + 25,
+  UNW_VE_V26  = 64 + 26,
+  UNW_VE_V27  = 64 + 27,
+  UNW_VE_V28  = 64 + 28,
+  UNW_VE_V29  = 64 + 29,
+  UNW_VE_V30  = 64 + 30,
+  UNW_VE_V31  = 64 + 31,
+  UNW_VE_V32  = 64 + 32,
+  UNW_VE_V33  = 64 + 33,
+  UNW_VE_V34  = 64 + 34,
+  UNW_VE_V35  = 64 + 35,
+  UNW_VE_V36  = 64 + 36,
+  UNW_VE_V37  = 64 + 37,
+  UNW_VE_V38  = 64 + 38,
+  UNW_VE_V39  = 64 + 39,
+  UNW_VE_V40  = 64 + 40,
+  UNW_VE_V41  = 64 + 41,
+  UNW_VE_V42  = 64 + 42,

[PATCH] D94871: [Clang][OpenMP] Fixed an issue that clang crashed when compiling OpenMP program in device only mode without host IR

2021-01-16 Thread Shilei Tian via Phabricator via cfe-commits
tianshilei1992 created this revision.
tianshilei1992 added reviewers: jdoerfert, ABataev, grokos.
Herald added subscribers: guansong, yaxunl.
tianshilei1992 requested review of this revision.
Herald added subscribers: cfe-commits, sstefan1.
Herald added a project: clang.

D94745  rewrites the `deviceRTLs` using OpenMP 
and compiles it by directly
calling the device compilation. `clang` crashes because entry in
`OffloadEntriesDeviceGlobalVar` is unintialized. Current design supposes the
device compilation can only be invoked after host compilation with the host IR
such that `clang` can initialize `OffloadEntriesDeviceGlobalVar` from host IR.
This avoids us using device compilation directly, especially when we only have
code wrapped into `declare target` which are all device code.

In this patch, we updated the logic that if a declaration is in `declare 
target`,
and it is not in the map, we will first initialize it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D94871

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.h


Index: clang/lib/CodeGen/CGOpenMPRuntime.h
===
--- clang/lib/CodeGen/CGOpenMPRuntime.h
+++ clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -674,7 +674,8 @@
 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
  CharUnits VarSize,
  OMPTargetGlobalVarEntryKind Flags,
- llvm::GlobalValue::LinkageTypes Linkage);
+ llvm::GlobalValue::LinkageTypes Linkage,
+ bool IsDeclareTargetDeclaration = false);
 /// Checks if the variable with the given name has been registered already.
 bool hasDeviceGlobalVarEntryInfo(StringRef VarName) const {
   return OffloadEntriesDeviceGlobalVar.count(VarName) > 0;
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -3015,8 +3015,13 @@
 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
  CharUnits VarSize,
  OMPTargetGlobalVarEntryKind Flags,
- llvm::GlobalValue::LinkageTypes Linkage) {
+ llvm::GlobalValue::LinkageTypes Linkage,
+ bool IsDeclareTargetDeclaration) {
   if (CGM.getLangOpts().OpenMPIsDevice) {
+// A global variable might be not in the map if it is declared in declare
+// target and device compilation is invoked without host IR.
+if (IsDeclareTargetDeclaration && !hasDeviceGlobalVarEntryInfo(VarName))
+  initializeDeviceGlobalVarEntryInfo(VarName, Flags, OffloadingEntriesNum);
 auto  = OffloadEntriesDeviceGlobalVar[VarName];
 assert(Entry.isValid() && Entry.getFlags() == Flags &&
"Entry not initialized!");
@@ -10514,7 +10519,7 @@
   }
 
   OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo(
-  VarName, Addr, VarSize, Flags, Linkage);
+  VarName, Addr, VarSize, Flags, Linkage, static_cast(Res));
 }
 
 bool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) {


Index: clang/lib/CodeGen/CGOpenMPRuntime.h
===
--- clang/lib/CodeGen/CGOpenMPRuntime.h
+++ clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -674,7 +674,8 @@
 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
  CharUnits VarSize,
  OMPTargetGlobalVarEntryKind Flags,
- llvm::GlobalValue::LinkageTypes Linkage);
+ llvm::GlobalValue::LinkageTypes Linkage,
+ bool IsDeclareTargetDeclaration = false);
 /// Checks if the variable with the given name has been registered already.
 bool hasDeviceGlobalVarEntryInfo(StringRef VarName) const {
   return OffloadEntriesDeviceGlobalVar.count(VarName) > 0;
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -3015,8 +3015,13 @@
 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
  CharUnits VarSize,
  OMPTargetGlobalVarEntryKind Flags,
- llvm::GlobalValue::LinkageTypes Linkage) {
+ llvm::GlobalValue::LinkageTypes Linkage,
+ bool IsDeclareTargetDeclaration) {
   if (CGM.getLangOpts().OpenMPIsDevice) {

[PATCH] D94854: [Clang] Fix SwiftCallingConv's aggregate lowering for _Atomic(_Bool).

2021-01-16 Thread Varun Gandhi via Phabricator via cfe-commits
varungandhi-apple added a comment.

> The way you'd test it on the Clang side would be to just write a test case 
> that passes such an aggregate and tests that it's passed as an `i8`.

Ah, I just noticed an attribute `__attribute__((swiftcall))` that is used in 
some test cases, I can add a test for it.

---

> But I'm not sure it's at all unreasonable to pass this as an i1 rather than 
> an i8; seems like something that Swift should handle correctly in its 
> call-lowering code.

Here is the code in the compiler which is creating the `i8`.

  void addStructField(const clang::FieldDecl *clangField,
  VarDecl *swiftField) {
unsigned fieldOffset = 
ClangLayout.getFieldOffset(clangField->getFieldIndex());
assert(!clangField->isBitField());
Size offset(fieldOffset / 8);
  
// If we have a Swift import of this type, use our lowered information.
if (swiftField) { /* snip */ }
  
// Otherwise, add it as an opaque blob.
auto fieldSize = ClangContext.getTypeSizeInChars(clangField->getType());
return addOpaqueField(offset, Size(fieldSize.getQuantity()));
  }

From what I understand, the `i8` is actually correct. (I looked at LLVM IR 
generated by small examples and those seem to use `i8` for loads, stores and 
layout.)

That said, there is special handling in `NativeConventionSchema::mapIntoNative` 
and `NativeConventionSchema::mapFromNative`. Here's the code in `mapIntoNative`.

  if (fromNonNative.size() == 1) {
auto *elt = fromNonNative.claimNext();
if (nativeTy != elt->getType()) {
  if (isa(nativeTy) &&
  isa(elt->getType()))
elt = IGF.Builder.CreateZExt(elt, nativeTy);

This ends up trying to zext from i8 to i1 and trips over.

Are you suggesting that I change the code in `mapIntoNative`/`mapFromNative` to 
flip the zext/trunc the other way around based on sizes? Should I be adding the 
special case to `addStructField`? Something else?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D94854

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


[PATCH] D94131: [clang-tidy] Use new mapAnyOf matcher

2021-01-16 Thread Nathan James via Phabricator via cfe-commits
njames93 requested changes to this revision.
njames93 added a comment.
This revision now requires changes to proceed.

Can you either update the description of this patch to include the 
binaryOperation changes, or remove those changes from here.




Comment at: 
clang-tools-extra/clang-tidy/bugprone/SpuriouslyWakeUpFunctionsCheck.cpp:62
 Finder->addMatcher(
-ifStmt(
-
-allOf(hasWaitDescendantCPP,
-  unless(anyOf(hasDescendant(ifStmt(hasWaitDescendantCPP)),
-   hasDescendant(whileStmt(hasWaitDescendantCPP)),
-   hasDescendant(forStmt(hasWaitDescendantCPP)),
-   hasDescendant(doStmt(hasWaitDescendantCPP)
-
-),
+ifStmt(allOf(
+hasWaitDescendantCPP,

While were here, this allOf matcher could be removed.



Comment at: 
clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp:43-45
+  const auto HasNoSelfCheck = cxxMethodDecl(unless(hasDescendant(
+  binaryOperation(hasAnyOperatorName("==", "!="),
+  hasEitherOperand(ignoringParenCasts(cxxThisExpr()));

nit: Can this unrelated change be removed from this patch.



Comment at: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp:313
// may be instantiated to use std::move() on built-in types.
-   binaryOperator(hasOperatorName("="), hasLHS(DeclRefMatcher)),
-   cxxOperatorCallExpr(hasOverloadedOperatorName("="),
-   hasArgument(0, DeclRefMatcher)),
+   binaryOperation(hasOperatorName("="), hasLHS(DeclRefMatcher)),
// Declaration. We treat this as a type of reinitialization too,

nit: ditto.



Comment at: clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp:33-34
   const auto IsSourceMutatingAssignment = traverse(
-  TK_AsIs,
-  expr(anyOf(binaryOperator(isAssignmentOperator(), hasLHS(IsPartOfSource))
- .bind(MutatingOperatorName),
- cxxOperatorCallExpr(isAssignmentOperator(),
- hasArgument(0, IsPartOfSource))
- .bind(MutatingOperatorName;
+  TK_AsIs, binaryOperation(hasOperatorName("="), hasLHS(IsPartOfSource))
+   .bind(MutatingOperatorName));
 

And here.



Comment at: clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp:42
   const auto IsSelfMutatingAssignment =
-  expr(anyOf(binaryOperator(isAssignmentOperator(), hasLHS(IsPartOfSelf)),
- cxxOperatorCallExpr(isAssignmentOperator(),
- hasArgument(0, IsPartOfSelf;
+  binaryOperation(isAssignmentOperator(), hasLHS(IsPartOfSelf));
 

Here.



Comment at: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp:213-215
+ hasCondition(ignoringImplicit(binaryOperation(
+ hasOperatorName("!="), hasOperands(IteratorComparisonMatcher,
+IteratorBoundMatcher,

Also unrelated.



Comment at: 
clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp:186-188
+if (match(traverse(TK_AsIs,
+   compoundStmt(has(ignoringParenImpCasts(binaryOperation(
+   hasOperatorName("="), hasLHS(LHS), hasRHS(RHS)),

Also unrelated.



Comment at: clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp:51-54
+  callOrConstruct(forEachArgumentWithParam(
+  MoveCallMatcher,
+  
parmVarDecl(hasType(references(isConstQualified())
+  .bind("receiving-expr"),

Unrelated changes again.



Comment at: 
clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp:75
  cxxUnresolvedConstructExpr(hasType(booleanType())),
- callExpr(hasAnyArgumentWithParam(
+ callOrConstruct(hasAnyArgumentWithParam(
  expr(equalsBoundNode(ExprName)),

Unrelated change.



Comment at: 
clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp:181-186
+  binaryOperation(unless(isInTemplateInstantiation()),
+  hasAnyOperatorName("==", "!="),
+  hasOperands(ignoringParenImpCasts(WrongComparend),
+  ignoringParenImpCasts(STLArg)),
+  unless(hasAncestor(cxxMethodDecl(
+  ofClass(equalsBoundNode("container"))

Unrelated change



Comment at: clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp:70
   

[PATCH] D94131: [clang-tidy] Use new mapAnyOf matcher

2021-01-16 Thread Stephen Kelly via Phabricator via cfe-commits
steveire updated this revision to Diff 317177.
steveire added a comment.

Update


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D94131

Files:
  clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/SpuriouslyWakeUpFunctionsCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
  clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp
  clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp
  clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
  clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
  clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp
  clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp

Index: clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
===
--- clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
+++ clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
@@ -66,10 +66,8 @@
   substTemplateTypeParmType(hasReplacementType(ConstReferenceOrValue;
   auto UsedAsConstRefOrValueArg = forEachArgumentWithParam(
   DeclRefToVar, parmVarDecl(hasType(ConstReferenceOrValueOrReplaced)));
-  Matches = match(findAll(callExpr(UsedAsConstRefOrValueArg)), Stmt, Context);
-  extractNodesByIdTo(Matches, "declRef", DeclRefs);
   Matches =
-  match(findAll(cxxConstructExpr(UsedAsConstRefOrValueArg)), Stmt, Context);
+  match(findAll(callOrConstruct(UsedAsConstRefOrValueArg)), Stmt, Context);
   extractNodesByIdTo(Matches, "declRef", DeclRefs);
   // References and pointers to const assignments.
   Matches =
Index: clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp
@@ -37,11 +37,10 @@
   has(compoundStmt(hasAnySubstatement(returnStmt(unless(has(expr())
   .bind("return"))),
   this);
-  auto CompoundContinue =
-  has(compoundStmt(hasAnySubstatement(continueStmt())).bind("continue"));
   Finder->addMatcher(
-  stmt(anyOf(forStmt(), cxxForRangeStmt(), whileStmt(), doStmt()),
-   CompoundContinue),
+  mapAnyOf(forStmt, cxxForRangeStmt, whileStmt, doStmt)
+  .with(hasBody(compoundStmt(hasAnySubstatement(continueStmt()))
+.bind("continue"))),
   this);
 }
 
Index: clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
@@ -56,26 +56,23 @@
   const char *ExprName = "__booleanContextExpr";
   auto Result =
   expr(expr().bind(ExprName),
-   anyOf(hasParent(varDecl(hasType(booleanType(,
+   anyOf(hasParent(
+ mapAnyOf(varDecl, fieldDecl).with(hasType(booleanType(,
  hasParent(cxxConstructorDecl(
  hasAnyConstructorInitializer(cxxCtorInitializer(
  withInitializer(expr(equalsBoundNode(ExprName))),
  forField(hasType(booleanType())),
- hasParent(fieldDecl(hasType(booleanType(,
  hasParent(stmt(anyOf(
  explicitCastExpr(hasDestinationType(booleanType())),
- ifStmt(hasCondition(expr(equalsBoundNode(ExprName,
- doStmt(hasCondition(expr(equalsBoundNode(ExprName,
- whileStmt(hasCondition(expr(equalsBoundNode(ExprName,
- forStmt(hasCondition(expr(equalsBoundNode(ExprName,
- conditionalOperator(
- hasCondition(expr(equalsBoundNode(ExprName,
+ mapAnyOf(ifStmt, doStmt, whileStmt, forStmt,
+  conditionalOperator)
+ .with(hasCondition(expr(equalsBoundNode(ExprName,
  parenListExpr(hasParent(varDecl(hasType(booleanType(),
  parenExpr(hasParent(
  explicitCastExpr(hasDestinationType(booleanType(),
  returnStmt(forFunction(returns(booleanType(,
  cxxUnresolvedConstructExpr(hasType(booleanType())),
- 

[PATCH] D94865: [ASTMatchers] Add callOrConstruct matcher

2021-01-16 Thread Stephen Kelly via Phabricator via cfe-commits
steveire created this revision.
steveire added a reviewer: aaron.ballman.
steveire requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D94865

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

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -860,6 +860,48 @@
  mapAnyOf(unaryOperator, cxxOperatorCallExpr)
  .with(hasAnyOperatorName("+", "!"),
forFunction(functionDecl(hasName("opFree")));
+
+  Code = R"cpp(
+struct ConstructorTakesInt
+{
+  ConstructorTakesInt(int i) {}
+};
+
+void callTakesInt(int i)
+{
+
+}
+
+void doCall()
+{
+  callTakesInt(42);
+}
+
+void doConstruct()
+{
+  ConstructorTakesInt cti(42);
+}
+)cpp";
+
+  EXPECT_TRUE(matches(
+  Code,
+  traverse(TK_IgnoreUnlessSpelledInSource,
+   callOrConstruct(
+   forFunction(functionDecl(hasName("doCall"))),
+   hasArgument(0, integerLiteral(equals(42))),
+   hasAnyArgument(integerLiteral(equals(42))),
+   forEachArgumentWithParam(integerLiteral(equals(42)),
+parmVarDecl(hasName("i")));
+
+  EXPECT_TRUE(matches(
+  Code,
+  traverse(TK_IgnoreUnlessSpelledInSource,
+   callOrConstruct(
+   forFunction(functionDecl(hasName("doConstruct"))),
+   hasArgument(0, integerLiteral(equals(42))),
+   hasAnyArgument(integerLiteral(equals(42))),
+   forEachArgumentWithParam(integerLiteral(equals(42)),
+parmVarDecl(hasName("i")));
 }
 
 TEST_P(ASTMatchersTest, IsDerivedFrom) {
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -152,6 +152,7 @@
   REGISTER_MATCHER(builtinType);
   REGISTER_MATCHER(cStyleCastExpr);
   REGISTER_MATCHER(callExpr);
+  REGISTER_MATCHER(callOrConstruct);
   REGISTER_MATCHER(caseStmt);
   REGISTER_MATCHER(castExpr);
   REGISTER_MATCHER(characterLiteral);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -924,6 +924,7 @@
 const internal::MapAnyOfMatcher
 binaryOperation;
+const internal::MapAnyOfMatcher callOrConstruct;
 const internal::VariadicDynCastAllOfMatcher unaryOperator;
 const internal::VariadicDynCastAllOfMatcher
 conditionalOperator;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2829,6 +2829,43 @@
CXXRewrittenBinaryOperator>
 binaryOperation;
 
+/// Matches function calls and constructor calls
+///
+/// Because CallExpr and CXXConstructExpr do not share a common
+/// base class with API accessing arguments etc, AST Matchers for code
+/// which should match both are typically duplicated. This matcher
+/// removes the need for duplication.
+///
+/// Given code
+/// \code
+/// struct ConstructorTakesInt
+/// {
+///   ConstructorTakesInt(int i) {}
+/// };
+///
+/// void callTakesInt(int i)
+/// {
+/// }
+///
+/// void doCall()
+/// {
+///   callTakesInt(42);
+/// }
+///
+/// void doConstruct()
+/// {
+///   ConstructorTakesInt cti(42);
+/// }
+/// \endcode
+///
+/// The matcher
+/// \code
+/// callOrConstruct(hasArgument(0, integerLiteral(equals(42
+/// \endcode
+/// matches the expression in both doCall and doConstruct
+extern const internal::MapAnyOfMatcher
+callOrConstruct;
+
 /// Matches unary expressions that have a specific type of argument.
 ///
 /// Given
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -5613,6 +5613,40 @@
 
 
 
+Matcher*callOrConstructMatcher*...Matcher*
+Matches function calls and constructor calls
+
+Because CallExpr and CXXConstructExpr do not share a common
+base class with API accessing arguments etc, AST Matchers for code
+which should match both are typically duplicated. This matcher
+removes the need for duplication.
+

[PATCH] D94864: [ASTMatchers] Re-order the internals to allow another use-case

2021-01-16 Thread Stephen Kelly via Phabricator via cfe-commits
steveire created this revision.
steveire added a reviewer: aaron.ballman.
steveire requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Add an operator overload to ArgumentAdaptingMatcherFunc to allow use of
mapAnyOf within hasAncestor, hasParent etc.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D94864

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

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -491,6 +491,14 @@
   Code, traverse(TK_IgnoreUnlessSpelledInSource,
  mapAnyOf(ifStmt, forStmt).with(hasCondition(falseExpr);
 
+  EXPECT_TRUE(
+  matches(Code, cxxBoolLiteral(equals(true),
+   hasAncestor(mapAnyOf(ifStmt, forStmt);
+
+  EXPECT_TRUE(
+  matches(Code, cxxBoolLiteral(equals(false),
+   hasAncestor(mapAnyOf(ifStmt, forStmt);
+
   Code = R"cpp(
 void func(bool b) {}
 struct S {
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1171,6 +1171,232 @@
  TemplateSpecializationType, TemplateTypeParmType, TypedefType,
  UnresolvedUsingType, ObjCIvarRefExpr>;
 
+/// A Matcher that allows binding the node it matches to an id.
+///
+/// BindableMatcher provides a \a bind() method that allows binding the
+/// matched node to an id if the match was successful.
+template  class BindableMatcher : public Matcher {
+public:
+  explicit BindableMatcher(const Matcher ) : Matcher(M) {}
+  explicit BindableMatcher(MatcherInterface *Implementation)
+  : Matcher(Implementation) {}
+
+  /// Returns a matcher that will bind the matched node on a match.
+  ///
+  /// The returned matcher is equivalent to this matcher, but will
+  /// bind the matched node on a match.
+  Matcher bind(StringRef ID) const {
+return DynTypedMatcher(*this)
+.tryBind(ID)
+->template unconditionalConvertTo();
+  }
+
+  /// Same as Matcher's conversion operator, but enables binding on
+  /// the returned matcher.
+  operator DynTypedMatcher() const {
+DynTypedMatcher Result = static_cast &>(*this);
+Result.setAllowBind(true);
+return Result;
+  }
+};
+
+/// Matches any instance of the given NodeType.
+///
+/// This is useful when a matcher syntactically requires a child matcher,
+/// but the context doesn't care. See for example: anything().
+class TrueMatcher {
+public:
+  using ReturnTypes = AllNodeBaseTypes;
+
+  template  operator Matcher() const {
+return DynTypedMatcher::trueMatcher(ASTNodeKind::getFromNodeKind())
+.template unconditionalConvertTo();
+  }
+};
+
+/// Creates a Matcher that matches if all inner matchers match.
+template 
+BindableMatcher
+makeAllOfComposite(ArrayRef *> InnerMatchers) {
+  // For the size() == 0 case, we return a "true" matcher.
+  if (InnerMatchers.empty()) {
+return BindableMatcher(TrueMatcher());
+  }
+  // For the size() == 1 case, we simply return that one matcher.
+  // No need to wrap it in a variadic operation.
+  if (InnerMatchers.size() == 1) {
+return BindableMatcher(*InnerMatchers[0]);
+  }
+
+  using PI = llvm::pointee_iterator *const *>;
+
+  std::vector DynMatchers(PI(InnerMatchers.begin()),
+   PI(InnerMatchers.end()));
+  return BindableMatcher(
+  DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
+ ASTNodeKind::getFromNodeKind(),
+ std::move(DynMatchers))
+  .template unconditionalConvertTo());
+}
+
+/// Creates a Matcher that matches if
+/// T is dyn_cast'able into InnerT and all inner matchers match.
+///
+/// Returns BindableMatcher, as matchers that use dyn_cast have
+/// the same object both to match on and to run submatchers on,
+/// so there is no ambiguity with what gets bound.
+template 
+BindableMatcher
+makeDynCastAllOfComposite(ArrayRef *> InnerMatchers) {
+  return BindableMatcher(
+  makeAllOfComposite(InnerMatchers).template dynCastTo());
+}
+
+/// A VariadicDynCastAllOfMatcher object is a
+/// variadic functor that takes a number of Matcher and returns a
+/// Matcher that matches TargetT nodes that are matched by all of the
+/// given matchers, if SourceT can be dynamically casted into TargetT.
+///
+/// For example:
+///   const VariadicDynCastAllOfMatcher record;
+/// Creates a functor record(...) that creates a Matcher given
+/// a variable number of arguments of type Matcher.
+/// The returned 

[PATCH] D93986: [clang-format] Add the possibility to align assignments spanning empty lines or comments

2021-01-16 Thread Björn Schäpers via Phabricator via cfe-commits
HazardyKnusperkeks added a comment.

Not what I had in mind, but for me that's okay. I can not say anything to the 
change of the script though.

What I hat in mind was explaining (maybe in length) the enum and for the 
alignment settings just show an example with `None` and one of the other 
options, while referring to the enum documentation for all options.




Comment at: clang/include/clang/Format/Format.h:87
 
-  /// \brief If ``true``, aligns consecutive C/C++ preprocessor macros.
+  /// Styles for alignment of consecutive tokens. Tokens can be assignment 
signs
+  /// (see

If you don't document this with `///` you don't need to remove the error from 
the script, or am I mistaken?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D93986

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


[PATCH] D94130: [ASTMatchers] Add support for CXXRewrittenBinaryOperator

2021-01-16 Thread Stephen Kelly via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb765eaf9a617: [ASTMatchers] Add support for 
CXXRewrittenBinaryOperator (authored by stephenkelly).

Changed prior to commit:
  https://reviews.llvm.org/D94130?vs=316751=317173#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D94130

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/AST/ASTNodeTraverser.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/lib/ASTMatchers/ASTMatchFinder.cpp
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/AST/ASTTraverserTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -3330,6 +3330,527 @@
   EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaImplicitCapture)));
   EXPECT_FALSE(matches(
   Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaImplicitCapture)));
+
+  Code = R"cpp(
+struct S {};
+
+struct HasOpEq
+{
+bool operator==(const S& other)
+{
+return true;
+}
+};
+
+void binop()
+{
+HasOpEq s1;
+S s2;
+if (s1 != s2)
+return;
+}
+)cpp";
+  {
+auto M = unaryOperator(
+hasOperatorName("!"),
+has(cxxOperatorCallExpr(hasOverloadedOperatorName("==";
+EXPECT_TRUE(
+matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
+EXPECT_FALSE(
+matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
+ true, {"-std=c++20"}));
+  }
+  {
+auto M = declRefExpr(to(varDecl(hasName("s1";
+EXPECT_TRUE(
+matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
+EXPECT_TRUE(
+matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
+ true, {"-std=c++20"}));
+  }
+  {
+auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("=="));
+EXPECT_TRUE(
+matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
+EXPECT_FALSE(
+matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
+ true, {"-std=c++20"}));
+  }
+  {
+auto M = cxxOperatorCallExpr(hasOverloadedOperatorName("!="));
+EXPECT_FALSE(
+matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
+EXPECT_FALSE(
+matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
+ true, {"-std=c++20"}));
+  }
+  auto withDescendants = [](StringRef lName, StringRef rName) {
+return stmt(hasDescendant(declRefExpr(to(varDecl(hasName(lName),
+hasDescendant(declRefExpr(to(varDecl(hasName(rName));
+  };
+  {
+auto M = cxxRewrittenBinaryOperator(withDescendants("s1", "s2"));
+EXPECT_TRUE(
+matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
+EXPECT_TRUE(
+matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
+ true, {"-std=c++20"}));
+  }
+  {
+auto M = cxxRewrittenBinaryOperator(
+has(declRefExpr(to(varDecl(hasName("s1"),
+has(declRefExpr(to(varDecl(hasName("s2"));
+EXPECT_FALSE(
+matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
+EXPECT_TRUE(
+matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
+ true, {"-std=c++20"}));
+  }
+  {
+EXPECT_TRUE(matchesConditionally(
+Code,
+traverse(TK_AsIs,
+ cxxRewrittenBinaryOperator(
+ hasOperatorName("!="), hasAnyOperatorName("<", "!="),
+ isComparisonOperator(),
+ hasLHS(ignoringImplicit(
+ declRefExpr(to(varDecl(hasName("s1")),
+ hasRHS(ignoringImplicit(
+ declRefExpr(to(varDecl(hasName("s2")),
+ hasEitherOperand(ignoringImplicit(
+ declRefExpr(to(varDecl(hasName("s2")),
+ hasOperands(ignoringImplicit(
+ declRefExpr(to(varDecl(hasName("s1"),
+ ignoringImplicit(declRefExpr(
+ to(varDecl(hasName("s2",
+true, {"-std=c++20"}));
+EXPECT_TRUE(matchesConditionally(
+Code,
+   

[clang] b765eaf - [ASTMatchers] Add support for CXXRewrittenBinaryOperator

2021-01-16 Thread Stephen Kelly via cfe-commits

Author: Stephen Kelly
Date: 2021-01-16T13:44:22Z
New Revision: b765eaf9a617bd3da30f47ece731b33593929885

URL: 
https://github.com/llvm/llvm-project/commit/b765eaf9a617bd3da30f47ece731b33593929885
DIFF: 
https://github.com/llvm/llvm-project/commit/b765eaf9a617bd3da30f47ece731b33593929885.diff

LOG: [ASTMatchers] Add support for CXXRewrittenBinaryOperator

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

Added: 


Modified: 
clang/docs/LibASTMatchersReference.html
clang/include/clang/AST/ASTNodeTraverser.h
clang/include/clang/AST/ExprCXX.h
clang/include/clang/ASTMatchers/ASTMatchers.h
clang/include/clang/ASTMatchers/ASTMatchersInternal.h
clang/lib/ASTMatchers/ASTMatchFinder.cpp
clang/lib/ASTMatchers/ASTMatchersInternal.cpp
clang/lib/ASTMatchers/Dynamic/Registry.cpp
clang/unittests/AST/ASTTraverserTest.cpp
clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Removed: 




diff  --git a/clang/docs/LibASTMatchersReference.html 
b/clang/docs/LibASTMatchersReference.html
index 453d8f16c25a..912da6e62c2f 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -498,6 +498,42 @@ Traverse Mode
 
 
 
+
+
+
+
+
+
+  Rewritten binary operators
+
+binaryOperator(
+  hasOperatorName(""),
+  hasRHS(integerLiteral(equals(0)))
+  )
+
+given:
+
+#include compare
+
+class HasSpaceship {
+public:
+   int x;
+   bool operator==(const HasSpaceship&) const = default;
+   std::strong_ordering operator<=>(const HasSpaceship&) const = default;
+};
+
+bool isLess(const HasSpaceship& a, const HasSpaceship& b) {
+   return a < b;
+}
+
+
+
+1 match found.
+
+
+No match found.
+
+
 
 
 
@@ -1523,6 +1559,25 @@ Node Matchers
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxRewrittenBinaryOperatorMatcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXRewrittenBinaryOperator.html;>CXXRewrittenBinaryOperator...
+Matches 
rewritten binary operators
+
+Example matches use of "":
+  #include compare
+  struct HasSpaceshipMem {
+int a;
+constexpr auto operator=(const HasSpaceshipMem) const = 
default;
+  };
+  void compare() {
+HasSpaceshipMem hs1, hs2;
+if (hs1  hs2)
+return;
+  }
+See also the binaryOperation() matcher for more-general matching
+of this AST node.
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1Stmt.html;>StmtcxxStaticCastExprMatcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXStaticCastExpr.html;>CXXStaticCastExpr...
 Matches a C++ 
static_cast expression.
 
@@ -3405,6 +3460,53 @@ Narrowing Matchers
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXRewrittenBinaryOperator.html;>CXXRewrittenBinaryOperatorhasAnyOperatorNameStringRef, ..., 
StringRef
+Matches operator 
expressions (binary or unary) that have any of the
+specified names.
+
+   hasAnyOperatorName("+", "-")
+ Is equivalent to
+   anyOf(hasOperatorName("+"), hasOperatorName("-"))
+
+
+
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXRewrittenBinaryOperator.html;>CXXRewrittenBinaryOperatorhasOperatorNamestd::string 
Name
+Matches the 
operator Name of operator expressions (binary or
+unary).
+
+Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
+  !(a || b)
+
+
+
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXRewrittenBinaryOperator.html;>CXXRewrittenBinaryOperatorisAssignmentOperator
+Matches all 
kinds of assignment operators.
+
+Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator()))
+  if (a == b)
+a += b;
+
+Example 2: matches s1 = s2
+   (matcher = cxxOperatorCallExpr(isAssignmentOperator()))
+  struct S { S operator=(const S); };
+  void x() { S s1, s2; s1 = s2; }
+
+
+
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXRewrittenBinaryOperator.html;>CXXRewrittenBinaryOperatorisComparisonOperator
+Matches 
comparison operators.
+
+Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
+  if (a == b)
+a += b;
+
+Example 2: matches s1  s2
+   (matcher = cxxOperatorCallExpr(isComparisonOperator()))
+  struct S { bool operator(const S other); };
+  void x(S s1, S s2) { bool b1 = s1  s2; }
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html;>CXXUnresolvedConstructExprargumentCountIsunsigned N
 Checks that a call 
expression or a constructor call expression has
 a specific number of arguments (including absent default arguments).
@@ -5174,8 +5276,8 @@ Narrowing Matchers
 
 
 
-Matcherhttps://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html;>UnaryOperatorhasAnyOperatorNameStringRef, ..., 
StringRef
-Matches operator 
expressions (binary or unary) that have any of the
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html;>UnaryOperatorhasAnyOperatorNameStringRef, ..., 
StringRef

[PATCH] D94129: [ASTMatchers] Add binaryOperation matcher

2021-01-16 Thread Stephen Kelly via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGe810e95e4bb9: [ASTMatchers] Add binaryOperation matcher 
(authored by stephenkelly).

Changed prior to commit:
  https://reviews.llvm.org/D94129?vs=316749=317172#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D94129

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

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -470,6 +470,10 @@
 return;
   }
 
+  if (GetParam().hasDelayedTemplateParsing()) {
+return;
+  }
+
   StringRef Code = R"cpp(
 void F() {
   if (true) {}
@@ -556,6 +560,15 @@
 if (s1 != s2)
 return;
 }
+
+template
+void templ()
+{
+T s1;
+T s2;
+if (s1 != s2)
+return;
+}
 )cpp";
 
   EXPECT_TRUE(matches(
@@ -669,6 +682,38 @@
  .with(hasAnyOperatorName("==", "!="),
forFunction(functionDecl(hasName("opFree")));
 
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ binaryOperation(
+ hasOperatorName("!="),
+ forFunction(functionDecl(hasName("binop"))),
+ hasLHS(declRefExpr(to(varDecl(hasName("s1"),
+ hasRHS(declRefExpr(to(varDecl(hasName("s2");
+
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ binaryOperation(
+ hasOperatorName("!="),
+ forFunction(functionDecl(hasName("opMem"))),
+ hasLHS(declRefExpr(to(varDecl(hasName("s1"),
+ hasRHS(declRefExpr(to(varDecl(hasName("s2");
+
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ binaryOperation(
+ hasOperatorName("!="),
+ forFunction(functionDecl(hasName("opFree"))),
+ hasLHS(declRefExpr(to(varDecl(hasName("s1"),
+ hasRHS(declRefExpr(to(varDecl(hasName("s2");
+
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ binaryOperation(
+ hasOperatorName("!="),
+ forFunction(functionDecl(hasName("templ"))),
+ hasLHS(declRefExpr(to(varDecl(hasName("s1"),
+ hasRHS(declRefExpr(to(varDecl(hasName("s2");
+
   Code = R"cpp(
 struct HasOpBangMem
 {
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -143,6 +143,7 @@
   REGISTER_MATCHER(autoreleasePoolStmt)
   REGISTER_MATCHER(binaryConditionalOperator);
   REGISTER_MATCHER(binaryOperator);
+  REGISTER_MATCHER(binaryOperation);
   REGISTER_MATCHER(blockDecl);
   REGISTER_MATCHER(blockExpr);
   REGISTER_MATCHER(blockPointerType);
Index: clang/lib/ASTMatchers/Dynamic/Marshallers.h
===
--- clang/lib/ASTMatchers/Dynamic/Marshallers.h
+++ clang/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -925,6 +925,50 @@
   const StringRef MatcherName;
 };
 
+template 
+class MapAnyOfMatcherDescriptor : public MatcherDescriptor {
+  std::vector Funcs;
+
+public:
+  MapAnyOfMatcherDescriptor(StringRef MatcherName)
+  : Funcs{DynCastAllOfMatcherDescriptor(
+ast_matchers::internal::VariadicDynCastAllOfMatcher{},
+MatcherName)...} {}
+
+  VariantMatcher create(SourceRange NameRange, ArrayRef Args,
+Diagnostics *Error) const override {
+std::vector InnerArgs;
+
+for (auto const  : Funcs) {
+  InnerArgs.push_back(F.create(NameRange, Args, Error));
+  if (!Error->errors().empty())
+return {};
+}
+return VariantMatcher::SingleMatcher(
+ast_matchers::internal::BindableMatcher(
+VariantMatcher::VariadicOperatorMatcher(
+ast_matchers::internal::DynTypedMatcher::VO_AnyOf,
+std::move(InnerArgs))
+.getTypedMatcher()));
+  }
+
+  bool isVariadic() const override { return true; }
+  unsigned getNumArgs() const override { return 0; }
+
+  void 

[clang] e810e95 - [ASTMatchers] Add binaryOperation matcher

2021-01-16 Thread Stephen Kelly via cfe-commits

Author: Stephen Kelly
Date: 2021-01-16T13:44:09Z
New Revision: e810e95e4bb908d1c8844e2c6f7da999732cabc9

URL: 
https://github.com/llvm/llvm-project/commit/e810e95e4bb908d1c8844e2c6f7da999732cabc9
DIFF: 
https://github.com/llvm/llvm-project/commit/e810e95e4bb908d1c8844e2c6f7da999732cabc9.diff

LOG: [ASTMatchers] Add binaryOperation matcher

This is a simple utility which allows matching on binaryOperator and
cxxOperatorCallExpr. It can also be extended to support
cxxRewrittenBinaryOperator.

Add generic support for MapAnyOfMatchers to auto-marshalling functions.

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

Added: 


Modified: 
clang/docs/LibASTMatchersReference.html
clang/docs/tools/dump_ast_matchers.py
clang/include/clang/ASTMatchers/ASTMatchers.h
clang/lib/ASTMatchers/ASTMatchersInternal.cpp
clang/lib/ASTMatchers/Dynamic/Marshallers.h
clang/lib/ASTMatchers/Dynamic/Registry.cpp
clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Removed: 




diff  --git a/clang/docs/LibASTMatchersReference.html 
b/clang/docs/LibASTMatchersReference.html
index 497e2d4584a2..453d8f16c25a 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -1206,6 +1206,7 @@ Node Matchers
 
 Example matches a || b
   !(a || b)
+See also the binaryOperation() matcher for more-general matching.
 
 
 
@@ -1505,6 +1506,8 @@ Node Matchers
   ostream operator (ostream out, int i) { };
   ostream o; int b = 1, c = 1;
   o  b  c;
+See also the binaryOperation() matcher for more-general matching of binary
+uses of this AST node.
 
 
 
@@ -5438,6 +5441,48 @@ AST Traversal Matchers
 Return 
typeNameParameters
 
 
+Matcher*binaryOperationMatcher*...Matcher*
+Matches nodes which 
can be used with binary operators.
+
+The code
+  var1 != var2;
+might be represented in the clang AST as a binaryOperator or a
+cxxOperatorCallExpr, depending on
+
+* whether the types of var1 and var2 are fundamental (binaryOperator) or at
+  least one is a class type (cxxOperatorCallExpr)
+* whether the code appears in a template declaration, if at least one of the
+  vars is a dependent-type (binaryOperator)
+
+This matcher elides details in places where the matchers for the nodes are
+compatible.
+
+Given
+  binaryOperation(
+hasOperatorName("!="),
+hasLHS(expr().bind("lhs")),
+hasRHS(expr().bind("rhs"))
+  )
+matches each use of "!=" in:
+  struct S{
+  bool operator!=(const S) const;
+  };
+
+  void foo()
+  {
+ 1 != 2;
+ S() != S();
+  }
+
+  templatetypename T
+  void templ()
+  {
+ 1 != 2;
+ T() != S();
+  }
+
+
+
 Matcher*eachOfMatcher*, ..., 
Matcher*
 Matches if any of the given 
matchers matches.
 

diff  --git a/clang/docs/tools/dump_ast_matchers.py 
b/clang/docs/tools/dump_ast_matchers.py
index d3aff1284f60..18afbdd36c6e 100755
--- a/clang/docs/tools/dump_ast_matchers.py
+++ b/clang/docs/tools/dump_ast_matchers.py
@@ -379,6 +379,14 @@ def act_on_decl(declaration, comment, allowed_types):
 add_matcher('*', name, 'Matcher<*>, ..., Matcher<*>', comment)
 return
 
+m = re.match(
+r"""^.*MapAnyOfMatcher<.*>\s*
+  ([a-zA-Z]*);$""",
+declaration, flags=re.X)
+if m:
+  name = m.groups()[0]
+  add_matcher('*', name, 'Matcher<*>...Matcher<*>', comment)
+  return
 
 # Parse free standing matcher functions, like:
 #   Matcher Name(Matcher InnerMatcher) {

diff  --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index e81ac4cb7bf8..8140e20c9cad 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -1971,6 +1971,8 @@ extern const internal::VariadicDynCastAllOfMatcher
 ///   ostream  int b = 1, c = 1;
 ///   o << b << c;
 /// \endcode
+/// See also the binaryOperation() matcher for more-general matching of binary
+/// uses of this AST node.
 extern const internal::VariadicDynCastAllOfMatcher
 cxxOperatorCallExpr;
 
@@ -2393,6 +2395,7 @@ extern const internal::VariadicDynCastAllOfMatcher stmtExpr;
 /// \code
 ///   !(a || b)
 /// \endcode
+/// See also the binaryOperation() matcher for more-general matching.
 extern const internal::VariadicDynCastAllOfMatcher
 binaryOperator;
 
@@ -2729,6 +2732,53 @@ auto mapAnyOf(internal::VariadicDynCastAllOfMatcher const &...) {
   return internal::MapAnyOfHelper();
 }
 
+/// Matches nodes which can be used with binary operators.
+///
+/// The code
+/// \code
+///   var1 != var2;
+/// \endcode
+/// might be represented in the clang AST as a binaryOperator or a
+/// cxxOperatorCallExpr, depending on
+///
+/// * whether the types of var1 and var2 are fundamental (binaryOperator) or at
+///   least one is a class type (cxxOperatorCallExpr)
+/// * whether the code appears in a template declaration, if at least one of 
the
+///   vars is a 

[PATCH] D94128: [ASTMatchers] Make cxxOperatorCallExpr matchers API-compatible with n-ary operators

2021-01-16 Thread Stephen Kelly via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGdbe056c2e37f: [ASTMatchers] Make cxxOperatorCallExpr 
matchers API-compatible with n-ary… (authored by stephenkelly).

Changed prior to commit:
  https://reviews.llvm.org/D94128?vs=316743=317169#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D94128

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

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1313,6 +1313,85 @@
   traverse(TK_AsIs, hasRHS(hasType(pointsTo(qualType());
   EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
   EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
+
+  StringRef Code = R"cpp(
+struct HasOpEqMem
+{
+bool operator==(const HasOpEqMem& other) const
+{
+return true;
+}
+};
+
+struct HasOpFree
+{
+};
+bool operator==(const HasOpFree& lhs, const HasOpFree& rhs)
+{
+return true;
+}
+
+void opMem()
+{
+HasOpEqMem s1;
+HasOpEqMem s2;
+if (s1 == s2)
+return;
+}
+
+void opFree()
+{
+HasOpFree s1;
+HasOpFree s2;
+if (s1 == s2)
+return;
+}
+)cpp";
+  auto s1Expr = declRefExpr(to(varDecl(hasName("s1";
+  auto s2Expr = declRefExpr(to(varDecl(hasName("s2";
+  EXPECT_TRUE(matches(
+  Code,
+  traverse(TK_IgnoreUnlessSpelledInSource,
+   cxxOperatorCallExpr(forFunction(functionDecl(hasName("opMem"))),
+   hasOperatorName("=="), hasLHS(s1Expr),
+   hasRHS(s2Expr);
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ cxxOperatorCallExpr(
+ forFunction(functionDecl(hasName("opMem"))),
+ hasAnyOperatorName("!=", "=="), hasLHS(s1Expr);
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ cxxOperatorCallExpr(
+ forFunction(functionDecl(hasName("opMem"))),
+ hasOperatorName("=="), hasOperands(s1Expr, s2Expr);
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ cxxOperatorCallExpr(
+ forFunction(functionDecl(hasName("opMem"))),
+ hasOperatorName("=="), hasEitherOperand(s2Expr);
+
+  EXPECT_TRUE(matches(
+  Code,
+  traverse(TK_IgnoreUnlessSpelledInSource,
+   cxxOperatorCallExpr(forFunction(functionDecl(hasName("opFree"))),
+   hasOperatorName("=="), hasLHS(s1Expr),
+   hasRHS(s2Expr);
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ cxxOperatorCallExpr(
+ forFunction(functionDecl(hasName("opFree"))),
+ hasAnyOperatorName("!=", "=="), hasLHS(s1Expr);
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ cxxOperatorCallExpr(
+ forFunction(functionDecl(hasName("opFree"))),
+ hasOperatorName("=="), hasOperands(s1Expr, s2Expr);
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ cxxOperatorCallExpr(
+ forFunction(functionDecl(hasName("opFree"))),
+ hasOperatorName("=="), hasEitherOperand(s2Expr);
 }
 
 TEST(MatchBinaryOperator, HasEitherOperand) {
@@ -1461,6 +1540,60 @@
 
   EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
   EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
+
+  StringRef Code = R"cpp(
+struct HasOpBangMem
+{
+bool operator!() const
+{
+return false;
+}
+};
+struct HasOpBangFree
+{
+};
+bool operator!(HasOpBangFree const&)
+{
+return false;
+}
+
+void opMem()
+{
+HasOpBangMem s1;
+if (!s1)
+return;
+}
+void opFree()
+{
+HasOpBangFree s1;
+if (!s1)
+return;
+}
+)cpp";
+  auto s1Expr = declRefExpr(to(varDecl(hasName("s1";
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ cxxOperatorCallExpr(
+ forFunction(functionDecl(hasName("opMem"))),
+ hasOperatorName("!"), hasUnaryOperand(s1Expr);
+  EXPECT_TRUE(matches(
+  

[clang] dbe056c - [ASTMatchers] Make cxxOperatorCallExpr matchers API-compatible with n-ary operators

2021-01-16 Thread Stephen Kelly via cfe-commits

Author: Stephen Kelly
Date: 2021-01-16T12:53:11Z
New Revision: dbe056c2e37f00b9f33ab63bba73dbb004e13562

URL: 
https://github.com/llvm/llvm-project/commit/dbe056c2e37f00b9f33ab63bba73dbb004e13562
DIFF: 
https://github.com/llvm/llvm-project/commit/dbe056c2e37f00b9f33ab63bba73dbb004e13562.diff

LOG: [ASTMatchers] Make cxxOperatorCallExpr matchers API-compatible with n-ary 
operators

This makes them composable with mapAnyOf().

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

Added: 


Modified: 
clang/docs/LibASTMatchersReference.html
clang/include/clang/ASTMatchers/ASTMatchers.h
clang/include/clang/ASTMatchers/ASTMatchersInternal.h
clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Removed: 




diff  --git a/clang/docs/LibASTMatchersReference.html 
b/clang/docs/LibASTMatchersReference.html
index e5de645266b7..497e2d4584a2 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -3232,6 +3232,16 @@ Narrowing Matchers
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html;>CXXOperatorCallExprhasAnyOperatorNameStringRef, ..., 
StringRef
+Matches operator 
expressions (binary or unary) that have any of the
+specified names.
+
+   hasAnyOperatorName("+", "-")
+ Is equivalent to
+   anyOf(hasOperatorName("+"), hasOperatorName("-"))
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html;>CXXOperatorCallExprhasAnyOverloadedOperatorNameStringRef,
 ..., StringRef
 Matches overloaded operator names.
 
@@ -3244,6 +3254,15 @@ Narrowing Matchers
 
 
 
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html;>CXXOperatorCallExprhasOperatorNamestd::string 
Name
+Matches the 
operator Name of operator expressions (binary or
+unary).
+
+Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
+  !(a || b)
+
+
+
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html;>CXXOperatorCallExprhasOverloadedOperatorNameStringRef
 Name
 Matches 
overloaded operator names.
 
@@ -5152,8 +5171,8 @@ Narrowing Matchers
 
 
 
-Matcherhttps://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html;>UnaryOperatorhasAnyOperatorNameStringRef, ..., 
StringRef
-Matches operator 
expressions (binary or unary) that have any of the
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html;>UnaryOperatorhasAnyOperatorNameStringRef, ..., 
StringRef
+Matches operator 
expressions (binary or unary) that have any of the
 specified names.
 
hasAnyOperatorName("+", "-")
@@ -5162,8 +5181,8 @@ Narrowing Matchers
 
 
 
-Matcherhttps://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html;>UnaryOperatorhasOperatorNamestd::string 
Name
-Matches the 
operator Name of operator expressions (binary or
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html;>UnaryOperatorhasOperatorNamestd::string 
Name
+Matches the 
operator Name of operator expressions (binary or
 unary).
 
 Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
@@ -5689,16 +5708,16 @@ AST Traversal Matchers
 
 
 
-Matcherhttps://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html;>ArraySubscriptExprhasLHSMatcherhttps://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr 
InnerMatcher
-Matches the left hand side 
of binary operator expressions.
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html;>ArraySubscriptExprhasLHSMatcherhttps://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr 
InnerMatcher
+Matches the left hand side 
of binary operator expressions.
 
 Example matches a (matcher = binaryOperator(hasLHS()))
   a || b
 
 
 
-Matcherhttps://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html;>ArraySubscriptExprhasRHSMatcherhttps://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr 
InnerMatcher
-Matches the right hand side 
of binary operator expressions.
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html;>ArraySubscriptExprhasRHSMatcherhttps://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr 
InnerMatcher
+Matches the right hand side 
of binary operator expressions.
 
 Example matches b (matcher = binaryOperator(hasRHS()))
   a || b
@@ -5749,7 +5768,7 @@ AST Traversal Matchers
 
 
 
-Matcherhttps://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html;>BinaryOperatorhasEitherOperandMatcherhttps://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr  
InnerMatcher
+Matcherhttps://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html;>BinaryOperatorhasEitherOperandMatcherhttps://clang.llvm.org/doxygen/classclang_1_1Expr.html;>Expr 
InnerMatcher
 Matches if either 
the left hand side or the right hand side of a
 binary operator matches.
 
@@ -5763,7 +5782,7 @@ AST Traversal Matchers
 
 
 

[PATCH] D94127: [ASTMatchers] Add mapAnyOf matcher

2021-01-16 Thread Stephen Kelly via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa7101450a42e: [ASTMatchers] Add mapAnyOf matcher (authored 
by stephenkelly).

Changed prior to commit:
  https://reviews.llvm.org/D94127?vs=316712=317168#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D94127

Files:
  clang/docs/LibASTMatchersReference.html
  clang/docs/tools/dump_ast_matchers.py
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -465,6 +465,59 @@
   cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll();
 }
 
+TEST_P(ASTMatchersTest, MapAnyOf) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+
+  StringRef Code = R"cpp(
+void F() {
+  if (true) {}
+  for ( ; false; ) {}
+}
+)cpp";
+
+  auto trueExpr = cxxBoolLiteral(equals(true));
+  auto falseExpr = cxxBoolLiteral(equals(false));
+
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ mapAnyOf(ifStmt, forStmt).with(hasCondition(trueExpr);
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ mapAnyOf(ifStmt, forStmt).with(hasCondition(falseExpr);
+
+  Code = R"cpp(
+void func(bool b) {}
+struct S {
+  S(bool b) {}
+};
+void F() {
+  func(false);
+  S s(true);
+}
+)cpp";
+  EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ mapAnyOf(callExpr, cxxConstructExpr)
+ .with(hasArgument(0, trueExpr);
+  EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ mapAnyOf(callExpr, cxxConstructExpr)
+ .with(hasArgument(0, falseExpr);
+
+  EXPECT_TRUE(
+  matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ mapAnyOf(callExpr, cxxConstructExpr)
+ .with(hasArgument(0, expr()),
+   hasDeclaration(functionDecl());
+
+  EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ mapAnyOf(callExpr, cxxConstructExpr;
+
+  EXPECT_TRUE(matches(
+  Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ mapAnyOf(callExpr, cxxConstructExpr).bind("call";
+}
+
 TEST_P(ASTMatchersTest, IsDerivedFrom) {
   if (!GetParam().isCXX()) {
 return;
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1987,6 +1987,68 @@
   llvm::Regex::RegexFlags Flags,
   StringRef MatcherID);
 
+template 
+constexpr auto applyMatcherImpl(F &, Tuple &,
+std::index_sequence) {
+  return std::forward(f)(std::get(std::forward(args))...);
+}
+
+template 
+constexpr auto applyMatcher(F &, Tuple &) {
+  return applyMatcherImpl(
+  std::forward(f), std::forward(args),
+  std::make_index_sequence<
+  std::tuple_size::type>::value>());
+}
+
+template 
+struct GetCladeImpl {
+  using Type = Head;
+};
+template 
+struct GetCladeImpl
+: GetCladeImpl::value,
+   typename Tail::head, typename Tail::tail> {};
+
+template 
+struct GetClade : GetCladeImpl {};
+
+template 
+struct MapAnyOfMatcherImpl {
+
+  template 
+  BindableMatcher
+  operator()(InnerMatchers &&... InnerMatcher) const {
+// TODO: Use std::apply from c++17
+return VariadicAllOfMatcher()(applyMatcher(
+internal::VariadicOperatorMatcherFunc<
+0, std::numeric_limits::max()>{
+internal::DynTypedMatcher::VO_AnyOf},
+applyMatcher(
+[&](auto... Matcher) {
+  return std::make_tuple(Matcher(
+  std::forward(InnerMatcher)...)...);
+},
+std::tuple<
+VariadicDynCastAllOfMatcher...>(;
+  }
+};
+
+template 
+using MapAnyOfMatcher =
+MapAnyOfMatcherImpl::Type,
+MatcherTypes...>;
+
+template  struct MapAnyOfHelper {
+  using CladeType = typename GetClade::Type;
+
+  MapAnyOfMatcher with;
+
+  operator BindableMatcher() const { return with(); }
+
+  Matcher bind(StringRef ID) const { return with().bind(ID); }
+};
+
 } // namespace internal
 
 } // namespace 

[clang] a710145 - [ASTMatchers] Add mapAnyOf matcher

2021-01-16 Thread Stephen Kelly via cfe-commits

Author: Stephen Kelly
Date: 2021-01-16T12:53:11Z
New Revision: a7101450a42e4f1ed5af1a38a6def08f1b5b58fe

URL: 
https://github.com/llvm/llvm-project/commit/a7101450a42e4f1ed5af1a38a6def08f1b5b58fe
DIFF: 
https://github.com/llvm/llvm-project/commit/a7101450a42e4f1ed5af1a38a6def08f1b5b58fe.diff

LOG: [ASTMatchers] Add mapAnyOf matcher

Make it possible to compose a matcher for different base nodes.

This accepts one or more node matcher functors and zero or more
matchers, composing the latter into the former.

This allows composing of matchers where the same inner matcher name is
used for the same concept, but with a different node functor. Currently,
there is a limitation that the nodes must be in the same "clade", so
while

  mapAnyOf(ifStmt, forStmt).with(hasBody(stmt()))

can be used, functionDecl can not be added to the tuple.

It is possible to use this in clang-query, but it will require changes
to the QueryParser, so is deferred to a future review.

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

Added: 


Modified: 
clang/docs/LibASTMatchersReference.html
clang/docs/tools/dump_ast_matchers.py
clang/include/clang/ASTMatchers/ASTMatchers.h
clang/include/clang/ASTMatchers/ASTMatchersInternal.h
clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Removed: 




diff  --git a/clang/docs/LibASTMatchersReference.html 
b/clang/docs/LibASTMatchersReference.html
index 18acfc48..e5de645266b7 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -2593,6 +2593,29 @@ Narrowing Matchers
 
 
 
+unspecifiedmapAnyOfnodeMatcherFunction...
+Matches any of the 
NodeMatchers with InnerMatchers nested within
+
+Given
+  if (true);
+  for (; true; );
+with the matcher
+  mapAnyOf(ifStmt, forStmt).with(
+hasCondition(cxxBoolLiteralExpr(equals(true)))
+).bind("trueCond")
+matches the if and the for. It is equivalent to:
+  auto trueCond = hasCondition(cxxBoolLiteralExpr(equals(true)));
+  anyOf(
+ifStmt(trueCond).bind("trueCond"),
+forStmt(trueCond).bind("trueCond")
+);
+
+The with() chain-call accepts zero or more matchers which are combined
+as-if with allOf() in each of the node matchers.
+Usable as: Any Matcher
+
+
+
 Matcher*unlessMatcher*
 Matches if the provided 
matcher does not match.
 
@@ -2980,7 +3003,7 @@ Narrowing Matchers
 
 
 Matcherhttps://clang.llvm.org/doxygen/classclang_1_1CXXDependentScopeMemberExpr.html;>CXXDependentScopeMemberExprhasMemberNamestd::string N
-Matches 
template-dependent, but known, member names
+Matches 
template-dependent, but known, member names.
 
 In template declarations, dependent members are not resolved and so can
 not be matched to particular named declarations.

diff  --git a/clang/docs/tools/dump_ast_matchers.py 
b/clang/docs/tools/dump_ast_matchers.py
index 045833be7673..d3aff1284f60 100755
--- a/clang/docs/tools/dump_ast_matchers.py
+++ b/clang/docs/tools/dump_ast_matchers.py
@@ -119,8 +119,15 @@ def add_matcher(result_type, name, args, comment, 
is_dyncast=False):
   ids[name] += 1
   args = unify_arguments(args)
   result_type = unify_type(result_type)
+
+  docs_result_type = esc('Matcher<%s>' % result_type);
+
+  if name == 'mapAnyOf':
+args = "nodeMatcherFunction..."
+docs_result_type = "unspecified"
+
   matcher_html = TD_TEMPLATE % {
-'result': esc('Matcher<%s>' % result_type),
+'result': docs_result_type,
 'name': name,
 'args': esc(args),
 'comment': esc(strip_doxygen(comment)),
@@ -135,7 +142,7 @@ def add_matcher(result_type, name, args, comment, 
is_dyncast=False):
   # exclude known narrowing matchers that also take other matchers as
   # arguments.
   elif ('Matcher<' not in args or
-name in ['allOf', 'anyOf', 'anything', 'unless']):
+name in ['allOf', 'anyOf', 'anything', 'unless', 'mapAnyOf']):
 dict = narrowing_matchers
 lookup = result_type + name + esc(args)
   else:

diff  --git a/clang/include/clang/ASTMatchers/ASTMatchers.h 
b/clang/include/clang/ASTMatchers/ASTMatchers.h
index a45e08345fb3..dd99e6a420af 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -847,6 +847,12 @@ traverse(TraversalKind TK, const 
internal::PolymorphicMatcherWithParam2<
   TK, InnerMatcher);
 }
 
+template 
+internal::Matcher::Type>
+traverse(TraversalKind TK, const internal::MapAnyOfHelper ) 
{
+  return traverse(TK, InnerMatcher.with());
+}
+
 /// Matches expressions that match InnerMatcher after any implicit AST
 /// nodes are stripped off.
 ///
@@ -2693,6 +2699,36 @@ extern const internal::VariadicDynCastAllOfMatcher
 unaryExprOrTypeTraitExpr;
 
+/// Matches any of the \p NodeMatchers with InnerMatchers nested within
+///
+/// Given
+/// \code
+///   if (true);
+///   for (; true; );
+/// \endcode
+/// with the matcher
+/// \code
+///   mapAnyOf(ifStmt, forStmt).with(

[PATCH] D93986: [clang-format] Add the possibility to align assignments spanning empty lines or comments

2021-01-16 Thread Lukas Barth via Phabricator via cfe-commits
tinloaf updated this revision to Diff 317166.
tinloaf added a comment.

Fixed documentation for the `AlignConsecutive*` options. I have used the 
suggested approach: Remove all documentation from `AlignConsecutiveStyle` and 
instead put the documentation of the possible values and what they do in the 
`AlignConsecutive*` options' docs.

I had to make two small changes to the documentation dump script for this:

- Non-documented options in enums are silently ignored instead of raising an 
error, since `AlignConsecutiveStyle` has non-documented options now.
- Indentation in the `code-block` lines is preserved, so that we can have 
indented code blocks in the documentation of the possible values.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D93986

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/docs/tools/dump_format_style.py
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/WhitespaceManager.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -11330,8 +11330,8 @@
"*/\n"
"}",
Tab));
-  Tab.AlignConsecutiveAssignments = true;
-  Tab.AlignConsecutiveDeclarations = true;
+  Tab.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  Tab.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
   Tab.TabWidth = 4;
   Tab.IndentWidth = 4;
   verifyFormat("class Assign {\n"
@@ -11569,8 +11569,8 @@
"*/\n"
"}",
Tab));
-  Tab.AlignConsecutiveAssignments = true;
-  Tab.AlignConsecutiveDeclarations = true;
+  Tab.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  Tab.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
   Tab.TabWidth = 4;
   Tab.IndentWidth = 4;
   verifyFormat("class Assign {\n"
@@ -12405,9 +12405,9 @@
 
 TEST_F(FormatTest, AlignConsecutiveMacros) {
   FormatStyle Style = getLLVMStyle();
-  Style.AlignConsecutiveAssignments = true;
-  Style.AlignConsecutiveDeclarations = true;
-  Style.AlignConsecutiveMacros = false;
+  Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveMacros = FormatStyle::ACS_None;
 
   verifyFormat("#define a 3\n"
"#define  4\n"
@@ -12431,7 +12431,7 @@
"#define (x, y) (x - y)",
Style);
 
-  Style.AlignConsecutiveMacros = true;
+  Style.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
   verifyFormat("#define a3\n"
"#define  4\n"
"#define ccc  (5)",
@@ -12471,7 +12471,7 @@
"};",
Style);
 
-  Style.AlignConsecutiveMacros = false;
+  Style.AlignConsecutiveMacros = FormatStyle::ACS_None;
   Style.ColumnLimit = 20;
 
   verifyFormat("#define a  \\\n"
@@ -12485,7 +12485,7 @@
"  \"\"\n",
Style);
 
-  Style.AlignConsecutiveMacros = true;
+  Style.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
   verifyFormat("#define a  \\\n"
"  \"aa\"\n"
"#define D  \\\n"
@@ -12496,12 +12496,766 @@
"  \"F\"  \\\n"
"  \"\"\n",
Style);
+
+  // Test across comments
+  Style.MaxEmptyLinesToKeep = 10;
+  Style.ReflowComments = false;
+  Style.AlignConsecutiveMacros = FormatStyle::ACS_AcrossComments;
+  EXPECT_EQ("#define a3\n"
+"// line comment\n"
+"#define  4\n"
+"#define ccc  (5)",
+format("#define a 3\n"
+   "// line comment\n"
+   "#define  4\n"
+   "#define ccc (5)",
+   Style));
+
+  EXPECT_EQ("#define a3\n"
+"/* block comment */\n"
+"#define  4\n"
+"#define ccc  (5)",
+format("#define a  3\n"
+   "/* block comment */\n"
+   "#define  4\n"
+   "#define ccc (5)",
+   Style));
+
+  EXPECT_EQ("#define a3\n"
+"/* multi-line *\n"
+" * block comment */\n"
+"#define  4\n"
+"#define ccc  (5)",
+format("#define a 3\n"
+   "/* multi-line *\n"
+   " * block comment */\n"
+   "#define  4\n"
+   "#define ccc (5)",
+   Style));
+
+  EXPECT_EQ("#define a3\n"
+"// multi-line line comment\n"
+"//\n"
+"#define  4\n"
+"#define ccc  (5)",
+

[PATCH] D94366: [Clang] Emit mustprogress for infinite C++ loops

2021-01-16 Thread Dávid Bolvanský via Phabricator via cfe-commits
xbolva00 added inline comments.



Comment at: clang/test/CodeGen/attr-mustprogress-1.cpp:32
 //
 void f1() {
   for (; 1;)

Test for (; 42; )?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D94366

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


[PATCH] D94366: [Clang] Emit mustprogress for infinite C++ loops

2021-01-16 Thread Dávid Bolvanský via Phabricator via cfe-commits
xbolva00 added inline comments.



Comment at: clang/lib/CodeGen/CGStmt.cpp:797
   if (llvm::ConstantInt *C = dyn_cast(BoolCondVal)) {
 if (C->isOne()) {
   EmitBoolCondBranch = false;

Anything non-zero?



Comment at: clang/test/CodeGen/attr-mustprogress-1.cpp:118
 void w1() {
   while (1)
 ;

Can you add test for eg. while (42) ?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D94366

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


[PATCH] D93776: [clang-format] Add StatementAttributeLikeMacros option

2021-01-16 Thread Marek Kurdej via Phabricator via cfe-commits
curdeius accepted this revision.
curdeius added a comment.
This revision is now accepted and ready to land.

LGTM apart from the minor comment.
But I'd like @mydeveloperday to have a look too.




Comment at: clang/lib/Format/FormatToken.h:54
   TYPE(FunctionTypeLParen) 
\
+  TYPE(StatementAttributeLikeMacro)
\
   TYPE(ImplicitStringLiteral)  
\

HazardyKnusperkeks wrote:
> This one I will move down, it was named differently before and I forgot to 
> resort it after renaming.
Please sort it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D93776

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