[PATCH] D116351: Update Bug report URL to Github Issues

2021-12-30 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu marked an inline comment as done.
ChuanqiXu added inline comments.



Comment at: llvm/docs/CommandGuide/llvm-objcopy.rst:539
 
-To report bugs, please visit .
+To report bugs, please visit .
 

MaskRay wrote:
> https://github.com/llvm/llvm-project/labels/tools:llvm-objcopy/strip
> 
> You need to check whether other tools have dedicated labels.
Thanks for reminding me this. I have found there is a label for lldb too. But I 
don't find labels for other tools.


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

https://reviews.llvm.org/D116351

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


[PATCH] D116368: [clang][dataflow] Add transfer function for VarDecl statements

2021-12-30 Thread Stanislav Gatev via Phabricator via cfe-commits
sgatev updated this revision to Diff 396660.
sgatev marked 12 inline comments as done.
sgatev added a comment.

Address reviewers' comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116368

Files:
  clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
  clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
  clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
  clang/include/clang/Analysis/FlowSensitive/Transfer.h
  clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
  clang/include/clang/Analysis/FlowSensitive/Value.h
  clang/lib/Analysis/FlowSensitive/CMakeLists.txt
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
  clang/lib/Analysis/FlowSensitive/Transfer.cpp
  clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
  clang/unittests/Analysis/FlowSensitive/CMakeLists.txt
  clang/unittests/Analysis/FlowSensitive/NoopAnalysis.h
  clang/unittests/Analysis/FlowSensitive/TestingSupport.h
  clang/unittests/Analysis/FlowSensitive/TestingSupportTest.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
  clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
===
--- clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
@@ -6,12 +6,14 @@
 //
 //===--===//
 
+#include "NoopAnalysis.h"
 #include "TestingSupport.h"
 #include "clang/AST/Decl.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/DataflowLattice.h"
 #include "clang/Tooling/Tooling.h"
@@ -28,6 +30,8 @@
 #include 
 #include 
 
+namespace {
+
 using namespace clang;
 using namespace dataflow;
 using ::testing::IsEmpty;
@@ -50,7 +54,8 @@
 ControlFlowContext::build(nullptr, Body, Result.Context));
 
 AnalysisT Analysis(*Result.Context);
-Environment Env;
+DataflowAnalysisContext DACtx;
+Environment Env(DACtx);
 BlockStates = runDataflowAnalysis(CFCtx, Analysis, Env);
   }
 
@@ -75,27 +80,6 @@
   return Callback.BlockStates;
 }
 
-class NoopLattice {
-public:
-  bool operator==(const NoopLattice &) const { return true; }
-
-  LatticeJoinEffect join(const NoopLattice &) {
-return LatticeJoinEffect::Unchanged;
-  }
-};
-
-class NoopAnalysis : public DataflowAnalysis {
-public:
-  NoopAnalysis(ASTContext &Context)
-  : DataflowAnalysis(Context) {}
-
-  static NoopLattice initialElement() { return {}; }
-
-  NoopLattice transfer(const Stmt *S, const NoopLattice &E, Environment &Env) {
-return {};
-  }
-};
-
 TEST(DataflowAnalysisTest, NoopAnalysis) {
   auto BlockStates = runAnalysis(R"(
 void target() {}
@@ -314,3 +298,5 @@
   UnorderedElementsAre("baz", "foo"));
   // FIXME: Called functions at point `p` should contain only "foo".
 }
