[PATCH] D140693: [Driver][RISCV] Adjust the priority between -mcpu, -mtune and -march

2022-12-30 Thread Kito Cheng via Phabricator via cfe-commits
kito-cheng updated this revision to Diff 485674.
kito-cheng added a comment.

Changes:

- Stop calling getRISCVTargetCPU in getCPUName.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140693

Files:
  clang/lib/Driver/ToolChains/Arch/RISCV.cpp
  clang/lib/Driver/ToolChains/Arch/RISCV.h
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/test/Driver/riscv-cpus.c
  clang/test/Driver/riscv-march-mcpu-mtune.c

Index: clang/test/Driver/riscv-march-mcpu-mtune.c
===
--- /dev/null
+++ clang/test/Driver/riscv-march-mcpu-mtune.c
@@ -0,0 +1,82 @@
+// Check the priority between -mcpu, -mtune and -march
+
+// sifive-e76 is rv32imafc and sifive-e31 is rv32imac
+
+// -mcpu, -mtune and -march are not given, pipeline model and arch ext. use
+// default setting.
+// RUN: %clang --target=riscv32-elf -### -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-DEFAULT %s
+// CHECK-DEFAULT: "-target-feature" "+m" "-target-feature" "+a"
+// CHECK-DEFAULT: "-target-feature" "+c"
+// CHECK-DEFAULT: "-tune-cpu" "generic-rv32"
+// CHECK-DEFAULT-NOT: "-target-cpu"
+
+// -mtune is given, pipeline model take from -mtune, arch ext. use
+// default setting.
+// RUN: %clang --target=riscv32 -mtune=sifive-e76 -### -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=MTUNE-E76 %s
+// MTUNE-E76: "-target-feature" "+m" "-target-feature" "+a"
+// MTUNE-E76: "-target-feature" "+c"
+// MTUNE-E76: "-tune-cpu" "sifive-e76"
+// MTUNE-E76-NOT: "-target-cpu"
+// MTUNE-E76-NOT: "-target-feature" "+f"
+
+// -march is given, arch ext. take from -march, pipeline model use
+// default setting.
+// RUN: %clang --target=riscv32 -### -c %s -march=rv32imafdc 2>&1 \
+// RUN: | FileCheck -check-prefix=MARCH-RV32IMAFDC %s
+// MARCH-RV32IMAFDC: "-target-feature" "+m" "-target-feature" "+a"
+// MARCH-RV32IMAFDC: "-target-feature" "+f" "-target-feature" "+d"
+// MARCH-RV32IMAFDC: "-target-feature" "+c"
+// MARCH-RV32IMAFDC: "-tune-cpu" "generic-rv32"
+// MARCH-RV32IMAFDC-NOT: "-target-cpu"
+
+// -mcpu is given, pipeline model and arch ext. from -mcpu.
+// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e76 2>&1 \
+// RUN: | FileCheck -check-prefix=MCPU-E76 %s
+// MCPU-E76: "-target-feature" "+m" "-target-feature" "+a"
+// MCPU-E76: "-target-feature" "+f" "-target-feature" "+c"
+// MCPU-E76: "-tune-cpu" "sifive-e76"
+// MCPU-E76-NOT: "-target-cpu"
+
+// -mcpu and -mtune are given, so pipeline model take from -mtune, and arch ext.
+// take from -mcpu since -march is not given.
+// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e76 -mtune=sifive-e31 2>&1 \
+// RUN: | FileCheck -check-prefix=MCPU-E76-MTUNE-E31 %s
+// MCPU-E76-MTUNE-E31: "-target-feature" "+m" "-target-feature" "+a"
+// MCPU-E76-MTUNE-E31: "-target-feature" "+f" "-target-feature" "+c"
+// MCPU-E76-MTUNE-E31: "-tune-cpu" "sifive-e31"
+// MCPU-E76-MTUNE-E31-NOT: "-tune-cpu" "sifive-e76"
+// MCPU-E76-MTUNE-E31-NOT: "-target-cpu"
+
+// RUN: %clang --target=riscv32 -### -c %s -mtune=sifive-e76 -mcpu=sifive-e31 2>&1 \
+// RUN: | FileCheck -check-prefix=MTUNE-E76-MCPU-E31 %s
+// MTUNE-E76-MCPU-E31: "-target-feature" "+m" "-target-feature" "+a"
+// MTUNE-E76-MCPU-E31: "-target-feature" "+c"
+// MTUNE-E76-MCPU-E31: "-tune-cpu" "sifive-e76"
+// MTUNE-E76-MCPU-E31-NOT: "-tune-cpu" "sifive-e31"
+// MTUNE-E76-MCPU-E31-NOT: "-target-cpu"
+// MTUNE-E76-MCPU-E31-NOT: "-target-feature" "+f"
+
+// -mcpu and -march are given, so pipeline model take from -mcpu since -mtune is
+// not given, and arch ext. take from -march.
+// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e31 -march=rv32ic 2>&1 \
+// RUN: | FileCheck -check-prefix=MCPU-E31-MARCH-RV32I %s
+// MCPU-E31-MARCH-RV32I: "-target-feature" "+c"
+// MCPU-E31-MARCH-RV32I: "-tune-cpu" "sifive-e31"
+// MCPU-E31-MARCH-RV32I-NOT: "-target-cpu"
+// MCPU-E31-MARCH-RV32I-NOT: "-target-feature" "+m"
+// MCPU-E31-MARCH-RV32I-NOT: "-target-feature" "+a"
+// MCPU-E31-MARCH-RV32I-NOT: "-target-feature" "+f"
+
+// -mcpu, -march and -mtune are given, so pipeline model take from -mtune
+// and arch ext. take from -march, -mcpu is unused.
+// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e31 -mtune=sifive-e76 -march=rv32ic 2>&1 \
+// RUN: | FileCheck -check-prefix=MCPU-E31-MTUNE-E76-MARCH-RV32I %s
+// MCPU-E31-MTUNE-E76-MARCH-RV32I: "-target-feature" "+c"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I: "-tune-cpu" "sifive-e76"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-cpu"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-tune-cpu" "sifive-e31"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-feature" "+m"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-feature" "+a"
+// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-feature" "+f"
Index: clang/test/Driver/riscv-cpus.c
===
--- clang/test/Driver/ris

[PATCH] D140693: [Driver][RISCV] Adjust the priority between -mcpu, -mtune and -march

2022-12-30 Thread Craig Topper via Phabricator via cfe-commits
craig.topper added inline comments.