+
+} // namespace
Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===
--- /dev/null
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -0,0 +1,540 @@
+//===- unittests/Analysis/FlowSensitive/TransferTest.cpp --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "NoopAnalysis.h"
+#include "TestingSupport.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+#include "clang/Analysis/FlowSensitive/Value.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+#include 
+
+namespace {
+
+using namespace clang;
+using namespace dataflow;
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::IsNull;
+using ::testing::NotNull;
+using ::testing::Pair;
+
+class TransferTest : public ::testing::Test {
+protected:
+  template 
+  void runDataflow(llvm::StringRef Code, Matcher Match) {
+test::checkDataflow(
+Code, "target",
+[](

[PATCH] D116368: [clang][dataflow] Add transfer function for VarDecl statements

2021-12-30 Thread Stanislav Gatev via Phabricator via cfe-commits
sgatev added inline comments.



Comment at: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h:61
+  ///  `D` must not be assigned a storage location.
+  void setStorageLocation(const VarDecl &D, StorageLocation &Loc) {
+assert(VarDeclToLoc.find(&D) == VarDeclToLoc.end());

xazax.hun wrote:
> Are other language constructs coming in a follow-up PR? (E.g.: FieldDecl, 
> locations on the heap). I'd like to some TODO comments if that is the case. 
> Or if they are not supported by design, I'd love to some some comments about 
> that.
> 
> Environment is referencing `ValueDecl` as opposed to `VarDecl`. What is the 
> reason for this asymmetry?
> I think I overall find it confusing that some of the DeclToLoc mapping is 
> here some is in the Environment.
> Does this has something to do with the fact that certain mappings should be 
> the same regardless of which basic blocks we are processing (i.e., invariant 
> globally so we do not need to duplicate it)? If that is the case please make 
> it clear in the comments. 
> Are other language constructs coming in a follow-up PR? (E.g.: FieldDecl, 
> locations on the heap). I'd like to some TODO comments if that is the case. 
> Or if they are not supported by design, I'd love to some some comments about 
> that.

Yes, more is coming in a follow-up. Nothing unsupported by design comes to mind 
at this point. I added FIXMEs to indicate the language constructs that we plan 
to implement first, but we will certainly need to add more going forward. 
Please let me know if there's something in particular that you'd like to see 
implemented early.

> Environment is referencing ValueDecl as opposed to VarDecl. What is the 
> reason for this asymmetry?

This is not intentional. I updated `DataflowAnalysisContext` to use `ValueDecl` 
as well.

> I think I overall find it confusing that some of the DeclToLoc mapping is 
> here some is in the Environment.
> Does this has something to do with the fact that certain mappings should be 
> the same regardless of which basic blocks we are processing (i.e., invariant 
> globally so we do not need to duplicate it)? If that is the case please make 
> it clear in the comments.

`DeclToLoc` in `Environment` holds the set of `ValueDecl` to `StorageLocation` 
assignments that are in scope for a particular basic block. `DeclToLoc` in 
`DataflowAnalysisContext` aggregates the assignments across all basic blocks 
and is mainly used to produce stable storage locations when the same basic 
blocks are evaluated multiple times.  I added comments in the code explaining 
this.



Comment at: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h:76
+  std::vector> Locs;
+  std::vector> Vals;
+  llvm::DenseMap VarDeclToLoc;

xazax.hun wrote:
> Just curious: would it make sense to deduplicate these values?
I think no because even if the values are equal we'd like to track them 
separately as they represent different identities which is important for 
inference. For example:

```
std::optional a = foo();
std::optional b = bar();
std::optional c = a;
// at this point we can model `a`, `b`, and `c` with the same value, however
if (a.has_value()) {
  // here we gain knowledge only about the values of `a` and `c`
  a.value(); // safe
  c.value(); // safe
  b.value(); // unsafe 
}
```

In our analysis we model the above by assigning the same value to the storage 
locations for `a` and `c` and assigning a different value to the storage 
location for `b`, even if the two values are equal.



Comment at: clang/include/clang/Analysis/FlowSensitive/Value.h:78
+
+  StorageLocation *getLocation() const { return Loc; }
+

xazax.hun wrote:
> I wonder if getLocation is ambiguous. (The pointer's own location vs the 
> pointee location.) How about something like `getPointeeLoc`?
That's much better! I also changed the `StorageLocation` pointer to a reference 
in the constructor and the getter.



Comment at: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp:32
+template 
+bool denseMapsAreEqual(const llvm::DenseMap &Map1,
+   const llvm::DenseMap &Map2) {

xazax.hun wrote:
> Shouldn't we add `operator==` instead?
I'd be happy to do that. Do we need reviews from other folks for it? Would it 
make sense to move the code to the other location in a follow-up PR, to limit 
the scope of the change?



Comment at: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp:46
+template 
+llvm::DenseMap intersectDenseMaps(const llvm::DenseMap &Map1,
+const llvm::DenseMap &Map2) {

xazax.hun wrote:
> I wonder if these algorithms should rather be somewhere in the support 
> library.
I'd be happy to do that. Do we need reviews from other folks for it? Would it 
make sense to move the code to the other location in a follow-up 

[PATCH] D113752: [Parse] Use empty RecoveryExpr when if/while/do/switch conditions fail to parse

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall marked 6 inline comments as done.
sammccall added a comment.

In D113752#3188486 , @hokein wrote:

> since we're now preserving  more invalid code, we should check whether 
> const-evaluator is cable of handling these newly-added invalid case.
>
> - the follow case will result an value-dependent violation, the fix would be 
> to handle value-dependent condition in `EvaluateSwitch` 
> (`clang/lib/AST/ExprConstant.cpp`)

Great catch, thanks!
I added constant-evaluation to ensure we don't crash for all the varieties of 
broken loops I could think of.
They're in `SemaCXX/constexpr-function-recovery-crash.cpp` which seems to be 
very similar. Maybe slightly misplaced as really we're testing AST/ExprConstant.




Comment at: clang/test/Parser/cxx0x-attributes.cpp:155
   alignas(4 ns::i; // expected-note {{to match this '('}}
+   // expected-error@-1 {{expected ';' after do/while}}
 } // expected-error 2{{expected ')'}} expected-error {{expected expression}}

hokein wrote:
> This looks like a bogus diagnostic, but I think it is ok, as this is a 
> poor-recovery case for clang already -- IIUC, the do-while statement range 
> claims to the `}` on Line56.
> 
> this is a case which can be improved by our bracket-matching repair :)
Right. My understanding is the diagnostic is bogus if you put both missing `)`s 
before the semicolon, but clang is noticing them/implicitly inserting them 
before the `}`.

The code is horribly mangled here in any case, I'm not sure what diagnostic I'd 
want as a user really.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D113752

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


[PATCH] D113752: [Parse] Use empty RecoveryExpr when if/while/do/switch conditions fail to parse

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall updated this revision to Diff 396662.
sammccall marked an inline comment as done.
sammccall added a comment.

Add constant-evaluation for broken switches, and a bunch of evaluation tests.
Address other comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D113752

Files:
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/AST/ast-dump-invalid.cpp
  clang/test/AST/loop-recovery.cpp
  clang/test/Parser/cxx0x-attributes.cpp
  clang/test/Sema/complex-int.c
  clang/test/SemaCXX/condition.cpp
  clang/test/SemaCXX/constexpr-function-recovery-crash.cpp

Index: clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
===
--- clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
+++ clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
@@ -74,3 +74,25 @@
 constexpr void test11() {
   for (X& e : array) {}
 }
+
+#define TEST_EVALUATE(Name, X) \
+  constexpr int testEvaluate##Name() { \
+X return 0;\
+  }\
+  constexpr int forceEvaluate##Name = testEvaluate##Name()
+// Check that a variety of broken loops don't crash constant evaluation.
+// We're not checking specific recovery here so don't assert diagnostics.
+TEST_EVALUATE(Switch, switch (!!){});  // expected-error + {{}}
+TEST_EVALUATE(SwitchInit, switch (auto x = !!){}); // expected-error + {{}}
+TEST_EVALUATE(For, for (!!){}); // expected-error + {{}}
+// FIXME: should bail out instead of looping.
+// expected-note@-2 + {{infinite loop}}
+// expected-note@-3 {{in call}}
+TEST_EVALUATE(ForRange, for (auto x : !!){}); // expected-error + {{}}
+TEST_EVALUATE(While, while (!!){});   // expected-error + {{}}
+TEST_EVALUATE(DoWhile, do {} while (!!););// expected-error + {{}}
+TEST_EVALUATE(If, if (!!){};);// expected-error + {{}}
+TEST_EVALUATE(IfInit, if (auto x = !!; 1){};);// expected-error + {{}}
+TEST_EVALUATE(ForInit, if (!!;;){};); // expected-error + {{}}
+TEST_EVALUATE(ForCond, if (; !!;){};);// expected-error + {{}}
+TEST_EVALUATE(ForInc, if (;; !!){};); // expected-error + {{}}
Index: clang/test/SemaCXX/condition.cpp
===
--- clang/test/SemaCXX/condition.cpp
+++ clang/test/SemaCXX/condition.cpp
@@ -20,6 +20,8 @@
   while (struct S {} *x=0) ; // expected-error {{'S' cannot be defined in a condition}}
   while (struct {} *x=0) ; // expected-error-re {{'(unnamed struct at {{.*}})' cannot be defined in a condition}}
   switch (enum {E} x=0) ; // expected-error-re {{'(unnamed enum at {{.*}})' cannot be defined in a condition}}
+  // expected-warning@-1 {{switch statement has empty body}}
+  // expected-note@-2 {{put the semicolon on a separate line}}
 
   if (int x=0) { // expected-note 2 {{previous definition is here}}
 int x;  // expected-error {{redefinition of 'x'}}
Index: clang/test/Sema/complex-int.c
===
--- clang/test/Sema/complex-int.c
+++ clang/test/Sema/complex-int.c
@@ -18,8 +18,8 @@
 result = xx*yy;
 
 switch (arr) { // expected-error{{statement requires expression of integer type ('_Complex int' invalid)}}
-  case brr: ;
-  case xx: ;
+  case brr: ; // expected-error{{integer constant expression must have integer type}}
+  case xx: ; // expected-error{{integer constant expression must have integer type}}
 }
 switch (ii) {
   case brr: ; // expected-error{{integer constant expression must have integer type}}
Index: clang/test/Parser/cxx0x-attributes.cpp
===
--- clang/test/Parser/cxx0x-attributes.cpp
+++ clang/test/Parser/cxx0x-attributes.cpp
@@ -152,6 +152,7 @@
   [[ab]ab] ns::i); // expected-error {{an attribute list cannot appear here}}
   do {} while ( // expected-note {{to match this '('}}
   alignas(4 ns::i; // expected-note {{to match this '('}}
+   // expected-error@-1 {{expected ';' after do/while}}
 } // expected-error 2{{expected ')'}} expected-error {{expected expression}}
 
 [[]] using T = int; // expected-error {{an attribute list cannot appear here}}
Index: clang/test/AST/loop-recovery.cpp
===
--- /dev/null
+++ clang/test/AST/loop-recovery.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+// RUN: not %clang_cc1 -fsyntax-only -ast-dump %s -std=c++17 | FileCheck %s
+

[PATCH] D116412: [Clang][Sema] Fix attribute mismatch warning for ObjC class properties

2021-12-30 Thread Egor Zhdan via Phabricator via cfe-commits
egorzhdan created this revision.
egorzhdan requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

If a class declares an instance property, and an inheritor class declares a 
class property with the same name, Clang Sema currently treats the latter as an 
overridden property, and compares the attributes of the two properties to check 
for a mismatch. The resulting diagnostics might be misleading, since neither of 
the properties actually overrides the another one.

rdar://86018435


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116412

Files:
  clang/lib/Sema/SemaObjCProperty.cpp
  clang/test/SemaObjC/class-property-inheritance.m

Index: clang/test/SemaObjC/class-property-inheritance.m
===
--- /dev/null
+++ clang/test/SemaObjC/class-property-inheritance.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+@class MyObject;
+
+@interface TopClassWithInstanceProperty
+@property(nullable, readonly, strong) MyObject *foo;
+@end
+
+@interface SubClassWithClassProperty : TopClassWithInstanceProperty
+@property(nonnull, readonly, copy, class) MyObject *foo;
+@end
+
+@interface TopClassWithClassProperty
+@property(nullable, readonly, class) MyObject *foo;
+@end
+
+@interface SubClassWithInstanceProperty : TopClassWithClassProperty
+@property(nonnull, readonly, copy) MyObject *foo;
+@end
Index: clang/lib/Sema/SemaObjCProperty.cpp
===
--- clang/lib/Sema/SemaObjCProperty.cpp
+++ clang/lib/Sema/SemaObjCProperty.cpp
@@ -225,43 +225,56 @@
   if (Res->getType().getObjCLifetime())
 checkPropertyDeclWithOwnership(*this, Res);
 
-  llvm::SmallPtrSet KnownProtos;
-  if (ObjCInterfaceDecl *IFace = dyn_cast(ClassDecl)) {
-// For a class, compare the property against a property in our superclass.
-bool FoundInSuper = false;
-ObjCInterfaceDecl *CurrentInterfaceDecl = IFace;
-while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) {
-  if (ObjCPropertyDecl *SuperProp =
-  Super->lookup(Res->getDeclName()).find_first()) {
-DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false);
-FoundInSuper = true;
-break;
+  // For an instance property, check consistency with the properties of
+  // superclasses.
+  if (Res->isInstanceProperty()) {
+llvm::SmallPtrSet KnownProtos;
+if (ObjCInterfaceDecl *IFace = dyn_cast(ClassDecl)) {
+  // For a class, compare the property against a property in our superclass.
+  bool FoundInSuper = false;
+  ObjCInterfaceDecl *CurrentInterfaceDecl = IFace;
+  while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) {
+ObjCPropertyDecl *SuperProp = nullptr;
+for (auto *LookupResult : Super->lookup(Res->getDeclName())) {
+  if (auto *Prop = dyn_cast(LookupResult)) {
+if (Prop->isInstanceProperty()) {
+  SuperProp = Prop;
+  break;
+}
+  }
+}
+if (SuperProp) {
+  DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(),
+   false);
+  FoundInSuper = true;
+  break;
+}
+CurrentInterfaceDecl = Super;
   }
-  CurrentInterfaceDecl = Super;
-}
 
-if (FoundInSuper) {
-  // Also compare the property against a property in our protocols.
-  for (auto *P : CurrentInterfaceDecl->protocols()) {
-CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
+  if (FoundInSuper) {
+// Also compare the property against a property in our protocols.
+for (auto *P : CurrentInterfaceDecl->protocols()) {
+  CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
+}
+  } else {
+// Slower path: look in all protocols we referenced.
+for (auto *P : IFace->all_referenced_protocols()) {
+  CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
+}
   }
+} else if (ObjCCategoryDecl *Cat = dyn_cast(ClassDecl)) {
+  // We don't check if class extension. Because properties in class
+  // extension are meant to override some of the attributes and checking has
+  // already done when property in class extension is constructed.
+  if (!Cat->IsClassExtension())
+for (auto *P : Cat->protocols())
+  CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
 } else {
-  // Slower path: look in all protocols we referenced.
-  for (auto *P : IFace->all_referenced_protocols()) {
+  ObjCProtocolDecl *Proto = cast(ClassDecl);
+  for (auto *P : Proto->protocols())
 CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
-  }
 }
-  } else if (ObjCCategoryDecl *Cat = dyn_cast(ClassDecl)) {
-// We don't check if class extension. Because prop

[PATCH] D115604: [Support] Expand `` as the base directory in configuration files.

2021-12-30 Thread Jack Andersen via Phabricator via cfe-commits
jackoalan updated this revision to Diff 396667.
jackoalan marked 5 inline comments as done.
jackoalan added a comment.

Update ReadConfigFile test with additional `` expansion contexts 
(non-prefixed, non-suffixed, escaped in middle).


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

https://reviews.llvm.org/D115604

Files:
  clang/docs/ReleaseNotes.rst
  clang/docs/UsersManual.rst
  clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
  llvm/include/llvm/Support/CommandLine.h
  llvm/lib/Support/CommandLine.cpp
  llvm/unittests/Support/CommandLineTest.cpp

Index: llvm/unittests/Support/CommandLineTest.cpp
===
--- llvm/unittests/Support/CommandLineTest.cpp
+++ llvm/unittests/Support/CommandLineTest.cpp
@@ -827,7 +827,7 @@
   llvm::BumpPtrAllocator A;
   llvm::StringSaver Saver(A);
   ASSERT_TRUE(llvm::cl::ExpandResponseFiles(
-  Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true,
+  Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true, false,
   /*CurrentDir=*/StringRef(TestRoot), FS));
   EXPECT_THAT(Argv, testing::Pointwise(
 StringEquality(),
@@ -889,9 +889,9 @@
 #else
   cl::TokenizerCallback Tokenizer = cl::TokenizeGNUCommandLine;
 #endif
-  ASSERT_FALSE(cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false,
-   /*CurrentDir=*/llvm::StringRef(TestRoot),
-   FS));
+  ASSERT_FALSE(
+  cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, false,
+  /*CurrentDir=*/llvm::StringRef(TestRoot), FS));
 
   EXPECT_THAT(Argv,
   testing::Pointwise(StringEquality(),
@@ -929,7 +929,7 @@
   BumpPtrAllocator A;
   StringSaver Saver(A);
   ASSERT_FALSE(cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv,
-   false, false,
+   false, false, false,
/*CurrentDir=*/StringRef(TestRoot), FS));
 
   // ASSERT instead of EXPECT to prevent potential out-of-bounds access.
@@ -964,7 +964,7 @@
   BumpPtrAllocator A;
   StringSaver Saver(A);
   ASSERT_TRUE(cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv,
-  false, true,
+  false, true, false,
   /*CurrentDir=*/StringRef(TestRoot), FS));
   EXPECT_THAT(Argv,
   testing::Pointwise(StringEquality(), {"test/test", "-flag"}));
@@ -984,7 +984,7 @@
   BumpPtrAllocator A;
   StringSaver Saver(A);
   ASSERT_TRUE(cl::ExpandResponseFiles(Saver, cl::TokenizeWindowsCommandLine,
-  Argv, true, true,
+  Argv, true, true, false,
   /*CurrentDir=*/StringRef(TestRoot), FS));
   const char *Expected[] = {"clang", "-Xclang", "-Wno-whatever", nullptr,
 "input.cpp"};
@@ -1038,25 +1038,38 @@
   llvm::SmallVector Argv;
 
   TempDir TestDir("unittest", /*Unique*/ true);
+  TempDir TestSubDir(TestDir.path("subdir"), /*Unique*/ false);
 
-  llvm::SmallString<128> TestCfg;
-  llvm::sys::path::append(TestCfg, TestDir.path(), "foo");
-
+  llvm::SmallString<128> TestCfg = TestDir.path("foo");
   TempFile ConfigFile(TestCfg, "",
   "# Comment\n"
   "-option_1\n"
+  "-option_2=/dir1\n"
+  "-option_3=\n"
+  "-option_4 \n"
+  "-option_5=\n"
   "@subconfig\n"
-  "-option_3=abcd\n"
-  "-option_4=\\\n"
+  "-option_10=abcd\n"
+  "-option_11=\\\n"
   "cdef\n");
 
-  llvm::SmallString<128> TestCfg2;
-  llvm::sys::path::append(TestCfg2, TestDir.path(), "subconfig");
+  llvm::SmallString<128> TestCfg2 = TestDir.path("subconfig");
   TempFile ConfigFile2(TestCfg2, "",
-   "-option_2\n"
+   "-option_6\n"
+   "-option_7=/dir2\n"
+   "@subdir/subfoo\n"
"\n"
"   # comment\n");
 
+  llvm::SmallString<128> TestCfg3 = TestSubDir.path("subfoo");
+  TempFile ConfigFile3(TestCfg3, "",
+   "-option_8=/dir3\n"
+   "@/subfoo2\n");
+
+  llvm::SmallString<128> TestCfg4 = TestSubDir.path("subfoo2");
+  TempFile ConfigFile4(TestCfg4, "", "-option_9\n");
+
   // Make sure the current directory is not the directory where config files
   // resides. In this case the code that expands response files will not find
   // 'subconfig' unless it resolves nested inclusions relative to the including
@@ -1071,11 +1084,22 @@
   bool Result = llvm::cl::readConfigFile(ConfigFile.path(), Saver, Argv);

[PATCH] D116368: [clang][dataflow] Add transfer function for VarDecl statements

2021-12-30 Thread Stanislav Gatev via Phabricator via cfe-commits
sgatev updated this revision to Diff 396668.
sgatev added a comment.

Canonicalize types.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116368

Files:
  clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
  clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
  clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
  clang/include/clang/Analysis/FlowSensitive/Transfer.h
  clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
  clang/include/clang/Analysis/FlowSensitive/Value.h
  clang/lib/Analysis/FlowSensitive/CMakeLists.txt
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
  clang/lib/Analysis/FlowSensitive/Transfer.cpp
  clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
  clang/unittests/Analysis/FlowSensitive/CMakeLists.txt
  clang/unittests/Analysis/FlowSensitive/NoopAnalysis.h
  clang/unittests/Analysis/FlowSensitive/TestingSupport.h
  clang/unittests/Analysis/FlowSensitive/TestingSupportTest.cpp
  clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
  clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
===
--- clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
@@ -6,12 +6,14 @@
 //
 //===--===//
 
+#include "NoopAnalysis.h"
 #include "TestingSupport.h"
 #include "clang/AST/Decl.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/DataflowLattice.h"
 #include "clang/Tooling/Tooling.h"
@@ -28,6 +30,8 @@
 #include 
 #include 
 
+namespace {
+
 using namespace clang;
 using namespace dataflow;
 using ::testing::IsEmpty;
@@ -50,7 +54,8 @@
 ControlFlowContext::build(nullptr, Body, Result.Context));
 
 AnalysisT Analysis(*Result.Context);
-Environment Env;
+DataflowAnalysisContext DACtx;
+Environment Env(DACtx);
 BlockStates = runDataflowAnalysis(CFCtx, Analysis, Env);
   }
 
@@ -75,27 +80,6 @@
   return Callback.BlockStates;
 }
 
-class NoopLattice {
-public:
-  bool operator==(const NoopLattice &) const { return true; }
-
-  LatticeJoinEffect join(const NoopLattice &) {
-return LatticeJoinEffect::Unchanged;
-  }
-};
-
-class NoopAnalysis : public DataflowAnalysis {
-public:
-  NoopAnalysis(ASTContext &Context)
-  : DataflowAnalysis(Context) {}
-
-  static NoopLattice initialElement() { return {}; }
-
-  NoopLattice transfer(const Stmt *S, const NoopLattice &E, Environment &Env) {
-return {};
-  }
-};
-
 TEST(DataflowAnalysisTest, NoopAnalysis) {
   auto BlockStates = runAnalysis(R"(
 void target() {}
@@ -314,3 +298,5 @@
   UnorderedElementsAre("baz", "foo"));
   // FIXME: Called functions at point `p` should contain only "foo".
 }
+
+} // namespace
Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===
--- /dev/null
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -0,0 +1,540 @@
+//===- unittests/Analysis/FlowSensitive/TransferTest.cpp --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "NoopAnalysis.h"
+#include "TestingSupport.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+#include "clang/Analysis/FlowSensitive/Value.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+#include 
+
+namespace {
+
+using namespace clang;
+using namespace dataflow;
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::IsNull;
+using ::testing::NotNull;
+using ::testing::Pair;
+
+class TransferTest : public ::testing::Test {
+protected:
+  template 
+  void runDataflow(llvm::StringRef Code, Matcher Match) {
+test::checkDataflow(
+Code, "target",
+[](ASTContext &C, Environment &) { return NoopAnalysis

[PATCH] D115604: [Support] Expand `` as the base directory in configuration files.

2021-12-30 Thread Jack Andersen via Phabricator via cfe-commits
jackoalan marked an inline comment as done.
jackoalan added inline comments.



Comment at: llvm/lib/Support/CommandLine.cpp:1099
+else
+  llvm::sys::path::append(ResponseFile, LHS);
+ResponseFile.append(BasePath);

sepavloff wrote:
> What happens if `` is used without trailing path? Such line:
> ```
> --sysroot= -abc
> ```
>  would be processed correctly?
Yes, `if (!Remaining.empty())` handles this case. I've added more test coverage 
for varying expansion contexts.


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

https://reviews.llvm.org/D115604

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


[PATCH] D115604: [Support] Expand `` as the base directory in configuration files.

2021-12-30 Thread Jack Andersen via Phabricator via cfe-commits
jackoalan updated this revision to Diff 396670.
jackoalan added a comment.

Add ReadConfigFile test case for multiple `` in one arg.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115604

Files:
  clang/docs/ReleaseNotes.rst
  clang/docs/UsersManual.rst
  clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
  llvm/include/llvm/Support/CommandLine.h
  llvm/lib/Support/CommandLine.cpp
  llvm/unittests/Support/CommandLineTest.cpp

Index: llvm/unittests/Support/CommandLineTest.cpp
===
--- llvm/unittests/Support/CommandLineTest.cpp
+++ llvm/unittests/Support/CommandLineTest.cpp
@@ -827,7 +827,7 @@
   llvm::BumpPtrAllocator A;
   llvm::StringSaver Saver(A);
   ASSERT_TRUE(llvm::cl::ExpandResponseFiles(
-  Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true,
+  Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true, false,
   /*CurrentDir=*/StringRef(TestRoot), FS));
   EXPECT_THAT(Argv, testing::Pointwise(
 StringEquality(),
@@ -889,9 +889,9 @@
 #else
   cl::TokenizerCallback Tokenizer = cl::TokenizeGNUCommandLine;
 #endif
-  ASSERT_FALSE(cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false,
-   /*CurrentDir=*/llvm::StringRef(TestRoot),
-   FS));
+  ASSERT_FALSE(
+  cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, false,
+  /*CurrentDir=*/llvm::StringRef(TestRoot), FS));
 
   EXPECT_THAT(Argv,
   testing::Pointwise(StringEquality(),
@@ -929,7 +929,7 @@
   BumpPtrAllocator A;
   StringSaver Saver(A);
   ASSERT_FALSE(cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv,
-   false, false,
+   false, false, false,
/*CurrentDir=*/StringRef(TestRoot), FS));
 
   // ASSERT instead of EXPECT to prevent potential out-of-bounds access.
@@ -964,7 +964,7 @@
   BumpPtrAllocator A;
   StringSaver Saver(A);
   ASSERT_TRUE(cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv,
-  false, true,
+  false, true, false,
   /*CurrentDir=*/StringRef(TestRoot), FS));
   EXPECT_THAT(Argv,
   testing::Pointwise(StringEquality(), {"test/test", "-flag"}));
@@ -984,7 +984,7 @@
   BumpPtrAllocator A;
   StringSaver Saver(A);
   ASSERT_TRUE(cl::ExpandResponseFiles(Saver, cl::TokenizeWindowsCommandLine,
-  Argv, true, true,
+  Argv, true, true, false,
   /*CurrentDir=*/StringRef(TestRoot), FS));
   const char *Expected[] = {"clang", "-Xclang", "-Wno-whatever", nullptr,
 "input.cpp"};
@@ -1038,25 +1038,39 @@
   llvm::SmallVector Argv;
 
   TempDir TestDir("unittest", /*Unique*/ true);
+  TempDir TestSubDir(TestDir.path("subdir"), /*Unique*/ false);
 
-  llvm::SmallString<128> TestCfg;
-  llvm::sys::path::append(TestCfg, TestDir.path(), "foo");
-
+  llvm::SmallString<128> TestCfg = TestDir.path("foo");
   TempFile ConfigFile(TestCfg, "",
   "# Comment\n"
   "-option_1\n"
+  "-option_2=/dir1\n"
+  "-option_3=\n"
+  "-option_4 \n"
+  "-option_5=\n"
+  "-option_6=/dir1,/dir2\n"
   "@subconfig\n"
-  "-option_3=abcd\n"
-  "-option_4=\\\n"
+  "-option_11=abcd\n"
+  "-option_12=\\\n"
   "cdef\n");
 
-  llvm::SmallString<128> TestCfg2;
-  llvm::sys::path::append(TestCfg2, TestDir.path(), "subconfig");
+  llvm::SmallString<128> TestCfg2 = TestDir.path("subconfig");
   TempFile ConfigFile2(TestCfg2, "",
-   "-option_2\n"
+   "-option_7\n"
+   "-option_8=/dir2\n"
+   "@subdir/subfoo\n"
"\n"
"   # comment\n");
 
+  llvm::SmallString<128> TestCfg3 = TestSubDir.path("subfoo");
+  TempFile ConfigFile3(TestCfg3, "",
+   "-option_9=/dir3\n"
+   "@/subfoo2\n");
+
+  llvm::SmallString<128> TestCfg4 = TestSubDir.path("subfoo2");
+  TempFile ConfigFile4(TestCfg4, "", "-option_10\n");
+
   // Make sure the current directory is not the directory where config files
   // resides. In this case the code that expands response files will not find
   // 'subconfig' unless it resolves nested inclusions relative to the including
@@ -1071,11 +1085,26 @@
   bool Result = llvm::cl::readConfigFile(ConfigFile.path(), Saver, Argv);
 
   EXPECT_

[PATCH] D115501: [clang][ARM] Emit warnings when PACBTI-M is used with unsupported architectures

2021-12-30 Thread Amilendra Kodithuwakku via Phabricator via cfe-commits
amilendra updated this revision to Diff 396671.
amilendra added a comment.

Address review comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115501

Files:
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/Basic/Targets/AArch64.cpp
  clang/lib/Basic/Targets/AArch64.h
  clang/lib/Basic/Targets/ARM.cpp
  clang/lib/Basic/Targets/ARM.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/arm-branch-protection-attr-2.c
  clang/test/CodeGen/arm_acle.c
  clang/test/Driver/arm-security-options.c
  clang/test/Frontend/arm-branch-protection-default-arch.c
  clang/test/Frontend/arm-ignore-branch-protection-option.c
  clang/test/Frontend/arm-invalid-branch-protection.c
  clang/test/Sema/arm-branch-protection-attr-warn.c
  clang/test/Sema/arm-branch-protection.c

Index: clang/test/Sema/arm-branch-protection.c
===
--- /dev/null
+++ clang/test/Sema/arm-branch-protection.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple thumbv6m -verify -fsyntax-only %s
+
+// expected-no-diagnostics
+// Armv8.1-M.Main
+__attribute__((target("arch=cortex-m55,branch-protection=bti"))) void f1() {}
+__attribute__((target("arch=cortex-m55,branch-protection=pac-ret"))) void f2() {}
+__attribute__((target("arch=cortex-m55,branch-protection=bti+pac-ret"))) void f3() {}
+__attribute__((target("arch=cortex-m55,branch-protection=bti+pac-ret+leaf"))) void f4() {}
+// Armv8-M.Main
+__attribute__((target("arch=cortex-m33,branch-protection=bti"))) void f5() {}
+__attribute__((target("arch=cortex-m33,branch-protection=pac-ret"))) void f6() {}
+__attribute__((target("arch=cortex-m33,branch-protection=bti+pac-ret"))) void f7() {}
+__attribute__((target("arch=cortex-m33,branch-protection=bti+pac-ret+leaf"))) void f8() {}
+// Armv7-M
+__attribute__((target("arch=cortex-m3,branch-protection=bti"))) void f9() {}
+__attribute__((target("arch=cortex-m3,branch-protection=pac-ret"))) void f10() {}
+__attribute__((target("arch=cortex-m3,branch-protection=bti+pac-ret"))) void f11() {}
+__attribute__((target("arch=cortex-m3,branch-protection=bti+pac-ret+leaf"))) void f12() {}
+// Armv7E-M
+__attribute__((target("arch=cortex-m4,branch-protection=bti"))) void f13() {}
+__attribute__((target("arch=cortex-m4,branch-protection=pac-ret"))) void f14() {}
+__attribute__((target("arch=cortex-m4,branch-protection=bti+pac-ret"))) void f15() {}
+__attribute__((target("arch=cortex-m4,branch-protection=bti+pac-ret+leaf"))) void f16() {}
Index: clang/test/Sema/arm-branch-protection-attr-warn.c
===
--- /dev/null
+++ clang/test/Sema/arm-branch-protection-attr-warn.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple thumbv6m -verify -fsyntax-only %s
+
+// expected-warning@+1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
+__attribute__((target("arch=cortex-m0,branch-protection=bti"))) void f1() {}
+
+// expected-warning@+1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
+__attribute__((target("arch=cortex-m0,branch-protection=pac-ret"))) void f2() {}
+
+// expected-warning@+1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
+__attribute__((target("arch=cortex-m0,branch-protection=bti+pac-ret"))) void f3() {}
+
+// expected-warning@+1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
+__attribute__((target("arch=cortex-m0,branch-protection=bti+pac-ret+leaf"))) void f4() {}
Index: clang/test/Frontend/arm-invalid-branch-protection.c
===
--- clang/test/Frontend/arm-invalid-branch-protection.c
+++ clang/test/Frontend/arm-invalid-branch-protection.c
@@ -1,7 +1,7 @@
 // REQUIRES: arm-registered-target
-// RUN: %clang -target arm-arm-none-eabi -mbranch-protection=pac-ret+b-key -c %s -o /dev/null 2>&1 | FileCheck %s
-// RUN: %clang -target arm-arm-none-eabi -mbranch-protection=pac-ret+b-key+leaf -c %s -o /dev/null 2>&1 | FileCheck %s
-// RUN: %clang -target arm-arm-none-eabi -mbranch-protection=bti+pac-ret+b-key -c %s -o /dev/null 2>&1 | FileCheck %s
-// RUN: %clang -target arm-arm-none-eabi -mbranch-protection=bti+pac-ret+b-key+leaf -c %s -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -mbranch-protection=pac-ret+b-key -c %s -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -mbranch-protection=pac-ret+b-key+leaf -c %s -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -mbranch-protection=bti+pac-ret+b-key -c %s -o /dev/nu

[PATCH] D49482: Haiku: add a test for haiku driver

2021-12-30 Thread Alexander von Gluck IV via Phabricator via cfe-commits
kallisti5 updated this revision to Diff 396674.
kallisti5 added a comment.
Herald added subscribers: luke957, s.egerton, simoncook.
Herald added a project: clang.

I've reworked these tests to be a lot more in-depth.   Both c and c++ are 
passing.  I plan on trying to get more of our clang / llvm patches upstream.. 
so this is the first step.

  ./bin/llvm-lit -asvv ../clang/test/Driver/haiku.c
  llvm-lit: 
/home/kallisti5/Code/llvm-project/llvm/utils/lit/lit/llvm/config.py:436: note: 
using clang: /home/kallisti5/Code/llvm-project/build/bin/clang
  PASS: Clang :: Driver/haiku.c (1 of 1)
  Script:
  --
  : 'RUN: at line 1';   /home/kallisti5/Code/llvm-project/build/bin/clang 
-no-canonical-prefixes -target x86_64-unknown-haiku  
--sysroot=/home/kallisti5/Code/llvm-project/clang/test/Driver/Inputs/basic_haiku_tree
 /home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.c -### 2>&1  | 
/home/kallisti5/Code/llvm-project/build/bin/FileCheck 
--check-prefixes=CHECK,CHECK-X86_64 
/home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.c
  : 'RUN: at line 4';   /home/kallisti5/Code/llvm-project/build/bin/clang 
-no-canonical-prefixes -target i586-pc-haiku  
--sysroot=/home/kallisti5/Code/llvm-project/clang/test/Driver/Inputs/basic_haiku_tree
 /home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.c -### 2>&1  | 
/home/kallisti5/Code/llvm-project/build/bin/FileCheck 
--check-prefixes=CHECK,CHECK-X86 
/home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.c
  : 'RUN: at line 7';   /home/kallisti5/Code/llvm-project/build/bin/clang 
-no-canonical-prefixes -target riscv64-unknown-haiku  
--sysroot=/home/kallisti5/Code/llvm-project/clang/test/Driver/Inputs/basic_haiku_tree
 /home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.c -### 2>&1  | 
/home/kallisti5/Code/llvm-project/build/bin/FileCheck 
--check-prefixes=CHECK,CHECK-RV64 
/home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.c
  --
  Exit Code: 0
  
  
  
  
  Testing Time: 0.07s
Passed: 1



  ./bin/llvm-lit -asvv ../clang/test/Driver/haiku.cpp
  llvm-lit: 
/home/kallisti5/Code/llvm-project/llvm/utils/lit/lit/llvm/config.py:436: note: 
using clang: /home/kallisti5/Code/llvm-project/build/bin/clang
  PASS: Clang :: Driver/haiku.cpp (1 of 1)
  Script:
  --
  : 'RUN: at line 1';   /home/kallisti5/Code/llvm-project/build/bin/clang 
--driver-mode=g++ -no-canonical-prefixes -target i586-pc-haiku  
--sysroot=/home/kallisti5/Code/llvm-project/clang/test/Driver/Inputs/basic_haiku_tree
 /home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.cpp -### 
-stdlib=platform 2>&1  | /home/kallisti5/Code/llvm-project/build/bin/FileCheck 
--check-prefixes=CHECK,CHECK-X86 
/home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.cpp
  : 'RUN: at line 4';   /home/kallisti5/Code/llvm-project/build/bin/clang 
--driver-mode=g++ -no-canonical-prefixes -target x86_64-unknown-haiku  
--sysroot=/home/kallisti5/Code/llvm-project/clang/test/Driver/Inputs/basic_haiku_tree
 /home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.cpp -### 
-stdlib=platform 2>&1  | /home/kallisti5/Code/llvm-project/build/bin/FileCheck 
--check-prefixes=CHECK,CHECK-X86_64 
/home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.cpp
  : 'RUN: at line 7';   /home/kallisti5/Code/llvm-project/build/bin/clang 
--driver-mode=g++ -no-canonical-prefixes -target riscv64-unknown-haiku  
--sysroot=/home/kallisti5/Code/llvm-project/clang/test/Driver/Inputs/basic_haiku_tree
 /home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.cpp -### 
-stdlib=platform 2>&1  | /home/kallisti5/Code/llvm-project/build/bin/FileCheck 
--check-prefixes=CHECK,CHECK-RV64 
/home/kallisti5/Code/llvm-project/clang/test/Driver/haiku.cpp
  --
  Exit Code: 0
  
  
  
  
  Testing Time: 0.06s
Passed: 1


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D49482

Files:
  clang/test/Driver/Inputs/basic_haiku_tree/boot/system/develop/headers/.keep
  clang/test/Driver/Inputs/basic_haiku_tree/boot/system/develop/lib/crti.o
  clang/test/Driver/Inputs/basic_haiku_tree/boot/system/develop/lib/crtn.o
  clang/test/Driver/Inputs/basic_haiku_tree/boot/system/lib/.keep
  clang/test/Driver/haiku.c
  clang/test/Driver/haiku.cpp


Index: clang/test/Driver/haiku.cpp
===
--- /dev/null
+++ clang/test/Driver/haiku.cpp
@@ -0,0 +1,19 @@
+// RUN: %clangxx -no-canonical-prefixes -target i586-pc-haiku \
+// RUN: --sysroot=%S/Inputs/basic_haiku_tree %s -### -stdlib=platform 2>&1 \
+// RUN: | FileCheck --check-prefixes=CHECK,CHECK-X86 %s
+// RUN: %clangxx -no-canonical-prefixes -target x86_64-unknown-haiku \
+// RUN: --sysroot=%S/Inputs/basic_haiku_tree %s -### -stdlib=platform 2>&1 \
+// RUN: | FileCheck --check-prefixes=CHECK,CHECK-X86_64 %s
+// RUN: %clangxx -no-canonical-prefixes -target riscv64-unknown-haiku \
+// RUN: --sysroot=%S/Inputs/basic_haiku_tree

[PATCH] D115604: [Support] Expand `` as the base directory in configuration files.

2021-12-30 Thread Jack Andersen via Phabricator via cfe-commits
jackoalan added a comment.

Actually, I just thought of a possible limitation of using path-append when 
suffixing with something that isn't actually a path component. However, I 
cannot say how critical this limitation is.

  -Wl,-rpath,,foo.o

This will cause a trailing `/` to be inserted after ``. However, since 
`` is guaranteed to be a directory, a trailing slash should not be 
harmful in most cases.

The primary motivation of using path-append is to tidy cases that would 
otherwise expand as `dir//file`. Although most practical filesystems handle 
paths with empty components gracefully, `vfs::InMemoryFileSystem` does not.

Weighing these two issues, I still think it is worth using path-append.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115604

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


[PATCH] D49482: Haiku: add a test for haiku driver

2021-12-30 Thread Alexander von Gluck IV via Phabricator via cfe-commits
kallisti5 added a comment.

I should mention that there are no crt checks since the Haiku toolchain driver 
doesn't actually look for our crt's yet.

https://github.com/llvm/llvm-project/blob/main/clang/lib/Driver/ToolChains/Haiku.cpp
vs
https://github.com/llvm/llvm-project/blob/main/clang/lib/Driver/ToolChains/NetBSD.cpp#L239

With the change above though (adding basic_haiku_tree)  i'm preparing for that 
in a future commit after our port is better up-streamed.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D49482

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


[PATCH] D116385: [clangd] Code action for creating an ObjC initializer

2021-12-30 Thread David Goldman via Phabricator via cfe-commits
dgoldman updated this revision to Diff 396676.
dgoldman added a comment.

Minor change to how we get the loc of `@end`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116385

Files:
  clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt
  clang-tools-extra/clangd/refactor/tweaks/ObjCMemberwiseInitializer.cpp
  clang-tools-extra/clangd/unittests/CMakeLists.txt
  clang-tools-extra/clangd/unittests/tweaks/ObjCMemberwiseInitializerTests.cpp

Index: clang-tools-extra/clangd/unittests/tweaks/ObjCMemberwiseInitializerTests.cpp
===
--- /dev/null
+++ clang-tools-extra/clangd/unittests/tweaks/ObjCMemberwiseInitializerTests.cpp
@@ -0,0 +1,150 @@
+//===-- ObjCMemberwiseInitializerTests.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(ObjCMemberwiseInitializer);
+
+TEST_F(ObjCMemberwiseInitializerTest, TestAvailability) {
+  FileName = "TestTU.m";
+
+  // Ensure the action can't be triggered since arc is disabled.
+  EXPECT_UNAVAILABLE(R"cpp(
+@interface Fo^o
+@end
+  )cpp");
+
+  ExtraArgs.push_back("-fobjc-arc");
+
+  // Ensure the action can be initiated on the interface and implementation.
+  EXPECT_AVAILABLE(R"cpp(
+@interface Fo^o
+@end
+  )cpp");
+  EXPECT_AVAILABLE(R"cpp(
+@interface Foo
+@end
+
+@implementation F^oo
+@end
+  )cpp");
+
+  // Ensure that the action can be triggered on ivars and properties,
+  // including selecting both.
+  EXPECT_AVAILABLE(R"cpp(
+@interface Foo {
+  id _fi^eld;
+}
+@end
+  )cpp");
+  EXPECT_AVAILABLE(R"cpp(
+@interface Foo
+@property(nonatomic) id fi^eld;
+@end
+  )cpp");
+  EXPECT_AVAILABLE(R"cpp(
+@interface Foo {
+  id _fi^eld;
+}
+@property(nonatomic) id pr^op;
+@end
+  )cpp");
+
+  // Ensure that the action can't be triggered on property synthesis
+  // and methods.
+  EXPECT_UNAVAILABLE(R"cpp(
+@interface Foo
+@property(nonatomic) id prop;
+@end
+
+@implementation Foo
+@dynamic pr^op;
+@end
+  )cpp");
+  EXPECT_UNAVAILABLE(R"cpp(
+@interface Foo
+@end
+
+@implementation Foo
+- (void)fo^o {}
+@end
+  )cpp");
+}
+
+TEST_F(ObjCMemberwiseInitializerTest, Test) {
+  FileName = "TestTU.m";
+  ExtraArgs.push_back("-fobjc-arc");
+
+  const char *Input = R"cpp(
+@interface Foo {
+  id [[_field;
+}
+@property(nonatomic) id prop]];
+@property(nonatomic) id notSelected;
+@end)cpp";
+  const char *Output = R"cpp(
+@interface Foo {
+  id _field;
+}
+@property(nonatomic) id prop;
+@property(nonatomic) id notSelected;
+
+- (instancetype)initWithField:(id)field prop:(id)prop;
+
+@end)cpp";
+  EXPECT_EQ(apply(Input), Output);
+
+  Input = R"cpp(
+@interface Foo
+@property(nonatomic, nullable) id somePrettyLongPropertyName;
+@property(nonatomic, nonnull) id someReallyLongPropertyName;
+@end
+
+@implementation F^oo
+
+- (instancetype)init {
+  return self;
+}
+
+@end)cpp";
+  Output = R"cpp(
+@interface Foo
+@property(nonatomic, nullable) id somePrettyLongPropertyName;
+@property(nonatomic, nonnull) id someReallyLongPropertyName;
+@end
+
+@implementation Foo
+
+- (instancetype)init {
+  return self;
+}
+
+- (instancetype)initWithSomePrettyLongPropertyName:(nullable id)somePrettyLongPropertyName someReallyLongPropertyName:(nonnull id)someReallyLongPropertyName {
+  self = [super init];
+  if (self) {
+_somePrettyLongPropertyName = somePrettyLongPropertyName;
+_someReallyLongPropertyName = someReallyLongPropertyName;
+  }
+  return self;
+}
+
+@end)cpp";
+  EXPECT_EQ(apply(Input), Output);
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
Index: clang-tools-extra/clangd/unittests/CMakeLists.txt
===
--- clang-tools-extra/clangd/unittests/CMakeLists.txt
+++ clang-tools-extra/clangd/unittests/CMakeLists.txt
@@ -117,6 +117,7 @@
   tweaks/ExtractFunctionTests.cpp
   tweaks/ExtractVariableTests.cpp
   tweaks/ObjCLocalizeStringLiteralTests.cpp
+  tweaks/ObjCMemberwiseInitializerTests.cpp
   tweaks/PopulateSwitchTests.cpp
   tweaks/RawStringLiteralTests.cpp
   tweaks/RemoveUsingNamespaceTests.cpp
Index: clang-tools-extra/clangd/refactor/tweaks/ObjCMemberwiseInitializer.cpp
===
--- /dev/null
+++ clang-tools-extra/clangd/refactor/tweaks/ObjCMemberwiseInitializer.cpp
@@ -0,0 +1,332 @@
+//===--- ObjCM

[PATCH] D116414: [AST] Produce ReturnStmt containing RecoveryExpr when type is wrong

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall created this revision.
sammccall added a reviewer: hokein.
sammccall requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Previously we just drop the ReturnStmt and its argument from the AST,
which blocks analysis of broken code.

Fixes https://github.com/llvm/llvm-project/issues/39944


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116414

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaStmt.cpp
  clang/test/AST/ast-dump-recovery.cpp
  clang/test/SemaCXX/constant-expression-cxx11.cpp
  clang/test/SemaCXX/constant-expression-cxx14.cpp

Index: clang/test/SemaCXX/constant-expression-cxx14.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx14.cpp
+++ clang/test/SemaCXX/constant-expression-cxx14.cpp
@@ -876,14 +876,12 @@
 namespace Lifetime {
   constexpr int &get(int &&r) { return r; }
   // cxx2b-error@-1 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
-  // cxx2b-error@-2 {{no return statement in constexpr function}} See PR40598
   constexpr int f() {
 int &r = get(123);
 return r;
-// cxx2b-note@-1 {{use of reference outside its lifetime is not allowed in a constant expression}}
-// cxx14_20-note@-2 {{read of object outside its lifetime}}
+// cxx14_20-note@-1 {{read of object outside its lifetime}}
   }
-  static_assert(f() == 123, ""); // expected-error {{constant expression}} expected-note {{in call}}
+  static_assert(f() == 123, ""); // expected-error {{constant expression}} cxx14_20-note {{in call}}
 
   constexpr int g() {
 int *p = 0;
Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1939,20 +1939,16 @@
 
   constexpr int &get(int &&n) { return n; }
   // cxx2b-error@-1 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
-  // cxx2b-error@-2 {{no return statement in constexpr function}} See PR40598
   constexpr int &&get_rv(int &&n) { return static_cast(n); }
   struct S {
 int &&r;
 int &s;
 int t;
-constexpr S() : r(get_rv(0)), s(get(0)), t(r) {} // expected-note {{read of object outside its lifetime}}
-constexpr S(int) : r(get_rv(0)), s(get(0)), t(s) {}
-// cxx2b-warning@-1 {{reference 's' is not yet bound to a value when used here}}
-// cxx2b-note@-2{{read of uninitialized object is not allowed in a constant expression}}
-// cxx11_20-note@-3 {{read of object outside its lifetime}}
+constexpr S() : r(get_rv(0)), s(get(0)), t(r) {} // cxx11_20-note {{read of object outside its lifetime}}
+constexpr S(int) : r(get_rv(0)), s(get(0)), t(s) {} // cxx11_20-note {{read of object outside its lifetime}}
   };
-  constexpr int k1 = S().t; // expected-error {{constant expression}} expected-note {{in call}}
-  constexpr int k2 = S(0).t; // expected-error {{constant expression}} expected-note {{in call}}
+  constexpr int k1 = S().t; // expected-error {{constant expression}} cxx11_20-note {{in call}}
+  constexpr int k2 = S(0).t; // expected-error {{constant expression}} cxx11_20-note {{in call}}
 
   struct Q {
 int n = 0;
Index: clang/test/AST/ast-dump-recovery.cpp
===
--- clang/test/AST/ast-dump-recovery.cpp
+++ clang/test/AST/ast-dump-recovery.cpp
@@ -351,3 +351,43 @@
 // CHECK-NEXT: |   `-RecoveryExpr {{.*}} ''
   };
 }
+
+float *brokenReturn() {
+  // CHECK:  FunctionDecl {{.*}} brokenReturn
+  return 42;
+  // CHECK:  ReturnStmt
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} 'float *'
+  // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 42
+}
+
+// Return deduction treats the first, second *and* third differently!
+auto *brokenDeducedReturn(int *x, float *y, double *z) {
+  // CHECK:  FunctionDecl {{.*}} brokenDeducedReturn
+  if (x) return x;
+  // CHECK:  ReturnStmt
+  // CHECK-NEXT: `-ImplicitCastExpr {{.*}} 
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'x' 'int *'
+  if (y) return y;
+  // CHECK:  ReturnStmt
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int *'
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'y' 'float *'
+  if (z) return z;
+  // CHECK:  ReturnStmt
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int *'
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'z' 'double *'
+  return x;
+  // Unfortunate: we wrap a valid return in RecoveryExpr.
+  // This is to avoid running deduction again after it failed once.
+  // CHECK:  ReturnStmt
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int *'
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'x' 'int *'
+}
+
+void returnInitListFromVoid() {
+  // CHECK:  FunctionDecl {{.*}} returnInitListFromVoid
+  return {7,8};
+  // CHECK:  ReturnStmt
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} ''
+  // CHECK-NEXT:   |-IntegerLiteral

[PATCH] D116159: [ARM][AArch64] clang support for Armv9.3-A

2021-12-30 Thread Tomas Matheson via Phabricator via cfe-commits
tmatheson updated this revision to Diff 396679.
tmatheson marked 2 inline comments as done.
tmatheson added a comment.

Remove redundancies in arm tests


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116159

Files:
  clang/lib/Basic/Targets/AArch64.cpp
  clang/lib/Basic/Targets/AArch64.h
  clang/lib/Basic/Targets/ARM.cpp
  clang/lib/Driver/ToolChains/Arch/AArch64.cpp
  clang/test/Driver/aarch64-cpus.c
  clang/test/Driver/arm-cortex-cpus.c
  clang/test/Preprocessor/arm-target-features.c

Index: clang/test/Preprocessor/arm-target-features.c
===
--- clang/test/Preprocessor/arm-target-features.c
+++ clang/test/Preprocessor/arm-target-features.c
@@ -879,6 +879,11 @@
 // CHECK-V92A: #define __ARM_ARCH_9_2A__ 1
 // CHECK-V92A: #define __ARM_ARCH_PROFILE 'A'
 
+// RUN: %clang -target armv9.3a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V93A %s
+// CHECK-V93A: #define __ARM_ARCH 9
+// CHECK-V93A: #define __ARM_ARCH_9_3A__ 1
+// CHECK-V93A: #define __ARM_ARCH_PROFILE 'A'
+
 // RUN: %clang -target arm-none-none-eabi -march=armv7-m -mfpu=softvfp -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SOFTVFP %s
 // CHECK-SOFTVFP-NOT: #define __ARM_FP 0x
 
Index: clang/test/Driver/arm-cortex-cpus.c
===
--- clang/test/Driver/arm-cortex-cpus.c
+++ clang/test/Driver/arm-cortex-cpus.c
@@ -437,6 +437,22 @@
 // RUN: %clang -target arm -march=armebv9.2-a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V92A %s
 // CHECK-BE-V92A: "-cc1"{{.*}} "-triple" "armebv9.2{{.*}}" "-target-cpu" "generic"
 
+// RUN: %clang -target armv9.3a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V93A %s
+// RUN: %clang -target arm -march=armv9.3a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V93A %s
+// RUN: %clang -target arm -march=armv9.3-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V93A %s
+// RUN: %clang -target armv9.3a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V93A %s
+// RUN: %clang -target arm -march=armv9.3a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V93A %s
+// RUN: %clang -target arm -march=armv9.3-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V93A %s
+// CHECK-V93A: "-cc1"{{.*}} "-triple" "armv9.3{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target armebv9.3a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V93A %s
+// RUN: %clang -target armv9.3a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V93A %s
+// RUN: %clang -target armeb -march=armebv9.3a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V93A %s
+// RUN: %clang -target armeb -march=armebv9.3-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V93A %s
+// RUN: %clang -target arm -march=armebv9.3a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V93A %s
+// RUN: %clang -target arm -march=armebv9.3-a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V93A %s
+// CHECK-BE-V93A: "-cc1"{{.*}} "-triple" "armebv9.3{{.*}}" "-target-cpu" "generic"
+
 // Once we have CPUs with optional v8.2-A FP16, we will need a way to turn it
 // on and off. Cortex-A53 is a placeholder for now.
 // RUN: %clang -target armv8a-linux-eabi -mcpu=cortex-a53+fp16 -### -c %s 2>&1 | FileCheck --check-prefix CHECK-CORTEX-A53-FP16 %s
Index: clang/test/Driver/aarch64-cpus.c
===
--- clang/test/Driver/aarch64-cpus.c
+++ clang/test/Driver/aarch64-cpus.c
@@ -876,6 +876,22 @@
 // RUN: %clang -target aarch64_be -mbig-endian -march=armv9.2-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV92A-BE %s
 // GENERICV92A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.2a" "-target-feature" "+i8mm" "-target-feature" "+bf16" "-target-feature" "+sve" "-target-feature" "+sve2"
 
+// RUN: %clang -target aarch64 -march=armv9.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A %s
+// RUN: %clang -target aarch64 -march=armv9.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A %s
+// RUN: %clang -target aarch64 -mlittle-endian -march=armv9.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A %s
+// RUN: %clang -target aarch64 -mlittle-endian -march=armv9.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A %s
+// RUN: %clang -target aarch64_be -mlittle-endian -march=armv9.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A %s
+// RUN: %clang -target aarch64_be -mlittle-endian -march=armv9.3-a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A %s
+// GENERICV93A: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9.3a"
+
+// RUN: %clang -target aarch64_be -march=armv9.3a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV93A-BE %s

[PATCH] D116414: [AST] Produce ReturnStmt containing RecoveryExpr when type is wrong

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall updated this revision to Diff 396680.
sammccall added a comment.

Add evaluation test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116414

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaStmt.cpp
  clang/test/AST/ast-dump-recovery.cpp
  clang/test/SemaCXX/constant-expression-cxx11.cpp
  clang/test/SemaCXX/constant-expression-cxx14.cpp
  clang/test/SemaCXX/constexpr-function-recovery-crash.cpp

Index: clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
===
--- clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
+++ clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
@@ -74,3 +74,6 @@
 constexpr void test11() {
   for (X& e : array) {}
 }
+
+constexpr int test12() { return "wrong"; } // expected-error {{cannot initialize return object of type 'int'}}
+constexpr int force12 = test12();  // expected-error {{must be initialized by a constant}}
Index: clang/test/SemaCXX/constant-expression-cxx14.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx14.cpp
+++ clang/test/SemaCXX/constant-expression-cxx14.cpp
@@ -876,14 +876,12 @@
 namespace Lifetime {
   constexpr int &get(int &&r) { return r; }
   // cxx2b-error@-1 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
-  // cxx2b-error@-2 {{no return statement in constexpr function}} See PR40598
   constexpr int f() {
 int &r = get(123);
 return r;
-// cxx2b-note@-1 {{use of reference outside its lifetime is not allowed in a constant expression}}
-// cxx14_20-note@-2 {{read of object outside its lifetime}}
+// cxx14_20-note@-1 {{read of object outside its lifetime}}
   }
-  static_assert(f() == 123, ""); // expected-error {{constant expression}} expected-note {{in call}}
+  static_assert(f() == 123, ""); // expected-error {{constant expression}} cxx14_20-note {{in call}}
 
   constexpr int g() {
 int *p = 0;
Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1939,20 +1939,16 @@
 
   constexpr int &get(int &&n) { return n; }
   // cxx2b-error@-1 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
-  // cxx2b-error@-2 {{no return statement in constexpr function}} See PR40598
   constexpr int &&get_rv(int &&n) { return static_cast(n); }
   struct S {
 int &&r;
 int &s;
 int t;
-constexpr S() : r(get_rv(0)), s(get(0)), t(r) {} // expected-note {{read of object outside its lifetime}}
-constexpr S(int) : r(get_rv(0)), s(get(0)), t(s) {}
-// cxx2b-warning@-1 {{reference 's' is not yet bound to a value when used here}}
-// cxx2b-note@-2{{read of uninitialized object is not allowed in a constant expression}}
-// cxx11_20-note@-3 {{read of object outside its lifetime}}
+constexpr S() : r(get_rv(0)), s(get(0)), t(r) {} // cxx11_20-note {{read of object outside its lifetime}}
+constexpr S(int) : r(get_rv(0)), s(get(0)), t(s) {} // cxx11_20-note {{read of object outside its lifetime}}
   };
-  constexpr int k1 = S().t; // expected-error {{constant expression}} expected-note {{in call}}
-  constexpr int k2 = S(0).t; // expected-error {{constant expression}} expected-note {{in call}}
+  constexpr int k1 = S().t; // expected-error {{constant expression}} cxx11_20-note {{in call}}
+  constexpr int k2 = S(0).t; // expected-error {{constant expression}} cxx11_20-note {{in call}}
 
   struct Q {
 int n = 0;
Index: clang/test/AST/ast-dump-recovery.cpp
===
--- clang/test/AST/ast-dump-recovery.cpp
+++ clang/test/AST/ast-dump-recovery.cpp
@@ -351,3 +351,43 @@
 // CHECK-NEXT: |   `-RecoveryExpr {{.*}} ''
   };
 }
+
+float *brokenReturn() {
+  // CHECK:  FunctionDecl {{.*}} brokenReturn
+  return 42;
+  // CHECK:  ReturnStmt
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} 'float *'
+  // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 42
+}
+
+// Return deduction treats the first, second *and* third differently!
+auto *brokenDeducedReturn(int *x, float *y, double *z) {
+  // CHECK:  FunctionDecl {{.*}} brokenDeducedReturn
+  if (x) return x;
+  // CHECK:  ReturnStmt
+  // CHECK-NEXT: `-ImplicitCastExpr {{.*}} 
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'x' 'int *'
+  if (y) return y;
+  // CHECK:  ReturnStmt
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int *'
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'y' 'float *'
+  if (z) return z;
+  // CHECK:  ReturnStmt
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int *'
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'z' 'double *'
+  return x;
+  // Unfortunate: we wrap a valid return in RecoveryExpr.
+  // This 

[PATCH] D116414: [AST] Produce ReturnStmt containing RecoveryExpr when type is wrong

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.

No changes to evaluation makes sense as these patterns already exist today: 
`return undef();` produces a RecoveryExpr and `return;` is preserved in the AST 
with no value even for non-void functions.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116414

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


[PATCH] D116415: [Arm] Remove duplicate CPU tests

2021-12-30 Thread Tomas Matheson via Phabricator via cfe-commits
tmatheson created this revision.
Herald added a subscriber: kristof.beyls.
tmatheson requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

There are some duplicate test lines in clang/test/Driver/arm-cortex-cpus.c.
Looks like these were duplicated from the corresponding v8.0a tests, which test
both "-target armv8" and "-target armv8a". "-target armv8.X" without the "a"
doesn't work for later versions though.

Several tests also specify the -mlittle-endian twice, which looks unintentional.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116415

Files:
  clang/test/Driver/arm-cortex-cpus.c

Index: clang/test/Driver/arm-cortex-cpus.c
===
--- clang/test/Driver/arm-cortex-cpus.c
+++ clang/test/Driver/arm-cortex-cpus.c
@@ -143,7 +143,7 @@
 // RUN: %clang -target arm -march=armv8 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
 // RUN: %clang -target armv8a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
 // RUN: %clang -target arm -march=armv8a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
-// RUN: %clang -target arm -mlittle-endian -march=armv8-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
+// RUN: %clang -target arm -march=armv8-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
 // CHECK-V8A: "-cc1"{{.*}} "-triple" "armv8-{{.*}}" "-target-cpu" "generic"
 
 // RUN: %clang -target armv8r-linux-gnueabi -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8R %s
@@ -176,7 +176,7 @@
 // RUN: %clang -mcpu=generic -target arm -march=armv8 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-GENERIC %s
 // RUN: %clang -mcpu=generic -target armv8a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-GENERIC %s
 // RUN: %clang -mcpu=generic -target arm -march=armv8a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-GENERIC %s
-// RUN: %clang -mcpu=generic -target arm -mlittle-endian -march=armv8-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-GENERIC %s
+// RUN: %clang -mcpu=generic -target arm -march=armv8-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-GENERIC %s
 // CHECK-V8A-GENERIC: "-cc1"{{.*}} "-triple" "armv8-{{.*}}" "-target-cpu" "generic"
 
 // RUN: %clang -target armebv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A %s
@@ -214,17 +214,15 @@
 // RUN: %clang -target arm -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
 // RUN: %clang -target armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
 // RUN: %clang -target arm -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
-// RUN: %clang -target arm -march=armv8.1a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
 // RUN: %clang -target armv8.1a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
 // RUN: %clang -target arm -march=armv8.1a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
-// RUN: %clang -target arm -mlittle-endian -march=armv8.1-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
+// RUN: %clang -target arm -march=armv8.1-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
 // RUN: %clang -mcpu=generic -target arm -march=armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
 // RUN: %clang -mcpu=generic -target armv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
 // RUN: %clang -mcpu=generic -target arm -march=armv8.1-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
-// RUN: %clang -mcpu=generic -target arm -march=armv8.1a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
 // RUN: %clang -mcpu=generic -target armv8.1a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
 // RUN: %clang -mcpu=generic -target arm -march=armv8.1a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
-// RUN: %clang -mcpu=generic -target arm -mlittle-endian -march=armv8.1-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
+// RUN: %clang -mcpu=generic -target arm -march=armv8.1-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V81A %s
 // CHECK-V81A: "-cc1"{{.*}} "-triple" "armv8.1a-{{.*}}" "-target-cpu" "generic"
 
 // RUN: %clang -target armebv8.1a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V81A %s
@@ -254,10 +252,9 @@
 // RUN: %clang -target armv8.2a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V82A %s
 // RUN: %clang -target arm -march=armv8.2a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V82A %s
 // RUN: %clang -target arm -march=armv8.2-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V82A %s
-// RUN: %clang -target arm -march=armv8.2a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V82A %s

[PATCH] D116159: [ARM][AArch64] clang support for Armv9.3-A

2021-12-30 Thread Tomas Matheson via Phabricator via cfe-commits
tmatheson added inline comments.



Comment at: clang/test/Driver/arm-cortex-cpus.c:445
+// RUN: %clang -target armv9.3a -mlittle-endian -### -c %s 2>&1 | FileCheck 
-check-prefix=CHECK-V93A %s
+// RUN: %clang -target arm -march=armv9.3a -mlittle-endian -### -c %s 2>&1 | 
FileCheck -check-prefix=CHECK-V93A %s
+// RUN: %clang -target arm -mlittle-endian -march=armv9.3-a -mlittle-endian 
-### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V93A %s

nickdesaulniers wrote:
> Is this `RUN` line a duplicate of L443? Maybe you meant to test a hyphen in 
> the `march`?
Good catch, I've removed it. The same redundancy has been copy-pasted a few 
times by the look of it. Looks like the origins are in testing that armv8 and 
armv8a are synonymous, which doesn't seem to be the case for later versions.

I have created D116415 for the occurrences.



Comment at: clang/test/Driver/arm-cortex-cpus.c:446
+// RUN: %clang -target arm -march=armv9.3a -mlittle-endian -### -c %s 2>&1 | 
FileCheck -check-prefix=CHECK-V93A %s
+// RUN: %clang -target arm -mlittle-endian -march=armv9.3-a -mlittle-endian 
-### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V93A %s
+// CHECK-V93A: "-cc1"{{.*}} "-triple" "armv9.3{{.*}}" "-target-cpu" "generic"

nickdesaulniers wrote:
> nickdesaulniers wrote:
> > how about thumb targets? I recognize this test doesn't already do so for 
> > older extensions.
> This test sets `-mlittle-endian` twice. Is that intentional? Should the 
> aarch64 test above `clang/test/Driver/aarch64-cpus.c` also have such a test, 
> or should this `RUN` line be removed? Or was something else meant to be 
> tested?
Also copy-pasted from above; I don't see any point to it, so removed. See also 
D116415.



Comment at: clang/test/Driver/arm-cortex-cpus.c:446
+// RUN: %clang -target arm -march=armv9.3a -mlittle-endian -### -c %s 2>&1 | 
FileCheck -check-prefix=CHECK-V93A %s
+// RUN: %clang -target arm -mlittle-endian -march=armv9.3-a -mlittle-endian 
-### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V93A %s
+// CHECK-V93A: "-cc1"{{.*}} "-triple" "armv9.3{{.*}}" "-target-cpu" "generic"

tmatheson wrote:
> nickdesaulniers wrote:
> > nickdesaulniers wrote:
> > > how about thumb targets? I recognize this test doesn't already do so for 
> > > older extensions.
> > This test sets `-mlittle-endian` twice. Is that intentional? Should the 
> > aarch64 test above `clang/test/Driver/aarch64-cpus.c` also have such a 
> > test, or should this `RUN` line be removed? Or was something else meant to 
> > be tested?
> Also copy-pasted from above; I don't see any point to it, so removed. See 
> also D116415.
The above tests seem so be considered sufficient since 8.2, nothing much has 
changed afaik so I don't see any need to add them.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116159

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


[PATCH] D116370: [clang][dataflow] Add multi-variable constant propagation example.

2021-12-30 Thread Stanislav Gatev via Phabricator via cfe-commits
sgatev added inline comments.



Comment at: 
clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp:9
+//
+// This file defines a simplistic version of Constant Propagation as an example
+// of a forward, monotonic dataflow analysis. The analysis tracks all

Indent two spaces.



Comment at: 
clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp:160
+: ValueLattice::top();
+return Vars;
+  }

Consider removing this `return` and moving the assignment that follows in an 
`else` block. I think this way the two cases (with and without initializer) 
will be more apparent.



Comment at: 
clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp:162
+  }
+  Vars[Var] = ValueLattice::top();
+  return Vars;

I believe this should be `bottom` as `ValueLattice::bottom` models an undefined 
value.



Comment at: 
clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp:171-173
+  Vars[Var] = (E->EvaluateAsInt(R, Context) && R.Val.isInt())
+  ? ValueLattice(R.Val.getInt().getExtValue())
+  : ValueLattice::top();

I think this makes the transfer function non-monotonic. Concretely, `Vars[var]` 
can be `top` and the right-hand side can be something else. The transfer 
function must be monotonic to guarantee termination. Perhaps this should be 
`Vars[Var].join(...)`?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116370

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


[PATCH] D116386: [clang-tidy] Narrow cppguidelines-macro-usage to actual constants

2021-12-30 Thread Richard via Phabricator via cfe-commits
LegalizeAdulthood updated this revision to Diff 396683.
LegalizeAdulthood marked an inline comment as not done.
LegalizeAdulthood added a comment.

Improve name of predicate function.
Use standard algorithms instead of raw loops


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

https://reviews.llvm.org/D116386

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-macro-usage.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-macro-usage.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-macro-usage.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-macro-usage.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t -- -header-filter=.* -system-headers --
+// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage -std=c++17-or-later %t -- -header-filter=.* -system-headers --
 
 #ifndef INCLUDE_GUARD
 #define INCLUDE_GUARD
@@ -6,6 +6,21 @@
 #define PROBLEMATIC_CONSTANT 0
 // CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT' used to declare a constant; consider using a 'constexpr' constant
 
+#define PROBLEMATIC_CONSTANT_CHAR '0'
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT_CHAR' used to declare a constant; consider using a 'constexpr' constant
+
+#define PROBLEMATIC_CONSTANT_WIDE_CHAR L'0'
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT_WIDE_CHAR' used to declare a constant; consider using a 'constexpr' constant
+
+#define PROBLEMATIC_CONSTANT_UTF8_CHAR u8'0'
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT_UTF8_CHAR' used to declare a constant; consider using a 'constexpr' constant
+
+#define PROBLEMATIC_CONSTANT_UTF16_CHAR u'0'
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT_UTF16_CHAR' used to declare a constant; consider using a 'constexpr' constant
+
+#define PROBLEMATIC_CONSTANT_UTF32_CHAR U'0'
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT_UTF32_CHAR' used to declare a constant; consider using a 'constexpr' constant
+
 #define PROBLEMATIC_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
 // CHECK-MESSAGES: [[@LINE-1]]:9: warning: function-like macro 'PROBLEMATIC_FUNCTION' used; consider a 'constexpr' template function
 
@@ -15,4 +30,17 @@
 #define PROBLEMATIC_VARIADIC2(x, ...) (__VA_ARGS__)
 // CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro 'PROBLEMATIC_VARIADIC2' used; consider using a 'constexpr' variadic template function
 
+// These are all examples of common macros that shouldn't have constexpr suggestions.
+#define COMMA ,
+
+#define NORETURN [[noreturn]]
+
+#define DEPRECATED attribute((deprecated))
+
+#if LIB_EXPORTS
+#define DLLEXPORTS __declspec(dllexport)
+#else
+#define DLLEXPORTS __declspec(dllimport)
+#endif
+
 #endif
Index: clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp
===
--- clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp
+++ clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp
@@ -78,22 +78,53 @@
   this, SM, AllowedRegexp, CheckCapsOnly, IgnoreCommandLineMacros));
 }
 
+namespace {
+
+bool isConstantTokenSequence(const MacroInfo *Info) {
+  auto IsConstantToken = [](const Token &Token) {
+switch (Token.getKind()) {
+case tok::comment:
+case tok::numeric_constant:
+case tok::char_constant:
+case tok::wide_char_constant:
+case tok::utf8_char_constant:
+case tok::utf16_char_constant:
+case tok::utf32_char_constant:
+case tok::string_literal:
+case tok::wide_string_literal:
+case tok::header_name:
+case tok::utf8_string_literal:
+case tok::utf16_string_literal:
+case tok::utf32_string_literal:
+  return true;
+default:
+  return false;
+}
+  };
+  return std::all_of(Info->tokens_begin(), Info->tokens_end(), IsConstantToken);
+}
+
+} // namespace
+
 void MacroUsageCheck::warnMacro(const MacroDirective *MD, StringRef MacroName) {
-  StringRef Message =
-  "macro '%0' used to declare a constant; consider using a 'constexpr' "
-  "constant";
+  const MacroInfo *Info = MD->getMacroInfo();
+  StringRef Message;
 
+  if (isConstantTokenSequence(Info))
+Message = "macro '%0' used to declare a constant; consider using a "
+  "'constexpr' constant";
   /// A variadic macro is function-like at the same time. Therefore variadic
   /// macros are checked first and will be excluded for the function-like
   /// diagnostic.
-  if (MD->getMacroInfo()->isVariadic())
+  else if (Info->isVariadic())
 Message = "variadic macro '%0' used; consider using a 'constexpr' "
   "variadic template function";
-  else if (MD->getMacroInfo()->isFunctionLike())
+  else if (Info->isFunctionLike())
 

[PATCH] D116283: [clang-format] Add an option to add a space between operator overloading and opening parentheses

2021-12-30 Thread Rajat Bajpai via Phabricator via cfe-commits
rajatbajpai added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:14545
   verifyFormat("auto lambda = []() { return 0; };", SomeSpace2);
+
+  FormatStyle SpaceAfterOperatorOverloading = getLLVMStyle();

MyDeveloperDay wrote:
> There should be a PARSE unit test too please
I'm sorry if I misunderstood it, do you mean tests using CHECK_PARSE? I am 
confirming this because I didn't find any such test case for existing 
//SpaceBeforeParensOptions// options.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116283

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


[PATCH] D116370: [clang][dataflow] Add multi-variable constant propagation example.

2021-12-30 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel added inline comments.



Comment at: 
clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp:162
+  }
+  Vars[Var] = ValueLattice::top();
+  return Vars;

sgatev wrote:
> I believe this should be `bottom` as `ValueLattice::bottom` models an 
> undefined value.
No, because it's not truly undefined -- it has either a default value or 
implementation-defined value (for scalars).  So, an uninitialized variable has 
some value, just an unknown one.



Comment at: 
clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp:171-173
+  Vars[Var] = (E->EvaluateAsInt(R, Context) && R.Val.isInt())
+  ? ValueLattice(R.Val.getInt().getExtValue())
+  : ValueLattice::top();

sgatev wrote:
> I think this makes the transfer function non-monotonic. Concretely, 
> `Vars[var]` can be `top` and the right-hand side can be something else. The 
> transfer function must be monotonic to guarantee termination. Perhaps this 
> should be `Vars[Var].join(...)`?
Keep in mind that CP analysis is not looking at a variable's value *over the 
course of program*, but only *at each program point*. If we wanted to know 
whether a variable could be replaced entirely with a constant, then we'd need 
the former, in which case you'd be right that join would be correct here.

To the more general point: monotonic means something more subtle. Specifically, 
it doesn't relate inputs to outputs, but input-output pairs to each other. 
Specifically, for monotinically increasing functions `f`:
```
if a <= b then f(a) <= f(b)
```
In this case, no matter the inputs to f, the output is a constant (the value of 
the expression at that point or `top`), which trivially satisfies the 
requirement `f(a) <= f(b)`.

Intuitively, transfer functions model program behavior, so indeed it would be 
odd to enforce that `x <= f(x)`. Assignment is a good example -- at that 
program point, we know *exactly* the value of the variable, no matter what it 
held before.




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116370

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


[PATCH] D116370: [clang][dataflow] Add multi-variable constant propagation example.

2021-12-30 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel updated this revision to Diff 396684.
ymandel added a comment.

address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116370

Files:
  clang/unittests/Analysis/FlowSensitive/CMakeLists.txt
  clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp

Index: clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp
===
--- /dev/null
+++ clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp
@@ -0,0 +1,485 @@
+//===- unittests/Analysis/FlowSensitive/SingelVarConstantPropagation.cpp --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file defines a simplistic version of Constant Propagation as an example
+//  of a forward, monotonic dataflow analysis. The analysis tracks all
+//  variables in the scope, but lacks escape analysis.
+//
+//===--===//
+
+#include "TestingSupport.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/MapLattice.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Testing/Support/Annotations.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace dataflow {
+namespace {
+using namespace ast_matchers;
+
+// Models the value of an expression at a program point, for all paths through
+// the program.
+struct ValueLattice {
+  enum class ValueState : bool {
+Undefined,
+Defined,
+  };
+  // `State` determines the meaning of the lattice when `Value` is `None`:
+  //  * `Undefined` -> bottom,
+  //  * `Defined` -> top.
+  ValueState State;
+
+  // When `None`, the lattice is either at top or bottom, based on `State`.
+  llvm::Optional Value;
+
+  constexpr ValueLattice() : State(ValueState::Undefined), Value(llvm::None) {}
+  constexpr ValueLattice(int64_t V) : State(ValueState::Defined), Value(V) {}
+  constexpr ValueLattice(ValueState S) : State(S), Value(llvm::None) {}
+
+  static constexpr ValueLattice bottom() {
+return ValueLattice(ValueState::Undefined);
+  }
+  static constexpr ValueLattice top() {
+return ValueLattice(ValueState::Defined);
+  }
+
+  friend bool operator==(const ValueLattice &Lhs, const ValueLattice &Rhs) {
+return Lhs.State == Rhs.State && Lhs.Value == Rhs.Value;
+  }
+  friend bool operator!=(const ValueLattice &Lhs, const ValueLattice &Rhs) {
+return !(Lhs == Rhs);
+  }
+
+  LatticeJoinEffect join(const ValueLattice &Other) {
+if (*this == Other || Other == bottom() || *this == top())
+  return LatticeJoinEffect::Unchanged;
+
+if (*this == bottom()) {
+  *this = Other;
+  return LatticeJoinEffect::Changed;
+}
+
+*this = top();
+return LatticeJoinEffect::Changed;
+  }
+};
+
+std::ostream &operator<<(std::ostream &OS, const ValueLattice &L) {
+  if (L.Value.hasValue())
+return OS << *L.Value;
+  switch (L.State) {
+  case ValueLattice::ValueState::Undefined:
+return OS << "None";
+  case ValueLattice::ValueState::Defined:
+return OS << "Any";
+  }
+}
+
+using ConstantPropagationLattice = VarMapLattice;
+
+constexpr char kDecl[] = "decl";
+constexpr char kVar[] = "var";
+constexpr char kInit[] = "init";
+constexpr char kJustAssignment[] = "just-assignment";
+constexpr char kAssignment[] = "assignment";
+constexpr char kRHS[] = "rhs";
+
+auto refToVar() { return declRefExpr(to(varDecl().bind(kVar))); }
+
+// N.B. This analysis is deliberately simplistic, leaving out many important
+// details needed for a real analysis. Most notably, the transfer function does
+// not account for the variable's address possibly escaping, which would
+// invalidate the analysis. It also could be optimized to drop out-of-scope
+// variables from the map.
+class ConstantPropagationAnalysis
+: public DataflowAnalysis {
+public:
+  explicit ConstantPropagationAnalysis(ASTContext &Context)
+  : DataflowAnalysis(Context) {}
+
+  static ConstantPropagationLattice initialElement() {
+return ConstantPropagationLattice::bottom();
+  }
+
+  ConstantPropagat

[PATCH] D116370: [clang][dataflow] Add multi-variable constant propagation example.

2021-12-30 Thread Gábor Horváth via Phabricator via cfe-commits
xazax.hun accepted this revision.
xazax.hun added a comment.
This revision is now accepted and ready to land.

In D116370#3213191 , @ymandel wrote:

> In D116370#3213120 , @xazax.hun 
> wrote:
>
>> Does it make sense to have both the single and multi variable tracking 
>> tests? Or do we want to have these as some sort of steps in a tutorial?
>
> Right -- the intent in keeping the original one was for an (eventual) 
> tutorial.  For that matter, if you think there's changes I should make to the 
> single variable version to bring them closer together, I'd be happy to do 
> that.

I think from the tutorial's point of view that would be awesome! But I'm also 
happy with doing that in a follow-up PR some later time.




Comment at: 
clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp:53
+  };
+  // `State` determines the meaning of the lattice when `Value` is `None`:
+  //  * `Undefined` -> bottom,

If `ValueSate` only makes sense when `Value` is none, this almost looks like a 
`std::variant`. Unfortunately, as far as I understand LLVM 
is not at C++17 yet. I did not find an equivalent structure in the LLVM support 
library, but in case you agree, I think we could leave a TODO to change this 
after the C++ standard requirement was raised.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116370

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


[PATCH] D116369: [clang][dataflow] Add parameterized map lattice.

2021-12-30 Thread Gábor Horváth via Phabricator via cfe-commits
xazax.hun accepted this revision.
xazax.hun added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/include/clang/Analysis/FlowSensitive/MapLattice.h:92
+  /// entry as it was in the source map.
+  LatticeJoinEffect join(const MapLattice &Other) {
+LatticeJoinEffect Effect = LatticeJoinEffect::Unchanged;

ymandel wrote:
> xazax.hun wrote:
> > It looks like apart from the join operation the rest of the methods are 
> > simply forwarding to DenseMap. I was wondering if it would make more sense 
> > to make the framework support `join` as a free function (possibly using 
> > some custom type traits?) to avoid forcing the user to write wrappers like 
> > this.
> Good point, but I think that these concerns are separable -- that is, how 
> much forwarding we do and whether we should enable `join` an arbitrary types.
> 
> For the first issue, an alternative design here would be to simply expose the 
> container as a public field and drop all the methods except for `join`.  I 
> intentionally left some abstraction in place, though, because I think that 
> `DenseMap` is not the right container, its just "good enough" to get started. 
> I think ultimately we'll want functional data structures, because the current 
> setup forces an absurd amount of copying.
> 
> For the second issue, I'm open to the idea -- it would be like Haskell's type 
> classes in some sense, but I prefer the design where the lattice's operations 
> are grouped together as a unit. I think that we could fit it into the current 
> design with some form of SFINAE-based discrimination on the lattice type 
> parameter of `DataflowAnalysis`.
> 
> Given that, what do you think of just renaming this to `DenseMapLattice` and 
> exposing the container field publicly? When we're ready with a better map 
> lattice, we can add that alongside this one with a different name.
Alternatively, I was wondering if deriving from `llvm::DenseMap` would reduce the amount of boilerplate this needs.

I'm a big fan of the typeclass approach, so I'd be really happy if the 
framework supported something like that but it is definitely out of scope for 
the PR.

> I think ultimately we'll want functional data structures, because the current 
> setup forces an absurd amount of copying.

+1.

> Given that, what do you think of just renaming this to DenseMapLattice and 
> exposing the container field publicly? When we're ready with a better map 
> lattice, we can add that alongside this one with a different name.

Since we do not consider this to be the final/definitive solution, I'm fine 
with either approach or leaving this as is. 





Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116369

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


[PATCH] D116417: [clang][ObjC] Add fix it for missing methods in impl

2021-12-30 Thread David Goldman via Phabricator via cfe-commits
dgoldman created this revision.
dgoldman requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

We suggest inserting the method with an empty body at the end
of the implementation decl.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116417

Files:
  clang/lib/Sema/SemaDeclObjC.cpp

Index: clang/lib/Sema/SemaDeclObjC.cpp
===
--- clang/lib/Sema/SemaDeclObjC.cpp
+++ clang/lib/Sema/SemaDeclObjC.cpp
@@ -2212,9 +2212,8 @@
 Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count);
 }
 
-static void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc,
-ObjCMethodDecl *method,
-bool &IncompleteImpl,
+static void WarnUndefinedMethod(Sema &S, ObjCImplDecl *Impl,
+ObjCMethodDecl *method, bool &IncompleteImpl,
 unsigned DiagID,
 NamedDecl *NeededFor = nullptr) {
   // No point warning no definition of method which is 'unavailable'.
@@ -2227,10 +2226,22 @@
   // separate warnings.  We will give that approach a try, as that
   // matches what we do with protocols.
   {
-const Sema::SemaDiagnosticBuilder &B = S.Diag(ImpLoc, DiagID);
+const Sema::SemaDiagnosticBuilder &B = S.Diag(Impl->getLocation(), DiagID);
 B << method;
 if (NeededFor)
   B << NeededFor;
+
+// Provide a simple fix it which inserts the missing method with an empty
+// body at the end of the implementation. In the future we could try to find
+// a better place to put it.
+std::string Str;
+llvm::raw_string_ostream Out(Str);
+PrintingPolicy Policy(Impl->getASTContext().getPrintingPolicy());
+method->print(Out, Policy);
+Str.append(" {\n\n}\n\n");
+
+SourceLocation Loc = Impl->getAtEndRange().getBegin();
+B << FixItHint::CreateInsertion(Loc, Str);
   }
 
   // Issue a note to the original declaration.
@@ -2679,14 +2690,10 @@
 
 /// CheckProtocolMethodDefs - This routine checks unimplemented methods
 /// Declared in protocol, and those referenced by it.
-static void CheckProtocolMethodDefs(Sema &S,
-SourceLocation ImpLoc,
-ObjCProtocolDecl *PDecl,
-bool& IncompleteImpl,
-const Sema::SelectorSet &InsMap,
-const Sema::SelectorSet &ClsMap,
-ObjCContainerDecl *CDecl,
-LazyProtocolNameSet &ProtocolsExplictImpl) {
+static void CheckProtocolMethodDefs(
+Sema &S, ObjCImplDecl *Impl, ObjCProtocolDecl *PDecl, bool &IncompleteImpl,
+const Sema::SelectorSet &InsMap, const Sema::SelectorSet &ClsMap,
+ObjCContainerDecl *CDecl, LazyProtocolNameSet &ProtocolsExplictImpl) {
   ObjCCategoryDecl *C = dyn_cast(CDecl);
   ObjCInterfaceDecl *IDecl = C ? C->getClassInterface()
: dyn_cast(CDecl);
@@ -2773,9 +2780,8 @@
   if (C || MethodInClass->isPropertyAccessor())
 continue;
 unsigned DIAG = diag::warn_unimplemented_protocol_method;
-if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
-  WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG,
-  PDecl);
+if (!S.Diags.isIgnored(DIAG, Impl->getLocation())) {
+  WarnUndefinedMethod(S, Impl, method, IncompleteImpl, DIAG, PDecl);
 }
   }
 }
@@ -2796,15 +2802,15 @@
 continue;
 
   unsigned DIAG = diag::warn_unimplemented_protocol_method;
-  if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
-WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl);
+  if (!S.Diags.isIgnored(DIAG, Impl->getLocation())) {
+WarnUndefinedMethod(S, Impl, method, IncompleteImpl, DIAG, PDecl);
   }
 }
   }
   // Check on this protocols's referenced protocols, recursively.
   for (auto *PI : PDecl->protocols())
-CheckProtocolMethodDefs(S, ImpLoc, PI, IncompleteImpl, InsMap, ClsMap,
-CDecl, ProtocolsExplictImpl);
+CheckProtocolMethodDefs(S, Impl, PI, IncompleteImpl, InsMap, ClsMap, CDecl,
+ProtocolsExplictImpl);
 }
 
 /// MatchAllMethodDeclarations - Check methods declared in interface
@@ -2827,7 +2833,7 @@
 if (!I->isPropertyAccessor() &&
 !InsMap.count(I->getSelector())) {
   if (ImmediateClass)
-WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl,
+WarnUndefinedMethod(*this, IMPDecl, I, IncompleteImpl,
 diag::warn_undef_method_impl);
   continue;
 } else {
@@ -2857,7 +2863,7 @@
 if (!I->isPropertyAccessor() &&
 !ClsMap.count(I->getSelector())) {
   if (ImmediateClass)
-

[PATCH] D116368: [clang][dataflow] Add transfer function for VarDecl statements

2021-12-30 Thread Gábor Horváth via Phabricator via cfe-commits
xazax.hun accepted this revision.
xazax.hun added a comment.
This revision is now accepted and ready to land.

I have one nit inline, and some topics that should probably be deferred to 
follow-up PRs. Overall, looks good to me, thanks!




Comment at: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h:76
+  std::vector> Locs;
+  std::vector> Vals;
+  llvm::DenseMap VarDeclToLoc;

sgatev wrote:
> xazax.hun wrote:
> > Just curious: would it make sense to deduplicate these values?
> I think no because even if the values are equal we'd like to track them 
> separately as they represent different identities which is important for 
> inference. For example:
> 
> ```
> std::optional a = foo();
> std::optional b = bar();
> std::optional c = a;
> // at this point we can model `a`, `b`, and `c` with the same value, however
> if (a.has_value()) {
>   // here we gain knowledge only about the values of `a` and `c`
>   a.value(); // safe
>   c.value(); // safe
>   b.value(); // unsafe 
> }
> ```
> 
> In our analysis we model the above by assigning the same value to the storage 
> locations for `a` and `c` and assigning a different value to the storage 
> location for `b`, even if the two values are equal.
I see. This makes sense, thanks!



Comment at: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp:32
+template 
+bool denseMapsAreEqual(const llvm::DenseMap &Map1,
+   const llvm::DenseMap &Map2) {

sgatev wrote:
> xazax.hun wrote:
> > Shouldn't we add `operator==` instead?
> I'd be happy to do that. Do we need reviews from other folks for it? Would it 
> make sense to move the code to the other location in a follow-up PR, to limit 
> the scope of the change?
Actually, I think DenseMaps should already have `operator==` so we should be 
able to remove this code.



Comment at: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp:46
+template 
+llvm::DenseMap intersectDenseMaps(const llvm::DenseMap &Map1,
+const llvm::DenseMap &Map2) {

sgatev wrote:
> xazax.hun wrote:
> > I wonder if these algorithms should rather be somewhere in the support 
> > library.
> I'd be happy to do that. Do we need reviews from other folks for it? Would it 
> make sense to move the code to the other location in a follow-up PR, to limit 
> the scope of the change?
Yep, I'm fine with moving this in a follow-up PR.



Comment at: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp:88
+for (const FieldDecl *Field : Type->getAsRecordDecl()->fields()) {
+  FieldLocs.insert({Field, &createStorageLocation(Field->getType())});
+}

sgatev wrote:
> xazax.hun wrote:
> > Could this end up creating an overly large state? There might be objects 
> > with quite a lot fields but each function would only access a small subset 
> > of those. Alternatively, we could attempt to create the representations for 
> > fields on demand (this is the approach what the clang static analyzer is 
> > using). 
> That's a great point, however I don't think initialization on demand plays 
> well with the dataflow algorithm. For example:
> 
> ```
> struct S {
>   int Val;
> };
> 
> void target(bool b) {
>   // basic block 1:
>   S Foo;
>   int Bar;
>   if (b) {
> // basic block 2:
> Bar = Foo.Val;
>   } else {
> // basic block 3:
> Bar = Foo.Val;
>   }
>   // basic block 4:
>   ...
> }
> ```
> In basic block 4 we should be able to infer that the value that is assigned 
> to the storage location for `Bar` is unambiguous. However, since `Foo.Value` 
> isn't created in basic block 1, this means that it's not inherited by basic 
> block 2 and basic block 3. Each of these blocks will end up creating distinct 
> values to assign to the storage location for `Foo.Value` and so in basic 
> block 4 the value for `Bar` will end up being ambiguous.
> 
> Alternatively, we can do a pass over all statements in all basic blocks 
> before running the analysis to identify which fields are used in the 
> function. We can use this information here to initialize only parts that are 
> being used.
> 
> What do you think?
I am not convinced about this example. I think it should not matter where and 
when we create the location for Foo.Val, it always should be equivalent to the 
others, i.e., they should have the same identity regardless their creation. 
Basically, I think the identity of such a location should be determined by the 
base object (Foo in this case), and the access path to the subobject. 

This would be a non-trivial change, so I'm ok with deferring this discussion to 
some follow-up PRs. But I'd love to see some alternatives explored because 
eagerly evaluating all fields used to bite me in the past in other static 
analysis tools performance-wise.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.or

[PATCH] D115604: [Support] Expand `` as the base directory in configuration files.

2021-12-30 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff accepted this revision.
sepavloff added a comment.
This revision is now accepted and ready to land.

LGTM

Thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115604

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


[PATCH] D116417: [clang][ObjC] Add fix it for missing methods in impl

2021-12-30 Thread David Goldman via Phabricator via cfe-commits
dgoldman updated this revision to Diff 396690.
dgoldman added a comment.

Add a test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116417

Files:
  clang/lib/Sema/SemaDeclObjC.cpp
  clang/test/FixIt/fixit-objc-missing-method-impl.m

Index: clang/test/FixIt/fixit-objc-missing-method-impl.m
===
--- /dev/null
+++ clang/test/FixIt/fixit-objc-missing-method-impl.m
@@ -0,0 +1,14 @@
+// RUN: cp %s %t
+// RUN: not %clang_cc1 -pedantic -Werror -fixit -x objective-c %t
+// RUN: %clang_cc1 -pedantic -Werror -x objective-c %t
+
+__attribute__((objc_root_class))
+@interface NSObject
+@end
+
+@interface Foo : NSObject
+- (void)fooey;
+@end
+
+@implementation Foo
+@end
Index: clang/lib/Sema/SemaDeclObjC.cpp
===
--- clang/lib/Sema/SemaDeclObjC.cpp
+++ clang/lib/Sema/SemaDeclObjC.cpp
@@ -2212,9 +2212,8 @@
 Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count);
 }
 
-static void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc,
-ObjCMethodDecl *method,
-bool &IncompleteImpl,
+static void WarnUndefinedMethod(Sema &S, ObjCImplDecl *Impl,
+ObjCMethodDecl *method, bool &IncompleteImpl,
 unsigned DiagID,
 NamedDecl *NeededFor = nullptr) {
   // No point warning no definition of method which is 'unavailable'.
@@ -2227,10 +2226,22 @@
   // separate warnings.  We will give that approach a try, as that
   // matches what we do with protocols.
   {
-const Sema::SemaDiagnosticBuilder &B = S.Diag(ImpLoc, DiagID);
+const Sema::SemaDiagnosticBuilder &B = S.Diag(Impl->getLocation(), DiagID);
 B << method;
 if (NeededFor)
   B << NeededFor;
+
+// Provide a simple fix it which inserts the missing method with an empty
+// body at the end of the implementation. In the future we could try to find
+// a better place to put it.
+std::string Str;
+llvm::raw_string_ostream Out(Str);
+PrintingPolicy Policy(Impl->getASTContext().getPrintingPolicy());
+method->print(Out, Policy);
+Str.append(" {\n\n}\n\n");
+
+SourceLocation Loc = Impl->getAtEndRange().getBegin();
+B << FixItHint::CreateInsertion(Loc, Str);
   }
 
   // Issue a note to the original declaration.
@@ -2679,14 +2690,10 @@
 
 /// CheckProtocolMethodDefs - This routine checks unimplemented methods
 /// Declared in protocol, and those referenced by it.
-static void CheckProtocolMethodDefs(Sema &S,
-SourceLocation ImpLoc,
-ObjCProtocolDecl *PDecl,
-bool& IncompleteImpl,
-const Sema::SelectorSet &InsMap,
-const Sema::SelectorSet &ClsMap,
-ObjCContainerDecl *CDecl,
-LazyProtocolNameSet &ProtocolsExplictImpl) {
+static void CheckProtocolMethodDefs(
+Sema &S, ObjCImplDecl *Impl, ObjCProtocolDecl *PDecl, bool &IncompleteImpl,
+const Sema::SelectorSet &InsMap, const Sema::SelectorSet &ClsMap,
+ObjCContainerDecl *CDecl, LazyProtocolNameSet &ProtocolsExplictImpl) {
   ObjCCategoryDecl *C = dyn_cast(CDecl);
   ObjCInterfaceDecl *IDecl = C ? C->getClassInterface()
: dyn_cast(CDecl);
@@ -2773,9 +2780,8 @@
   if (C || MethodInClass->isPropertyAccessor())
 continue;
 unsigned DIAG = diag::warn_unimplemented_protocol_method;
-if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
-  WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG,
-  PDecl);
+if (!S.Diags.isIgnored(DIAG, Impl->getLocation())) {
+  WarnUndefinedMethod(S, Impl, method, IncompleteImpl, DIAG, PDecl);
 }
   }
 }
@@ -2796,15 +2802,15 @@
 continue;
 
   unsigned DIAG = diag::warn_unimplemented_protocol_method;
-  if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
-WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl);
+  if (!S.Diags.isIgnored(DIAG, Impl->getLocation())) {
+WarnUndefinedMethod(S, Impl, method, IncompleteImpl, DIAG, PDecl);
   }
 }
   }
   // Check on this protocols's referenced protocols, recursively.
   for (auto *PI : PDecl->protocols())