Comment at: clang/lib/Driver/ToolChains/Clang.cpp:5457
+  // RISC-V will handle -mcpu option in Clang::AddRISCVTargetArgs.
+  if (!Triple.isRISCV()) {
+// Add the target cpu

kito-cheng wrote:
> craig.topper wrote:
> > I wonder if we should stop getCPUName from calling `getRISCVTargetCPU` 
> > instead? Have you audited all callers of getCPUName?
> That sounds a better way, that prevent us to auditing every caller of 
> `getCPUName`.
I think we need to do the audit either way.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140693

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


[PATCH] D140772: [clang-tidy] Fix minor bug in add_new_check.py

2022-12-30 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp accepted this revision.
carlosgalvezp added a comment.
This revision is now accepted and ready to land.

LGTM, I have a suggestion for further improvement.




Comment at: clang-tools-extra/clang-tidy/add_new_check.py:324-328
   doc_files = []
-  for subdir in list(filter(lambda s: not s.endswith('.rst') and not 
s.endswith('.py'),
- os.listdir(docs_dir))):
+  for subdir in list(filter(os.path.isdir, os.listdir(docs_dir))):
 for file in filter(lambda s: s.endswith('.rst'), 
os.listdir(os.path.join(docs_dir, subdir))):
   doc_files.append([subdir, file])
   doc_files.sort()

It feels this whole code could be made much simpler, readable and safer by just 
doing:

  doc_files = glob.glob(os.path.join(docs_dir, "**", "*.rst"), recursive=True)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140772

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


[PATCH] D140018: [clang-tidy] Support std::string_view in readability-redundant-string-cstr

2022-12-30 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp added a comment.

@tberghammer Do you need help to land the patch?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140018

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


[PATCH] D140775: [clangd] Hover: show CalleeArgInfo for literals

2022-12-30 Thread Tom Praschan via Phabricator via cfe-commits
tom-anders created this revision.
tom-anders added reviewers: nridge, sammccall.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
tom-anders requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

This is very useful when inlay hints are disabled.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140775

Files:
  clang-tools-extra/clangd/Hover.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp

Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -900,6 +900,22 @@
  HI.CalleeArgInfo->Type = "int &";
  HI.CallPassType = HoverInfo::PassType{PassMode::Ref, false};
}},
+  {// Literal passed to function call
+   R"cpp(
+  void fun(int arg_a, const int &arg_b) {};
+  void code() {
+int a = 1;
+fun(a, [[^2]]);
+  }
+  )cpp",
+   [](HoverInfo &HI) {
+ HI.Name = "literal";
+ HI.Kind = index::SymbolKind::Unknown;
+ HI.CalleeArgInfo.emplace();
+ HI.CalleeArgInfo->Name = "arg_b";
+ HI.CalleeArgInfo->Type = "const int &";
+ HI.CallPassType = HoverInfo::PassType{PassMode::ConstRef, false};
+   }},
   {// Extra info for method call.
R"cpp(
   class C {
@@ -1226,8 +1242,10 @@
   } Tests[] = {
   // Integer tests
   {"int_by_value([[^int_x]]);", PassMode::Value, false},
+  {"int_by_value([[^123]]);", PassMode::Value, false},
   {"int_by_ref([[^int_x]]);", PassMode::Ref, false},
   {"int_by_const_ref([[^int_x]]);", PassMode::ConstRef, false},
+  {"int_by_const_ref([[^123]]);", PassMode::ConstRef, false},
   {"int_by_value([[^int_ref]]);", PassMode::Value, false},
   {"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef, false},
   {"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef, false},
@@ -1245,6 +1263,8 @@
   {"float_by_value([[^int_x]]);", PassMode::Value, true},
   {"float_by_value([[^int_ref]]);", PassMode::Value, true},
   {"float_by_value([[^int_const_ref]]);", PassMode::Value, true},
+  {"float_by_value([[^123.0f]]);", PassMode::Value, false},
+  {"float_by_value([[^123]]);", PassMode::Value, true},
   {"custom_by_value([[^int_x]]);", PassMode::Ref, true},
   {"custom_by_value([[^float_x]]);", PassMode::Value, true},
   {"custom_by_value([[^base]]);", PassMode::ConstRef, true},
Index: clang-tools-extra/clangd/Hover.cpp
===
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -776,15 +776,11 @@
   return HI;
 }
 
-HoverInfo getStringLiteralContents(const StringLiteral *SL,
-   const PrintingPolicy &PP) {
-  HoverInfo HI;
-
+void addStringLiteralContents(const StringLiteral *SL, const PrintingPolicy &PP,
+  HoverInfo &HI) {
   HI.Name = "string-literal";
   HI.Size = (SL->getLength() + 1) * SL->getCharByteWidth();
   HI.Type = SL->getType().getAsString(PP).c_str();
-
-  return HI;
 }
 
 bool isLiteral(const Expr *E) {
@@ -795,7 +791,7 @@
  llvm::isa(E) ||
  llvm::isa(E) || llvm::isa(E) ||
  llvm::isa(E) || llvm::isa(E) ||
- llvm::isa(E);
+ llvm::isa(E) || llvm::isa(E);
 }
 
 llvm::StringLiteral getNameForExpr(const Expr *E) {
@@ -809,20 +805,34 @@
   return llvm::StringLiteral("expression");
 }
 
+void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI,
+   const PrintingPolicy &PP);
+
 // Generates hover info for `this` and evaluatable expressions.
 // FIXME: Support hover for literals (esp user-defined)
-std::optional getHoverContents(const Expr *E, ParsedAST &AST,
+std::optional getHoverContents(const SelectionTree::Node *N,
+  const Expr *E, ParsedAST &AST,
   const PrintingPolicy &PP,
   const SymbolIndex *Index) {
+  HoverInfo HI;
+
   // There's not much value in hovering over "42" and getting a hover card
-  // saying "42 is an int", similar for other literals.
-  if (isLiteral(E))
+  // saying "42 is an int", similar for most other literals.
+  // However, if we have CalleeArgInfo, it's still useful to show it.
+  if (isLiteral(E)) {
+maybeAddCalleeArgInfo(N, HI, PP);
+// Print the type and the size for string literals
+if (const StringLiteral *SL = dyn_cast(E)) {
+  addStringLiteralContents(SL, PP, HI);
+  return HI;
+}
+if (HI.CalleeArgInfo) {
+  HI.Name = "literal";
+  return HI;
+}
 return std::nullopt;
+  }
 
-  HoverInfo HI;
-  // Print the type and the size for string 

[PATCH] D140775: [clangd] Hover: show CalleeArgInfo for literals

2022-12-30 Thread Tom Praschan via Phabricator via cfe-commits
tom-anders added inline comments.



Comment at: clang-tools-extra/clangd/Hover.cpp:808
 
+void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI,
+   const PrintingPolicy &PP);

(I also modified this function, so I added this forward declaration for easier 
review.

If this patch gets accepted, I'd move the definition up to here before landing)



Comment at: clang-tools-extra/clangd/Hover.cpp:830
+if (HI.CalleeArgInfo) {
+  HI.Name = "literal";
+  return HI;

`HoverInfo::present` has an assertion that the `Name` has to be non-empty. I'm 
open for other name suggestions here (Or we could of course adjust 
`HoverInfo::present` instead)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140775

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


[PATCH] D140776: [clang][Interp] Handle defined functions without a body

2022-12-30 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Turns out that this happens when explicitly defaulting a constructor or 
destructor.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140776

Files:
  clang/lib/AST/Interp/ByteCodeEmitter.cpp
  clang/test/AST/Interp/records.cpp


Index: clang/test/AST/Interp/records.cpp
===
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -325,3 +325,9 @@
// expected-error {{must be initialized 
by a constant expression}}
// FIXME: Missing reason for rejection.
 };
+
+namespace EmptyCtor {
+  struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
+  constexpr piecewise_construct_t piecewise_construct =
+piecewise_construct_t();
+};
Index: clang/lib/AST/Interp/ByteCodeEmitter.cpp
===
--- clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -73,7 +73,9 @@
   }
 
   assert(Func);
-  if (!HasBody)
+  // For not-yet-defined functions, we only create a Function instance and
+  // compile their body later.
+  if (!FuncDecl->isDefined())
 return Func;
 
   // Compile the function body.


Index: clang/test/AST/Interp/records.cpp
===
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -325,3 +325,9 @@
// expected-error {{must be initialized by a constant expression}}
// FIXME: Missing reason for rejection.
 };
+
+namespace EmptyCtor {
+  struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
+  constexpr piecewise_construct_t piecewise_construct =
+piecewise_construct_t();
+};
Index: clang/lib/AST/Interp/ByteCodeEmitter.cpp
===
--- clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -73,7 +73,9 @@
   }
 
   assert(Func);
-  if (!HasBody)
+  // For not-yet-defined functions, we only create a Function instance and
+  // compile their body later.
+  if (!FuncDecl->isDefined())
 return Func;
 
   // Compile the function body.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D138870: clang/AMDGPU: Remove flat-address-space from feature map

2022-12-30 Thread Joe Nash via Phabricator via cfe-commits
Joe_Nash added a comment.

The code looks fine, but as you say, the change visible in user code and could 
break something. Do you want to handle that somehow? Maybe wait for @b-sumner




Comment at: clang/test/OpenMP/metadirective_device_isa_codegen_amdgcn.cpp:17
 #pragma omp metadirective \
-when(device = {isa("flat-address-space")} \
+when(device = {isa("dpp")} \
  : parallel) default(single)

Was the "dpp" attribute chosen arbitrarily?


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

https://reviews.llvm.org/D138870

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


[PATCH] D140696: [clang][dataflow] Treat unions as structs.

2022-12-30 Thread Dani Ferreira Franco Moura via Phabricator via cfe-commits
merrymeerkat updated this revision to Diff 485693.
merrymeerkat added a comment.

Extend documentation comment on storage locations with a FIXME about unions.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140696

Files:
  clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
  clang/lib/Analysis/FlowSensitive/Transfer.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -1518,6 +1518,50 @@
   });
 }
 