-CheckProtocolMethodDefs(S, ImpLoc, PI, IncompleteImpl, InsMap, ClsMap,
-CDecl, ProtocolsExplictImpl);
+CheckProtocolMethodDefs(S, Impl, PI, IncompleteImpl, InsMap, ClsMap, CDecl,
+ProtocolsExplictImpl);
 }
 
 /// MatchAllMethodDeclarations - Check methods declared in interface
@@ -2827,7 +2833,7 @@
 if (!I->isPr

[PATCH] D116415: [Arm] Remove duplicate CPU tests

2021-12-30 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers accepted this revision.
nickdesaulniers added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/test/Driver/arm-cortex-cpus.c:217
 // RUN: %clang -target arm -march=armv8.1-a -### -c %s 2>&1 | FileCheck 
-check-prefix=CHECK-V81A %s
-// RUN: %clang -target arm -march=armv8.1a -mlittle-endian -### -c %s 2>&1 | 
FileCheck -check-prefix=CHECK-V81A %s
 // RUN: %clang -target armv8.1a -mlittle-endian -### -c %s 2>&1 | FileCheck 
-check-prefix=CHECK-V81A %s

I'm definitely ok with the half of changes in this patch that remove 
`-mlittle-endian` when it appears twice on one line.

The other half of the changes remove `-mlittle-endian` when it's not specified 
more than once. I suspect `-mlittle-endian` is implied by `-target` in this 
case; was the test validating that by being explicit about endianness?  I guess 
I don't see how being explicit about the endianness could affect the `-triple`, 
which is what is being checked, so I guess this LGTM.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116415

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


[PATCH] D115501: [clang][ARM] Emit warnings when PACBTI-M is used with unsupported architectures

2021-12-30 Thread Amilendra Kodithuwakku via Phabricator via cfe-commits
amilendra updated this revision to Diff 396695.
amilendra added a comment.

Fix clang-format errors.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115501

Files:
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/Basic/Targets/AArch64.cpp
  clang/lib/Basic/Targets/AArch64.h
  clang/lib/Basic/Targets/ARM.cpp
  clang/lib/Basic/Targets/ARM.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/arm-branch-protection-attr-2.c
  clang/test/CodeGen/arm_acle.c
  clang/test/Driver/arm-security-options.c
  clang/test/Frontend/arm-branch-protection-default-arch.c
  clang/test/Frontend/arm-ignore-branch-protection-option.c
  clang/test/Frontend/arm-invalid-branch-protection.c
  clang/test/Sema/arm-branch-protection-attr-warn.c
  clang/test/Sema/arm-branch-protection.c

Index: clang/test/Sema/arm-branch-protection.c
===
--- /dev/null
+++ clang/test/Sema/arm-branch-protection.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple thumbv6m -verify -fsyntax-only %s
+
+// expected-no-diagnostics
+// Armv8.1-M.Main
+__attribute__((target("arch=cortex-m55,branch-protection=bti"))) void f1() {}
+__attribute__((target("arch=cortex-m55,branch-protection=pac-ret"))) void f2() {}
+__attribute__((target("arch=cortex-m55,branch-protection=bti+pac-ret"))) void f3() {}
+__attribute__((target("arch=cortex-m55,branch-protection=bti+pac-ret+leaf"))) void f4() {}
+// Armv8-M.Main
+__attribute__((target("arch=cortex-m33,branch-protection=bti"))) void f5() {}
+__attribute__((target("arch=cortex-m33,branch-protection=pac-ret"))) void f6() {}
+__attribute__((target("arch=cortex-m33,branch-protection=bti+pac-ret"))) void f7() {}
+__attribute__((target("arch=cortex-m33,branch-protection=bti+pac-ret+leaf"))) void f8() {}
+// Armv7-M
+__attribute__((target("arch=cortex-m3,branch-protection=bti"))) void f9() {}
+__attribute__((target("arch=cortex-m3,branch-protection=pac-ret"))) void f10() {}
+__attribute__((target("arch=cortex-m3,branch-protection=bti+pac-ret"))) void f11() {}
+__attribute__((target("arch=cortex-m3,branch-protection=bti+pac-ret+leaf"))) void f12() {}
+// Armv7E-M
+__attribute__((target("arch=cortex-m4,branch-protection=bti"))) void f13() {}
+__attribute__((target("arch=cortex-m4,branch-protection=pac-ret"))) void f14() {}
+__attribute__((target("arch=cortex-m4,branch-protection=bti+pac-ret"))) void f15() {}
+__attribute__((target("arch=cortex-m4,branch-protection=bti+pac-ret+leaf"))) void f16() {}
Index: clang/test/Sema/arm-branch-protection-attr-warn.c
===
--- /dev/null
+++ clang/test/Sema/arm-branch-protection-attr-warn.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple thumbv6m -verify -fsyntax-only %s
+
+// expected-warning@+1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
+__attribute__((target("arch=cortex-m0,branch-protection=bti"))) void f1() {}
+
+// expected-warning@+1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
+__attribute__((target("arch=cortex-m0,branch-protection=pac-ret"))) void f2() {}
+
+// expected-warning@+1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
+__attribute__((target("arch=cortex-m0,branch-protection=bti+pac-ret"))) void f3() {}
+
+// expected-warning@+1 {{unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored}}
+__attribute__((target("arch=cortex-m0,branch-protection=bti+pac-ret+leaf"))) void f4() {}
Index: clang/test/Frontend/arm-invalid-branch-protection.c
===
--- clang/test/Frontend/arm-invalid-branch-protection.c
+++ clang/test/Frontend/arm-invalid-branch-protection.c
@@ -1,7 +1,7 @@
 // REQUIRES: arm-registered-target
-// RUN: %clang -target arm-arm-none-eabi -mbranch-protection=pac-ret+b-key -c %s -o /dev/null 2>&1 | FileCheck %s
-// RUN: %clang -target arm-arm-none-eabi -mbranch-protection=pac-ret+b-key+leaf -c %s -o /dev/null 2>&1 | FileCheck %s
-// RUN: %clang -target arm-arm-none-eabi -mbranch-protection=bti+pac-ret+b-key -c %s -o /dev/null 2>&1 | FileCheck %s
-// RUN: %clang -target arm-arm-none-eabi -mbranch-protection=bti+pac-ret+b-key+leaf -c %s -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -mbranch-protection=pac-ret+b-key -c %s -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -mbranch-protection=pac-ret+b-key+leaf -c %s -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -mbranch-protection=bti+pac-ret+b-key -c %s -o /dev/nu

[clang] 9d37d0e - [Support] Expand `` as the base directory in configuration files.

2021-12-30 Thread Jack Andersen via cfe-commits

Author: Jack Andersen
Date: 2021-12-30T13:43:47-05:00
New Revision: 9d37d0ea34858288faf6351b9bdc0a0b91107c82

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

LOG: [Support] Expand `` as the base directory in configuration files.

Extends response file expansion to recognize `` and expand to the
current file's directory. This makes it much easier to author clang config
files rooted in portable, potentially not-installed SDK directories.

A typical use case may be something like the following:

```
# sample_sdk.cfg
--target=sample
-isystem /include
-L /lib
-T /ldscripts/link.ld
```

Reviewed By: sepavloff

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

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/docs/UsersManual.rst
clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp
llvm/unittests/Support/CommandLineTest.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 44485fcd7e26f..ce9b3547155af 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -63,6 +63,9 @@ Non-comprehensive list of changes in this release
 
 - Maximum _ExtInt size was decreased from 16,777,215 bits to 8,388,608 bits.
   Motivation for this was discussed in PR51829.
+- Configuration file syntax extended with  token. This expands to
+  the base path of the current config file. See :ref:`configuration-files` for
+  details.
 
 New Compiler Flags
 --

diff  --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 26da5a0ff2554..1173fd337841c 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -843,6 +843,8 @@ a special character, which is the convention used by GNU 
Make. The -MV
 option tells Clang to put double-quotes around the entire filename, which
 is the convention used by NMake and Jom.
 
+.. _configuration-files:
+
 Configuration files
 ---
 
@@ -917,6 +919,22 @@ relative to the including file. For example, if a 
configuration file
 `~/.llvm/target.cfg` contains the directive `@os/linux.opts`, the file
 `linux.opts` is searched for in the directory `~/.llvm/os`.
 
+To generate paths relative to the configuration file, the `` token may
+be used. This will expand to the absolute path of the directory containing the
+configuration file.
+
+In cases where a configuration file is deployed alongside SDK contents, the
+SDK directory can remain fully portable by using `` prefixed paths.
+In this way, the user may only need to specify a root configuration file with
+`--config` to establish every aspect of the SDK with the compiler:
+
+::
+
+--target=foo
+-isystem /include
+-L /lib
+-T /ldscripts/link.ld
+
 Language and Target-Independent Features
 
 

diff  --git a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp 
b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
index 29787b8a88942..75d0d50d851f9 100644
--- a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
+++ b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -61,7 +61,7 @@ class ExpandResponseFilesDatabase : public 
CompilationDatabase {
 continue;
   llvm::BumpPtrAllocator Alloc;
   llvm::StringSaver Saver(Alloc);
-  llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false,
+  llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, 
false,
 llvm::StringRef(Cmd.Directory), *FS);
   // Don't assign directly, Argv aliases CommandLine.
   std::vector ExpandedArgv(Argv.begin(), Argv.end());

diff  --git a/llvm/include/llvm/Support/CommandLine.h 
b/llvm/include/llvm/Support/CommandLine.h
index 2c3edd858a3fb..120ab18409158 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -2082,7 +2082,8 @@ void tokenizeConfigFile(StringRef Source, StringSaver 
&Saver,
 ///
 /// It reads content of the specified file, tokenizes it and expands "@file"
 /// commands resolving file names in them relative to the directory where
-/// CfgFilename resides.
+/// CfgFilename resides. It also expands "" to the base path of the
+/// current config file.
 ///
 bool readConfigFile(StringRef CfgFileName, StringSaver &Saver,
 SmallVectorImpl &Argv);
@@ -2102,13 +2103,15 @@ bool readConfigFile(StringRef CfgFileName, StringSaver 
&Saver,
 /// with nullptrs in the Argv vector.
 /// \param [in] RelativeNames true if names of nested response files must be
 /// resolved relative to including file.
+/// \param [in] ExpandBasePath If true, "" expands to the base path of
+/// the current

[PATCH] D115604: [Support] Expand `` as the base directory in configuration files.

2021-12-30 Thread Jack Andersen 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 rG9d37d0ea3485: [Support] Expand `` as the base 
directory in configuration files. (authored by jackoalan).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115604

Files:
  clang/docs/ReleaseNotes.rst
  clang/docs/UsersManual.rst
  clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
  llvm/include/llvm/Support/CommandLine.h
  llvm/lib/Support/CommandLine.cpp
  llvm/unittests/Support/CommandLineTest.cpp

Index: llvm/unittests/Support/CommandLineTest.cpp
===
--- llvm/unittests/Support/CommandLineTest.cpp
+++ llvm/unittests/Support/CommandLineTest.cpp
@@ -827,7 +827,7 @@
   llvm::BumpPtrAllocator A;
   llvm::StringSaver Saver(A);
   ASSERT_TRUE(llvm::cl::ExpandResponseFiles(
-  Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true,
+  Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true, false,
   /*CurrentDir=*/StringRef(TestRoot), FS));
   EXPECT_THAT(Argv, testing::Pointwise(
 StringEquality(),
@@ -889,9 +889,9 @@
 #else
   cl::TokenizerCallback Tokenizer = cl::TokenizeGNUCommandLine;
 #endif
-  ASSERT_FALSE(cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false,
-   /*CurrentDir=*/llvm::StringRef(TestRoot),
-   FS));
+  ASSERT_FALSE(
+  cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, false,
+  /*CurrentDir=*/llvm::StringRef(TestRoot), FS));
 
   EXPECT_THAT(Argv,
   testing::Pointwise(StringEquality(),
@@ -929,7 +929,7 @@
   BumpPtrAllocator A;
   StringSaver Saver(A);
   ASSERT_FALSE(cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv,
-   false, false,
+   false, false, false,
/*CurrentDir=*/StringRef(TestRoot), FS));
 
   // ASSERT instead of EXPECT to prevent potential out-of-bounds access.
@@ -964,7 +964,7 @@
   BumpPtrAllocator A;
   StringSaver Saver(A);
   ASSERT_TRUE(cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv,
-  false, true,
+  false, true, false,
   /*CurrentDir=*/StringRef(TestRoot), FS));
   EXPECT_THAT(Argv,
   testing::Pointwise(StringEquality(), {"test/test", "-flag"}));
@@ -984,7 +984,7 @@
   BumpPtrAllocator A;
   StringSaver Saver(A);
   ASSERT_TRUE(cl::ExpandResponseFiles(Saver, cl::TokenizeWindowsCommandLine,
-  Argv, true, true,
+  Argv, true, true, false,
   /*CurrentDir=*/StringRef(TestRoot), FS));
   const char *Expected[] = {"clang", "-Xclang", "-Wno-whatever", nullptr,
 "input.cpp"};
@@ -1038,25 +1038,39 @@
   llvm::SmallVector Argv;
 
   TempDir TestDir("unittest", /*Unique*/ true);
+  TempDir TestSubDir(TestDir.path("subdir"), /*Unique*/ false);
 
-  llvm::SmallString<128> TestCfg;
-  llvm::sys::path::append(TestCfg, TestDir.path(), "foo");
-
+  llvm::SmallString<128> TestCfg = TestDir.path("foo");
   TempFile ConfigFile(TestCfg, "",
   "# Comment\n"
   "-option_1\n"
+  "-option_2=/dir1\n"
+  "-option_3=\n"
+  "-option_4 \n"
+  "-option_5=\n"
+  "-option_6=/dir1,/dir2\n"
   "@subconfig\n"
-  "-option_3=abcd\n"
-  "-option_4=\\\n"
+  "-option_11=abcd\n"
+  "-option_12=\\\n"
   "cdef\n");
 
-  llvm::SmallString<128> TestCfg2;
-  llvm::sys::path::append(TestCfg2, TestDir.path(), "subconfig");
+  llvm::SmallString<128> TestCfg2 = TestDir.path("subconfig");
   TempFile ConfigFile2(TestCfg2, "",
-   "-option_2\n"
+   "-option_7\n"
+   "-option_8=/dir2\n"
+   "@subdir/subfoo\n"
"\n"
"   # comment\n");
 
+  llvm::SmallString<128> TestCfg3 = TestSubDir.path("subfoo");
+  TempFile ConfigFile3(TestCfg3, "",
+   "-option_9=/dir3\n"
+   "@/subfoo2\n");
+
+  llvm::SmallString<128> TestCfg4 = TestSubDir.path("subfoo2");
+  TempFile ConfigFile4(TestCfg4, "", "-option_10\n");
+
   // Make sure the current directory is not the directory where config files
   // resides. In this case the code that expands response files will not find
   // 'subconfig' unless it resolves nested inclusions relative

[PATCH] D116314: [clang-format] Add style to separate definition blocks

2021-12-30 Thread Björn Schäpers via Phabricator via cfe-commits
HazardyKnusperkeks added inline comments.



Comment at: clang/include/clang/Format/Format.h:3104-3105
+  ///
+  ///class C {}
+  ///};
+  /// \endcode





Comment at: clang/lib/Format/DefinitionBlockSeparator.cpp:55
+  auto insertReplacement = [&]() {
+// Do not handle EOF newlines
+assert(TargetToken);

HazardyKnusperkeks wrote:
> Here also full stop, please. And following comments.
Not done. :)


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

https://reviews.llvm.org/D116314

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


[PATCH] D116316: [clang-format] Add an experimental option to remove optional control statement braces in LLVM C++ code

2021-12-30 Thread Björn Schäpers via Phabricator via cfe-commits
HazardyKnusperkeks added inline comments.



Comment at: clang/lib/Format/UnwrappedLineParser.cpp:2303
+  assert(IfRightBrace->MatchingParen == IfLeftBrace);
+  IfLeftBrace->MatchingParen = nullptr;
+  IfRightBrace->MatchingParen = nullptr;

owenpan wrote:
> HazardyKnusperkeks wrote:
> > Why null that?
> `MatchingParen` is used to flag braces that may be optional. If it turns out 
> that they should not be removed, we must reset it. Otherwise, the test case 
> on line 23314 in FormatTest.cpp below would fail.
Is `MatchingParen` for (if) braces null before this patch? Because I would 
expect that always to be set, if there is a matching brace and maybe base 
patches on that assumption.


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

https://reviews.llvm.org/D116316

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


[PATCH] D116283: [clang-format] Add an option to add a space between operator overloading and opening parentheses

2021-12-30 Thread Björn Schäpers via Phabricator via cfe-commits
HazardyKnusperkeks added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:14545
   verifyFormat("auto lambda = []() { return 0; };", SomeSpace2);
+
+  FormatStyle SpaceAfterOperatorOverloading = getLLVMStyle();

rajatbajpai wrote:
> MyDeveloperDay wrote:
> > There should be a PARSE unit test too please
> I'm sorry if I misunderstood it, do you mean tests using CHECK_PARSE? I am 
> confirming this because I didn't find any such test case for existing 
> //SpaceBeforeParensOptions// options.
Than this has slipped through, but there should be a test for every parsing 
aspect.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116283

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


[PATCH] D107275: [Sema] a[x] has type T when a has type T* or T[], even when T is dependent

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.

In D107275#3182906 , @kadircet wrote:

> I am more worried about creating "incorrect" nodes in some cases. I think it 
> isn't valid in C/C++ for both LHS && RHS to be pointers/arrays in a subscript 
> expression, but I've got no idea about when it's diagnosed in clang and what 
> is put into the AST.
>
> ... we'll have a bunch of expressions with erroneous `ResultType` info which 
> might trip over some things.

Yeah, I think this is a problem. To put it another way:

- if `X is Foo*` and y is dependent, `x[y]` has type `Foo` *or* it is invalid
- if we claim it has type `Foo` then either template-instantiation must check 
it's valid, or we may accept invalid code
- accepting invalid code can turn into miscompiles via SFINAE

Probably rebuilding during template instantiation does verify enough but I'm 
not 100% sure.

In the motivating case, the subscript is a known integer type and the LHS is an 
array or pointer. In this case we don't have the above concern, and we also 
don't have my #1 above. So I'll restrict the code to cover that case.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D107275

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


[PATCH] D116385: [clangd] Code action for creating an ObjC initializer

2021-12-30 Thread David Goldman via Phabricator via cfe-commits
dgoldman updated this revision to Diff 396706.
dgoldman added a comment.

Add another minor test case


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116385

Files:
  clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt
  clang-tools-extra/clangd/refactor/tweaks/ObjCMemberwiseInitializer.cpp
  clang-tools-extra/clangd/unittests/CMakeLists.txt
  clang-tools-extra/clangd/unittests/tweaks/ObjCMemberwiseInitializerTests.cpp

Index: clang-tools-extra/clangd/unittests/tweaks/ObjCMemberwiseInitializerTests.cpp
===
--- /dev/null
+++ clang-tools-extra/clangd/unittests/tweaks/ObjCMemberwiseInitializerTests.cpp
@@ -0,0 +1,152 @@
+//===-- ObjCMemberwiseInitializerTests.cpp --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "TestTU.h"
+#include "TweakTesting.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(ObjCMemberwiseInitializer);
+
+TEST_F(ObjCMemberwiseInitializerTest, TestAvailability) {
+  FileName = "TestTU.m";
+
+  // Ensure the action can't be triggered since arc is disabled.
+  EXPECT_UNAVAILABLE(R"cpp(
+@interface Fo^o
+@end
+  )cpp");
+
+  ExtraArgs.push_back("-fobjc-arc");
+
+  // Ensure the action can be initiated on the interface and implementation,
+  // but not on the forward declaration.
+  EXPECT_AVAILABLE(R"cpp(
+@interface Fo^o
+@end
+  )cpp");
+  EXPECT_AVAILABLE(R"cpp(
+@interface Foo
+@end
+
+@implementation F^oo
+@end
+  )cpp");
+  EXPECT_UNAVAILABLE("@class Fo^o;");
+
+  // Ensure that the action can be triggered on ivars and properties,
+  // including selecting both.
+  EXPECT_AVAILABLE(R"cpp(
+@interface Foo {
+  id _fi^eld;
+}
+@end
+  )cpp");
+  EXPECT_AVAILABLE(R"cpp(
+@interface Foo
+@property(nonatomic) id fi^eld;
+@end
+  )cpp");
+  EXPECT_AVAILABLE(R"cpp(
+@interface Foo {
+  id _fi^eld;
+}
+@property(nonatomic) id pr^op;
+@end
+  )cpp");
+
+  // Ensure that the action can't be triggered on property synthesis
+  // and methods.
+  EXPECT_UNAVAILABLE(R"cpp(
+@interface Foo
+@property(nonatomic) id prop;
+@end
+
+@implementation Foo
+@dynamic pr^op;
+@end
+  )cpp");
+  EXPECT_UNAVAILABLE(R"cpp(
+@interface Foo
+@end
+
+@implementation Foo
+- (void)fo^o {}
+@end
+  )cpp");
+}
+
+TEST_F(ObjCMemberwiseInitializerTest, Test) {
+  FileName = "TestTU.m";
+  ExtraArgs.push_back("-fobjc-arc");
+
+  const char *Input = R"cpp(
+@interface Foo {
+  id [[_field;
+}
+@property(nonatomic) id prop]];
+@property(nonatomic) id notSelected;
+@end)cpp";
+  const char *Output = R"cpp(
+@interface Foo {
+  id _field;
+}
+@property(nonatomic) id prop;
+@property(nonatomic) id notSelected;
+
+- (instancetype)initWithField:(id)field prop:(id)prop;
+
+@end)cpp";
+  EXPECT_EQ(apply(Input), Output);
+
+  Input = R"cpp(
+@interface Foo
+@property(nonatomic, nullable) id somePrettyLongPropertyName;
+@property(nonatomic, nonnull) id someReallyLongPropertyName;
+@end
+
+@implementation F^oo
+
+- (instancetype)init {
+  return self;
+}
+
+@end)cpp";
+  Output = R"cpp(
+@interface Foo
+@property(nonatomic, nullable) id somePrettyLongPropertyName;
+@property(nonatomic, nonnull) id someReallyLongPropertyName;
+@end
+
+@implementation Foo
+
+- (instancetype)init {
+  return self;
+}
+
+- (instancetype)initWithSomePrettyLongPropertyName:(nullable id)somePrettyLongPropertyName someReallyLongPropertyName:(nonnull id)someReallyLongPropertyName {
+  self = [super init];
+  if (self) {
+_somePrettyLongPropertyName = somePrettyLongPropertyName;
+_someReallyLongPropertyName = someReallyLongPropertyName;
+  }
+  return self;
+}
+
+@end)cpp";
+  EXPECT_EQ(apply(Input), Output);
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
Index: clang-tools-extra/clangd/unittests/CMakeLists.txt
===
--- clang-tools-extra/clangd/unittests/CMakeLists.txt
+++ clang-tools-extra/clangd/unittests/CMakeLists.txt
@@ -117,6 +117,7 @@
   tweaks/ExtractFunctionTests.cpp
   tweaks/ExtractVariableTests.cpp
   tweaks/ObjCLocalizeStringLiteralTests.cpp
+  tweaks/ObjCMemberwiseInitializerTests.cpp
   tweaks/PopulateSwitchTests.cpp
   tweaks/RawStringLiteralTests.cpp
   tweaks/RemoveUsingNamespaceTests.cpp
Index: clang-tools-extra/clangd/refactor/tweaks/ObjCMemberwiseInitializer.cpp
===
--- /dev/null
+++ clang-tools-extra/clangd/refactor/tweaks

[PATCH] D116314: [clang-format] Add style to separate definition blocks

2021-12-30 Thread ksyx via Phabricator via cfe-commits
ksyx updated this revision to Diff 396709.
ksyx marked 2 inline comments as done.
ksyx added a comment.

minor fixes.


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

https://reviews.llvm.org/D116314

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/CMakeLists.txt
  clang/lib/Format/DefinitionBlockSeparator.cpp
  clang/lib/Format/DefinitionBlockSeparator.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/WhitespaceManager.cpp
  clang/lib/Format/WhitespaceManager.h
  clang/unittests/Format/CMakeLists.txt
  clang/unittests/Format/DefinitionBlockSeparatorTest.cpp

Index: clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
===
--- /dev/null
+++ clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
@@ -0,0 +1,316 @@
+//===- DefinitionBlockSeparatorTest.cpp - Formatting unit tests ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "FormatTestUtils.h"
+#include "clang/Format/Format.h"
+
+#include "llvm/Support/Debug.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "definition-block-separator-test"
+
+namespace clang {
+namespace format {
+namespace {
+
+class DefinitionBlockSeparatorTest : public ::testing::Test {
+protected:
+  static std::string
+  separateDefinitionBlocks(llvm::StringRef Code,
+   const std::vector &Ranges,
+   const FormatStyle &Style = getLLVMStyle()) {
+LLVM_DEBUG(llvm::errs() << "---\n");
+LLVM_DEBUG(llvm::errs() << Code << "\n\n");
+tooling::Replacements Replaces =
+clang::format::separateDefinitionBlocks(Style, Code, Ranges, "");
+auto Result = applyAllReplacements(Code, Replaces);
+EXPECT_TRUE(static_cast(Result));
+LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+return *Result;
+  }
+
+  static std::string
+  separateDefinitionBlocks(llvm::StringRef Code,
+   const FormatStyle &Style = getLLVMStyle()) {
+return separateDefinitionBlocks(
+Code,
+/*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
+  }
+
+  static void verifyFormat(llvm::StringRef Code,
+   const FormatStyle &Style = getLLVMStyle(),
+   llvm::StringRef ExpectedCode = "") {
+bool HasOriginalCode = true;
+if (ExpectedCode == "") {
+  ExpectedCode = Code;
+  HasOriginalCode = false;
+}
+
+FormatStyle InverseStyle = Style;
+if (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always)
+  InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
+else
+  InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+EXPECT_EQ(ExpectedCode.str(), separateDefinitionBlocks(ExpectedCode, Style))
+<< "Expected code is not stable";
+std::string InverseResult = separateDefinitionBlocks(Code, InverseStyle);
+EXPECT_NE(Code.str(), InverseResult)
+<< "Inverse formatting makes no difference";
+std::string CodeToFormat =
+HasOriginalCode ? Code.str() : removeEmptyLines(Code);
+std::string Result = separateDefinitionBlocks(CodeToFormat, Style);
+EXPECT_EQ(ExpectedCode.str(), Result) << "Test failed. Formatted:\n"
+  << Result;
+  }
+
+  static std::string removeEmptyLines(llvm::StringRef Code) {
+std::string Result = "";
+for (auto Char : Code.str()) {
+  if (Result.size()) {
+auto LastChar = Result.back();
+if ((Char == '\n' && LastChar == '\n') ||
+(Char == '\r' && (LastChar == '\r' || LastChar == '\n')))
+  continue;
+  }
+  Result.push_back(Char);
+}
+return Result;
+  }
+};
+
+TEST_F(DefinitionBlockSeparatorTest, Basic) {
+  FormatStyle Style = getLLVMStyle();
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+  verifyFormat("int foo() {\n"
+   "  int i, j;\n"
+   "}\n"
+   "\n"
+   "int bar() {\n"
+   "  int j, k;\n"
+   "}",
+   Style);
+
+  verifyFormat("struct foo {\n"
+   "  int i, j;\n"
+   "};\n"
+   "\n"
+   "struct bar {\n"
+   "  int j, k;\n"
+   "};",
+   Style);
+
+  verifyFormat("class foo {\n"
+   "  int i, j;\n"
+   "};\n"
+   "\n"
+   "class bar {\n"
+   "  int j, k;\n"
+   "};",
+   Style);
+
+  verifyFormat("namespace foo {\n"
+   "  int i, j;\n"
+   "}\n"
+   "\n"
+   "namespace bar {\n"
+   "  int j, k;

[PATCH] D116280: [clang] adds unary type trait checks as compiler built-ins

2021-12-30 Thread Christopher Di Bella via Phabricator via cfe-commits
cjdb updated this revision to Diff 396711.
cjdb edited the summary of this revision.
cjdb added a comment.

rebases to activate CI


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116280

Files:
  clang/include/clang/Basic/TokenKinds.def
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/SemaCXX/type-traits.cpp

Index: clang/test/SemaCXX/type-traits.cpp
===
--- clang/test/SemaCXX/type-traits.cpp
+++ clang/test/SemaCXX/type-traits.cpp
@@ -345,11 +345,19 @@
 }
 
 typedef Enum EnumType;
+typedef EnumClass EnumClassType;
 
 void is_enum()
 {
   { int arr[T(__is_enum(Enum))]; }
   { int arr[T(__is_enum(EnumType))]; }
+  { int arr[T(__is_enum(SignedEnum))]; }
+  { int arr[T(__is_enum(UnsignedEnum))]; }
+
+  { int arr[T(__is_enum(EnumClass))]; }
+  { int arr[T(__is_enum(EnumClassType))]; }
+  { int arr[T(__is_enum(SignedEnumClass))]; }
+  { int arr[T(__is_enum(UnsignedEnumClass))]; }
 
   { int arr[F(__is_enum(int))]; }
   { int arr[F(__is_enum(Union))]; }
@@ -363,6 +371,30 @@
   { int arr[F(__is_enum(HasAnonymousUnion))]; }
 }
 
+void is_scoped_enum()
+{
+  { int arr[F(__is_scoped_enum(Enum))]; }
+  { int arr[F(__is_scoped_enum(EnumType))]; }
+  { int arr[F(__is_scoped_enum(SignedEnum))]; }
+  { int arr[F(__is_scoped_enum(UnsignedEnum))]; }
+
+  { int arr[T(__is_scoped_enum(EnumClass))]; }
+  { int arr[T(__is_scoped_enum(EnumClassType))]; }
+  { int arr[T(__is_scoped_enum(SignedEnumClass))]; }
+  { int arr[T(__is_scoped_enum(UnsignedEnumClass))]; }
+
+  { int arr[F(__is_scoped_enum(int))]; }
+  { int arr[F(__is_scoped_enum(Union))]; }
+  { int arr[F(__is_scoped_enum(Int))]; }
+  { int arr[F(__is_scoped_enum(IntAr))]; }
+  { int arr[F(__is_scoped_enum(UnionAr))]; }
+  { int arr[F(__is_scoped_enum(Derives))]; }
+  { int arr[F(__is_scoped_enum(ClassType))]; }
+  { int arr[F(__is_scoped_enum(cvoid))]; }
+  { int arr[F(__is_scoped_enum(IntArNB))]; }
+  { int arr[F(__is_scoped_enum(HasAnonymousUnion))]; }
+}
+
 struct FinalClass final {
 };
 
@@ -702,6 +734,36 @@
   int t31[F(__is_array(cvoid*))];
 }
 
+void is_bounded_array()
+{
+  int t01[T(__is_bounded_array(IntAr))];
+  int t02[F(__is_bounded_array(IntArNB))];
+  int t03[T(__is_bounded_array(UnionAr))];
+
+  int t10[F(__is_bounded_array(void))];
+  int t11[F(__is_bounded_array(cvoid))];
+  int t12[F(__is_bounded_array(float))];
+  int t13[F(__is_bounded_array(double))];
+  int t14[F(__is_bounded_array(long double))];
+  int t15[F(__is_bounded_array(bool))];
+  int t16[F(__is_bounded_array(char))];
+  int t17[F(__is_bounded_array(signed char))];
+  int t18[F(__is_bounded_array(unsigned char))];
+  int t19[F(__is_bounded_array(wchar_t))];
+  int t20[F(__is_bounded_array(short))];
+  int t21[F(__is_bounded_array(unsigned short))];
+  int t22[F(__is_bounded_array(int))];
+  int t23[F(__is_bounded_array(unsigned int))];
+  int t24[F(__is_bounded_array(long))];
+  int t25[F(__is_bounded_array(unsigned long))];
+  int t26[F(__is_bounded_array(Union))];
+  int t27[F(__is_bounded_array(Derives))];
+  int t28[F(__is_bounded_array(ClassType))];
+  int t29[F(__is_bounded_array(Enum))];
+  int t30[F(__is_bounded_array(void*))];
+  int t31[F(__is_bounded_array(cvoid*))];
+}
+
 template  void tmpl_func(T&) {}
 
 template  struct type_wrapper {
@@ -934,6 +996,43 @@
   int t34[F(__is_pointer(void (StructWithMembers::*) ()))];
 }
 
+void is_null_pointer()
+{
+  StructWithMembers x;
+
+  int t00[T(__is_null_pointer(decltype(nullptr)))];
+  int t01[F(__is_null_pointer(void*))];
+  int t02[F(__is_null_pointer(cvoid*))];
+  int t03[F(__is_null_pointer(cvoid*))];
+  int t04[F(__is_null_pointer(char*))];
+  int t05[F(__is_null_pointer(int*))];
+  int t06[F(__is_null_pointer(int**))];
+  int t07[F(__is_null_pointer(ClassType*))];
+  int t08[F(__is_null_pointer(Derives*))];
+  int t09[F(__is_null_pointer(Enum*))];
+  int t10[F(__is_null_pointer(IntArNB*))];
+  int t11[F(__is_null_pointer(Union*))];
+  int t12[F(__is_null_pointer(UnionAr*))];
+  int t13[F(__is_null_pointer(StructWithMembers*))];
+  int t14[F(__is_null_pointer(void (*)()))];
+
+  int t20[F(__is_null_pointer(void))];
+  int t21[F(__is_null_pointer(cvoid))];
+  int t22[F(__is_null_pointer(cvoid))];
+  int t23[F(__is_null_pointer(char))];
+  int t24[F(__is_null_pointer(int))];
+  int t25[F(__is_null_pointer(int))];
+  int t26[F(__is_null_pointer(ClassType))];
+  int t27[F(__is_null_pointer(Derives))];
+  int t28[F(__is_null_pointer(Enum))];
+  int t29[F(__is_null_pointer(IntArNB))];
+  int t30[F(__is_null_pointer(Union))];
+  int t31[F(__is_null_pointer(UnionAr))];
+  int t32[F(__is_null_pointer(StructWithMembers))];
+  int t33[F(__is_null_pointer(int StructWithMembers::*))];
+  int t34[F(__is_null_pointer(void (StructWithMembers::*) ()))];
+}
+
 void is_member_object_pointer()
 {
   StructWithMembers x;
Index: clang/lib

[PATCH] D116314: [clang-format] Add style to separate definition blocks

2021-12-30 Thread Björn Schäpers via Phabricator via cfe-commits
HazardyKnusperkeks requested changes to this revision.
HazardyKnusperkeks added a comment.
This revision now requires changes to proceed.

Only some small changes, then it looks good to me. And I will definitely use 
it, once it is landed.




Comment at: clang/include/clang/Format/Format.h:3056
+SDS_Leave,
+/// Insert empty lines between definition blocks.
+SDS_Always,

Right?



Comment at: clang/include/clang/Format/Format.h:4097
+   ArrayRef Ranges,
+   StringRef FileName = "");
+

The only use of this function I found is in the tests and it sets the argument, 
or am I mistaken?



Comment at: clang/lib/Format/DefinitionBlockSeparator.cpp:33-34
+SmallVectorImpl &Lines, tooling::Replacements &Result) {
+  if (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Leave)
+return;
+  auto likelyDefinition = [this](AnnotatedLine *Line) {

It should never be instantiated with that.



Comment at: clang/lib/Format/DefinitionBlockSeparator.cpp:35
+return;
+  auto likelyDefinition = [this](AnnotatedLine *Line) {
+if (Line->MightBeFunctionDecl && Line->mightBeFunctionDefinition())





Comment at: clang/lib/Format/DefinitionBlockSeparator.cpp:59
+  for (unsigned I = 0; I < Lines.size(); I++) {
+auto Line = Lines[I];
+FormatToken *TargetToken = nullptr;





Comment at: clang/lib/Format/DefinitionBlockSeparator.cpp:63
+auto OpeningLineIndex = Line->MatchingOpeningBlockLineIndex;
+const auto insertReplacement = [&](int NewlineToInsert) {
+  assert(TargetLine);





Comment at: clang/lib/Format/DefinitionBlockSeparator.cpp:76
+};
+const auto followingOtherOpening = [&]() {
+  return OpeningLineIndex == 0 ||





Comment at: clang/lib/Format/DefinitionBlockSeparator.cpp:80
+};
+const auto hasEnumOnLine = [Line]() {
+  FormatToken *CurrentToken = Line->First;





Comment at: clang/lib/Format/DefinitionBlockSeparator.cpp:93
+if (hasEnumOnLine()) {
+  // We have no scope opening/closing information for enum
+  IsDefBlock = 1;





Comment at: clang/lib/Format/DefinitionBlockSeparator.cpp:128
+
+// Not the last token
+if (IsDefBlock && I + 1 < Lines.size()) {





Comment at: clang/lib/Format/Format.cpp:455
+template <>
+struct ScalarEnumerationTraits {
+  static void enumeration(IO &IO, FormatStyle::SeparateDefinitionStyle &Value) 
{

Please try to find a better place, regarding sorting (yeah the are some 
mismatches).



Comment at: clang/lib/Format/Format.cpp:783
 IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines);
+IO.mapOptional("SeparateDefinitionBlocks", Style.SeparateDefinitionBlocks);
 IO.mapOptional("SortIncludes", Style.SortIncludes);

Please sort before ShortNamespaceLines



Comment at: clang/lib/Format/Format.cpp:3059
 
+  if (Style.SeparateDefinitionBlocks)
+Passes.emplace_back([&](const Environment &Env) {





Comment at: clang/lib/Format/WhitespaceManager.h:48
 
+  /// Infers whether the input is using CRLF
+  static bool inputUsesCRLF(StringRef Text, bool DefaultToCRLF);




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

https://reviews.llvm.org/D116314

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


[PATCH] D116425: [clang-tidy] Improve modernize-redundant-void-arg to recognize macro uses

2021-12-30 Thread Richard via Phabricator via cfe-commits
LegalizeAdulthood created this revision.
LegalizeAdulthood added a reviewer: alexfh.
LegalizeAdulthood added a project: clang-tools-extra.
Herald added subscribers: carlosgalvezp, xazax.hun.
LegalizeAdulthood requested review of this revision.

Sometimes a macro invocation will look like an argument list
declaration.  Improve the check to detect this situation and not
try to modify the macro invocation.

Thanks to Nathan James for the fix.

Fixes #43791


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116425

Files:
  clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
@@ -556,3 +556,9 @@
   S_3();
   g_3();
 }
+
+#define return_t(T) T
+return_t(void) func(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: redundant void argument list in 
function declaration
+// CHECK-FIXES: return_t(void) func();
+#undef return_t
Index: clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -97,9 +97,12 @@
 
 void RedundantVoidArgCheck::processFunctionDecl(
 const MatchFinder::MatchResult &Result, const FunctionDecl *Function) {
+  const auto *Method = dyn_cast(Function);
+  SourceLocation Start = Method && Method->getParent()->isLambda()
+ ? Method->getBeginLoc()
+ : Function->getLocation();
+  SourceLocation End = Function->getEndLoc();
   if (Function->isThisDeclarationADefinition()) {
-SourceLocation Start = Function->getBeginLoc();
-SourceLocation End = Function->getEndLoc();
 if (const Stmt *Body = Function->getBody()) {
   End = Body->getBeginLoc();
   if (End.isMacroID() &&
@@ -110,7 +113,7 @@
 removeVoidArgumentTokens(Result, SourceRange(Start, End),
  "function definition");
   } else {
-removeVoidArgumentTokens(Result, Function->getSourceRange(),
+removeVoidArgumentTokens(Result, SourceRange(Start, End),
  "function declaration");
   }
 }


Index: clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
@@ -556,3 +556,9 @@
   S_3();
   g_3();
 }
+
+#define return_t(T) T
+return_t(void) func(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: redundant void argument list in function declaration
+// CHECK-FIXES: return_t(void) func();
+#undef return_t
Index: clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -97,9 +97,12 @@
 
 void RedundantVoidArgCheck::processFunctionDecl(
 const MatchFinder::MatchResult &Result, const FunctionDecl *Function) {
+  const auto *Method = dyn_cast(Function);
+  SourceLocation Start = Method && Method->getParent()->isLambda()
+ ? Method->getBeginLoc()
+ : Function->getLocation();
+  SourceLocation End = Function->getEndLoc();
   if (Function->isThisDeclarationADefinition()) {
-SourceLocation Start = Function->getBeginLoc();
-SourceLocation End = Function->getEndLoc();
 if (const Stmt *Body = Function->getBody()) {
   End = Body->getBeginLoc();
   if (End.isMacroID() &&
@@ -110,7 +113,7 @@
 removeVoidArgumentTokens(Result, SourceRange(Start, End),
  "function definition");
   } else {
-removeVoidArgumentTokens(Result, Function->getSourceRange(),
+removeVoidArgumentTokens(Result, SourceRange(Start, End),
  "function declaration");
   }
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116316: [clang-format] Add an experimental option to remove optional control statement braces in LLVM C++ code

2021-12-30 Thread Owen Pan via Phabricator via cfe-commits
owenpan added inline comments.



Comment at: clang/lib/Format/UnwrappedLineParser.cpp:2303
+  assert(IfRightBrace->MatchingParen == IfLeftBrace);
+  IfLeftBrace->MatchingParen = nullptr;
+  IfRightBrace->MatchingParen = nullptr;

HazardyKnusperkeks wrote:
> owenpan wrote:
> > HazardyKnusperkeks wrote:
> > > Why null that?
> > `MatchingParen` is used to flag braces that may be optional. If it turns 
> > out that they should not be removed, we must reset it. Otherwise, the test 
> > case on line 23314 in FormatTest.cpp below would fail.
> Is `MatchingParen` for (if) braces null before this patch? Because I would 
> expect that always to be set, if there is a matching brace and maybe base 
> patches on that assumption.
Yes, it's not set until it's in the token annotator. That's why I added the 
assertion in the annotator.


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

https://reviews.llvm.org/D116316

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


[PATCH] D107275: [Sema] a[x] has type T when a has type T* or T[], even when T is dependent

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.

In D107275#3214272 , @sammccall wrote:

> In the motivating case, the subscript is a known integer type and the LHS is 
> an array or pointer. In this case we don't have the above concern, and we 
> also don't have my #1 above. So I'll restrict the code to cover that case.

Actually I like the restriction a lot, but this *doesn't* take care of #1.
Even with the restriction, we can still end up with a non-dependent type for 
our type-dependent ArraySubscriptExpr:

Case 1: base and index do not have dependent types. One example of this is that 
base can be a reference to a static member of the current instantiation that is 
an array of unknown bound.

  template 
  struct foo {
static int arr[];
static constexpr int first = arr[0]; // arr is type-dependent but has 
non-dependent type int[].
  };

Case 2: base is an array with dependent size.

  template 
  struct foo {
static int arr[N];
static constexpr int first = arr[0];
  };

Case 3: index is a dependent type that is nevertheless known to be a good index.

  static int arr[];
  
  template 
  struct foo {
enum E { Zero = 0; }
static constexpr int first = arr[Zero];
  };

So I see two options:

- arbitrarily force the type to be dependent - if we end up with a 
non-dependent type, use DependentTy instead. This "forgetting" the type is 
consistent with other situations, like `this->member` inside a template, which 
the standard says is type-dependent and clang assigns DependentTy.
- accept that we have type-dependent expressions of non-dependent types in some 
cases. This is consistent with the idea that such exceptions exist today (the 
DeclRefExpr to unknown-bound-array static members mentioned above).

I feel a little out of my depth, so I'm going to go with the "safe option" of 
bailing out to DependentTy.
@rsmith or other experts, It would be great to get guidance on whether it's 
safe to create type-dependent expressions without dependent types.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D107275

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


[PATCH] D116314: [clang-format] Add style to separate definition blocks

2021-12-30 Thread ksyx via Phabricator via cfe-commits
ksyx updated this revision to Diff 396727.
ksyx marked 9 inline comments as done.
ksyx added a comment.

- Apply review suggestions.
- Assert the style is not `SDS_Leave` in private method, while return no change 
in public method if so.
- Rename loop variable `Line` to `CurrentLine`


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

https://reviews.llvm.org/D116314

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/CMakeLists.txt
  clang/lib/Format/DefinitionBlockSeparator.cpp
  clang/lib/Format/DefinitionBlockSeparator.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/WhitespaceManager.cpp
  clang/lib/Format/WhitespaceManager.h
  clang/unittests/Format/CMakeLists.txt
  clang/unittests/Format/DefinitionBlockSeparatorTest.cpp

Index: clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
===
--- /dev/null
+++ clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
@@ -0,0 +1,316 @@
+//===- DefinitionBlockSeparatorTest.cpp - Formatting unit tests ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "FormatTestUtils.h"
+#include "clang/Format/Format.h"
+
+#include "llvm/Support/Debug.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "definition-block-separator-test"
+
+namespace clang {
+namespace format {
+namespace {
+
+class DefinitionBlockSeparatorTest : public ::testing::Test {
+protected:
+  static std::string
+  separateDefinitionBlocks(llvm::StringRef Code,
+   const std::vector &Ranges,
+   const FormatStyle &Style = getLLVMStyle()) {
+LLVM_DEBUG(llvm::errs() << "---\n");
+LLVM_DEBUG(llvm::errs() << Code << "\n\n");
+tooling::Replacements Replaces =
+clang::format::separateDefinitionBlocks(Style, Code, Ranges, "");
+auto Result = applyAllReplacements(Code, Replaces);
+EXPECT_TRUE(static_cast(Result));
+LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+return *Result;
+  }
+
+  static std::string
+  separateDefinitionBlocks(llvm::StringRef Code,
+   const FormatStyle &Style = getLLVMStyle()) {
+return separateDefinitionBlocks(
+Code,
+/*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
+  }
+
+  static void verifyFormat(llvm::StringRef Code,
+   const FormatStyle &Style = getLLVMStyle(),
+   llvm::StringRef ExpectedCode = "") {
+bool HasOriginalCode = true;
+if (ExpectedCode == "") {
+  ExpectedCode = Code;
+  HasOriginalCode = false;
+}
+
+FormatStyle InverseStyle = Style;
+if (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always)
+  InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
+else
+  InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+EXPECT_EQ(ExpectedCode.str(), separateDefinitionBlocks(ExpectedCode, Style))
+<< "Expected code is not stable";
+std::string InverseResult = separateDefinitionBlocks(Code, InverseStyle);
+EXPECT_NE(Code.str(), InverseResult)
+<< "Inverse formatting makes no difference";
+std::string CodeToFormat =
+HasOriginalCode ? Code.str() : removeEmptyLines(Code);
+std::string Result = separateDefinitionBlocks(CodeToFormat, Style);
+EXPECT_EQ(ExpectedCode.str(), Result) << "Test failed. Formatted:\n"
+  << Result;
+  }
+
+  static std::string removeEmptyLines(llvm::StringRef Code) {
+std::string Result = "";
+for (auto Char : Code.str()) {
+  if (Result.size()) {
+auto LastChar = Result.back();
+if ((Char == '\n' && LastChar == '\n') ||
+(Char == '\r' && (LastChar == '\r' || LastChar == '\n')))
+  continue;
+  }
+  Result.push_back(Char);
+}
+return Result;
+  }
+};
+
+TEST_F(DefinitionBlockSeparatorTest, Basic) {
+  FormatStyle Style = getLLVMStyle();
+  Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+  verifyFormat("int foo() {\n"
+   "  int i, j;\n"
+   "}\n"
+   "\n"
+   "int bar() {\n"
+   "  int j, k;\n"
+   "}",
+   Style);
+
+  verifyFormat("struct foo {\n"
+   "  int i, j;\n"
+   "};\n"
+   "\n"
+   "struct bar {\n"
+   "  int j, k;\n"
+   "};",
+   Style);
+
+  verifyFormat("class foo {\n"
+   "  int i, j;\n"
+   "};\n"
+   "\n"
+   "class bar {\n"
+   "  int j, k;\n"
+   "};",
+   Style);
+
+  verif

[PATCH] D116314: [clang-format] Add style to separate definition blocks

2021-12-30 Thread ksyx via Phabricator via cfe-commits
ksyx added inline comments.



Comment at: clang/include/clang/Format/Format.h:4097
+   ArrayRef Ranges,
+   StringRef FileName = "");
+

HazardyKnusperkeks wrote:
> The only use of this function I found is in the tests and it sets the 
> argument, or am I mistaken?
I suppose this function might also be called from some users of the library 
other than clangfmt itself? Besides, the declarations nearby are setting this 
default value.



Comment at: clang/lib/Format/DefinitionBlockSeparator.cpp:35
+return;
+  auto likelyDefinition = [this](AnnotatedLine *Line) {
+if (Line->MightBeFunctionDecl && Line->mightBeFunctionDefinition())

HazardyKnusperkeks wrote:
> 
[[ 
https://github.com/llvm/llvm-project/blob/298367ee6e36eeb1b193ad9fa92082c2ef2345a3/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp#L2393
 | Some other lambdas ]] I found use lowercased leading letter, as it looks 
like a function (call).


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

https://reviews.llvm.org/D116314

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


[PATCH] D107275: [Sema] a[x] has type T when a has type T* or T[], even when T is dependent

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall updated this revision to Diff 396730.
sammccall added a comment.

Restrict to array/pointer + index, insist on a dependent type.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D107275

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/AST/ast-dump-array.cpp

Index: clang/test/AST/ast-dump-array.cpp
===
--- clang/test/AST/ast-dump-array.cpp
+++ clang/test/AST/ast-dump-array.cpp
@@ -26,3 +26,58 @@
   using const_array_T_size = const T[Size];
   // CHECK: `-DependentSizedArrayType 0x{{[^ ]*}} 'const T[Size]' dependent   
 };
+
+struct V {};
+template 
+void testDependentSubscript() {
+  U* a;
+  U b[5];
+  Idx i{};
+  enum E { One = 1 };
+
+  // Can types of subscript expressions can be determined?
+  // LHS is a type-dependent array, RHS is a known integer type.
+  a[1];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+  b[1];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+
+  // Reverse case: RHS is a type-dependent array, LHS is an integer.
+  1[a];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+  1[b];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+
+  // LHS is a type-dependent array, RHS is type-dependent.
+  a[i];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+  b[i];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+
+  V *a2;
+  V b2[5];
+
+  // LHS is a known array, RHS is type-dependent.
+  a2[i];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+  b2[i];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+
+  // LHS is a known array, RHS is a type-dependent index.
+  // We know the element type is V, but insist on some dependent type.
+  a2[One];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+  b2[One];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+
+  V b3[N];
+  // LHS is an array with dependent bounds but known elements.
+  // We insist on a dependent type.
+  b3[0];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+
+  U b4[N];
+  // LHS is an array with dependent bounds and dependent elements.
+  b4[0];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -4645,6 +4645,38 @@
   return isa(BaseNoParens);
 }
 
+// Returns the type used for LHS[RHS], given one of LHS, RHS is type-dependent.
+// Typically this is DependentTy, but can sometimes be more precise.
+//
+// There are cases when we could determine a non-dependent type:
+//  - LHS and RHS may have non-dependent types despite being type-dependent
+//(e.g. unbounded array static members of the current instantiation)
+//  - one may be a dependent-sized array with known element type
+//  - one may be a dependent-typed valid index (enum in current instantiation)
+//
+// We *always* return a dependent type, in such cases it is DependentTy.
+// This avoids creating type-dependent expressions with non-dependent types.
+// FIXME: is this important to avoid? See https://reviews.llvm.org/D107275
+static QualType getDependentArraySubscriptType(Expr *LHS, Expr *RHS,
+   const ASTContext &Ctx) {
+  assert(LHS->isTypeDependent() || RHS->isTypeDependent());
+  QualType LTy = LHS->getType(), RTy = RHS->getType();
+  QualType Result = Ctx.DependentTy;
+  if (RTy->isIntegralOrUnscopedEnumerationType()) {
+if (const PointerType *PT = LTy->getAs())
+  Result = PT->getPointeeType();
+else if (const ArrayType *AT = LTy->getAsArrayTypeUnsafe())
+  Result = AT->getElementType();
+  } else if (LTy->isIntegralOrUnscopedEnumerationType()) {
+if (const PointerType *PT = RTy->getAs())
+  Result = PT->getPointeeType();
+else if (const ArrayType *AT = RTy->getAsArrayTypeUnsafe())
+  Result = AT->getElementType();
+  }
+  // Ensure we return a dependent type.
+  return Result->isDependentType() ? Result : Ctx.DependentTy;
+}
+
 ExprResult
 Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc,
   Expr *idx, SourceLocation rbLoc) {
@@ -4737,8 +4769,9 @@
   // Build an unanalyzed expression if either operand is type-dependent.
   if (getLangOpts().CPlusPlus &&
   (base->isTypeDependent() || idx->isTypeDependent())) {
-return new (Context) ArraySubscriptExpr(base, idx, Context.DependentTy,
-VK_LValue, OK_Ordinary, rbLoc);
+return new (Context) ArraySubscriptExpr(
+base, idx, getDependentArraySubscriptType(base, idx, getASTContext()),
+VK_LValue, OK_Ordinary, rbLoc);
   }
 
   // MSDN, property (C++)
@@ -5492,7 +5525,8 @@
   if (LHSTy->isDependentType() || 

[PATCH] D107275: [Sema] a[x] has type T when a has type T* or T[], even when T is dependent

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.

I'm going to land this now in its conservative version based on:

> if you think we're covered for those and others don't chime in this week I 
> suppose we can consider this as good to go.

Happy to address any more comments and/or make it less conservative.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D107275

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


[clang] 09f8315 - [Sema] a[x] has type T when a has type T* or T[], even when T is dependent

2021-12-30 Thread Sam McCall via cfe-commits

Author: Sam McCall
Date: 2021-12-31T01:30:39+01:00
New Revision: 09f8315bba391eac1dbdfbdc3fd654c0c0cbe3e7

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

LOG: [Sema] a[x] has type T when a has type T* or T[], even when T is dependent

This more precise type is useful for tools, e.g.
fixes https://github.com/clangd/clangd/issues/831

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

Added: 


Modified: 
clang/lib/Sema/SemaExpr.cpp
clang/test/AST/ast-dump-array.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 736e76152fe48..d454e4877bcef 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4645,6 +4645,38 @@ static bool isMSPropertySubscriptExpr(Sema &S, Expr 
*Base) {
   return isa(BaseNoParens);
 }
 
+// Returns the type used for LHS[RHS], given one of LHS, RHS is type-dependent.
+// Typically this is DependentTy, but can sometimes be more precise.
+//
+// There are cases when we could determine a non-dependent type:
+//  - LHS and RHS may have non-dependent types despite being type-dependent
+//(e.g. unbounded array static members of the current instantiation)
+//  - one may be a dependent-sized array with known element type
+//  - one may be a dependent-typed valid index (enum in current instantiation)
+//
+// We *always* return a dependent type, in such cases it is DependentTy.
+// This avoids creating type-dependent expressions with non-dependent types.
+// FIXME: is this important to avoid? See https://reviews.llvm.org/D107275
+static QualType getDependentArraySubscriptType(Expr *LHS, Expr *RHS,
+   const ASTContext &Ctx) {
+  assert(LHS->isTypeDependent() || RHS->isTypeDependent());
+  QualType LTy = LHS->getType(), RTy = RHS->getType();
+  QualType Result = Ctx.DependentTy;
+  if (RTy->isIntegralOrUnscopedEnumerationType()) {
+if (const PointerType *PT = LTy->getAs())
+  Result = PT->getPointeeType();
+else if (const ArrayType *AT = LTy->getAsArrayTypeUnsafe())
+  Result = AT->getElementType();
+  } else if (LTy->isIntegralOrUnscopedEnumerationType()) {
+if (const PointerType *PT = RTy->getAs())
+  Result = PT->getPointeeType();
+else if (const ArrayType *AT = RTy->getAsArrayTypeUnsafe())
+  Result = AT->getElementType();
+  }
+  // Ensure we return a dependent type.
+  return Result->isDependentType() ? Result : Ctx.DependentTy;
+}
+
 ExprResult
 Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc,
   Expr *idx, SourceLocation rbLoc) {
@@ -4737,8 +4769,9 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, 
SourceLocation lbLoc,
   // Build an unanalyzed expression if either operand is type-dependent.
   if (getLangOpts().CPlusPlus &&
   (base->isTypeDependent() || idx->isTypeDependent())) {
-return new (Context) ArraySubscriptExpr(base, idx, Context.DependentTy,
-VK_LValue, OK_Ordinary, rbLoc);
+return new (Context) ArraySubscriptExpr(
+base, idx, getDependentArraySubscriptType(base, idx, getASTContext()),
+VK_LValue, OK_Ordinary, rbLoc);
   }
 
   // MSDN, property (C++)
@@ -5492,7 +5525,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, 
SourceLocation LLoc,
   if (LHSTy->isDependentType() || RHSTy->isDependentType()) {
 BaseExpr = LHSExp;
 IndexExpr = RHSExp;
-ResultType = Context.DependentTy;
+ResultType =
+getDependentArraySubscriptType(LHSExp, RHSExp, getASTContext());
   } else if (const PointerType *PTy = LHSTy->getAs()) {
 BaseExpr = LHSExp;
 IndexExpr = RHSExp;

diff  --git a/clang/test/AST/ast-dump-array.cpp 
b/clang/test/AST/ast-dump-array.cpp
index 609ad31a0e420..418e4292680ee 100644
--- a/clang/test/AST/ast-dump-array.cpp
+++ b/clang/test/AST/ast-dump-array.cpp
@@ -26,3 +26,58 @@ class array {
   using const_array_T_size = const T[Size];
   // CHECK: `-DependentSizedArrayType 0x{{[^ ]*}} 'const T[Size]' dependent   

 };
+
+struct V {};
+template 
+void testDependentSubscript() {
+  U* a;
+  U b[5];
+  Idx i{};
+  enum E { One = 1 };
+
+  // Can types of subscript expressions can be determined?
+  // LHS is a type-dependent array, RHS is a known integer type.
+  a[1];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+  b[1];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+
+  // Reverse case: RHS is a type-dependent array, LHS is an integer.
+  1[a];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+  1[b];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+
+  // LHS is a type-dependent array, RHS is type-dependent.
+  a[i];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@

[PATCH] D107275: [Sema] a[x] has type T when a has type T* or T[], even when T is dependent

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG09f8315bba39: [Sema] a[x] has type T when a has type T* or 
T[], even when T is dependent (authored by sammccall).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D107275

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/AST/ast-dump-array.cpp

Index: clang/test/AST/ast-dump-array.cpp
===
--- clang/test/AST/ast-dump-array.cpp
+++ clang/test/AST/ast-dump-array.cpp
@@ -26,3 +26,58 @@
   using const_array_T_size = const T[Size];
   // CHECK: `-DependentSizedArrayType 0x{{[^ ]*}} 'const T[Size]' dependent   
 };
+
+struct V {};
+template 
+void testDependentSubscript() {
+  U* a;
+  U b[5];
+  Idx i{};
+  enum E { One = 1 };
+
+  // Can types of subscript expressions can be determined?
+  // LHS is a type-dependent array, RHS is a known integer type.
+  a[1];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+  b[1];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+
+  // Reverse case: RHS is a type-dependent array, LHS is an integer.
+  1[a];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+  1[b];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+
+  // LHS is a type-dependent array, RHS is type-dependent.
+  a[i];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+  b[i];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+
+  V *a2;
+  V b2[5];
+
+  // LHS is a known array, RHS is type-dependent.
+  a2[i];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+  b2[i];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+
+  // LHS is a known array, RHS is a type-dependent index.
+  // We know the element type is V, but insist on some dependent type.
+  a2[One];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+  b2[One];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+
+  V b3[N];
+  // LHS is an array with dependent bounds but known elements.
+  // We insist on a dependent type.
+  b3[0];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} ''
+
+  U b4[N];
+  // LHS is an array with dependent bounds and dependent elements.
+  b4[0];
+  // CHECK: ArraySubscriptExpr {{.*}}line:[[@LINE-1]]{{.*}} 'U'
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -4645,6 +4645,38 @@
   return isa(BaseNoParens);
 }
 
+// Returns the type used for LHS[RHS], given one of LHS, RHS is type-dependent.
+// Typically this is DependentTy, but can sometimes be more precise.
+//
+// There are cases when we could determine a non-dependent type:
+//  - LHS and RHS may have non-dependent types despite being type-dependent
+//(e.g. unbounded array static members of the current instantiation)
+//  - one may be a dependent-sized array with known element type
+//  - one may be a dependent-typed valid index (enum in current instantiation)
+//
+// We *always* return a dependent type, in such cases it is DependentTy.
+// This avoids creating type-dependent expressions with non-dependent types.
+// FIXME: is this important to avoid? See https://reviews.llvm.org/D107275
+static QualType getDependentArraySubscriptType(Expr *LHS, Expr *RHS,
+   const ASTContext &Ctx) {
+  assert(LHS->isTypeDependent() || RHS->isTypeDependent());
+  QualType LTy = LHS->getType(), RTy = RHS->getType();
+  QualType Result = Ctx.DependentTy;
+  if (RTy->isIntegralOrUnscopedEnumerationType()) {
+if (const PointerType *PT = LTy->getAs())
+  Result = PT->getPointeeType();
+else if (const ArrayType *AT = LTy->getAsArrayTypeUnsafe())
+  Result = AT->getElementType();
+  } else if (LTy->isIntegralOrUnscopedEnumerationType()) {
+if (const PointerType *PT = RTy->getAs())
+  Result = PT->getPointeeType();
+else if (const ArrayType *AT = RTy->getAsArrayTypeUnsafe())
+  Result = AT->getElementType();
+  }
+  // Ensure we return a dependent type.
+  return Result->isDependentType() ? Result : Ctx.DependentTy;
+}
+
 ExprResult
 Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc,
   Expr *idx, SourceLocation rbLoc) {
@@ -4737,8 +4769,9 @@
   // Build an unanalyzed expression if either operand is type-dependent.
   if (getLangOpts().CPlusPlus &&
   (base->isTypeDependent() || idx->isTypeDependent())) {
-return new (Context) ArraySubscriptExpr(base, idx, Context.DependentTy,
-VK_LValue, OK_Ordinary, rbLoc);
+return new (Context) ArraySubscriptExpr(
+

[PATCH] D116280: [clang] adds unary type trait checks as compiler built-ins

2021-12-30 Thread Christopher Di Bella via Phabricator via cfe-commits
cjdb updated this revision to Diff 396748.
cjdb edited the summary of this revision.
cjdb added a comment.

adds `__is_unbounded_array`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116280

Files:
  clang/include/clang/Basic/TokenKinds.def
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/SemaCXX/type-traits.cpp

Index: clang/test/SemaCXX/type-traits.cpp
===
--- clang/test/SemaCXX/type-traits.cpp
+++ clang/test/SemaCXX/type-traits.cpp
@@ -345,11 +345,19 @@
 }
 
 typedef Enum EnumType;
+typedef EnumClass EnumClassType;
 
 void is_enum()
 {
   { int arr[T(__is_enum(Enum))]; }
   { int arr[T(__is_enum(EnumType))]; }
+  { int arr[T(__is_enum(SignedEnum))]; }
+  { int arr[T(__is_enum(UnsignedEnum))]; }
+
+  { int arr[T(__is_enum(EnumClass))]; }
+  { int arr[T(__is_enum(EnumClassType))]; }
+  { int arr[T(__is_enum(SignedEnumClass))]; }
+  { int arr[T(__is_enum(UnsignedEnumClass))]; }
 
   { int arr[F(__is_enum(int))]; }
   { int arr[F(__is_enum(Union))]; }
@@ -363,6 +371,30 @@
   { int arr[F(__is_enum(HasAnonymousUnion))]; }
 }
 
+void is_scoped_enum()
+{
+  { int arr[F(__is_scoped_enum(Enum))]; }
+  { int arr[F(__is_scoped_enum(EnumType))]; }
+  { int arr[F(__is_scoped_enum(SignedEnum))]; }
+  { int arr[F(__is_scoped_enum(UnsignedEnum))]; }
+
+  { int arr[T(__is_scoped_enum(EnumClass))]; }
+  { int arr[T(__is_scoped_enum(EnumClassType))]; }
+  { int arr[T(__is_scoped_enum(SignedEnumClass))]; }
+  { int arr[T(__is_scoped_enum(UnsignedEnumClass))]; }
+
+  { int arr[F(__is_scoped_enum(int))]; }
+  { int arr[F(__is_scoped_enum(Union))]; }
+  { int arr[F(__is_scoped_enum(Int))]; }
+  { int arr[F(__is_scoped_enum(IntAr))]; }
+  { int arr[F(__is_scoped_enum(UnionAr))]; }
+  { int arr[F(__is_scoped_enum(Derives))]; }
+  { int arr[F(__is_scoped_enum(ClassType))]; }
+  { int arr[F(__is_scoped_enum(cvoid))]; }
+  { int arr[F(__is_scoped_enum(IntArNB))]; }
+  { int arr[F(__is_scoped_enum(HasAnonymousUnion))]; }
+}
+
 struct FinalClass final {
 };
 
@@ -702,6 +734,66 @@
   int t31[F(__is_array(cvoid*))];
 }
 
+void is_bounded_array()
+{
+  int t01[T(__is_bounded_array(IntAr))];
+  int t02[F(__is_bounded_array(IntArNB))];
+  int t03[T(__is_bounded_array(UnionAr))];
+
+  int t10[F(__is_bounded_array(void))];
+  int t11[F(__is_bounded_array(cvoid))];
+  int t12[F(__is_bounded_array(float))];
+  int t13[F(__is_bounded_array(double))];
+  int t14[F(__is_bounded_array(long double))];
+  int t15[F(__is_bounded_array(bool))];
+  int t16[F(__is_bounded_array(char))];
+  int t17[F(__is_bounded_array(signed char))];
+  int t18[F(__is_bounded_array(unsigned char))];
+  int t19[F(__is_bounded_array(wchar_t))];
+  int t20[F(__is_bounded_array(short))];
+  int t21[F(__is_bounded_array(unsigned short))];
+  int t22[F(__is_bounded_array(int))];
+  int t23[F(__is_bounded_array(unsigned int))];
+  int t24[F(__is_bounded_array(long))];
+  int t25[F(__is_bounded_array(unsigned long))];
+  int t26[F(__is_bounded_array(Union))];
+  int t27[F(__is_bounded_array(Derives))];
+  int t28[F(__is_bounded_array(ClassType))];
+  int t29[F(__is_bounded_array(Enum))];
+  int t30[F(__is_bounded_array(void*))];
+  int t31[F(__is_bounded_array(cvoid*))];
+}
+
+void is_unbounded_array()
+{
+  int t01[F(__is_unbounded_array(IntAr))];
+  int t02[T(__is_unbounded_array(IntArNB))];
+  int t03[F(__is_unbounded_array(UnionAr))];
+
+  int t10[F(__is_unbounded_array(void))];
+  int t11[F(__is_unbounded_array(cvoid))];
+  int t12[F(__is_unbounded_array(float))];
+  int t13[F(__is_unbounded_array(double))];
+  int t14[F(__is_unbounded_array(long double))];
+  int t15[F(__is_unbounded_array(bool))];
+  int t16[F(__is_unbounded_array(char))];
+  int t17[F(__is_unbounded_array(signed char))];
+  int t18[F(__is_unbounded_array(unsigned char))];
+  int t19[F(__is_unbounded_array(wchar_t))];
+  int t20[F(__is_unbounded_array(short))];
+  int t21[F(__is_unbounded_array(unsigned short))];
+  int t22[F(__is_unbounded_array(int))];
+  int t23[F(__is_unbounded_array(unsigned int))];
+  int t24[F(__is_unbounded_array(long))];
+  int t25[F(__is_unbounded_array(unsigned long))];
+  int t26[F(__is_unbounded_array(Union))];
+  int t27[F(__is_unbounded_array(Derives))];
+  int t28[F(__is_unbounded_array(ClassType))];
+  int t29[F(__is_unbounded_array(Enum))];
+  int t30[F(__is_unbounded_array(void*))];
+  int t31[F(__is_unbounded_array(cvoid*))];
+}
+
 template  void tmpl_func(T&) {}
 
 template  struct type_wrapper {
@@ -934,6 +1026,43 @@
   int t34[F(__is_pointer(void (StructWithMembers::*) ()))];
 }
 
+void is_null_pointer()
+{
+  StructWithMembers x;
+
+  int t00[T(__is_null_pointer(decltype(nullptr)))];
+  int t01[F(__is_null_pointer(void*))];
+  int t02[F(__is_null_pointer(cvoid*))];
+  int t03[F(__is_null_pointer(cvoid*))];
+  int t04[F(__is_null_pointer(char*))];
+  in

[PATCH] D114077: [clangd] Basic IncludeCleaner support for c/c++ standard library

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall updated this revision to Diff 396635.
sammccall added a comment.

(rebase before addressing comments)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D114077

Files:
  clang-tools-extra/clangd/Headers.cpp
  clang-tools-extra/clangd/Headers.h
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/clangd/IncludeCleaner.h
  clang-tools-extra/clangd/tool/ClangdMain.cpp
  clang-tools-extra/clangd/unittests/HeadersTests.cpp
  clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp

Index: clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
===
--- clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
+++ clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
@@ -8,7 +8,9 @@
 
 #include "Annotations.h"
 #include "IncludeCleaner.h"
+#include "SourceCode.h"
 #include "TestTU.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/Testing/Support/SupportHelpers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
@@ -18,7 +20,9 @@
 namespace {
 
 using ::testing::ElementsAre;
+using ::testing::ElementsAreArray;
 using ::testing::IsEmpty;
+using ::testing::Pointee;
 using ::testing::UnorderedElementsAre;
 
 std::string guard(llvm::StringRef Code) {
@@ -211,7 +215,7 @@
 auto AST = TU.build();
 
 std::vector Points;
-for (const auto &Loc : findReferencedLocations(AST)) {
+for (const auto &Loc : findReferencedLocations(AST).User) {
   if (AST.getSourceManager().getBufferName(Loc).endswith(
   TU.HeaderFilename)) {
 Points.push_back(offsetToPosition(
@@ -225,6 +229,82 @@
   }
 }
 
+TEST(IncludeCleaner, Stdlib) {
+  // Smoke tests only for finding used symbols/headers.
+  // Details of Decl -> stdlib::Symbol -> stdlib::Headers mapping tested there.
+  auto TU = TestTU::withHeaderCode(R"cpp(
+namespace std { class error_code {}; }
+class error_code {};
+namespace nonstd { class error_code {}; }
+  )cpp");
+  struct {
+llvm::StringRef Code;
+std::vector Symbols;
+std::vector Headers;
+  } Tests[] = {
+  {"std::error_code x;", {"std::error_code"}, {""}},
+  {"error_code x;", {}, {}},
+  {"nonstd::error_code x;", {}, {}},
+  };
+
+  for (const auto &Test : Tests) {
+TU.Code = Test.Code.str();
+ParsedAST AST = TU.build();
+std::vector WantSyms;
+for (const auto &SymName : Test.Symbols) {
+  auto QName = splitQualifiedName(SymName);
+  auto Sym = stdlib::Symbol::named(QName.first, QName.second);
+  EXPECT_TRUE(Sym) << SymName;
+  WantSyms.push_back(*Sym);
+}
+std::vector WantHeaders;
+for (const auto &HeaderName : Test.Headers) {
+  auto Header = stdlib::Header::named(HeaderName);
+  EXPECT_TRUE(Header) << HeaderName;
+  WantHeaders.push_back(*Header);
+}
+
+ReferencedLocations Locs = findReferencedLocations(AST);
+EXPECT_THAT(Locs.Stdlib, ElementsAreArray(WantSyms));
+ReferencedFiles Files = findReferencedFiles(Locs, AST.getIncludeStructure(),
+AST.getSourceManager());
+EXPECT_THAT(Files.Stdlib, ElementsAreArray(WantHeaders));
+  }
+}
+
+MATCHER_P(WrittenInclusion, Written, "") {
+  if (arg.Written != Written)
+*result_listener << arg.Written;
+  return arg.Written == Written;
+}
+
+TEST(IncludeCleaner, StdlibUnused) {
+  setIncludeCleanerAnalyzesStdlib(true);
+  auto Cleanup =
+  llvm::make_scope_exit([] { setIncludeCleanerAnalyzesStdlib(false); });
+
+  auto TU = TestTU::withCode(R"cpp(
+#include 
+#include 
+std::list x;
+  )cpp");
+  // Layout of std library impl is not relevant.
+  TU.AdditionalFiles["bits"] = R"cpp(
+#pragma once
+namespace std {
+  template  class list {};
+  template  class queue {};
+}
+  )cpp";
+  TU.AdditionalFiles["list"] = "#include ";
+  TU.AdditionalFiles["queue"] = "#include ";
+  TU.ExtraArgs = {"-isystem", testRoot()};
+  auto AST = TU.build();
+
+  auto Unused = computeUnusedIncludes(AST);
+  EXPECT_THAT(Unused, ElementsAre(Pointee(WrittenInclusion("";
+}
+
 TEST(IncludeCleaner, GetUnusedHeaders) {
   llvm::StringLiteral MainFile = R"cpp(
 #include "a.h"
@@ -301,7 +381,7 @@
   auto ReferencedFiles =
   findReferencedFiles(findReferencedLocations(AST), Includes, SM);
   llvm::StringSet<> ReferencedFileNames;
-  for (FileID FID : ReferencedFiles)
+  for (FileID FID : ReferencedFiles.User)
 ReferencedFileNames.insert(
 SM.getPresumedLoc(SM.getLocForStartOfFile(FID)).getFilename());
   // Note we deduped the names as _number_ of s is uninteresting.
@@ -352,7 +432,7 @@
   AST.getIncludeStructure(), AST.getSourceManager());
   llvm::StringSet<> ReferencedFileNames;
   auto &SM = AST.getSourceManager();
-  for (FileID FID : ReferencedFiles)
+  for (FileID FID : ReferencedFiles.User)
 ReferencedFileNames.insert(
 SM.getPr

[PATCH] D114077: [clangd] Basic IncludeCleaner support for c/c++ standard library

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall updated this revision to Diff 396639.
sammccall marked 4 inline comments as done.
sammccall added a comment.

address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D114077

Files:
  clang-tools-extra/clangd/Headers.cpp
  clang-tools-extra/clangd/Headers.h
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/clangd/IncludeCleaner.h
  clang-tools-extra/clangd/tool/ClangdMain.cpp
  clang-tools-extra/clangd/unittests/HeadersTests.cpp
  clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp

Index: clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
===
--- clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
+++ clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
@@ -8,7 +8,9 @@
 
 #include "Annotations.h"
 #include "IncludeCleaner.h"
+#include "SourceCode.h"
 #include "TestTU.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/Testing/Support/SupportHelpers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
@@ -18,7 +20,9 @@
 namespace {
 
 using ::testing::ElementsAre;
+using ::testing::ElementsAreArray;
 using ::testing::IsEmpty;
+using ::testing::Pointee;
 using ::testing::UnorderedElementsAre;
 
 std::string guard(llvm::StringRef Code) {
@@ -211,7 +215,7 @@
 auto AST = TU.build();
 
 std::vector Points;
-for (const auto &Loc : findReferencedLocations(AST)) {
+for (const auto &Loc : findReferencedLocations(AST).User) {
   if (AST.getSourceManager().getBufferName(Loc).endswith(
   TU.HeaderFilename)) {
 Points.push_back(offsetToPosition(
@@ -225,6 +229,82 @@
   }
 }
 
+TEST(IncludeCleaner, Stdlib) {
+  // Smoke tests only for finding used symbols/headers.
+  // Details of Decl -> stdlib::Symbol -> stdlib::Headers mapping tested there.
+  auto TU = TestTU::withHeaderCode(R"cpp(
+namespace std { class error_code {}; }
+class error_code {};
+namespace nonstd { class error_code {}; }
+  )cpp");
+  struct {
+llvm::StringRef Code;
+std::vector Symbols;
+std::vector Headers;
+  } Tests[] = {
+  {"std::error_code x;", {"std::error_code"}, {""}},
+  {"error_code x;", {}, {}},
+  {"nonstd::error_code x;", {}, {}},
+  };
+
+  for (const auto &Test : Tests) {
+TU.Code = Test.Code.str();
+ParsedAST AST = TU.build();
+std::vector WantSyms;
+for (const auto &SymName : Test.Symbols) {
+  auto QName = splitQualifiedName(SymName);
+  auto Sym = stdlib::Symbol::named(QName.first, QName.second);
+  EXPECT_TRUE(Sym) << SymName;
+  WantSyms.push_back(*Sym);
+}
+std::vector WantHeaders;
+for (const auto &HeaderName : Test.Headers) {
+  auto Header = stdlib::Header::named(HeaderName);
+  EXPECT_TRUE(Header) << HeaderName;
+  WantHeaders.push_back(*Header);
+}
+
+ReferencedLocations Locs = findReferencedLocations(AST);
+EXPECT_THAT(Locs.Stdlib, ElementsAreArray(WantSyms));
+ReferencedFiles Files = findReferencedFiles(Locs, AST.getIncludeStructure(),
+AST.getSourceManager());
+EXPECT_THAT(Files.Stdlib, ElementsAreArray(WantHeaders));
+  }
+}
+
+MATCHER_P(WrittenInclusion, Written, "") {
+  if (arg.Written != Written)
+*result_listener << arg.Written;
+  return arg.Written == Written;
+}
+
+TEST(IncludeCleaner, StdlibUnused) {
+  setIncludeCleanerAnalyzesStdlib(true);
+  auto Cleanup =
+  llvm::make_scope_exit([] { setIncludeCleanerAnalyzesStdlib(false); });
+
+  auto TU = TestTU::withCode(R"cpp(
+#include 
+#include 
+std::list x;
+  )cpp");
+  // Layout of std library impl is not relevant.
+  TU.AdditionalFiles["bits"] = R"cpp(
+#pragma once
+namespace std {
+  template  class list {};
+  template  class queue {};
+}
+  )cpp";
+  TU.AdditionalFiles["list"] = "#include ";
+  TU.AdditionalFiles["queue"] = "#include ";
+  TU.ExtraArgs = {"-isystem", testRoot()};
+  auto AST = TU.build();
+
+  auto Unused = computeUnusedIncludes(AST);
+  EXPECT_THAT(Unused, ElementsAre(Pointee(WrittenInclusion("";
+}
+
 TEST(IncludeCleaner, GetUnusedHeaders) {
   llvm::StringLiteral MainFile = R"cpp(
 #include "a.h"
@@ -301,7 +381,7 @@
   auto ReferencedFiles =
   findReferencedFiles(findReferencedLocations(AST), Includes, SM);
   llvm::StringSet<> ReferencedFileNames;
-  for (FileID FID : ReferencedFiles)
+  for (FileID FID : ReferencedFiles.User)
 ReferencedFileNames.insert(
 SM.getPresumedLoc(SM.getLocForStartOfFile(FID)).getFilename());
   // Note we deduped the names as _number_ of s is uninteresting.
@@ -352,7 +432,7 @@
   AST.getIncludeStructure(), AST.getSourceManager());
   llvm::StringSet<> ReferencedFileNames;
   auto &SM = AST.getSourceManager();
-  for (FileID FID : ReferencedFiles)
+  for (FileID FID : ReferencedFiles.User)
 ReferencedFileNames.

[PATCH] D114077: [clangd] Basic IncludeCleaner support for c/c++ standard library

2021-12-30 Thread Sam McCall via Phabricator via cfe-commits
sammccall added inline comments.



Comment at: clang-tools-extra/clangd/Headers.h:32
 namespace clang {
+class NamespaceDecl;
 namespace clangd {

kbobyrev wrote:
> Do we need a forward decl here?
Decl/NamespaceDecl are needed for the interface of the stdlib symbol 
recognizer, but we don't need to depend on any of the details of AST here.

Splitting the stdlib stuff into its own header seems possible if you'd prefer 
that?



Comment at: clang-tools-extra/clangd/Headers.h:330
+  static inline clang::clangd::stdlib::Header getEmptyKey() {
+return clang::clangd::stdlib::Header(-1);
+  }

kbobyrev wrote:
> maybe `DenseMapInfo::getEmptyKey()` and 
> `DenseMapInfo::getTombstoneKey()` just like above?
empty/tombstone keys are reserved values, and we know what sensible reserved 
values are better than the traits for unsigned do. 

I can fix the code above if you like.



Comment at: clang-tools-extra/clangd/IncludeCleaner.h:90
+/// FIXME: remove this hack once the implementation is good enough.
+void setIncludeCleanerAnalyzesStdlib(bool B);
+

kbobyrev wrote:
> Not sure but: don't we want a config option instead? We can remove it just as 
> easily since it's all "hidden" right now.
I think we discussed this offline a bunch?

A config option is a bunch more plumbing, and we don't actually want to expose 
this option.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D114077

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


[PATCH] D116386: [clang-tidy] Narrow cppguidelines-macro-usage to actual constants

2021-12-30 Thread Richard via Phabricator via cfe-commits
LegalizeAdulthood added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp:83-105
+bool isConstantToken(const MacroDirective *MD) {
+  for (const auto &Token : MD->getMacroInfo()->tokens()) {
+switch (Token.getKind()) {
+case tok::comment:
+case tok::numeric_constant:
+case tok::char_constant:
+case tok::wide_char_constant:

In the spirit of "avoid raw loops", would this be clearer expressed as 
std::all_of and the switch/case provided as a lambda?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116386

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


[PATCH] D116369: [clang][dataflow] Add parameterized map lattice.

2021-12-30 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel marked an inline comment as done.
ymandel added inline comments.



Comment at: clang/include/clang/Analysis/FlowSensitive/MapLattice.h:92
+  /// entry as it was in the source map.
+  LatticeJoinEffect join(const MapLattice &Other) {
+LatticeJoinEffect Effect = LatticeJoinEffect::Unchanged;

xazax.hun wrote:
> It looks like apart from the join operation the rest of the methods are 
> simply forwarding to DenseMap. I was wondering if it would make more sense to 
> make the framework support `join` as a free function (possibly using some 
> custom type traits?) to avoid forcing the user to write wrappers like this.
Good point, but I think that these concerns are separable -- that is, how much 
forwarding we do and whether we should enable `join` an arbitrary types.

For the first issue, an alternative design here would be to simply expose the 
container as a public field and drop all the methods except for `join`.  I 
intentionally left some abstraction in place, though, because I think that 
`DenseMap` is not the right container, its just "good enough" to get started. I 
think ultimately we'll want functional data structures, because the current 
setup forces an absurd amount of copying.

For the second issue, I'm open to the idea -- it would be like Haskell's type 
classes in some sense, but I prefer the design where the lattice's operations 
are grouped together as a unit. I think that we could fit it into the current 
design with some form of SFINAE-based discrimination on the lattice type 
parameter of `DataflowAnalysis`.

Given that, what do you think of just renaming this to `DenseMapLattice` and 
exposing the container field publicly? When we're ready with a better map 
lattice, we can add that alongside this one with a different name.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D116369

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


[PATCH] D116351: Update Bug report URL to Github Issues

2021-12-30 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay added a subscriber: jhenderson.
MaskRay added a comment.

@jhenderson




Comment at: libunwind/docs/index.rst:101
 * `LLVM Homepage `_
-* `LLVM Bugzilla `_
+* `LLVM Issues `_
 * `cfe-commits Mailing List`_

Quuxplusone wrote:
> 
https://github.com/llvm/llvm-project/labels/libunwind



Comment at: lld/docs/_templates/indexsidebar.html:3-4
 
 lld bugs should be reported at the
-  LLVM https://bugs.llvm.org/";>Bugzilla.
+  LLVM https://github.com/llvm/llvm-project/issues/";>Issues.

Quuxplusone wrote:
> 
While here, mention the labels: lld:COFF lld:ELF lld:MachO lld:wasm.



Comment at: llvm/docs/CommandGuide/llvm-objdump.rst:400
 
-To report bugs, please visit .
+To report bugs, please visit .
 

https://github.com/llvm/llvm-project/labels/tools:llvm-objdump



Comment at: llvm/docs/CommandGuide/llvm-size.rst:194
 
-To report bugs, please visit .
+To report bugs, please visit .

https://github.com/llvm/llvm-project/labels/tools:llvm-size



Comment at: llvm/docs/CommandGuide/llvm-strings.rst:126
 
-To report bugs, please visit .
+To report bugs, please visit .

https://github.com/llvm/llvm-project/labels/tools:llvm-strings



Comment at: llvm/docs/CommandGuide/llvm-strip.rst:197
 
-To report bugs, please visit .
+To report bugs, please visit .
 

https://github.com/llvm/llvm-project/labels/tools:llvm-objcopy%2Fstrip


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

https://reviews.llvm.org/D116351

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


[PATCH] D116351: Update Bug report URL to Github Issues

2021-12-30 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay added inline comments.



Comment at: libcxx/docs/index.rst:220
 * `libc++abi Homepage `_
-* `LLVM Bugzilla `_
+* `LLVM Issues `_
 * `libcxx-commits Mailing List`_

Quuxplusone wrote:
> 
Would https://github.com/llvm/llvm-project/labels/libc++ be better?

Unfortunately "New issue" on that page does not apply the label automatically.


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

https://reviews.llvm.org/D116351

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


[PATCH] D72326: [clang-format] Add option to explicitly specify a config file

2021-12-30 Thread Zhao Wei Liew via Phabricator via cfe-commits
zwliew updated this revision to Diff 396578.
zwliew added a comment.
Herald added subscribers: llvm-commits, openmp-commits, libcxx-commits, 
lldb-commits, Sanitizers, arjunp, sdasgup3, luke957, asavonic, 
jeroen.dobbelaere, wenzhicui, wrengr, Chia-hungDuan, armkevincheng, ormris, 
foad, eric-k256, dcaballe, cota, mravishankar, teijeong, frasercrmck, 
dexonsmith, rdzhabarov, tatianashp, dang, okura, jdoerfert, msifontes, 
sstefan1, jurahul, kuter, cmtice, Kayjukh, vkmr, grosul1, martong, Joonsoo, 
stephenneuendorffer, kerbowa, liufengdb, aartbik, lucyrfox, mgester, 
arpith-jacob, csigg, nicolasvasilache, antiagainst, shauheen, rriddle, 
mehdi_amini, luismarques, apazos, sameer.abuasal, pengfei, s.egerton, dmgreen, 
Jim, jocewei, rupprecht, PkmX, arphaman, the_o, brucehoult, MartinMosbeck, 
rogfer01, steven_wu, edward-jones, zzheng, MaskRay, jrtc27, gbedwell, niosHD, 
sabuasal, simoncook, johnrusso, rbar, asb, kbarton, aheejin, hiraditya, 
jgravelle-google, krytarowski, arichardson, sbc100, mgorny, nhaehnle, jvesely, 
nemanjai, emaste, dylanmckay, dschuff, arsenm.
Herald added a reviewer: deadalnix.
Herald added a reviewer: andreadb.
Herald added a reviewer: lebedev.ri.
Herald added a reviewer: jdoerfert.
Herald added a reviewer: jhenderson.
Herald added a reviewer: jdoerfert.
Herald added a reviewer: sstefan1.
Herald added a reviewer: nicolasvasilache.
Herald added a reviewer: aartbik.
Herald added a reviewer: MaskRay.
Herald added a reviewer: ftynse.
Herald added a reviewer: aaron.ballman.
Herald added a reviewer: baziotis.
Herald added a reviewer: aartbik.
Herald added a reviewer: sjarus.
Herald added a reviewer: clementval.
Herald added a reviewer: bondhugula.
Herald added a reviewer: lebedev.ri.
Herald added projects: Sanitizers, LLDB, libc++, OpenMP, MLIR, LLVM, lld-macho.
Herald added a reviewer: libc++.
Herald added a reviewer: lld-macho.
This revision now requires review to proceed.

Rebased on master for context


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72326

Files:
  clang/CMakeLists.txt
  clang/docs/ClangFormat.rst
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/AST/AbstractBasicReader.h
  clang/include/clang/AST/AbstractBasicWriter.h
  clang/include/clang/AST/AbstractTypeReader.h
  clang/include/clang/AST/AbstractTypeWriter.h
  clang/include/clang/AST/ComputeDependence.h
  clang/include/clang/AST/CurrentSourceLocExprScope.h
  clang/include/clang/AST/DeclObjCCommon.h
  clang/include/clang/AST/FormatString.h
  clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
  clang/include/clang/AST/LocInfoType.h
  clang/include/clang/AST/NonTrivialTypeVisitor.h
  clang/include/clang/AST/OSLog.h
  clang/include/clang/AST/OpenMPClause.h
  clang/include/clang/AST/QualTypeNames.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h
  clang/include/clang/ASTMatchers/Dynamic/Parser.h
  clang/include/clang/ASTMatchers/Dynamic/Registry.h
  clang/include/clang/ASTMatchers/Dynamic/VariantValue.h
  clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
  clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
  clang/include/clang/Analysis/AnyCall.h
  clang/include/clang/Analysis/BodyFarm.h
  clang/include/clang/Analysis/CloneDetection.h
  clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
  clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
  clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h
  clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
  clang/include/clang/Analysis/IssueHash.h
  clang/include/clang/Analysis/PathDiagnostic.h
  clang/include/clang/Analysis/RetainSummaryManager.h
  clang/include/clang/Analysis/SelectorExtras.h
  clang/include/clang/Basic/AlignedAllocation.h
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/AttrSubjectMatchRules.h
  clang/include/clang/Basic/DarwinSDKInfo.h
  clang/include/clang/Basic/DiagnosticError.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/OperatorPrecedence.h
  clang/include/clang/Basic/PragmaKinds.h
  clang/include/clang/Basic/ProfileList.h
  clang/include/clang/Basic/TargetID.h
  clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
  clang/include/clang/Format/Format.h
  clang/include/clang/Frontend/PCHContainerOperations.h
  clang/include/clang/Frontend/PrecompiledPreamble.h
  clang/include/clang/Frontend/SerializedDiagnostics.h
  clang/include/clang/IndexSerialization/SerializablePathCollection.h
  clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h
  clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h
  clang/include/clang/Parse/RAIIObjectsForParser.h
  clang/include/clang/Sema/CleanupInfo.h
  clang/include/clang/Sema/ParsedAttr.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Sema/SemaConcept.h
  clang/inc

[PATCH] D72326: [clang-format] Add option to explicitly specify a config file

2021-12-30 Thread Zhao Wei Liew via Phabricator via cfe-commits
zwliew added a comment.
Herald added a subscriber: JDevlieghere.

Oh no...I'm so sorry. Didn't mean to cause this large diff. Trying to fix it 
now.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72326

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


[PATCH] D72326: [clang-format] Add option to explicitly specify a config file

2021-12-30 Thread Zhao Wei Liew via Phabricator via cfe-commits
zwliew updated this revision to Diff 396579.
zwliew added a comment.

Fixed rebase and diff.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72326

Files:
  clang/docs/ClangFormat.rst
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -21584,6 +21584,70 @@
 Style.IndentWidth = 7;
 return Style;
   }());
+
+  // Test 9.9: use inheritance from a specific config file.
+  Style9 = getStyle("file:/e/sub/sub/.clang-format", "/e/sub/sub/code.cpp",
+"none", "", &FS);
+  ASSERT_TRUE(static_cast(Style9));
+  ASSERT_EQ(*Style9, SubSubStyle);
+}
+
+TEST(FormatStyle, GetStyleOfSpecificFile) {
+  llvm::vfs::InMemoryFileSystem FS;
+  // Specify absolute path to a format file in a parent directory.
+  ASSERT_TRUE(
+  FS.addFile("/e/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
+  ASSERT_TRUE(
+  FS.addFile("/e/explicit.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+  ASSERT_TRUE(FS.addFile("/e/sub/sub/sub/test.cpp", 0,
+ llvm::MemoryBuffer::getMemBuffer("int i;")));
+  auto Style = getStyle("file:/e/explicit.clang-format",
+"/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE(static_cast(Style));
+  ASSERT_EQ(*Style, getGoogleStyle());
+
+  // Specify relative path to a format file.
+  ASSERT_TRUE(
+  FS.addFile("../../e/explicit.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+  Style = getStyle("file:../../e/explicit.clang-format",
+   "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE(static_cast(Style));
+  ASSERT_EQ(*Style, getGoogleStyle());
+
+  // Specify path to a format file that does not exist.
+  Style = getStyle("file:/e/missing.clang-format", "/e/sub/sub/sub/test.cpp",
+   "LLVM", "", &FS);
+  ASSERT_FALSE(static_cast(Style));
+  llvm::consumeError(Style.takeError());
+
+  // Specify path to a file on the filesystem.
+  SmallString<128> FormatFilePath;
+  std::error_code ECF = llvm::sys::fs::createTemporaryFile(
+  "FormatFileTest", "tpl", FormatFilePath);
+  EXPECT_FALSE((bool)ECF);
+  llvm::raw_fd_ostream FormatFileTest(FormatFilePath, ECF);
+  EXPECT_FALSE((bool)ECF);
+  FormatFileTest << "BasedOnStyle: Google\n";
+  FormatFileTest.close();
+
+  SmallString<128> TestFilePath;
+  std::error_code ECT =
+  llvm::sys::fs::createTemporaryFile("CodeFileTest", "cc", TestFilePath);
+  EXPECT_FALSE((bool)ECT);
+  llvm::raw_fd_ostream CodeFileTest(TestFilePath, ECT);
+  CodeFileTest << "int i;\n";
+  CodeFileTest.close();
+
+  std::string format_file_arg = std::string("file:") + FormatFilePath.c_str();
+  Style = getStyle(format_file_arg, TestFilePath, "LLVM", "", nullptr);
+
+  llvm::sys::fs::remove(FormatFilePath.c_str());
+  llvm::sys::fs::remove(TestFilePath.c_str());
+  ASSERT_TRUE(static_cast(Style));
+  ASSERT_EQ(*Style, getGoogleStyle());
 }
 
 TEST_F(ReplacementTest, FormatCodeAfterReplacements) {
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -3181,6 +3181,8 @@
 ".clang-format file located in one of the parent\n"
 "directories of the source file (or current\n"
 "directory for stdin).\n"
+"Use -style=file: to explicitly specify"
+"the configuration file.\n"
 "Use -style=\"{key: value, ...}\" to set specific\n"
 "parameters, e.g.:\n"
 "  -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
@@ -3233,6 +3235,18 @@
 
 const char *DefaultFallbackStyle = "LLVM";
 
+llvm::ErrorOr>
+loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS,
+   FormatStyle *Style, bool AllowUnknownOptions) {
+  llvm::ErrorOr> Text =
+  FS->getBufferForFile(ConfigFile.str());
+  if (auto EC = Text.getError())
+return EC;
+  if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions))
+return EC;
+  return Text;
+}
+
 llvm::Expected getStyle(StringRef StyleName, StringRef FileName,
  StringRef FallbackStyleName,
  StringRef Code, llvm::vfs::FileSystem *FS,
@@ -3263,6 +3277,28 @@
   return Style;
   }
 
+  // User provided clang-format file using -style=file:path/to/format/file.
+  if (!Style.InheritsParentConfig &&
+  StyleName.startswith_insensitive("file:")) {
+auto ConfigFile = StyleName.substr(5);
+llvm::ErrorOr> Text =
+loadAndParseCon

[PATCH] D116351: Update Bug report URL to Github Issues

2021-12-30 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu updated this revision to Diff 396589.
ChuanqiXu marked 2 inline comments as done.
ChuanqiXu added a comment.

Address comments.


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

https://reviews.llvm.org/D116351

Files:
  clang-tools-extra/docs/clang-doc.rst
  clang/docs/CommandGuide/clang.rst
  clang/www/c_status.html
  clang/www/cxx_status.html
  clang/www/get_involved.html
  clang/www/get_started.html
  clang/www/menu.html.incl
  libcxx/docs/index.rst
  libunwind/docs/index.rst
  lld/docs/_templates/indexsidebar.html
  lldb/docs/index.rst
  llvm/CMakeLists.txt
  llvm/docs/CommandGuide/llvm-install-name-tool.rst
  llvm/docs/CommandGuide/llvm-libtool-darwin.rst
  llvm/docs/CommandGuide/llvm-lipo.rst
  llvm/docs/CommandGuide/llvm-objcopy.rst
  llvm/docs/CommandGuide/llvm-objdump.rst
  llvm/docs/CommandGuide/llvm-otool.rst
  llvm/docs/CommandGuide/llvm-size.rst
  llvm/docs/CommandGuide/llvm-strings.rst
  llvm/docs/CommandGuide/llvm-strip.rst
  llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
  llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
  utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h
  utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/config.h

Index: utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/config.h
===
--- utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/config.h
+++ utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/config.h
@@ -24,7 +24,7 @@
 #include "llvm/Config/llvm-config.h"
 
 /* Bug report URL. */
-#define BUG_REPORT_URL "https://bugs.llvm.org/";
+#define BUG_REPORT_URL "https://github.com/llvm/llvm-project/issues/";
 
 /* Define to 1 to enable backtraces, and to 0 otherwise. */
 #define ENABLE_BACKTRACES 1
@@ -332,7 +332,7 @@
 /* LTDL_SHLIB_EXT defined in Bazel */
 
 /* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "https://bugs.llvm.org/";
+#define PACKAGE_BUGREPORT "https://github.com/llvm/llvm-project/issues/";
 
 /* Define to the full name of this package. */
 #define PACKAGE_NAME "LLVM"
Index: utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h
===
--- utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h
+++ utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h
@@ -20,7 +20,7 @@
 #define CLANG_CONFIG_H
 
 /* Bug report URL. */
-#define BUG_REPORT_URL "https://bugs.llvm.org/";
+#define BUG_REPORT_URL "https://github.com/llvm/llvm-project/issues/";
 
 /* Default to -fPIE and -pie on Linux. */
 #define CLANG_DEFAULT_PIE_ON_LINUX 0
Index: llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
===
--- llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
+++ llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
@@ -72,7 +72,7 @@
   input = "config.h.cmake"
   output = "$target_gen_dir/config.h"
   values = [
-"BUG_REPORT_URL=https://bugs.llvm.org/";,
+"BUG_REPORT_URL=https://github.com/llvm/llvm-project/issues/";,
 "ENABLE_BACKTRACES=1",
 "ENABLE_CRASH_OVERRIDES=1",
 "BACKTRACE_HEADER=execinfo.h",
@@ -120,7 +120,7 @@
 "LLVM_VERSION_INFO=",
 "LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO=1",
 "LLVM_WINDOWS_PREFER_FORWARD_SLASH=",
-"PACKAGE_BUGREPORT=https://bugs.llvm.org/";,
+"PACKAGE_BUGREPORT=https://github.com/llvm/llvm-project/issues/";,
 "PACKAGE_NAME=LLVM",
 "PACKAGE_STRING=LLVM ${llvm_version}git",
 "PACKAGE_VERSION=${llvm_version}git",
Index: llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
===
--- llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
+++ llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
@@ -8,7 +8,7 @@
   input = "config.h.cmake"
   output = "$target_gen_dir/config.h"
   values = [
-"BUG_REPORT_URL=https://bugs.llvm.org/";,
+"BUG_REPORT_URL=https://github.com/llvm/llvm-project/issues/";,
 "CLANG_DEFAULT_PIE_ON_LINUX=",
 "CLANG_DEFAULT_LINKER=",
 "CLANG_DEFAULT_STD_C=",
Index: llvm/docs/CommandGuide/llvm-strip.rst
===
--- llvm/docs/CommandGuide/llvm-strip.rst
+++ llvm/docs/CommandGuide/llvm-strip.rst
@@ -194,7 +194,7 @@
 BUGS
 
 
-To report bugs, please visit .
+To report bugs, please visit .
 
 SEE ALSO
 
Index: llvm/docs/CommandGuide/llvm-strings.rst
===
--- llvm/docs/CommandGuide/llvm-strings.rst
+++ llvm/docs/CommandGuide/llvm-strings.rst
@@ -123,4 +123,4 @@
 BUGS
 
 
-To report bugs, please visit .
+To report bugs, please visit 

[PATCH] D116351: Update Bug report URL to Github Issues

2021-12-30 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu marked 14 inline comments as done.
ChuanqiXu added inline comments.



Comment at: clang/www/c_status.html:75-76
 
-The https://bugs.llvm.org/";>LLVM bug tracker contains a
-Clang C component that tracks known bugs with Clang's language
+The https://github.com/llvm/llvm-project/issues/";>LLVM Issues 
contains
+issuses labeled with c/c11/c18/c2x that tracks known bugs with Clang's language
 conformance.

Quuxplusone wrote:
> 
I use the lower-case 'c' to keep consistent with GitHub labels.



Comment at: clang/www/cxx_status.html:79-81
+The https://github.com/llvm/llvm-project/issues/";>LLVM Issues 
contains
+issues labelled with c++/c++11/c++14/c++17/c++20 that track known bugs with 
Clang's
+language conformance labelled in each language mode.

Quuxplusone wrote:
> (I think `, "C++17", "C++20", "C++23"` would just be redundant/noise here, 
> and would imply a thankless task for someone to go update this list every 3 
> years. Better to just cap it at one or two labels. The reader can be trusted 
> to figure out that C++20 issues should be labeled with `C++20`.)
I use the lower-case 'c' to keep consistent with GitHub labels.



Comment at: lld/docs/_templates/indexsidebar.html:3-4
 
 lld bugs should be reported at the
-  LLVM https://bugs.llvm.org/";>Bugzilla.
+  LLVM https://github.com/llvm/llvm-project/issues/";>Issues.

MaskRay wrote:
> Quuxplusone wrote:
> > 
> While here, mention the labels: lld:COFF lld:ELF lld:MachO lld:wasm.
I found label lld would cover the sub-labels.


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

https://reviews.llvm.org/D116351

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


[PATCH] D116351: Update Bug report URL to Github Issues

2021-12-30 Thread Fangrui Song via Phabricator via cfe-commits
MaskRay added inline comments.



Comment at: llvm/docs/CommandGuide/llvm-objcopy.rst:539
 
-To report bugs, please visit .
+To report bugs, please visit .
 

https://github.com/llvm/llvm-project/labels/tools:llvm-objcopy/strip

You need to check whether other tools have dedicated labels.


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

https://reviews.llvm.org/D116351

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


[PATCH] D116351: Update Bug report URL to Github Issues

2021-12-30 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu updated this revision to Diff 396627.
ChuanqiXu marked 2 inline comments as done.
ChuanqiXu added a comment.

Address comments.


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

https://reviews.llvm.org/D116351

Files:
  clang-tools-extra/docs/clang-doc.rst
  clang/docs/CommandGuide/clang.rst
  clang/www/c_status.html
  clang/www/cxx_status.html
  clang/www/get_involved.html
  clang/www/get_started.html
  clang/www/menu.html.incl
  libcxx/docs/index.rst
  libunwind/docs/index.rst
  lld/docs/_templates/indexsidebar.html
  lldb/docs/index.rst
  llvm/CMakeLists.txt
  llvm/docs/CommandGuide/llvm-install-name-tool.rst
  llvm/docs/CommandGuide/llvm-libtool-darwin.rst
  llvm/docs/CommandGuide/llvm-lipo.rst
  llvm/docs/CommandGuide/llvm-objcopy.rst
  llvm/docs/CommandGuide/llvm-objdump.rst
  llvm/docs/CommandGuide/llvm-otool.rst
  llvm/docs/CommandGuide/llvm-size.rst
  llvm/docs/CommandGuide/llvm-strings.rst
  llvm/docs/CommandGuide/llvm-strip.rst
  llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
  llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
  utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h
  utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/config.h

Index: utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/config.h
===
--- utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/config.h
+++ utils/bazel/llvm-project-overlay/llvm/include/llvm/Config/config.h
@@ -24,7 +24,7 @@
 #include "llvm/Config/llvm-config.h"
 
 /* Bug report URL. */
-#define BUG_REPORT_URL "https://bugs.llvm.org/";
+#define BUG_REPORT_URL "https://github.com/llvm/llvm-project/issues/";
 
 /* Define to 1 to enable backtraces, and to 0 otherwise. */
 #define ENABLE_BACKTRACES 1
@@ -332,7 +332,7 @@
 /* LTDL_SHLIB_EXT defined in Bazel */
 
 /* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "https://bugs.llvm.org/";
+#define PACKAGE_BUGREPORT "https://github.com/llvm/llvm-project/issues/";
 
 /* Define to the full name of this package. */
 #define PACKAGE_NAME "LLVM"
Index: utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h
===
--- utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h
+++ utils/bazel/llvm-project-overlay/clang/include/clang/Config/config.h
@@ -20,7 +20,7 @@
 #define CLANG_CONFIG_H
 
 /* Bug report URL. */
-#define BUG_REPORT_URL "https://bugs.llvm.org/";
+#define BUG_REPORT_URL "https://github.com/llvm/llvm-project/issues/";
 
 /* Default to -fPIE and -pie on Linux. */
 #define CLANG_DEFAULT_PIE_ON_LINUX 0
Index: llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
===
--- llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
+++ llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
@@ -72,7 +72,7 @@
   input = "config.h.cmake"
   output = "$target_gen_dir/config.h"
   values = [
-"BUG_REPORT_URL=https://bugs.llvm.org/";,
+"BUG_REPORT_URL=https://github.com/llvm/llvm-project/issues/";,
 "ENABLE_BACKTRACES=1",
 "ENABLE_CRASH_OVERRIDES=1",
 "BACKTRACE_HEADER=execinfo.h",
@@ -120,7 +120,7 @@
 "LLVM_VERSION_INFO=",
 "LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO=1",
 "LLVM_WINDOWS_PREFER_FORWARD_SLASH=",
-"PACKAGE_BUGREPORT=https://bugs.llvm.org/";,
+"PACKAGE_BUGREPORT=https://github.com/llvm/llvm-project/issues/";,
 "PACKAGE_NAME=LLVM",
 "PACKAGE_STRING=LLVM ${llvm_version}git",
 "PACKAGE_VERSION=${llvm_version}git",
Index: llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
===
--- llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
+++ llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
@@ -8,7 +8,7 @@
   input = "config.h.cmake"
   output = "$target_gen_dir/config.h"
   values = [
-"BUG_REPORT_URL=https://bugs.llvm.org/";,
+"BUG_REPORT_URL=https://github.com/llvm/llvm-project/issues/";,
 "CLANG_DEFAULT_PIE_ON_LINUX=",
 "CLANG_DEFAULT_LINKER=",
 "CLANG_DEFAULT_STD_C=",
Index: llvm/docs/CommandGuide/llvm-strip.rst
===
--- llvm/docs/CommandGuide/llvm-strip.rst
+++ llvm/docs/CommandGuide/llvm-strip.rst
@@ -194,7 +194,7 @@
 BUGS
 
 
-To report bugs, please visit .
+To report bugs, please visit .
 
 SEE ALSO
 
Index: llvm/docs/CommandGuide/llvm-strings.rst
===
--- llvm/docs/CommandGuide/llvm-strings.rst
+++ llvm/docs/CommandGuide/llvm-strings.rst
@@ -123,4 +123,4 @@
 BUGS
 
 
-To report bugs, please visit .
+To report bugs, please visit