+TEST(TransferTest, UnionThisMember) {
+  std::string Code = R"(
+union A {
+  int Foo;
+  int Bar;
+
+  void target() {
+(void)0; // [[p]]
+  }
+};
+  )";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+const auto *ThisLoc = dyn_cast(
+Env.getThisPointeeStorageLocation());
+ASSERT_THAT(ThisLoc, NotNull());
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+
+const auto *FooLoc =
+cast(&ThisLoc->getChild(*FooDecl));
+ASSERT_TRUE(isa_and_nonnull(FooLoc));
+
+const Value *FooVal = Env.getValue(*FooLoc);
+ASSERT_TRUE(isa_and_nonnull(FooVal));
+
+const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+ASSERT_THAT(BarDecl, NotNull());
+
+const auto *BarLoc =
+cast(&ThisLoc->getChild(*BarDecl));
+ASSERT_TRUE(isa_and_nonnull(BarLoc));
+
+const Value *BarVal = Env.getValue(*BarLoc);
+ASSERT_TRUE(isa_and_nonnull(BarVal));
+  });
+}
+
 TEST(TransferTest, StructThisInLambda) {
   std::string ThisCaptureCode = R"(
 struct A {
@@ -2537,12 +2581,34 @@
 ASSERT_THAT(BazDecl, NotNull());
 ASSERT_TRUE(BazDecl->getType()->isUnionType());
 
+auto BazFields = BazDecl->getType()->getAsRecordDecl()->fields();
+FieldDecl *FooDecl = nullptr;
+for (FieldDecl *Field : BazFields) {
+  if (Field->getNameAsString() == "Foo") {
+FooDecl = Field;
+  } else {
+FAIL() << "Unexpected field: " << Field->getNameAsString();
+  }
+}
+ASSERT_THAT(FooDecl, NotNull());
+
 const auto *BazLoc = dyn_cast_or_null(
 Env.getStorageLocation(*BazDecl, SkipPast::None));
 ASSERT_THAT(BazLoc, NotNull());
+ASSERT_THAT(Env.getValue(*BazLoc), NotNull());
+
+const auto *BazVal = cast(Env.getValue(*BazLoc));
+const auto *FooValFromBazVal = cast(BazVal->getChild(*FooDecl));
+const auto *FooValFromBazLoc = cast(Env.getValue(BazLoc->getChild(*FooDecl)));
+EXPECT_EQ(FooValFromBazLoc, FooValFromBazVal);
+
+const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
+ASSERT_THAT(BarDecl, NotNull());
+const auto *BarLoc = Env.getStorageLocation(*BarDecl, SkipPast::None);
+ASSERT_TRUE(isa_and_nonnull(BarLoc));
 
-// FIXME: Add support for union types.
-EXPECT_THAT(Env.getValue(*BazLoc), IsNull());
+EXPECT_EQ(Env.getValue(*BarLoc), FooValFromBazVal);
+EXPECT_EQ(Env.getValue(*BarLoc), FooValFromBazLoc);
   });
 }
 
Index: clang/lib/Analysis/FlowSensitive/Transfer.cpp
===
--- clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -480,10 +480,6 @@
 if (BaseLoc == nullptr)
   return;
 
-// FIXME: Add support for union types.
-if (BaseLoc->getType()->isUnionType())
-  return;
-
 auto &MemberLoc = BaseLoc->getChild(*Member);
 if (MemberLoc.getType()->isReferenceType()) {
   Env.setStorageLocation(*S, MemberLoc);
Index: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -223,14 +223,12 @@
 if (Parent->isLambda())
   MethodDecl = dyn_cast(Parent->getDeclContext());
 
+// FIXME: Initialize the ThisPointeeLoc of lambdas too.
 if (MethodDecl && !MethodDecl->isStatic()) {
   QualType ThisPointeeType = MethodDecl->getThisObjectType();
-  // FIXME: Add support for union types.
-  if (!ThisPointeeType->isUnionType()) {
-ThisPointeeLoc = &createStorageLocation(ThisPointeeType);
-if (Value *ThisPointeeVal = createValue(ThisPointeeType))
- 

[PATCH] D140696: [clang][dataflow] Treat unions as structs.

2022-12-30 Thread Dani Ferreira Franco Moura via Phabricator via cfe-commits
merrymeerkat added a comment.

@ymandel - thank you for pointing all of this out! And no need to apologise at 
all :)

I agree that the changes made here are not ideal. But the alternative is also 
not ideal.

The question becomes: is it better to model unions in a way that is lacking, or 
to not model them at all?

To model unions properly, we would need to be able to set the storage location 
of all the members of a union to be the same. But storage location is tied to 
type, so we can't create the same storage location for members of different 
types. From what I can tell, correctly modelling unions would require us to do 
an overhaul of how storage locations are implemented.

Like Dmitri said, I think most of the issues with this simple approach to 
modelling unions would only be revealed with UB code. So, unless we want to 
compare the storage locations of pointers to different union members (which I 
don't think will be a very common use), this modelling should work all right 
for defined behaviour. I added a documentation comment regarding the lacking 
implementation of storage location.

Coming back to the question above. Yitzhak, you seem to prefer not modelling 
union at all rather than having this model that falls short. Dmitri seems to 
prefer a model that works on most cases than no model. I am a bit torn, but I 
think I'm leaning a bit on the side of having a model that falls short. I don't 
think we plan on doing the storage location overhaul anytime soon, and until 
then it'd be good to at least have some functionality.

Happy new year by the way!!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140696

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


[PATCH] D138870: clang/AMDGPU: Remove flat-address-space from feature map

2022-12-30 Thread Matt Arsenault via Phabricator via cfe-commits
arsenm added a comment.

In D138870#4020204 , @Joe_Nash wrote:

> The code looks fine, but as you say, the change visible in user code and 
> could break something. Do you want to handle that somehow? Maybe wait for 
> @b-sumner

OpenMP assumes flat pointers all over, so if someone was relying on this 
behavior it wasn't doing anything useful. They had dead code




Comment at: clang/test/OpenMP/metadirective_device_isa_codegen_amdgcn.cpp:17
 #pragma omp metadirective \
-when(device = {isa("flat-address-space")} \
+when(device = {isa("dpp")} \
  : parallel) default(single)

Joe_Nash wrote:
> Was the "dpp" attribute chosen arbitrarily?
Yes, also meaningfully varies


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

https://reviews.llvm.org/D138870

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


[PATCH] D136554: Implement CWG2631

2022-12-30 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 485703.
cor3ntin added a comment.

Finding the issue took about all day.
I reduced your example to

  template 
  int templated_func() {
  return 0;
  }
  struct test_body {
int mem = templated_func();
  };
  
  struct S {
int a = [] { test_body{}; return 0;}(); // #1
  } s;

When parsing the lambda #1 , we were not considering test_body{} to be 
odr used, on account of the lambda being in the default initializer of a.

However, as it turns out, expressions in the body of a lambda are always 
considered ODR used even if the lambda appear in a default parameter, 
which I think makes sense.
(as the standard specifies that the body of a lambda is not a sub expression)

The actual code fix is to simplify the check we do to see if we are 
in a nested default initializer.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136554

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Sema/UsedDeclVisitor.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/AST/ast-dump-records.cpp
  clang/test/CXX/class/class.local/p1-0x.cpp
  clang/test/CXX/drs/dr26xx.cpp
  clang/test/CodeGenCXX/builtin-source-location.cpp
  clang/test/CodeGenCXX/default-arguments-with-immediate.cpp
  clang/test/CodeGenCXX/meminit-initializers-odr.cpp
  clang/test/PCH/default-argument-with-immediate-calls.cpp
  clang/test/SemaCXX/cxx11-default-member-initializers.cpp
  clang/test/SemaCXX/cxx2a-consteval-default-params.cpp
  clang/test/SemaCXX/source_location.cpp
  clang/www/cxx_dr_status.html

Index: clang/www/cxx_dr_status.html
===
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -15593,7 +15593,7 @@
 https://wg21.link/cwg2631";>2631
 DR
 Immediate function evaluations in default arguments
-Unknown
+Clang 16
   
   
 https://wg21.link/cwg2632";>2632
Index: clang/test/SemaCXX/source_location.cpp
===
--- clang/test/SemaCXX/source_location.cpp
+++ clang/test/SemaCXX/source_location.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify %s
+// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -DUSE_CONSTEVAL -fexceptions -verify %s
 // expected-no-diagnostics
 
 #define assert(...) ((__VA_ARGS__) ? ((void)0) : throw 42)
@@ -8,15 +9,22 @@
 template 
 struct Printer;
 
+#ifdef USE_CONSTEVAL
+#define SOURCE_LOC_EVAL_KIND consteval
+#else
+#define SOURCE_LOC_EVAL_KIND constexpr
+#endif
+
 namespace std {
 class source_location {
   struct __impl;
 
 public:
-  static constexpr source_location current(const __impl *__p = __builtin_source_location()) noexcept {
-source_location __loc;
-__loc.__m_impl = __p;
-return __loc;
+  static SOURCE_LOC_EVAL_KIND source_location
+current(const __impl *__p = __builtin_source_location()) noexcept {
+  source_location __loc;
+  __loc.__m_impl = __p;
+  return __loc;
   }
   constexpr source_location() = default;
   constexpr source_location(source_location const &) = default;
@@ -593,3 +601,73 @@
   }
   static_assert(test());
 }
+
+namespace Lambda {
+#line 8000 "TestLambda.cpp"
+constexpr int nested_lambda(int l = []{
+  return SL::current().line();
+}()) {
+  return l;
+}
+static_assert(nested_lambda() == __LINE__ - 4);
+
+constexpr int lambda_param(int l = [](int l = SL::current().line()) {
+  return l;
+}()) {
+  return l;
+}
+static_assert(lambda_param() == __LINE__);
+
+
+}
+
+constexpr int compound_literal_fun(int a =
+  (int){ SL::current().line() }
+) { return a ;}
+static_assert(compound_literal_fun() == __LINE__);
+
+struct CompoundLiteral {
+  int a = (int){ SL::current().line() };
+};
+static_assert(CompoundLiteral{}.a == __LINE__);
+
+
+// FIXME
+// Init captures are subexpressions of the lambda expression
+// so according to the standard immediate invocations in init captures
+// should be evaluated at the call site.
+// However Clang does not yet implement this as it would introduce
+// a fair bit of complexity.
+// We intend to implement that functionality once we find real world
+// use cases that require it.
+constexpr int test_init_capture(int a =
+[b = SL::current().line()] { return b; }()) {
+  return a;
+}
+#ifdef USE_CONSTEVAL
+static_assert(test_init_capture() == __LINE__ - 4);
+#else
+static_assert(test_init_ca

[PATCH] D137838: [Support] Move TargetParsers to new component

2022-12-30 Thread Sam Elliott via Phabricator via cfe-commits
lenary added a comment.

In D137838#4018930 , @vitalybuka 
wrote:

> This bot is broken after the patch 
> https://lab.llvm.org/buildbot/#/builders/236/builds/1480

Thanks for letting me know. I'm back in the office on the 3rd, and it looks 
like this will be top of my list to look at, not that I'm very familiar with 
the pass and what it's up to.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137838

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


[PATCH] D140772: [clang-tidy] Fix minor bug in add_new_check.py

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485710.
ccotter added a comment.

Fix isdir check


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140772

Files:
  clang-tools-extra/clang-tidy/add_new_check.py
  clang-tools-extra/docs/ReleaseNotes.rst


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -99,6 +99,9 @@
 - Change to Python 3 in the shebang of `add_new_check.py` and 
`rename_check.py`,
   as the existing code is not compatible with Python 2.
 
+- Fix a minor bug in `add_new_check.py` to only traverse subdirectories
+  when updating the list of checks in the documentation.
+
 New checks
 ^^
 
Index: clang-tools-extra/clang-tidy/add_new_check.py
===
--- clang-tools-extra/clang-tidy/add_new_check.py
+++ clang-tools-extra/clang-tidy/add_new_check.py
@@ -322,8 +322,7 @@
 lines = f.readlines()
   # Get all existing docs
   doc_files = []
-  for subdir in list(filter(lambda s: not s.endswith('.rst') and not 
s.endswith('.py'),
- os.listdir(docs_dir))):
+  for subdir in filter(lambda s: os.path.isdir(os.path.join(docs_dir, s)), 
os.listdir(docs_dir)):
 for file in filter(lambda s: s.endswith('.rst'), 
os.listdir(os.path.join(docs_dir, subdir))):
   doc_files.append([subdir, file])
   doc_files.sort()


Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -99,6 +99,9 @@
 - Change to Python 3 in the shebang of `add_new_check.py` and `rename_check.py`,
   as the existing code is not compatible with Python 2.
 
+- Fix a minor bug in `add_new_check.py` to only traverse subdirectories
+  when updating the list of checks in the documentation.
+
 New checks
 ^^
 
Index: clang-tools-extra/clang-tidy/add_new_check.py
===
--- clang-tools-extra/clang-tidy/add_new_check.py
+++ clang-tools-extra/clang-tidy/add_new_check.py
@@ -322,8 +322,7 @@
 lines = f.readlines()
   # Get all existing docs
   doc_files = []
-  for subdir in list(filter(lambda s: not s.endswith('.rst') and not s.endswith('.py'),
- os.listdir(docs_dir))):
+  for subdir in filter(lambda s: os.path.isdir(os.path.join(docs_dir, s)), os.listdir(docs_dir)):
 for file in filter(lambda s: s.endswith('.rst'), os.listdir(os.path.join(docs_dir, subdir))):
   doc_files.append([subdir, file])
   doc_files.sort()
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140772: [clang-tidy] Fix minor bug in add_new_check.py

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added inline comments.



Comment at: clang-tools-extra/clang-tidy/add_new_check.py:324-328
   doc_files = []
-  for subdir in list(filter(lambda s: not s.endswith('.rst') and not 
s.endswith('.py'),
- os.listdir(docs_dir))):
+  for subdir in list(filter(os.path.isdir, os.listdir(docs_dir))):
 for file in filter(lambda s: s.endswith('.rst'), 
os.listdir(os.path.join(docs_dir, subdir))):
   doc_files.append([subdir, file])
   doc_files.sort()

carlosgalvezp wrote:
> It feels this whole code could be made much simpler, readable and safer by 
> just doing:
> 
>   doc_files = glob.glob(os.path.join(docs_dir, "**", "*.rst"), recursive=True)
I gave this a shot, but realized the the glob returned the relative path 
`../docs/clang-tidy/checks//.rst`, and the existing logic only 
adds `[, .rst]` to the list. Python3.10's `glob.glob` has 
root_dir which would do the trick for us, but I don't think we can rely on 
Python3 yet? I think using glob might not improve the readability all that much 
since I'd have to strip out the `docs_dir` subpath, but happy to give that a go 
based on your feedback.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140772

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


[PATCH] D140776: [clang][Interp] Handle defined functions without a body

2022-12-30 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder updated this revision to Diff 485714.

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

https://reviews.llvm.org/D140776

Files:
  clang/lib/AST/Interp/ByteCodeEmitter.cpp
  clang/test/AST/Interp/records.cpp


Index: clang/test/AST/Interp/records.cpp
===
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -325,3 +325,9 @@
// expected-error {{must be initialized 
by a constant expression}}
// FIXME: Missing reason for rejection.
 };
+
+namespace EmptyCtor {
+  struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
+  constexpr piecewise_construct_t piecewise_construct =
+piecewise_construct_t();
+};
Index: clang/lib/AST/Interp/ByteCodeEmitter.cpp
===
--- clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -21,11 +21,6 @@
 
 Expected
 ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
-  // Function is not defined at all or not yet. We will
-  // create a Function instance but not compile the body. That
-  // will (maybe) happen later.
-  bool HasBody = FuncDecl->hasBody(FuncDecl);
-
   // Create a handle over the emitted code.
   Function *Func = P.getFunction(FuncDecl);
   if (!Func) {
@@ -73,7 +68,9 @@
   }
 
   assert(Func);
-  if (!HasBody)
+  // For not-yet-defined functions, we only create a Function instance and
+  // compile their body later.
+  if (!FuncDecl->isDefined())
 return Func;
 
   // Compile the function body.


Index: clang/test/AST/Interp/records.cpp
===
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -325,3 +325,9 @@
// expected-error {{must be initialized by a constant expression}}
// FIXME: Missing reason for rejection.
 };
+
+namespace EmptyCtor {
+  struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
+  constexpr piecewise_construct_t piecewise_construct =
+piecewise_construct_t();
+};
Index: clang/lib/AST/Interp/ByteCodeEmitter.cpp
===
--- clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -21,11 +21,6 @@
 
 Expected
 ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
-  // Function is not defined at all or not yet. We will
-  // create a Function instance but not compile the body. That
-  // will (maybe) happen later.
-  bool HasBody = FuncDecl->hasBody(FuncDecl);
-
   // Create a handle over the emitted code.
   Function *Func = P.getFunction(FuncDecl);
   if (!Func) {
@@ -73,7 +68,9 @@
   }
 
   assert(Func);
-  if (!HasBody)
+  // For not-yet-defined functions, we only create a Function instance and
+  // compile their body later.
+  if (!FuncDecl->isDefined())
 return Func;
 
   // Compile the function body.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140776: [clang][Interp] Handle defined functions without a body

2022-12-30 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder added a comment.

CI fails because other patches are missing, most likely 
https://reviews.llvm.org/D140668.


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

https://reviews.llvm.org/D140776

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


[clang] e632938 - [Sema] Avoid double hash lookup. NFCI

2022-12-30 Thread Benjamin Kramer via cfe-commits

Author: Benjamin Kramer
Date: 2022-12-30T19:25:38+01:00
New Revision: e6329388c39d18c428afdbbfd0f1330e782bc348

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

LOG: [Sema] Avoid double hash lookup. NFCI

Added: 


Modified: 
clang/lib/Sema/SemaLookup.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index c73acf1619930..97b3c97a9e51e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1623,10 +1623,8 @@ hasAcceptableDefaultArgument(Sema &S, const ParmDecl *D,
   if (!D->hasDefaultArgument())
 return false;
 
-  llvm::SmallDenseSet Visited;
-  while (D && !Visited.count(D)) {
-Visited.insert(D);
-
+  llvm::SmallPtrSet Visited;
+  while (D && Visited.insert(D).second) {
 auto &DefaultArg = D->getDefaultArgStorage();
 if (!DefaultArg.isInherited() && S.isAcceptable(D, Kind))
   return true;



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


[PATCH] D136554: Implement CWG2631

2022-12-30 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay added a comment.

@rupprecht You may consider contributing some interesting tests in a separate 
patch:)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136554

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


[PATCH] D140772: [clang-tidy] Fix minor bug in add_new_check.py

2022-12-30 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp added inline comments.



Comment at: clang-tools-extra/clang-tidy/add_new_check.py:324-328
   doc_files = []
-  for subdir in list(filter(lambda s: not s.endswith('.rst') and not 
s.endswith('.py'),
- os.listdir(docs_dir))):
+  for subdir in list(filter(os.path.isdir, os.listdir(docs_dir))):
 for file in filter(lambda s: s.endswith('.rst'), 
os.listdir(os.path.join(docs_dir, subdir))):
   doc_files.append([subdir, file])
   doc_files.sort()

ccotter wrote:
> carlosgalvezp wrote:
> > It feels this whole code could be made much simpler, readable and safer by 
> > just doing:
> > 
> >   doc_files = glob.glob(os.path.join(docs_dir, "**", "*.rst"), 
> > recursive=True)
> I gave this a shot, but realized the the glob returned the relative path 
> `../docs/clang-tidy/checks//.rst`, and the existing logic only 
> adds `[, .rst]` to the list. Python3.10's `glob.glob` has 
> root_dir which would do the trick for us, but I don't think we can rely on 
> Python3 yet? I think using glob might not improve the readability all that 
> much since I'd have to strip out the `docs_dir` subpath, but happy to give 
> that a go based on your feedback.
Good point, I was thinking of something along these lines:


```
from pathlib import Path

for doc_file in map(lambda s: Path(s), glob.glob(os.path.join(docs_dir, "*", 
"*.rst"))):
  doc_files.append([doc_file.parts[-1], doc_file.parts[-2])
```

The current patch is already a great cleanup so I'm fine with it as well :) 




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140772

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


[PATCH] D140772: [clang-tidy] Fix minor bug in add_new_check.py

2022-12-30 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp added inline comments.



Comment at: clang-tools-extra/clang-tidy/add_new_check.py:324-328
   doc_files = []
-  for subdir in list(filter(lambda s: not s.endswith('.rst') and not 
s.endswith('.py'),
- os.listdir(docs_dir))):
+  for subdir in list(filter(os.path.isdir, os.listdir(docs_dir))):
 for file in filter(lambda s: s.endswith('.rst'), 
os.listdir(os.path.join(docs_dir, subdir))):
   doc_files.append([subdir, file])
   doc_files.sort()

carlosgalvezp wrote:
> ccotter wrote:
> > carlosgalvezp wrote:
> > > It feels this whole code could be made much simpler, readable and safer 
> > > by just doing:
> > > 
> > >   doc_files = glob.glob(os.path.join(docs_dir, "**", "*.rst"), 
> > > recursive=True)
> > I gave this a shot, but realized the the glob returned the relative path 
> > `../docs/clang-tidy/checks//.rst`, and the existing logic 
> > only adds `[, .rst]` to the list. Python3.10's `glob.glob` 
> > has root_dir which would do the trick for us, but I don't think we can rely 
> > on Python3 yet? I think using glob might not improve the readability all 
> > that much since I'd have to strip out the `docs_dir` subpath, but happy to 
> > give that a go based on your feedback.
> Good point, I was thinking of something along these lines:
> 
> 
> ```
> from pathlib import Path
> 
> for doc_file in map(lambda s: Path(s), glob.glob(os.path.join(docs_dir, "*", 
> "*.rst"))):
>   doc_files.append([doc_file.parts[-1], doc_file.parts[-2])
> ```
> 
> The current patch is already a great cleanup so I'm fine with it as well :) 
> 
> 
Sorry, I meant:

```
doc_files.append([doc_file.parts[-2], doc_file.parts[-1])
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140772

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


[PATCH] D140772: [clang-tidy] Fix minor bug in add_new_check.py

2022-12-30 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp accepted this revision.
carlosgalvezp added a comment.

Thanks for the fix!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140772

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


[PATCH] D140547: Perform access checking to private members in simple requirement.

2022-12-30 Thread Utkarsh Saxena via Phabricator via cfe-commits
usaxena95 updated this revision to Diff 485725.
usaxena95 added a comment.

Perform access-dependent checks after transforming requires clause.
This is more generic and less invasive than the previous version which changed 
`RebuildMemberExpr` and also produced duplicate diagnostics.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140547

Files:
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp


Index: clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
===
--- clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
+++ clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
@@ -104,3 +104,54 @@
 constexpr bool b = requires (X &x) { static_cast(nullptr); };
 // expected-error@-1{{constraint variable 'x' cannot be used in an evaluated 
context}}
 // expected-note@-2{{'x' declared here}}
+
+namespace access_checks {
+template
+struct A {
+static constexpr bool foo();
+static constexpr bool bar();
+static constexpr bool baz();
+static constexpr bool faz();
+};
+
+class C{};
+
+class B {
+void p() {}
+bool data_member = true;
+static const bool static_member = true;
+friend struct A<0>;
+};
+
+template
+constexpr bool A::foo() {
+return requires(B b) { b.p(); };
+}
+static_assert(!A<1>::foo());
+static_assert(A<0>::foo());
+
+template
+constexpr bool A::bar() {
+return requires() { B::static_member; };
+}
+static_assert(!A<1>::bar());
+static_assert(A<0>::bar());
+
+template
+constexpr bool A::baz() {
+return requires(B b) { b.data_member; };
+}
+static_assert(!A<1>::baz());
+static_assert(A<0>::baz());
+
+template
+constexpr bool A::faz() {
+return requires(B a, B b) { 
+  a.p();
+  b.data_member;
+  B::static_member;
+};
+}
+static_assert(!A<1>::faz());
+static_assert(A<0>::faz());
+}
\ No newline at end of file
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/ASTMutationListener.h"
+#include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprConcepts.h"
@@ -1363,7 +1364,19 @@
 
 ExprResult TransformRequiresExpr(RequiresExpr *E) {
   LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
-  return inherited::TransformRequiresExpr(E);
+  ExprResult TransReq = inherited::TransformRequiresExpr(E);
+  {
+if (TransReq.isInvalid() || !E->getBody()->isDependentContext())
+  return TransReq;
+Sema::SFINAETrap Trap(SemaRef);
+// We recreated parameters, but not by instantiating them. There may be
+// pending access-dependent diagnostics to produce.
+// RequiresExpr Body serves as the DeclContext for the parameters.
+SemaRef.PerformDependentDiagnostics(E->getBody(), TemplateArgs);
+if (Trap.hasErrorOccurred())
+  return ExprError();
+  }
+  return TransReq;
 }
 
 bool TransformRequiresExprRequirements(


Index: clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
===
--- clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
+++ clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
@@ -104,3 +104,54 @@
 constexpr bool b = requires (X &x) { static_cast(nullptr); };
 // expected-error@-1{{constraint variable 'x' cannot be used in an evaluated context}}
 // expected-note@-2{{'x' declared here}}
+
+namespace access_checks {
+template
+struct A {
+static constexpr bool foo();
+static constexpr bool bar();
+static constexpr bool baz();
+static constexpr bool faz();
+};
+
+class C{};
+
+class B {
+void p() {}
+bool data_member = true;
+static const bool static_member = true;
+friend struct A<0>;
+};
+
+template
+constexpr bool A::foo() {
+return requires(B b) { b.p(); };
+}
+static_assert(!A<1>::foo());
+static_assert(A<0>::foo());
+
+template
+constexpr bool A::bar() {
+return requires() { B::static_member; };
+}
+static_assert(!A<1>::bar());
+static_assert(A<0>::bar());
+
+template
+constexpr bool A::baz() {
+return requires(B b) { b.data_member; };
+}
+static_assert(!A<1>::baz());
+static_assert(A<0>::baz());
+
+template
+constexpr bool A::faz() {
+return requires(B a, B b) { 
+  a.p();
+  b.data_member;
+  B::static_member;
+};
+}
+static_assert(!A<1>::faz());
+static_assert(A<0>::faz());
+}
\ No newline at end of file
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
=

[PATCH] D140547: Perform access checking to private members in simple requirement.

2022-12-30 Thread Utkarsh Saxena via Phabricator via cfe-commits
usaxena95 updated this revision to Diff 485726.
usaxena95 added a comment.

Improved comment and added comment.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140547

Files:
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp


Index: clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
===
--- clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
+++ clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
@@ -104,3 +104,54 @@
 constexpr bool b = requires (X &x) { static_cast(nullptr); };
 // expected-error@-1{{constraint variable 'x' cannot be used in an evaluated 
context}}
 // expected-note@-2{{'x' declared here}}
+
+namespace access_checks {
+template
+struct A {
+static constexpr bool foo();
+static constexpr bool bar();
+static constexpr bool baz();
+static constexpr bool faz();
+};
+
+class C{};
+
+class B {
+void p() {}
+bool data_member = true;
+static const bool static_member = true;
+friend struct A<0>;
+};
+
+template
+constexpr bool A::foo() {
+return requires(B b) { b.p(); };
+}
+static_assert(!A<1>::foo());
+static_assert(A<0>::foo());
+
+template
+constexpr bool A::bar() {
+return requires() { B::static_member; };
+}
+static_assert(!A<1>::bar());
+static_assert(A<0>::bar());
+
+template
+constexpr bool A::baz() {
+return requires(B b) { b.data_member; };
+}
+static_assert(!A<1>::baz());
+static_assert(A<0>::baz());
+
+template
+constexpr bool A::faz() {
+return requires(B a, B b) { 
+  a.p();
+  b.data_member;
+  B::static_member;
+};
+}
+static_assert(!A<1>::faz());
+static_assert(A<0>::faz());
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/ASTMutationListener.h"
+#include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprConcepts.h"
@@ -1362,6 +1363,14 @@
 }
 
 ExprResult TransformRequiresExpr(RequiresExpr *E) {
+  if (E->getBody()->isDependentContext()) {
+Sema::SFINAETrap Trap(SemaRef);
+// We recreate the RequiresExpr body, but not by instantiating it.
+// Produce pending diagnostics for dependent access check.
+SemaRef.PerformDependentDiagnostics(E->getBody(), TemplateArgs);
+if (Trap.hasErrorOccurred())
+  return ExprError();
+  }
   LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
   return inherited::TransformRequiresExpr(E);
 }


Index: clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
===
--- clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
+++ clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
@@ -104,3 +104,54 @@
 constexpr bool b = requires (X &x) { static_cast(nullptr); };
 // expected-error@-1{{constraint variable 'x' cannot be used in an evaluated context}}
 // expected-note@-2{{'x' declared here}}
+
+namespace access_checks {
+template
+struct A {
+static constexpr bool foo();
+static constexpr bool bar();
+static constexpr bool baz();
+static constexpr bool faz();
+};
+
+class C{};
+
+class B {
+void p() {}
+bool data_member = true;
+static const bool static_member = true;
+friend struct A<0>;
+};
+
+template
+constexpr bool A::foo() {
+return requires(B b) { b.p(); };
+}
+static_assert(!A<1>::foo());
+static_assert(A<0>::foo());
+
+template
+constexpr bool A::bar() {
+return requires() { B::static_member; };
+}
+static_assert(!A<1>::bar());
+static_assert(A<0>::bar());
+
+template
+constexpr bool A::baz() {
+return requires(B b) { b.data_member; };
+}
+static_assert(!A<1>::baz());
+static_assert(A<0>::baz());
+
+template
+constexpr bool A::faz() {
+return requires(B a, B b) { 
+  a.p();
+  b.data_member;
+  B::static_member;
+};
+}
+static_assert(!A<1>::faz());
+static_assert(A<0>::faz());
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/ASTMutationListener.h"
+#include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprConcepts.h"
@@ -1362,6 +1363,14 @@
 }
 
 ExprResult TransformRequiresExpr(RequiresExpr *E) {
+ 

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added subscribers: carlosgalvezp, shchenz, kbarton, xazax.hun, nemanjai.
Herald added a reviewer: njames93.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Implement CppCoreGuideline CP.53 to warn when a coroutine accepts
references parameters. Although the guideline mentions that it is safe
to access a reference parameter before suspension points, the guideline
recommends flagging all coroutine parameter references.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140793

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t
+
+// NOLINTBEGIN
+namespace std {
+  template 
+  struct coroutine_traits {
+using promise_type = typename T::promise_type;
+  };
+  template 
+  struct coroutine_handle;
+  template <>
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+  };
+  template 
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+operator coroutine_handle<>() const noexcept;
+  };
+} // namespace std
+
+struct Awaiter {
+  bool await_ready() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct Coro {
+  struct promise_type {
+Awaiter initial_suspend();
+Awaiter final_suspend() noexcept;
+void return_void();
+Coro get_return_object();
+void unhandled_exception();
+  };
+};
+// NOLINTEND
+
+struct Obj {};
+
+Coro no_args() {
+  co_return;
+}
+
+Coro no_references(int x, int* y, Obj z, const Obj w) {
+  co_return;
+}
+
+Coro accepts_references(int& x, const int &y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_and_non_references(int& x, int y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_to_objects(Obj& x) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro non_coro_accepts_references(int& x) {
+  if (x);
+  return Coro{};
+}
+
+void defines_a_lambda() {
+  auto NoArgs = [](int x) -> Coro { co_return; };
+
+  auto NoReferences = [](int x) -> Coro { co_return; };
+
+  auto WithReferences = [](int& x) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+
+  auto WithReferences2 = [](int&) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -182,6 +182,7 @@
`cppcoreguidelines-avoid-do-while `_,
`cppcoreguidelines-avoid-goto `_,
`cppcoreguidelines-avoid-non-const-global-variables `_,
+   `cppcoreguidelines-avoid-reference-coroutine-parameters `_, "Yes"
`cppcoreguidelines-init-variables `_, "Yes"
`cppcoreguidelines-interfaces-global-init `_,
`cppcoreguidelines-macro-usage `_,
Index: clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rs

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter added a comment.

Passing and accessing a reference is safe if the access is done before any 
suspend point (taking into account whether the initial coroutine suspend 
actually suspends or not). Although CP.53 recommends warning on any reference 
parameter regardless of whether the code only accesses the reference before any 
suspend points, I did implement (not in this changeset - in a separate branch) 
a version of this check that uses the CFG to determine whether reference 
parameters are never accessed after a suspend point. If there's interest, I 
could reimplement this check with this (perhaps as a tool option). That said, I 
do agree with CP.53 that relying on such access being safe is brittle e.g. if 
the code is refactored in the future to rearrange suspend points, so I went 
with this approach for the review.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

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


[PATCH] D140794: Add coroutineBodyStmt matcher

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter created this revision.
Herald added a subscriber: ChuanqiXu.
Herald added a project: All.
ccotter requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The coroutineBodyStmt matcher matches CoroutineBodyStmt AST nodes.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140794

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


Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -678,6 +678,26 @@
   EXPECT_TRUE(matchesConditionally(CoYieldCode, 
coyieldExpr(isExpansionInMainFile()), 
true, {"-std=c++20", "-I/"}, M));
+
+  StringRef NonCoroCode = R"cpp(
+#include 
+void non_coro_function() {
+}
+)cpp";
+
+  EXPECT_TRUE(matchesConditionally(CoReturnCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoAwaitCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoYieldCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+
+  EXPECT_FALSE(matchesConditionally(NonCoroCode,
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
 }
 
 TEST(Matcher, isClassMessage) {
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -168,6 +168,7 @@
   REGISTER_MATCHER(complexType);
   REGISTER_MATCHER(compoundLiteralExpr);
   REGISTER_MATCHER(compoundStmt);
+  REGISTER_MATCHER(coroutineBodyStmt);
   REGISTER_MATCHER(coawaitExpr);
   REGISTER_MATCHER(conditionalOperator);
   REGISTER_MATCHER(constantArrayType);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -909,6 +909,7 @@
 const internal::VariadicDynCastAllOfMatcher caseStmt;
 const internal::VariadicDynCastAllOfMatcher defaultStmt;
 const internal::VariadicDynCastAllOfMatcher compoundStmt;
+const internal::VariadicDynCastAllOfMatcher 
coroutineBodyStmt;
 const internal::VariadicDynCastAllOfMatcher cxxCatchStmt;
 const internal::VariadicDynCastAllOfMatcher cxxTryStmt;
 const internal::VariadicDynCastAllOfMatcher cxxThrowExpr;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2449,6 +2449,17 @@
 extern const internal::VariadicDynCastAllOfMatcher
 coyieldExpr;
 
+/// Matches coroutine body statements.
+///
+/// coroutineBodyStmt() matches the coroutine below
+/// \code
+///   generator gen() {
+/// co_return;
+///   }
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher
+coroutineBodyStmt;
+
 /// Matches nullptr literal.
 extern const internal::VariadicDynCastAllOfMatcher
 cxxNullPtrLiteralExpr;
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -855,6 +855,8 @@
 AST Matchers
 
 
+- Add ``coroutineBodyStmt`` matcher.
+
 clang-format
 
 - Add ``RemoveSemicolon`` option for removing ``;`` after a non-empty function 
definition.


Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -678,6 +678,26 @@
   EXPECT_TRUE(matchesConditionally(CoYieldCode, 
coyieldExpr(isExpansionInMainFile()), 
true, {"-std=c++20", "-I/"}, M));
+
+  StringRef NonCoroCode = R"cpp(
+#include 
+void non_coro_function() {
+}
+)cpp";
+
+  EXPECT_TRUE(matchesConditionally(CoReturnCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoAwaitCode, 
+   coroutineBodyStmt(),
+   true, 

[PATCH] D140757: [Hexagon][VE][WebAssembly] Define __GCC_HAVE_SYNC_COMPARE_AND_SWAP macros

2022-12-30 Thread Brad Smith via Phabricator via cfe-commits
brad updated this revision to Diff 485743.
brad added a comment.

Remove some whitespace.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140757

Files:
  clang/lib/Basic/Targets/Hexagon.cpp
  clang/lib/Basic/Targets/VE.cpp
  clang/lib/Basic/Targets/WebAssembly.cpp
  clang/test/Preprocessor/init.c
  clang/test/Preprocessor/predefined-arch-macros.c

Index: clang/test/Preprocessor/predefined-arch-macros.c
===
--- clang/test/Preprocessor/predefined-arch-macros.c
+++ clang/test/Preprocessor/predefined-arch-macros.c
@@ -4330,3 +4330,39 @@
 // CHECK_M68K_68020_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
 // CHECK_M68K_68020_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
 // CHECK_M68K_68020_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+
+// Begin Hexagon tests 
+
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target hexagon-unknown-linux \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_HEXAGON_ATOMICS
+
+// CHECK_HEXAGON_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK_HEXAGON_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK_HEXAGON_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK_HEXAGON_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+
+// Begin VE tests 
+
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target ve-unknown-linux \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_VE_ATOMICS
+
+// CHECK_VE_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK_VE_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK_VE_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK_VE_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+
+// Begin WebAssembly tests 
+
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm32-unknown-unknown \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_WASM_ATOMICS
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm64-unknown-unknown \
+// RUN:   | FileCheck -match-full-lines %s -check-prefix=CHECK_WASM_ATOMICS
+
+// CHECK_WASM_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK_WASM_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK_WASM_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK_WASM_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
Index: clang/test/Preprocessor/init.c
===
--- clang/test/Preprocessor/init.c
+++ clang/test/Preprocessor/init.c
@@ -1597,6 +1597,10 @@
 // WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
 // WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
 // WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// WEBASSEMBLY-NEXT:#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// WEBASSEMBLY-NEXT:#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// WEBASSEMBLY-NEXT:#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
 // WEBASSEMBLY-NEXT:#define __GNUC_MINOR__ {{.*}}
 // WEBASSEMBLY-NEXT:#define __GNUC_PATCHLEVEL__ {{.*}}
 // WEBASSEMBLY-NEXT:#define __GNUC_STDC_INLINE__ 1
Index: clang/lib/Basic/Targets/WebAssembly.cpp
===
--- clang/lib/Basic/Targets/WebAssembly.cpp
+++ clang/lib/Basic/Targets/WebAssembly.cpp
@@ -96,6 +96,11 @@
 Builder.defineMacro("__wasm_reference_types__");
   if (HasExtendedConst)
 Builder.defineMacro("__wasm_extended_const__");
+
+  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
 }
 
 void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap &Features,
Index: clang/lib/Basic/Targets/VE.cpp
===
--- clang/lib/Basic/Targets/VE.cpp
+++ clang/lib/Basic/Targets/VE.cpp
@@ -38,6 +38,11 @@
   // FIXME: define __FAST_MATH__ 1 if -ffast-math is enabled
   // FIXME: define __OPTIMIZE__ n if -On is enabled
   // FIXME: define __VECTOR__ n 1 if automatic vectorization is enabled
+
+  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
 }
 
 ArrayRef VETargetInfo::getTargetBuiltins() const {
Index: clang/lib/Basic/Targets/Hexagon.cpp
===
--- clang/lib/Basic/Targets/Hexagon.cpp
+++ clang/lib/Basic/Targets/Hexagon.cpp
@@ -102,6 +102,11 @@
 
   std::string NumPhySlots = isTinyCore() ? "3" : "4";
   Builder.defineMacro("__HE

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2022-12-30 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst:9
+
+This check implements
+[CppCoreGuideline 
CP.53](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines).

Reference link is usually placed at the end of documentation.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

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


[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485745.
ccotter added a comment.

move reference link


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t
+
+// NOLINTBEGIN
+namespace std {
+  template 
+  struct coroutine_traits {
+using promise_type = typename T::promise_type;
+  };
+  template 
+  struct coroutine_handle;
+  template <>
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+  };
+  template 
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+operator coroutine_handle<>() const noexcept;
+  };
+} // namespace std
+
+struct Awaiter {
+  bool await_ready() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct Coro {
+  struct promise_type {
+Awaiter initial_suspend();
+Awaiter final_suspend() noexcept;
+void return_void();
+Coro get_return_object();
+void unhandled_exception();
+  };
+};
+// NOLINTEND
+
+struct Obj {};
+
+Coro no_args() {
+  co_return;
+}
+
+Coro no_references(int x, int* y, Obj z, const Obj w) {
+  co_return;
+}
+
+Coro accepts_references(int& x, const int &y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_and_non_references(int& x, int y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_to_objects(Obj& x) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro non_coro_accepts_references(int& x) {
+  if (x);
+  return Coro{};
+}
+
+void defines_a_lambda() {
+  auto NoArgs = [](int x) -> Coro { co_return; };
+
+  auto NoReferences = [](int x) -> Coro { co_return; };
+
+  auto WithReferences = [](int& x) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+
+  auto WithReferences2 = [](int&) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -182,6 +182,7 @@
`cppcoreguidelines-avoid-do-while `_,
`cppcoreguidelines-avoid-goto `_,
`cppcoreguidelines-avoid-non-const-global-variables `_,
+   `cppcoreguidelines-avoid-reference-coroutine-parameters `_, "Yes"
`cppcoreguidelines-init-variables `_, "Yes"
`cppcoreguidelines-interfaces-global-init `_,
`cppcoreguidelines-macro-usage `_,
Index: clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
@@ -0,0 +1,20 @@
+.. title:: clang-tidy - cppcoreguidelines-avoid-reference-coroutine-parameters
+
+cppcoreguidelines-avoid-reference-coroutine-parameters
+==
+
+Warns 

[PATCH] D140793: [clang-tidy] Implement CppCoreGuideline CP.53

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485746.
ccotter added a comment.

spelling


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140793

Files:
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.h
  clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t
+
+// NOLINTBEGIN
+namespace std {
+  template 
+  struct coroutine_traits {
+using promise_type = typename T::promise_type;
+  };
+  template 
+  struct coroutine_handle;
+  template <>
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+  };
+  template 
+  struct coroutine_handle {
+coroutine_handle() noexcept;
+coroutine_handle(decltype(nullptr)) noexcept;
+static constexpr coroutine_handle from_address(void*);
+operator coroutine_handle<>() const noexcept;
+  };
+} // namespace std
+
+struct Awaiter {
+  bool await_ready() noexcept;
+  void await_suspend(std::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct Coro {
+  struct promise_type {
+Awaiter initial_suspend();
+Awaiter final_suspend() noexcept;
+void return_void();
+Coro get_return_object();
+void unhandled_exception();
+  };
+};
+// NOLINTEND
+
+struct Obj {};
+
+Coro no_args() {
+  co_return;
+}
+
+Coro no_references(int x, int* y, Obj z, const Obj w) {
+  co_return;
+}
+
+Coro accepts_references(int& x, const int &y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_and_non_references(int& x, int y) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro accepts_references_to_objects(Obj& x) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+  co_return;
+}
+
+Coro non_coro_accepts_references(int& x) {
+  if (x);
+  return Coro{};
+}
+
+void defines_a_lambda() {
+  auto NoArgs = [](int x) -> Coro { co_return; };
+
+  auto NoReferences = [](int x) -> Coro { co_return; };
+
+  auto WithReferences = [](int& x) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+
+  auto WithReferences2 = [](int&) -> Coro { co_return; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
+}
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -182,6 +182,7 @@
`cppcoreguidelines-avoid-do-while `_,
`cppcoreguidelines-avoid-goto `_,
`cppcoreguidelines-avoid-non-const-global-variables `_,
+   `cppcoreguidelines-avoid-reference-coroutine-parameters `_, "Yes"
`cppcoreguidelines-init-variables `_, "Yes"
`cppcoreguidelines-interfaces-global-init `_,
`cppcoreguidelines-macro-usage `_,
Index: clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.rst
@@ -0,0 +1,20 @@
+.. title:: clang-tidy - cppcoreguidelines-avoid-reference-coroutine-parameters
+
+cppcoreguidelines-avoid-reference-coroutine-parameters
+==
+
+Warns when a coro

[PATCH] D136031: [DirectX backend] support ConstantBuffer to DXILResource.h

2022-12-30 Thread Xiang Li via Phabricator via cfe-commits
python3kgae updated this revision to Diff 485747.
python3kgae added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136031

Files:
  llvm/lib/Target/DirectX/CBufferDataLayout.cpp
  llvm/lib/Target/DirectX/CBufferDataLayout.h
  llvm/lib/Target/DirectX/CMakeLists.txt
  llvm/lib/Target/DirectX/DXILResource.cpp
  llvm/lib/Target/DirectX/DXILResource.h
  llvm/test/CodeGen/DirectX/cbuf.ll
  llvm/test/CodeGen/DirectX/legacy_cb_layout_0.ll
  llvm/test/CodeGen/DirectX/legacy_cb_layout_1.ll
  llvm/test/CodeGen/DirectX/legacy_cb_layout_2.ll
  llvm/test/CodeGen/DirectX/legacy_cb_layout_3.ll

Index: llvm/test/CodeGen/DirectX/legacy_cb_layout_3.ll
===
--- /dev/null
+++ llvm/test/CodeGen/DirectX/legacy_cb_layout_3.ll
@@ -0,0 +1,81 @@
+; RUN: opt -S -dxil-metadata-emit < %s | FileCheck %s --check-prefix=DXILMD
+
+target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-unknown-shadermodel6.7-library"
+
+; cbuffer D
+; {
+;
+;   struct D
+;   {
+;
+;   int D0;   ; Offset:0
+;   struct struct.B
+;   {
+;
+;   double B0;; Offset:   16
+;   float3 B1;; Offset:   32
+;   float B2; ; Offset:   44
+;   double3 B3;   ; Offset:   48
+;   half B4;  ; Offset:   72
+;   double2 B5;   ; Offset:   80
+;   float B6; ; Offset:   96
+;   half3 B7; ; Offset:  100
+;   half3 B8; ; Offset:  106
+;   
+;   } D1; ; Offset:   16
+;
+;   half D2;  ; Offset:  112
+;   struct struct.C
+;   {
+;
+;   struct struct.A
+;   {
+;
+;   float A0; ; Offset:  128
+;   double A1;; Offset:  136
+;   float A2; ; Offset:  144
+;   half A3;  ; Offset:  148
+;   int16_t A4;   ; Offset:  150
+;   int64_t A5;   ; Offset:  152
+;   int A6;   ; Offset:  160
+;   
+;   } C0; ; Offset:  128
+;
+;   float C1[1];  ; Offset:  176
+;   struct struct.B
+;   {
+;
+;   double B0;; Offset:  192
+;   float3 B1;; Offset:  208
+;   float B2; ; Offset:  220
+;   double3 B3;   ; Offset:  224
+;   half B4;  ; Offset:  248
+;   double2 B5;   ; Offset:  256
+;   float B6; ; Offset:  272
+;   half3 B7; ; Offset:  276
+;   half3 B8; ; Offset:  282
+;   
+;   } C2[2];; ; Offset:  192
+;
+;   half C3;  ; Offset:  384
+;   
+;   } D3; ; Offset:  128
+;
+;   double D4;; Offset:  392
+;   
+;   } D;  ; Offset:0 Size:   400
+
+
+; Make sure the size is 400
+; DXILMD:!{i32 0, ptr @D.cb., !"", i32 0, i32 1, i32 1, i32 400}
+
+
+%struct.B = type <{ double, <3 x float>, float, <3 x double>, half, <2 x double>, float, <3 x half>, <3 x half> }>
+%struct.C = type <{ %struct.A, [1 x float], [2 x %struct.B], half }>
+%struct.A = type <{ float, double, float, half, i16, i64, i32 }>
+
+@D.cb. = external local_unnamed_addr constant { i32, %struct.B, half, %struct.C, double }
+
+!hlsl.cbufs = !{!0}
+!0 = !{ptr @D.cb., !"D.cb.ty", i32 13, i32 1, i32 0}
Index: llvm/test/CodeGen/DirectX/legacy_cb_layout_2.ll
===
--- /dev/null
+++ llvm/test/CodeGen/DirectX/legacy_cb_layout_2.ll
@@ -0,0 +1,51 @@
+; RUN: opt -S -dxil-metadata-emit < %s | FileCheck %s --check-prefix=DXILMD
+
+target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
+target triple = "dxil-unknown-shadermodel6.7-library"
+
+; cbuffer B
+; {
+;
+;   struct B
+;   {
+;
+;   double B0[2]; ; Offset:0
+;   float3 B1[3];

[PATCH] D140794: [ASTMatcher] Add coroutineBodyStmt matcher

2022-12-30 Thread Chris Cotter via Phabricator via cfe-commits
ccotter updated this revision to Diff 485748.
ccotter added a comment.

- Add hasBody matcher support for coroutineBodyStmt


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140794

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

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -678,6 +678,52 @@
   EXPECT_TRUE(matchesConditionally(CoYieldCode, 
coyieldExpr(isExpansionInMainFile()), 
true, {"-std=c++20", "-I/"}, M));
+
+  StringRef NonCoroCode = R"cpp(
+#include 
+void non_coro_function() {
+}
+)cpp";
+
+  EXPECT_TRUE(matchesConditionally(CoReturnCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoAwaitCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+  EXPECT_TRUE(matchesConditionally(CoYieldCode, 
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+
+  EXPECT_FALSE(matchesConditionally(NonCoroCode,
+   coroutineBodyStmt(),
+   true, {"-std=c++20", "-I/"}, M));
+
+  StringRef CoroWithDeclCode = R"cpp(
+#include 
+void coro() {
+  int thevar;
+  co_return 1;
+}
+)cpp";
+  EXPECT_TRUE(matchesConditionally(
+  CoroWithDeclCode,
+  coroutineBodyStmt(hasBody(compoundStmt(
+  has(declStmt(containsDeclaration(0, varDecl(hasName("thevar",
+  true, {"-std=c++20", "-I/"}, M));
+
+  StringRef CoroWithTryCatchDeclCode = R"cpp(
+#include 
+void coro() try {
+  int thevar;
+  co_return 1;
+} catch (...) {}
+)cpp";
+  EXPECT_TRUE(matchesConditionally(
+  CoroWithTryCatchDeclCode,
+  coroutineBodyStmt(hasBody(cxxTryStmt(has(compoundStmt(
+  has(declStmt(containsDeclaration(0, varDecl(hasName("thevar")),
+  true, {"-std=c++20", "-I/"}, M));
 }
 
 TEST(Matcher, isClassMessage) {
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -168,6 +168,7 @@
   REGISTER_MATCHER(complexType);
   REGISTER_MATCHER(compoundLiteralExpr);
   REGISTER_MATCHER(compoundStmt);
+  REGISTER_MATCHER(coroutineBodyStmt);
   REGISTER_MATCHER(coawaitExpr);
   REGISTER_MATCHER(conditionalOperator);
   REGISTER_MATCHER(constantArrayType);
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -909,6 +909,7 @@
 const internal::VariadicDynCastAllOfMatcher caseStmt;
 const internal::VariadicDynCastAllOfMatcher defaultStmt;
 const internal::VariadicDynCastAllOfMatcher compoundStmt;
+const internal::VariadicDynCastAllOfMatcher coroutineBodyStmt;
 const internal::VariadicDynCastAllOfMatcher cxxCatchStmt;
 const internal::VariadicDynCastAllOfMatcher cxxTryStmt;
 const internal::VariadicDynCastAllOfMatcher cxxThrowExpr;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2449,6 +2449,17 @@
 extern const internal::VariadicDynCastAllOfMatcher
 coyieldExpr;
 
+/// Matches coroutine body statements.
+///
+/// coroutineBodyStmt() matches the coroutine below
+/// \code
+///   generator gen() {
+/// co_return;
+///   }
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher
+coroutineBodyStmt;
+
 /// Matches nullptr literal.
 extern const internal::VariadicDynCastAllOfMatcher
 cxxNullPtrLiteralExpr;
@@ -5488,7 +5499,8 @@
   AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt,
   WhileStmt,
   CXXForRangeStmt,
-  FunctionDecl),
+  FunctionDecl,
+  CoroutineBodyStmt),
   internal::Matcher, InnerMatcher) {
   if (Finder->isTraversalIgnoringImplicitNodes() && isDefaultedHelper(&Node))
 return f