[PATCH] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one.

2018-03-10 Thread Vassil Vassilev via Phabricator via cfe-commits
v.g.vassilev updated this revision to Diff 137902.
v.g.vassilev added a comment.

Add sanity check.

We assert that the ODR hash of the template arguments should be the same as the 
one for from the actually found template specialization.

This way we managed to catch a few collisions in the ODRHash logic.


https://reviews.llvm.org/D41416

Files:
  include/clang/AST/DeclTemplate.h
  lib/AST/DeclTemplate.cpp
  lib/AST/ODRHash.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/Modules/cxx-templates.cpp

Index: test/Modules/cxx-templates.cpp
===
--- test/Modules/cxx-templates.cpp
+++ test/Modules/cxx-templates.cpp
@@ -249,24 +249,24 @@
 
 // CHECK-DUMP:  ClassTemplateDecl {{.*}} <{{.*[/\\]}}cxx-templates-common.h:1:1, {{.*}}>  col:{{.*}} in cxx_templates_common SomeTemplate
 // CHECK-DUMP:ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate
-// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
+// CHECK-DUMP-NEXT: TemplateArgument type 'char [1]'
 // CHECK-DUMP:ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition
 // CHECK-DUMP-NEXT: DefinitionData
 // CHECK-DUMP-NEXT:   DefaultConstructor
 // CHECK-DUMP-NEXT:   CopyConstructor
 // CHECK-DUMP-NEXT:   MoveConstructor
 // CHECK-DUMP-NEXT:   CopyAssignment
 // CHECK-DUMP-NEXT:   MoveAssignment
 // CHECK-DUMP-NEXT:   Destructor
-// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
-// CHECK-DUMP:ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate
 // CHECK-DUMP-NEXT: TemplateArgument type 'char [1]'
+// CHECK-DUMP:ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate
+// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
 // CHECK-DUMP:ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition
 // CHECK-DUMP-NEXT: DefinitionData
 // CHECK-DUMP-NEXT:   DefaultConstructor
 // CHECK-DUMP-NEXT:   CopyConstructor
 // CHECK-DUMP-NEXT:   MoveConstructor
 // CHECK-DUMP-NEXT:   CopyAssignment
 // CHECK-DUMP-NEXT:   MoveAssignment
 // CHECK-DUMP-NEXT:   Destructor
-// CHECK-DUMP-NEXT: TemplateArgument type 'char [1]'
+// CHECK-DUMP-NEXT: TemplateArgument type 'char [2]'
Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -162,22 +162,61 @@
   Record.AddSourceLocation(typeParams->getRAngleLoc());
 }
 
-/// Add to the record the first declaration from each module file that
-/// provides a declaration of D. The intent is to provide a sufficient
-/// set such that reloading this set will load all current redeclarations.
-void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
-  llvm::MapVector Firsts;
+/// Collect the first declaration from each module file that provides a
+/// declaration of D.
+void CollectFirstDeclFromEachModule(const Decl *D, bool IncludeLocal,
+llvm::MapVector &Firsts) {
+
   // FIXME: We can skip entries that we know are implied by others.
   for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) {
 if (R->isFromASTFile())
   Firsts[Writer.Chain->getOwningModuleFile(R)] = R;
 else if (IncludeLocal)
   Firsts[nullptr] = R;
   }
+}
+
+/// Add to the record the first declaration from each module file that
+/// provides a declaration of D. The intent is to provide a sufficient
+/// set such that reloading this set will load all current redeclarations.
+void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
+  llvm::MapVector Firsts;
+  CollectFirstDeclFromEachModule(D, IncludeLocal, Firsts);
+
   for (const auto &F : Firsts)
 Record.AddDeclRef(F.second);
 }
 
+/// Add to the record the first template specialization from each module
+/// file that provides a declaration of D. We store the DeclId and an
+/// ODRHash of the template arguments of D which should provide enough
+/// information to load D only if the template instantiator needs it.
+void AddFirstSpecializationDeclFromEachModule(const Decl *D,
+  bool IncludeLocal) {
+  assert(isa(D) ||
+ isa(D) || isa(D) &&
+ "Must not be called with other decls");
+  llvm::MapVector Firsts;
+  CollectFirstDeclFromEachModule(D, IncludeLocal, Firsts);
+
+  for (const auto &F : Firsts) {
+Record.AddDeclRef(F.second);
+ArrayRef Args;
+if (auto *CTSD = dyn_cast(D))
+  Args = CTSD->getTemplateArgs().asArray();
+else if (auto *VTSD = dyn_cast(D))
+  Args = VTSD->getTemplateArgs().asArray();
+   

[PATCH] D40731: Integrate CHash into CLang

2018-03-10 Thread Vassil Vassilev via Phabricator via cfe-commits
v.g.vassilev added a comment.

I am not sure if this is the right time but maybe testing and comparing the 
behavior of this patch against something such as the ODRHash will help you, me 
(and probably others) to understand the current patch better.

In https://reviews.llvm.org/D41416, I started working on lazy deserialization 
of template specializations. When you produce a PCM or PCH and a template 
instantiation is required it'd currently deserialize eagerly all possible 
template specializations (and standard libraries have a lot of them). I am 
computing the hashes of the template arguments and comparing against the usual 
Profile-ed hashes. In the assert, essentially I am comparing the behavior of 
the ODRHash and the Stmt::Profile logic for some cases.

Perhaps you can plugin your algorithm to it, create a pch and start comparing 
your logic with the when it comes to template arguments hashing and alike.

Of course this is not something that will give you perfect coverage and so on 
but it can stress test the implementation and compare it to the 2 major 
existing ones in clang.




Comment at: include/clang/AST/CHashVisitor.h:10
+//
+//  This file defines the APValue class.
+//

I suspect this is a copy-paste from the APValue class. Could you update the 
documentation what the file contains?



Comment at: include/clang/AST/CHashVisitor.h:291
+
+  /*
+   * In order to produce hashes for subtrees on the way, a hash

Clang uses `///` for doxygen style documentation.


Repository:
  rC Clang

https://reviews.llvm.org/D40731



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


[PATCH] D43197: [OpenMP] Add flag for linking runtime bitcode library

2018-03-10 Thread Jonas Hahnfeld via Phabricator via cfe-commits
Hahnfeld added inline comments.



Comment at: test/Driver/openmp-offload-gpu.c:150
+/// bitcode library and add it to the LIBRARY_PATH.
+// RUN:   touch %T/libomptarget-nvptx-sm_60.bc
+// RUN:   env LIBRARY_PATH=%T %clang -### -fopenmp=libomp 
-fopenmp-targets=nvptx64-nvidia-cuda \

gtbercea wrote:
> Hahnfeld wrote:
> > gtbercea wrote:
> > > gtbercea wrote:
> > > > Hahnfeld wrote:
> > > > > grokos wrote:
> > > > > > ABataev wrote:
> > > > > > > Create empty `libomptarget-nvptx-sm_60.bc` in `Driver/lib` 
> > > > > > > directory and use it in the test rather create|delete it 
> > > > > > > dynamically.
> > > > > > I'm also in favour of this approach. On some systems /tmp is not 
> > > > > > accessible and the regression test fails.
> > > > > This test doesn't (and shouldn't!) use `/tmp`. The build directory 
> > > > > and `%T` are always writable (if not, you have different issues on 
> > > > > your system).
> > > > > 
> > > > > Btw you need to pay attention that the driver now finds files next to 
> > > > > the compiler directory. You may want to make sure that the test 
> > > > > always passes / doesn't fail for wrong reasons.
> > > > Just added this.
> > > @Hahnfeld I've used %S instead.
> > > 
> > > The only way in which the test can be a false positive is when the lib 
> > > folder contains this .bc file. But there's no way to stop this from 
> > > happening since we check DefaultLibPath first.
> > (My comment was related to @grokos, the usage of `%T` and temporarily 
> > creating the bc lib. The current approach with `%S/Inputs` is much cleaner, 
> > but you need to create a subdirectory as everbody else did.)
> > 
> > Then you need to find a way to stop this. There already are some flags to 
> > change the sysroot etc., but I don't know if the influence what you use in 
> > this patch. In the worst case, you need to add a new flag to disable 
> > `DefaultLibPath` and use it in the tests. You can't propose to commit a 
> > test that is known to break (although I acknowledge that 
> > `libomptarget-nvptx-sm_20.bc` will probably never exist).
> I created a lib folder where the empty .bc is present: %S/Inputs/lib
> 
> Good point. sm_20.bc cannot be created since libomptarget requires sm_30 at 
> least which means that there can never be an sm_20 in the DefaultLibPath 
> folder so the only way to find it is to follow LIBRARY_PATH. This resolves 
> the issue.
Yes, and everybody else creates subdirectories with names that explain what 
they contain: `CUDA`, `debian`, `mingw` etc. You should pay more attention to 
follow a common style when already established.

Relying that `sm_20` will never be there is maybe not the cleanest solution but 
should work here. I'm fine unless somebody else objects.


Repository:
  rC Clang

https://reviews.llvm.org/D43197



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


[PATCH] D40381: Parse concept definition

2018-03-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/Parse/ParseTemplate.cpp:161
   // Parse the actual template declaration.
-  return ParseSingleDeclarationAfterTemplate(Context,
- ParsedTemplateInfo(&ParamLists,
- isSpecialization,
- 
LastParamListWasEmpty),
- ParsingTemplateParams,
- DeclEnd, AS, AccessAttrs);
+  if (!TryConsumeToken(tok::kw_concept))
+return ParseSingleDeclarationAfterTemplate(Context,

Perhaps add a LangOpts.ConceptsTS check here?


https://reviews.llvm.org/D40381



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


[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-03-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 137906.
saar.raz added a comment.

- Fixed incorrect checking of atomic constraint types.


Repository:
  rC Clang

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Parse/ParseExpr.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -231,6 +231,7 @@
   case Stmt::TypeTraitExprClass:
   case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ test/Parser/cxx-concept-declaration.cpp
@@ -9,8 +9,6 @@
 
 template concept D1 = true; // expected-error {{expected template parameter}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be 'bool'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -29,3 +27,22 @@
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
+
+template concept C7 = 2; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C8 = 2 && x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C9 = x || 2 || x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C10 = 8ull && x || x; // expected-error {{atomic constraint '8ULL' must be of type 'bool' (found 'unsigned long long')}}
+template concept C11 = sizeof(T); // expected-error {{atomic constraint 'sizeof(T)' must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+template concept C13 = (bool&&)true;
+template concept C14 = (const bool&)true;
+template concept C15 = (const bool)true;
+
+template
+struct integral_constant { static constexpr T value = v; };
+
+template  concept C16 = integral_constant::value && true;
+template  concept C17 = integral_constant::value;
+
+bool a = C16;
+bool b = C17;
Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
===
--- test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
+++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -1,5 +1,69 @@
 // RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
-// expected-no-diagnostics
 
-template concept C = true;
-static_assert(C);
+template concept C1 = true;
+static_assert(C1);
+
+template concept C2 = sizeof(T) == 4;
+static_assert(C2);
+static_assert(!C2);
+static_assert(C2);
+static_assert(!C2);
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);
+static_assert(!C3);
+
+struct A {
+static constexpr int add(int a, int b) {
+return a + b;
+}
+};
+struct B {
+static int add(int a, int b) {
+return a + b;
+}
+};
+template
+concept C4 = U::add(1, 2) == 3;
+static_assert(C4);
+static_assert(!C4); // expected-error {{concept specialization 'C4' resulted in a non-constant expression 'B::add(1, 2) == 3'}}
+
+template
+constexpr bool is_same_v = false;
+
+template
+constexpr bool is_same_v = true;
+
+template
+concept Same = is_same_v;
+
+static_assert(Same);
+static_assert(Same);
+static_assert(!Same);
+static_assert(!Same);
+static_assert(Same);
+
+static_assert(Same)>);
+static_assert(Same)>);
+static_assert(Same)>);
+static_assert(Same)>);
+
+template concept C5 = T{}; // expected-error {{atomic constraint 'int{}' must be of type 'bool' (found 'int')}}
+constexpr bool x = C5; // expected-note {{in concept specialization 'C5'}}
+
+template
+concept IsEven = (x % 2) == 0;
+
+static_assert(IsEven<20>);
+static_assert(!IsEven<11>);
+
+template typename P>
+concept IsTypePredicate = is_same_v::value), const bool>
+

[PATCH] D41569: Summary:Constraint enforcement and diagnostics

2018-03-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 137907.
saar.raz added a comment.

Fixed crash caused by substitution of pack expansion into non-pack parameters 
in constraint expressions.

Updating D41569: Summary:
=

Constraint enforcement and diagnostics


Repository:
  rC Clang

https://reviews.llvm.org/D41569

Files:
  include/clang/AST/ExprCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  include/clang/Sema/TemplateDeduction.h
  lib/AST/ExprCXX.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace class_templates
+{
+  template requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+  struct is_same { static constexpr bool value = false; };
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  struct is_same { static constexpr bool value = true; };
+
+  static_assert(!is_same::value);
+  static_assert(!is_same::value);
+  static_assert(is_same::value);
+  static_assert(is_same::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}}
+}
+
+namespace variable_templates
+{
+  template requires sizeof(T) >= 4
+  constexpr bool is_same_v = false;
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  constexpr bool is_same_v = true;
+
+  static_assert(!is_same_v);
+  static_assert(!is_same_v);
+  static_assert(is_same_v);
+}
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 2 // expected-note{{because 'sizeof(char) >= 2' (1 >= 2) evaluated to false}}
+struct A {
+  static constexpr int value = sizeof(T);
+};
+
+static_assert(A::value == 4);
+static_assert(A::value == 1); // expected-error{{constraints not satisfied for class template 'A' [with T = char]}}
+
+template
+  requires sizeof(T) != sizeof(U) // expected-note{{because 'sizeof(int) != sizeof(char [4])' (4 != 4) evaluated to false}}
+   && sizeof(T) >= 4 // expected-note{{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+constexpr int SizeDiff = sizeof(T) > sizeof(U) ? sizeof(T) - sizeof(U) : sizeof(U) - sizeof(T);
+
+static_assert(SizeDiff == 3);
+static_assert(SizeDiff == 0); // expected-error{{constraints not satisfied for variable template 'SizeDiff' [with T = int, U = char [4]]}}
+static_assert(SizeDiff == 3); // expected-error{{constraints not satisfied for variable template 'SizeDiff' [with T = char, U = int]}}
+
+template
+  requires ((sizeof(Ts) == 4) || ...) // expected-note{{because 'sizeof(char) == 4' (1 == 4) evaluated to false}} expected-note{{'sizeof(long long) == 4' (8 == 4) evaluated to false}} expected-note{{'sizeof(int [20]) == 4' (80 == 4) evaluated to false}}
+constexpr auto SumSizes = (sizeof(Ts) + ...);
+
+static_assert(SumSizes == 13);
+static_assert(SumSizes == 89); // expected-error{{constraints not satisfied for variable template 'SumSizes' [with Ts = ]}}
+
+template
+concept IsBig = sizeof(T) > 100; // expected-note{{because 'sizeof(int) > 100' (4 > 100) evaluated to false}}
+
+template
+  requires IsBig // expected-note{{'int' does not satisfy 'IsBig'}}
+using BigPtr = T*;
+
+static_assert(sizeof(BigPtr)); // expected-error{{constraints not satisfied for alias template 'BigPtr' [with T = int]
+
+template requires T::value // expected-note{{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}
+struct S { static constexpr bool value = true; };
+
+struct S2 { static constexpr bool value = true; };
+
+static_assert(S::value); // expected-error{{constraints not satisfied for class template 'S' [with T = int]}}
+static_assert(S::value);
+
+template
+struct AA
+{
+template requires sizeof(U) == sizeof(T) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to f

[PATCH] D41910: [Concepts] Constrained partial specializations and function overloads.

2018-03-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 137908.
saar.raz added a comment.

- Correct handling of non-substitutable concept specialization expressions.


Repository:
  rC Clang

https://reviews.llvm.org/D41910

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/Sema/Sema.h
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a = false; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a = true; // expected-error{{variable template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+bool b = false;
+
+template requires C1 && sizeof(T) <= 10
+bool b = true;
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c = false;
+
+template requires C1
+bool c = true;
+
+template
+bool d = false;
+
+template
+bool d = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template requires C1
+bool e = false;
+
+template
+bool e = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template
+constexpr int f = 1;
+
+template requires C1 && C2
+constexpr int f = 2;
+
+template requires C1 || C2
+constexpr int f = 3;
+
+static_assert(f == 2);
+static_assert(f == 3);
+static_assert(f == 1);
+
+
+
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a() { return false; } // expected-note {{candidate function [with T = unsigned int]}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a() { return true; } // expected-note {{candidate function [with T = unsigned int]}}
+
+bool av = a(); // expected-error {{call to 'a' is ambiguous}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+constexpr bool b() { return false; }
+
+template requires C1 && sizeof(T) <= 10
+constexpr bool b() { return true; }
+
+static_assert(b());
+static_assert(!b());
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c() { return false; }
+
+template requires C1
+bool c() { return true; }
+
+template requires C1
+constexpr bool d() { return false; }
+
+template
+constexpr bool d() { return true; }
+
+static_assert(!d());
+
+template
+constexpr int e() { return 1; }
+
+template requires C1 && C2
+constexpr int e() { return 2; }
+
+template requires C1 || C2
+constexpr int e() { return 3; }
+
+static_assert(e() == 2);
+static_assert(e() == 3);
+static_assert(e() == 1);
+
+
+
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+class A{}; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+class A{}; // expected-error{{class template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+class B{};
+
+template requires C1 && sizeof(T) <= 10
+class B{};
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+class C{};
+
+template requires C1
+class C{};
+
+template
+class D{}; // expected-note{{previous definition is here}}
+
+template
+class D{}; // expected-error{{class template partial specialization does not specialize any te

[PATCH] D44352: [Concepts] Constrained template parameters

2018-03-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz created this revision.
saar.raz added reviewers: nwilson, hubert.reinterpretcast, changyu, rsmith, 
faisalv, Quuxplusone.
Herald added a subscriber: cfe-commits.

Added support for constrained template parameters, both simple and with partial 
template arguments. Depends on https://reviews.llvm.org/D43357.


Repository:
  rC Clang

https://reviews.llvm.org/D44352

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/TemplateBase.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDumper.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/DeclTemplate.cpp
  lib/AST/ODRHash.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/SemaCXXScopeSpec.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.param/p10.cpp
  test/Parser/cxx-constrained-template-param-with-partial-id.cpp
  test/Parser/cxx-constrained-template-param.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -750,6 +750,10 @@
 }
 
 bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+  if (Expr *CE = D->getConstraintExpression())
+if (Visit(MakeCXCursor(CE, StmtParent, TU, RegionOfInterest)))
+  return true;
+
   // Visit the default argument.
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
@@ -898,6 +902,10 @@
 bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
   if (VisitDeclaratorDecl(D))
 return true;
+
+  if (Expr *CE = D->getConstraintExpression())
+if (Visit(MakeCXCursor(CE, StmtParent, TU, RegionOfInterest)))
+  return true;
   
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
 if (Expr *DefArg = D->getDefaultArgument())
@@ -929,7 +937,11 @@
 bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
   if (VisitTemplateParameters(D->getTemplateParameters()))
 return true;
-  
+
+  if (Expr *CE = D->getConstraintExpression())
+if (Visit(MakeCXCursor(CE, StmtParent, TU, RegionOfInterest)))
+  return true;
+
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
   VisitTemplateArgumentLoc(D->getDefaultArgument()))
 return true;
Index: test/Parser/cxx-constrained-template-param.cpp
===
--- /dev/null
+++ test/Parser/cxx-constrained-template-param.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
+// expected-no-diagnostics
+
+namespace type
+{
+  template
+  concept C1 = true;
+
+  template
+  using A = T[10];
+
+  using a = A;
+
+  namespace ns {
+template
+concept C2 = true;
+  }
+
+  template requires sizeof(T1) <= sizeof(T2)
+  struct B { };
+
+  using b = B;
+
+  template
+  struct C { };
+
+  using c1 = C;
+  using c2 = C;
+}
+
+namespace non_type
+{
+  template
+  concept C1 = true;
+
+  template
+  int A = v;
+
+  int& a = A<1>;
+
+  namespace ns {
+template
+concept C2 = true;
+  }
+
+  template requires sizeof(v1) <= sizeof(v2)
+  struct B { };
+
+  using b = B;
+
+  template
+  struct C { };
+
+  using c1 = C;
+  using c2 = C;
+}
+
+namespace temp
+{
+  template
+  struct test1 { };
+
+  template
+  struct test2 { };
+
+  template typename T>
+  concept C1 = true;
+
+  template
+  using A = TT;
+
+  using a = A;
+
+  namespace ns {
+template typename... TT>
+concept C2 = true;
+  }
+
+  template
+requires sizeof(TT1) <= sizeof(TT2)
+  struct B { };
+
+  using b = B;
+
+  template
+  struct C { };
+
+  using c1 = C;
+  using c2 = C;
+}
\ No newline at end of file
Index: test/Parser/cxx-constrained-template-param-with-partial-id.cpp
===
--- /dev/null
+++ test/Parser/cxx-constrained-template-param-with-partial-id.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
+
+template
+concept C1 = true;
+
+template // expected-error {{concept 'C1' requires more than 1 template argument; provide the remaining arguments explicitly to use it here}}
+using badA = T[10];
+
+template T>
+using A = T[10];
+
+using a = A;
+
+namespace ns {
+  template
+  concept C2 = true;
+}
+
+template // expected-error 2{{concept 'C2' requires more than 1 template argument; provide the remaining arguments explicitly to use it here}}
+requires sizeof(T1) <= sizeof(T2)
+struct bad

[PATCH] D40381: Parse concept definition

2018-03-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/Parse/ParseTemplate.cpp:383
+
+  if (!Tok.is(tok::identifier)) {
+Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;

We could accept 'bool' here to be nice to people coming in from the old 
Concepts TS version of these decls - and emit a proper warning.


https://reviews.llvm.org/D40381



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


[PATCH] D44295: [clang-tidy] Detects and fixes calls to grand-...parent virtual methods instead of calls to parent's virtual methods

2018-03-10 Thread Zinovy Nis via Phabricator via cfe-commits
zinovy.nis updated this revision to Diff 137911.

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44295

Files:
  clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tidy/bugprone/CMakeLists.txt
  clang-tidy/bugprone/ParentVirtualCallCheck.cpp
  clang-tidy/bugprone/ParentVirtualCallCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/bugprone-parent-virtual-call.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/bugprone-parent-virtual-call.cpp

Index: test/clang-tidy/bugprone-parent-virtual-call.cpp
===
--- /dev/null
+++ test/clang-tidy/bugprone-parent-virtual-call.cpp
@@ -0,0 +1,129 @@
+// RUN: %check_clang_tidy %s bugprone-parent-virtual-call %t
+
+extern int foo();
+
+class A {
+public:
+  A() = default;
+  virtual ~A() = default;
+
+  virtual int virt_1() { return foo() + 1; }
+  virtual int virt_2() { return foo() + 2; }
+
+  int non_virt() { return foo() + 3; }
+  static int stat() { return foo() + 4; }
+};
+
+class B : public A {
+public:
+  B() = default;
+
+  // Nothing to fix: calls to parent.
+  int virt_1() override { return A::virt_1() + 3; }
+  int virt_2() override { return A::virt_2() + 4; }
+};
+
+class C : public B {
+public:
+  int virt_1() override { return A::virt_1() + B::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'B'?
+  // CHECK-FIXES:  int virt_1() override { return B::virt_1() + B::virt_1(); }
+  int virt_2() override { return A::virt_1() + B::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'B'?
+  // CHECK-FIXES:  int virt_2() override { return B::virt_1() + B::virt_1(); }
+
+  // Test that non-virtual and static methods are not affected by this cherker.
+  int method_c() { return A::stat() + A::non_virt(); }
+};
+
+// Test that the check affects grand-grand..-parent calls too.
+class D : public C {
+public:
+  int virt_1() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: 'B::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-FIXES:  int virt_1() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+  int virt_2() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: 'B::virt_1' is a grand-parent's method, not parent's. Did you mean 'C'?
+  // CHECK-FIXES:  int virt_2() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+};
+
+// Test classes in anonymous namespaces.
+namespace {
+class BN : public A {
+public:
+  int virt_1() override { return A::virt_1() + 3; }
+  int virt_2() override { return A::virt_2() + 4; }
+};
+} // namespace N
+
+class CN : public BN {
+public:
+  int virt_1() override { return A::virt_1() + BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean '(anonymous namespace)::BN'?
+  // CHECK-FIXES:  int virt_1() override { return BN::virt_1() + BN::virt_1(); }
+  int virt_2() override { return A::virt_1() + BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean '(anonymous namespace)::BN'?
+  // CHECK-FIXES:  int virt_2() override { return BN::virt_1() + BN::virt_1(); }
+};
+
+// Test multiple inheritance fixes
+class AA {
+public:
+  AA() = default;
+  virtual ~AA() = default;
+
+  virtual int virt_1() { return foo() + 1; }
+  virtual int virt_2() { return foo() + 2; }
+
+  int non_virt() { return foo() + 3; }
+  static int stat() { return foo() + 4; }
+};
+
+class BB_1 : virtual public AA {
+public:
+  BB_1() = default;
+
+  // Nothing to fix: calls to parent.
+  int virt_1() override { return AA::virt_1() + 3; }
+  int virt_2() override { return AA::virt_2() + 4; }
+};
+
+class BB_2 : virtual public AA {
+public:
+BB_2() = default;
+};
+
+class CC : public BB_1, public BB_2 {
+public:
+  int virt_1() override { return AA::virt_1() + 3; }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'AA::virt_1' is a grand-parent's method, not parent's. Did you mean 'BB_1' or 'BB_2'? [bugprone-parent-virtual-call]
+  // No fix available due to multiple choice of parent class.
+};
+
+// Test templated classes.
+template  class BF : public A {
+public:
+  int virt_1() override { return A::virt_1() + 3; }
+};
+
+// Test templated parent class.
+class CF : public BF {
+public:
+  int virt_1() override { return A::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's method, not parent's. Did you mean 'BF'?
+  // CHECK-FIXES:  int virt_1() over

[PATCH] D44295: [clang-tidy] Detects and fixes calls to grand-...parent virtual methods instead of calls to parent's virtual methods

2018-03-10 Thread Malcolm Parsons via Phabricator via cfe-commits
malcolm.parsons added inline comments.



Comment at: test/clang-tidy/bugprone-parent-virtual-call.cpp:125
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: 'A::virt_1' is a grand-parent's 
method, not parent's. Did you mean 'BF'?
+  // CHECK-FIXES:  int virt_1() override { return BF::virt_1(); }
+};

Does this fixit compile?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44295



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


Re: r326946 - CodeGen: Fix address space of indirect function argument

2018-03-10 Thread John McCall via cfe-commits
> On Mar 9, 2018, at 8:51 PM, Richard Smith  wrote:
> 
> Hi,
> 
> This change increases the size of a CallArg, and thus that of a CallArgList, 
> dramatically (an LValue is *much* larger than an RValue, and unlike an 
> RValue, does not appear to be at all optimized for size). This results in 
> CallArgList (which contains inline storage for 16 CallArgs) ballooning in 
> size from ~500 bytes to 2KB, resulting in stack overflows on programs with 
> deep ASTs.
> 
> Given that this introduces a regression (due to stack overflow), I've 
> reverted in r327195. Sorry about that.

Seems reasonable.

The right short-term fix is probably a combination of the following:
  - put a little bit of effort into packing LValue (using fewer than 64 bits 
for the alignment and packing the bit-fields, I think)
  - drop the inline argument count to something like 8, which should still 
capture the vast majority of calls.

There are quite a few other space optimizations we could do the LValue 
afterwards.   I think we could eliminate BaseIVarExp completely by storing some 
sort of ObjC GC classification and then just evaluating the base expression 
normally.

> The program it broke looked something like this:
> 
> struct VectorBuilder {
>   VectorBuilder &operator,(int);
> };
> void f() {
>   VectorBuilder(),
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,
>   
> 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0;
> }
> 
> using Eigen's somewhat-ridiculous comma initializer technique 
> (https://eigen.tuxfamily.org/dox/group__TutorialAdvancedInitialization.html 
> ) 
> to build an approx 40 x 40 array.

> An AST 1600 levels deep is somewhat extreme, but it still seems like 
> something we should be able to handle within our default 8MB stack limit.

I mean, at some point this really is not supportable, even if it happens to 
build on current compilers.  If we actually documented and enforced our 
implementation limits like we're supposed to, I do not think we would allow 
this much call nesting.

John.

> 
> On 7 March 2018 at 13:45, Yaxun Liu via cfe-commits 
> mailto:cfe-commits@lists.llvm.org>> wrote:
> Author: yaxunl
> Date: Wed Mar  7 13:45:40 2018
> New Revision: 326946
> 
> URL: http://llvm

[PATCH] D44143: Create properly seeded random generator check

2018-03-10 Thread Borsik Gábor via Phabricator via cfe-commits
boga95 updated this revision to Diff 137915.
boga95 marked an inline comment as done.
boga95 added a comment.

Add capability to provide a user-configurable list of disallowed types which 
will trigger warning. Now it also detects C srand function. Rename check to 
cert-msc51-cpp. Add cert-msc32-c check. Change warning messages. Other minor 
fixes.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44143

Files:
  clang-tidy/cert/CERTTidyModule.cpp
  clang-tidy/cert/CMakeLists.txt
  clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp
  clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/cert-msc32-c.rst
  docs/clang-tidy/checks/cert-msc51-cpp.rst
  test/clang-tidy/cert-msc32-c.c
  test/clang-tidy/cert-msc51-cpp.cpp

Index: test/clang-tidy/cert-msc51-cpp.cpp
===
--- /dev/null
+++ test/clang-tidy/cert-msc51-cpp.cpp
@@ -0,0 +1,201 @@
+// RUN: %check_clang_tidy %s cert-msc51-cpp %t -- -config="{CheckOptions: [{key: cert-msc51-cpp.DisallowedSeedTypes, value: 'some_type,time_t'}]}" -- -std=c++11
+
+namespace std {
+
+template 
+struct linear_congruential_engine {
+  linear_congruential_engine(int _ = 0);
+  void seed(int _ = 0);
+};
+using default_random_engine = linear_congruential_engine;
+
+using size_t = int;
+template 
+struct mersenne_twister_engine {
+  mersenne_twister_engine(int _ = 0);
+  void seed(int _ = 0);
+};
+using mt19937 = mersenne_twister_engine;
+
+template 
+struct subtract_with_carry_engine {
+  subtract_with_carry_engine(int _ = 0);
+  void seed(int _ = 0);
+};
+using ranlux24_base = subtract_with_carry_engine;
+
+template 
+struct discard_block_engine {
+  discard_block_engine();
+  discard_block_engine(int _);
+  void seed();
+  void seed(int _);
+};
+using ranlux24 = discard_block_engine;
+
+template 
+struct independent_bits_engine {
+  independent_bits_engine();
+  independent_bits_engine(int _);
+  void seed();
+  void seed(int _);
+};
+using independent_bits = independent_bits_engine;
+
+template 
+struct shuffle_order_engine {
+  shuffle_order_engine();
+  shuffle_order_engine(int _);
+  void seed();
+  void seed(int _);
+};
+using shuffle_order = shuffle_order_engine;
+
+struct random_device {
+  random_device();
+  int operator()();
+};
+} // namespace std
+
+using time_t = unsigned int;
+time_t time(time_t *t);
+
+void f() {
+  const int seed = 2;
+  time_t t;
+
+  // One instantiation for every engine
+  std::default_random_engine engine1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  std::default_random_engine engine2(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::default_random_engine engine3(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::default_random_engine engine4(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine1.seed();
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  engine1.seed(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine1.seed(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine1.seed(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+  std::mt19937 engine5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  std::mt19937 engine6(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::mt19937 engine7(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::mt19937 engine8(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine5.seed();
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random

[PATCH] D43898: Preliminary refactoring in service of -Wreturn-std-move. NFC.

2018-03-10 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone marked 4 inline comments as done.
Quuxplusone added inline comments.



Comment at: lib/Sema/SemaStmt.cpp:2970
+  FunctionDecl *FD = Step.Function.Function;
+  if (isa(FD)) {
+// C++14 [class.copy]p32:

rtrieu wrote:
> Use early exit here:
> 
> 
> ```
> if (!isa(FD)
>   continue;
> 
> // old if-block code
> ```
I'd prefer not to do this, since D43322 is going to change this code into "if 
isa-red-fish... else if isa-blue-fish...". Therefore I think it makes sense to 
keep this intermediate stage as "if isa-red-fish...", rather than changing it 
into "if not-isa-red-fish continue... otherwise..."

If you really want this, I can change it; but it's just going to change back in 
D43322, and the goal of this patch was to make D43322 smaller.



Comment at: lib/Sema/SemaStmt.cpp:2999-3000
-// expression node to persist.
-Value = ImplicitCastExpr::Create(Context, Value->getType(), CK_NoOp,
- Value, nullptr, VK_XValue);
 

rtrieu wrote:
> At this point, the variable Value is updated.  Value is scoped to this 
> function, and used again after this code.  In your change, there is a new 
> Value variable in the static function.  Only that variable is updated and not 
> this one, making this a change in behavior.
Good catch! I've addressed this now by making the parameter `Expr *&Value`; but 
I'd be open to better approaches. Particularly because I still don't know what 
to do about the "unnecessary promoting `Value` to the heap" that will happen in 
D43322.


Repository:
  rC Clang

https://reviews.llvm.org/D43898



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


[PATCH] D43898: Preliminary refactoring in service of -Wreturn-std-move. NFC.

2018-03-10 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone updated this revision to Diff 137920.
Quuxplusone marked an inline comment as done.
Quuxplusone added a comment.

Addressed @rtrieu's comments.

@rtrieu, please take another look at this and https://reviews.llvm.org/D43322? 
Thanks!


Repository:
  rC Clang

https://reviews.llvm.org/D43898

Files:
  include/clang/Sema/Sema.h
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaStmt.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp

Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -741,7 +741,7 @@
 
   if (D->isNRVOVariable()) {
 QualType ReturnType = cast(DC)->getReturnType();
-if (SemaRef.isCopyElisionCandidate(ReturnType, Var, false))
+if (SemaRef.isCopyElisionCandidate(ReturnType, Var, Sema::CES_Strict))
   Var->setNRVOVariable(true);
   }
 
Index: lib/Sema/SemaStmt.cpp
===
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -2862,16 +2862,16 @@
 /// \param E The expression being returned from the function or block, or
 /// being thrown.
 ///
-/// \param AllowParamOrMoveConstructible Whether we allow function parameters or
+/// \param CESK Whether we allow function parameters or
 /// id-expressions that could be moved out of the function to be considered NRVO
 /// candidates. C++ prohibits these for NRVO itself, but we re-use this logic to
 /// determine whether we should try to move as part of a return or throw (which
 /// does allow function parameters).
 ///
 /// \returns The NRVO candidate variable, if the return statement may use the
 /// NRVO, or NULL if there is no such candidate.
 VarDecl *Sema::getCopyElisionCandidate(QualType ReturnType, Expr *E,
-   bool AllowParamOrMoveConstructible) {
+   CopyElisionSemanticsKind CESK) {
   if (!getLangOpts().CPlusPlus)
 return nullptr;
 
@@ -2884,29 +2884,29 @@
   if (!VD)
 return nullptr;
 
-  if (isCopyElisionCandidate(ReturnType, VD, AllowParamOrMoveConstructible))
+  if (isCopyElisionCandidate(ReturnType, VD, CESK))
 return VD;
   return nullptr;
 }
 
 bool Sema::isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD,
-  bool AllowParamOrMoveConstructible) {
+  CopyElisionSemanticsKind CESK) {
   QualType VDType = VD->getType();
   // - in a return statement in a function with ...
   // ... a class return type ...
   if (!ReturnType.isNull() && !ReturnType->isDependentType()) {
 if (!ReturnType->isRecordType())
   return false;
 // ... the same cv-unqualified type as the function return type ...
 // When considering moving this expression out, allow dissimilar types.
-if (!AllowParamOrMoveConstructible && !VDType->isDependentType() &&
+if (!(CESK & CES_AllowDifferentTypes) && !VDType->isDependentType() &&
 !Context.hasSameUnqualifiedType(ReturnType, VDType))
   return false;
   }
 
   // ...object (other than a function or catch-clause parameter)...
   if (VD->getKind() != Decl::Var &&
-  !(AllowParamOrMoveConstructible && VD->getKind() == Decl::ParmVar))
+  !((CESK & CES_AllowParameters) && VD->getKind() == Decl::ParmVar))
 return false;
   if (VD->isExceptionVariable()) return false;
 
@@ -2918,7 +2918,7 @@
   // variable will no longer be used.
   if (VD->hasAttr()) return false;
 
-  if (AllowParamOrMoveConstructible)
+  if (CESK & CES_AllowDifferentTypes)
 return true;
 
   // ...non-volatile...
@@ -2933,6 +2933,71 @@
   return true;
 }
 
+/// \brief Try to perform the initialization of a potentially-movable value,
+/// which is the operand to a return or throw statement.
+///
+/// This routine implements C++14 [class.copy]p32, which attempts to treat
+/// returned lvalues as rvalues in certain cases (to prefer move construction),
+/// then falls back to treating them as lvalues if that failed.
+///
+/// \param Res We will fill this in if move-initialization was possible.
+/// If move-initialization is not possible, such that we must fall back to
+/// treating the operand as an lvalue, we will leave Res in its original
+/// invalid state.
+static void TryMoveInitialization(Sema& S,
+  const InitializedEntity &Entity,
+  const VarDecl *NRVOCandidate,
+  QualType ResultType,
+  Expr *&Value,
+  ExprResult &Res) {
+  ImplicitCastExpr AsRvalue(ImplicitCastExpr::OnStack, Value->getType(),
+CK_NoOp, Value, VK_XValue);
+
+  Expr *InitExpr = &AsRvalue;
+
+  InitializationKind Kind = InitializationKind::CreateCopy(
+  Value->getLocStart(), Value->getLocStart());
+
+  InitializationSequence Seq(S, Entity, Kind, InitExpr);
+
+  if

[PATCH] D43322: Diagnose cases of "return x" that should be "return std::move(x)" for efficiency

2018-03-10 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone updated this revision to Diff 137921.
Quuxplusone added a comment.

Rebased on https://reviews.llvm.org/D43898 after addressing @rtrieu's latest 
comments over there.


Repository:
  rC Clang

https://reviews.llvm.org/D43322

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaStmt.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/SemaCXX/warn-return-std-move.cpp

Index: test/SemaCXX/warn-return-std-move.cpp
===
--- /dev/null
+++ test/SemaCXX/warn-return-std-move.cpp
@@ -0,0 +1,334 @@
+// RUN: %clang_cc1 -fsyntax-only -Wreturn-std-move -Wreturn-std-move-in-cxx11 -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wreturn-std-move -Wreturn-std-move-in-cxx11 -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
+// definitions for std::move
+namespace std {
+inline namespace foo {
+template  struct remove_reference { typedef T type; };
+template  struct remove_reference { typedef T type; };
+template  struct remove_reference { typedef T type; };
+
+template  typename remove_reference::type &&move(T &&t);
+} // namespace foo
+} // namespace std
+
+struct Instrument {
+Instrument() {}
+Instrument(Instrument&&) { /* MOVE */ }
+Instrument(const Instrument&) { /* COPY */ }
+};
+struct ConvertFromBase { Instrument i; };
+struct ConvertFromDerived { Instrument i; };
+struct Base {
+Instrument i;
+operator ConvertFromBase() const& { return ConvertFromBase{i}; }
+operator ConvertFromBase() && { return ConvertFromBase{std::move(i)}; }
+};
+struct Derived : public Base {
+operator ConvertFromDerived() const& { return ConvertFromDerived{i}; }
+operator ConvertFromDerived() && { return ConvertFromDerived{std::move(i)}; }
+};
+struct ConstructFromBase {
+Instrument i;
+ConstructFromBase(const Base& b): i(b.i) {}
+ConstructFromBase(Base&& b): i(std::move(b.i)) {}
+};
+struct ConstructFromDerived {
+Instrument i;
+ConstructFromDerived(const Derived& d): i(d.i) {}
+ConstructFromDerived(Derived&& d): i(std::move(d.i)) {}
+};
+
+struct TrivialInstrument {
+int i = 42;
+};
+struct ConvertFromTrivialBase { TrivialInstrument i; };
+struct ConvertFromTrivialDerived { TrivialInstrument i; };
+struct TrivialBase {
+TrivialInstrument i;
+operator ConvertFromTrivialBase() const& { return ConvertFromTrivialBase{i}; }
+operator ConvertFromTrivialBase() && { return ConvertFromTrivialBase{std::move(i)}; }
+};
+struct TrivialDerived : public TrivialBase {
+operator ConvertFromTrivialDerived() const& { return ConvertFromTrivialDerived{i}; }
+operator ConvertFromTrivialDerived() && { return ConvertFromTrivialDerived{std::move(i)}; }
+};
+struct ConstructFromTrivialBase {
+TrivialInstrument i;
+ConstructFromTrivialBase(const TrivialBase& b): i(b.i) {}
+ConstructFromTrivialBase(TrivialBase&& b): i(std::move(b.i)) {}
+};
+struct ConstructFromTrivialDerived {
+TrivialInstrument i;
+ConstructFromTrivialDerived(const TrivialDerived& d): i(d.i) {}
+ConstructFromTrivialDerived(TrivialDerived&& d): i(std::move(d.i)) {}
+};
+
+Derived test1() {
+Derived d1;
+return d1;  // ok
+}
+Base test2() {
+Derived d2;
+return d2;  // e1
+// expected-warning@-1{{will be copied despite being returned by name}}
+// expected-note@-2{{to avoid copying}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"std::move(d2)"
+}
+ConstructFromDerived test3() {
+Derived d3;
+return d3;  // e2-cxx11
+// expected-warning@-1{{would have been copied despite being returned by name}}
+// expected-note@-2{{to avoid copying on older compilers}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"std::move(d3)"
+}
+ConstructFromBase test4() {
+Derived d4;
+return d4;  // e3
+// expected-warning@-1{{will be copied despite being returned by name}}
+// expected-note@-2{{to avoid copying}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"std::move(d4)"
+}
+ConvertFromDerived test5() {
+Derived d5;
+return d5;  // e4
+// expected-warning@-1{{will be copied despite being returned by name}}
+// expected-note@-2{{to avoid copying}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"std::move(d5)"
+}
+ConvertFromBase test6() {
+Derived d6;
+return d6;  // e5
+// expected-warning@-1{{will be copied despite being returned by name}}
+// expected-note@-2{{to avoid copying}}
+// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"std::move(d6)"
+}
+
+// These test cases should not produce the warning.
+Derived ok1() { Derived d; return d; }
+Base ok2() { Derived d; return static_cast(d); }
+ConstructFromDerived ok3() { Derived d; return static_cast(d); }
+ConstructFromBase ok4() { Derived d; return static_cast(d); }
+ConvertFromDerived ok5() { 

[libcxxabi] r327227 - [demangler] Support for sequence numbers on lifetime extended temporaries.

2018-03-10 Thread Erik Pilkington via cfe-commits
Author: epilk
Date: Sat Mar 10 13:31:22 2018
New Revision: 327227

URL: http://llvm.org/viewvc/llvm-project?rev=327227&view=rev
Log:
[demangler] Support for sequence numbers on lifetime extended temporaries.

Modified:
libcxxabi/trunk/src/cxa_demangle.cpp
libcxxabi/trunk/test/test_demangle.pass.cpp

Modified: libcxxabi/trunk/src/cxa_demangle.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=327227&r1=327226&r2=327227&view=diff
==
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Sat Mar 10 13:31:22 2018
@@ -4324,6 +4324,8 @@ bool Db::parseCallOffset() {
 // # No 
 //::= TW  # Thread-local wrapper
 //::= TH  # Thread-local initialization
+//::= GR  _ # First temporary
+//::= GR   _# Subsequent temporaries
 //  extension ::= TC   _  # construction 
vtable for second-in-first
 //  extension ::= GR  # reference temporary for object
 Node *Db::parseSpecialName() {
@@ -4428,11 +4430,17 @@ Node *Db::parseSpecialName() {
   return make("guard variable for ", Name);
 }
 // GR  # reference temporary for object
+// GR  _ # First temporary
+// GR   _# Subsequent temporaries
 case 'R': {
   First += 2;
   Node *Name = parseName();
   if (Name == nullptr)
 return nullptr;
+  size_t Count;
+  bool ParsedSeqId = !parseSeqId(&Count);
+  if (!consumeIf('_') && ParsedSeqId)
+return nullptr;
   return make("reference temporary for ", Name);
 }
 }

Modified: libcxxabi/trunk/test/test_demangle.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=327227&r1=327226&r2=327227&view=diff
==
--- libcxxabi/trunk/test/test_demangle.pass.cpp (original)
+++ libcxxabi/trunk/test/test_demangle.pass.cpp Sat Mar 10 13:31:22 2018
@@ -29722,6 +29722,9 @@ const char* cases[][2] =
 // Structured bindings:
 {"_ZDC2a12a2E", "'structured-binding'[a1, a2]"},
 {"_ZN2NSDC1x1yEE", "NS::'structured-binding'[x, y]"},
+
+{"_ZGRDC1x1yE_", "reference temporary for 'structured-binding'[x, y]"},
+{"_ZGR1bIvE2_", "reference temporary for b"},
 };
 
 const unsigned N = sizeof(cases) / sizeof(cases[0]);


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


[libcxxabi] r327226 - [demangler] Support for structured bindings.

2018-03-10 Thread Erik Pilkington via cfe-commits
Author: epilk
Date: Sat Mar 10 13:31:15 2018
New Revision: 327226

URL: http://llvm.org/viewvc/llvm-project?rev=327226&view=rev
Log:
[demangler] Support for structured bindings.

Modified:
libcxxabi/trunk/src/cxa_demangle.cpp
libcxxabi/trunk/test/test_demangle.pass.cpp

Modified: libcxxabi/trunk/src/cxa_demangle.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=327226&r1=327225&r2=327226&view=diff
==
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Sat Mar 10 13:31:15 2018
@@ -197,6 +197,7 @@ public:
 KDtorName,
 KUnnamedTypeName,
 KClosureTypeName,
+KStructuredBindingName,
 KExpr,
 KBracedExpr,
 KBracedRangeExpr,
@@ -1337,6 +1338,19 @@ public:
   }
 };
 
+class StructuredBindingName : public Node {
+  NodeArray Bindings;
+public:
+  StructuredBindingName(NodeArray Bindings_)
+  : Node(KStructuredBindingName), Bindings(Bindings_) {}
+
+  void printLeft(OutputStream &S) const override {
+S += "'structured-binding'[";
+Bindings.printWithComma(S);
+S += ']';
+  }
+};
+
 // -- Expression Nodes --
 
 struct Expr : public Node {
@@ -2217,7 +2231,7 @@ Node *Db::parseUnscopedName(NameState *S
 //::= 
 //::= 
 //::= 
-// FIXME: ::= DC + E  # structured binding 
declaration
+//::= DC + E  # structured binding 
declaration
 Node *Db::parseUnqualifiedName(NameState *State) {
  // s are special-cased in parseNestedName().
  Node *Result;
@@ -2225,7 +2239,16 @@ Node *Db::parseUnqualifiedName(NameState
Result = parseUnnamedTypeName(State);
  else if (look() >= '1' && look() <= '9')
Result = parseSourceName(State);
- else
+ else if (consumeIf("DC")) {
+   size_t BindingsBegin = Names.size();
+   do {
+ Node *Binding = parseSourceName(State);
+ if (Binding == nullptr)
+   return nullptr;
+ Names.push_back(Binding);
+   } while (!consumeIf('E'));
+   Result = make(popTrailingNodeArray(BindingsBegin));
+ } else
Result = parseOperatorName(State);
  if (Result != nullptr)
Result = parseAbiTags(Result);
@@ -2689,7 +2712,7 @@ Node *Db::parseNestedName(NameState *Sta
 }
 
 // Parse an  thats actually a .
-if (look() == 'C' || look() == 'D') {
+if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
   if (SoFar == nullptr)
 return nullptr;
   Node *CtorDtor = parseCtorDtorName(SoFar, State);

Modified: libcxxabi/trunk/test/test_demangle.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=327226&r1=327225&r2=327226&view=diff
==
--- libcxxabi/trunk/test/test_demangle.pass.cpp (original)
+++ libcxxabi/trunk/test/test_demangle.pass.cpp Sat Mar 10 13:31:15 2018
@@ -29718,6 +29718,10 @@ const char* cases[][2] =
 {"_Z1fSsB1XS_", "f(std::string[abi:X], std::string[abi:X])"},
 
 {"___Z10blocksNRVOv_block_invoke", "invocation function for block in 
blocksNRVO()"},
+
+// Structured bindings:
+{"_ZDC2a12a2E", "'structured-binding'[a1, a2]"},
+{"_ZN2NSDC1x1yEE", "NS::'structured-binding'[x, y]"},
 };
 
 const unsigned N = sizeof(cases) / sizeof(cases[0]);
@@ -29848,7 +29852,6 @@ void test_invalid_cases()
 
 const char *xfail_cases[] = {
 "_Z1fUa9enable_ifIXLi1EEEv", // enable_if attribute
-"_ZDC2a12a2E", // decomposition decl
 "_ZW6FooBarE2f3v", // C++ modules TS
 
 // FIXME: Why does clang generate the "cp" expr?


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


Re: [libcxxabi] r327226 - [demangler] Support for structured bindings.

2018-03-10 Thread Richard Smith via cfe-commits
On 10 Mar 2018 13:33, "Erik Pilkington via cfe-commits" <
cfe-commits@lists.llvm.org> wrote:

Author: epilk
Date: Sat Mar 10 13:31:15 2018
New Revision: 327226

URL: http://llvm.org/viewvc/llvm-project?rev=327226&view=rev
Log:
[demangler] Support for structured bindings.

Modified:
libcxxabi/trunk/src/cxa_demangle.cpp
libcxxabi/trunk/test/test_demangle.pass.cpp

Modified: libcxxabi/trunk/src/cxa_demangle.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/
cxa_demangle.cpp?rev=327226&r1=327225&r2=327226&view=diff

==
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Sat Mar 10 13:31:15 2018
@@ -197,6 +197,7 @@ public:
 KDtorName,
 KUnnamedTypeName,
 KClosureTypeName,
+KStructuredBindingName,
 KExpr,
 KBracedExpr,
 KBracedRangeExpr,
@@ -1337,6 +1338,19 @@ public:
   }
 };

+class StructuredBindingName : public Node {
+  NodeArray Bindings;
+public:
+  StructuredBindingName(NodeArray Bindings_)
+  : Node(KStructuredBindingName), Bindings(Bindings_) {}
+
+  void printLeft(OutputStream &S) const override {
+S += "'structured-binding'[";
+Bindings.printWithComma(S);
+S += ']';
+  }
+};
+
 // -- Expression Nodes --

 struct Expr : public Node {
@@ -2217,7 +2231,7 @@ Node *Db::parseUnscopedName(NameState *S
 //::= 
 //::= 
 //::= 
-// FIXME: ::= DC + E  # structured binding
declaration
+//::= DC + E  # structured binding
declaration
 Node *Db::parseUnqualifiedName(NameState *State) {
  // s are special-cased in parseNestedName().
  Node *Result;
@@ -2225,7 +2239,16 @@ Node *Db::parseUnqualifiedName(NameState
Result = parseUnnamedTypeName(State);
  else if (look() >= '1' && look() <= '9')
Result = parseSourceName(State);
- else
+ else if (consumeIf("DC")) {
+   size_t BindingsBegin = Names.size();
+   do {
+ Node *Binding = parseSourceName(State);
+ if (Binding == nullptr)
+   return nullptr;
+ Names.push_back(Binding);
+   } while (!consumeIf('E'));
+   Result = make(popTrailingNodeArray(
BindingsBegin));
+ } else
Result = parseOperatorName(State);
  if (Result != nullptr)
Result = parseAbiTags(Result);
@@ -2689,7 +2712,7 @@ Node *Db::parseNestedName(NameState *Sta
 }

 // Parse an  thats actually a .
-if (look() == 'C' || look() == 'D') {
+if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
   if (SoFar == nullptr)
 return nullptr;
   Node *CtorDtor = parseCtorDtorName(SoFar, State);

Modified: libcxxabi/trunk/test/test_demangle.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/
test_demangle.pass.cpp?rev=327226&r1=327225&r2=327226&view=diff

==
--- libcxxabi/trunk/test/test_demangle.pass.cpp (original)
+++ libcxxabi/trunk/test/test_demangle.pass.cpp Sat Mar 10 13:31:15 2018
@@ -29718,6 +29718,10 @@ const char* cases[][2] =
 {"_Z1fSsB1XS_", "f(std::string[abi:X], std::string[abi:X])"},

 {"___Z10blocksNRVOv_block_invoke", "invocation function for block in
blocksNRVO()"},
+
+// Structured bindings:
+{"_ZDC2a12a2E", "'structured-binding'[a1, a2]"},
+{"_ZN2NSDC1x1yEE", "NS::'structured-binding'[x, y]"},


Do we really need the prefix here? In the front-end we just use "NS::[x,y]"
for this.

 };

 const unsigned N = sizeof(cases) / sizeof(cases[0]);
@@ -29848,7 +29852,6 @@ void test_invalid_cases()

 const char *xfail_cases[] = {
 "_Z1fUa9enable_ifIXLi1EEEv", // enable_if attribute
-"_ZDC2a12a2E", // decomposition decl
 "_ZW6FooBarE2f3v", // C++ modules TS

 // FIXME: Why does clang generate the "cp" expr?


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


[PATCH] D43650: [ARM] Add ARMv8.2-A FP16 vector intrinsics

2018-03-10 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added a comment.

This change broke building Qt for armv7, see PR36683 for details.


https://reviews.llvm.org/D43650



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


[libcxxabi] r327228 - [demangler] Simplify printing of structured bindings.

2018-03-10 Thread Erik Pilkington via cfe-commits
Author: epilk
Date: Sat Mar 10 14:33:49 2018
New Revision: 327228

URL: http://llvm.org/viewvc/llvm-project?rev=327228&view=rev
Log:
[demangler] Simplify printing of structured bindings.

Thanks to Richard Smith for the post-commit review!

Modified:
libcxxabi/trunk/src/cxa_demangle.cpp
libcxxabi/trunk/test/test_demangle.pass.cpp

Modified: libcxxabi/trunk/src/cxa_demangle.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=327228&r1=327227&r2=327228&view=diff
==
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Sat Mar 10 14:33:49 2018
@@ -1345,7 +1345,7 @@ public:
   : Node(KStructuredBindingName), Bindings(Bindings_) {}
 
   void printLeft(OutputStream &S) const override {
-S += "'structured-binding'[";
+S += '[';
 Bindings.printWithComma(S);
 S += ']';
   }

Modified: libcxxabi/trunk/test/test_demangle.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=327228&r1=327227&r2=327228&view=diff
==
--- libcxxabi/trunk/test/test_demangle.pass.cpp (original)
+++ libcxxabi/trunk/test/test_demangle.pass.cpp Sat Mar 10 14:33:49 2018
@@ -29720,10 +29720,10 @@ const char* cases[][2] =
 {"___Z10blocksNRVOv_block_invoke", "invocation function for block in 
blocksNRVO()"},
 
 // Structured bindings:
-{"_ZDC2a12a2E", "'structured-binding'[a1, a2]"},
-{"_ZN2NSDC1x1yEE", "NS::'structured-binding'[x, y]"},
+{"_ZDC2a12a2E", "[a1, a2]"},
+{"_ZN2NSDC1x1yEE", "NS::[x, y]"},
 
-{"_ZGRDC1x1yE_", "reference temporary for 'structured-binding'[x, y]"},
+{"_ZGRDC1x1yE_", "reference temporary for [x, y]"},
 {"_ZGR1bIvE2_", "reference temporary for b"},
 };
 


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


Re: [libcxxabi] r327226 - [demangler] Support for structured bindings.

2018-03-10 Thread Erik Pilkington via cfe-commits


On 2018-03-10 4:40 PM, Richard Smith wrote:
On 10 Mar 2018 13:33, "Erik Pilkington via cfe-commits" 
mailto:cfe-commits@lists.llvm.org>> wrote:


Author: epilk
Date: Sat Mar 10 13:31:15 2018
New Revision: 327226

URL: http://llvm.org/viewvc/llvm-project?rev=327226&view=rev

Log:
[demangler] Support for structured bindings.

Modified:
    libcxxabi/trunk/src/cxa_demangle.cpp
    libcxxabi/trunk/test/test_demangle.pass.cpp

Modified: libcxxabi/trunk/src/cxa_demangle.cpp
URL:

http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=327226&r1=327225&r2=327226&view=diff



==
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Sat Mar 10 13:31:15 2018
@@ -197,6 +197,7 @@ public:
     KDtorName,
     KUnnamedTypeName,
     KClosureTypeName,
+    KStructuredBindingName,
     KExpr,
     KBracedExpr,
     KBracedRangeExpr,
@@ -1337,6 +1338,19 @@ public:
   }
 };

+class StructuredBindingName : public Node {
+  NodeArray Bindings;
+public:
+  StructuredBindingName(NodeArray Bindings_)
+      : Node(KStructuredBindingName), Bindings(Bindings_) {}
+
+  void printLeft(OutputStream &S) const override {
+    S += "'structured-binding'[";
+    Bindings.printWithComma(S);
+    S += ']';
+  }
+};
+
 // -- Expression Nodes --

 struct Expr : public Node {
@@ -2217,7 +2231,7 @@ Node *Db::parseUnscopedName(NameState *S
 //                    ::= 
 //                    ::= 
 //                    ::= 
-// FIXME:             ::= DC + E   # structured
binding declaration
+//                    ::= DC + E   # structured
binding declaration
 Node *Db::parseUnqualifiedName(NameState *State) {
  // s are special-cased in parseNestedName().
  Node *Result;
@@ -2225,7 +2239,16 @@ Node *Db::parseUnqualifiedName(NameState
    Result = parseUnnamedTypeName(State);
  else if (look() >= '1' && look() <= '9')
    Result = parseSourceName(State);
- else
+ else if (consumeIf("DC")) {
+   size_t BindingsBegin = Names.size();
+   do {
+     Node *Binding = parseSourceName(State);
+     if (Binding == nullptr)
+       return nullptr;
+     Names.push_back(Binding);
+   } while (!consumeIf('E'));
+   Result =
make(popTrailingNodeArray(BindingsBegin));
+ } else
    Result = parseOperatorName(State);
  if (Result != nullptr)
    Result = parseAbiTags(Result);
@@ -2689,7 +2712,7 @@ Node *Db::parseNestedName(NameState *Sta
     }

     // Parse an  thats actually a .
-    if (look() == 'C' || look() == 'D') {
+    if (look() == 'C' || (look() == 'D' && look(1) != 'C')) {
       if (SoFar == nullptr)
         return nullptr;
       Node *CtorDtor = parseCtorDtorName(SoFar, State);

Modified: libcxxabi/trunk/test/test_demangle.pass.cpp
URL:

http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=327226&r1=327225&r2=327226&view=diff



==
--- libcxxabi/trunk/test/test_demangle.pass.cpp (original)
+++ libcxxabi/trunk/test/test_demangle.pass.cpp Sat Mar 10
13:31:15 2018
@@ -29718,6 +29718,10 @@ const char* cases[][2] =
     {"_Z1fSsB1XS_", "f(std::string[abi:X], std::string[abi:X])"},

     {"___Z10blocksNRVOv_block_invoke", "invocation function for
block in blocksNRVO()"},
+
+    // Structured bindings:
+    {"_ZDC2a12a2E", "'structured-binding'[a1, a2]"},
+    {"_ZN2NSDC1x1yEE", "NS::'structured-binding'[x, y]"},


Do we really need the prefix here? In the front-end we just use 
"NS::[x,y]" for this.
I suppose not, that printing is just as informative and less verbose. 
Fixed this in r327228, thanks for the review!


 };

 const unsigned N = sizeof(cases) / sizeof(cases[0]);
@@ -29848,7 +29852,6 @@ void test_invalid_cases()

 const char *xfail_cases[] = {
     "_Z1fUa9enable_ifIXLi1EEEv", // enable_if attribute
-    "_ZDC2a12a2E", // decomposition decl
     "_ZW6FooBarE2f3v", // C++ modules TS

     // FIXME: Why does clang generate the "cp" expr?


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


r327229 - [CodeGen] Eagerly emit lifetime.end markers for calls

2018-03-10 Thread George Burgess IV via cfe-commits
Author: gbiv
Date: Sat Mar 10 15:06:31 2018
New Revision: 327229

URL: http://llvm.org/viewvc/llvm-project?rev=327229&view=rev
Log:
[CodeGen] Eagerly emit lifetime.end markers for calls

In C, we'll wait until the end of the scope to clean up aggregate
temporaries used for returns from calls. This means in cases like:

{
  // Assuming that `Bar` is large enough to warrant indirect returns
  struct Bar b = {};
  b = foo(&b);
  b = foo(&b);
  b = foo(&b);
  b = foo(&b);
}

...We'll allocate space for 5 Bars on the stack (`b`, and 4
temporaries). This becomes painful in things like large switch
statements.

If cleaning up sooner is trivial, we should do it.

Added:
cfe/trunk/test/CodeGen/aggregate-assign-call.c
Modified:
cfe/trunk/lib/CodeGen/CGExprAgg.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=327229&r1=327228&r2=327229&view=diff
==
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Sat Mar 10 15:06:31 2018
@@ -23,6 +23,7 @@
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicInst.h"
 using namespace clang;
 using namespace CodeGen;
 
@@ -48,7 +49,7 @@ class AggExprEmitter : public StmtVisito
 
   // Calls `Fn` with a valid return value slot, potentially creating a 
temporary
   // to do so. If a temporary is created, an appropriate copy into `Dest` will
-  // be emitted.
+  // be emitted, as will lifetime markers.
   //
   // The given function should take a ReturnValueSlot, and return an RValue 
that
   // points to said slot.
@@ -250,16 +251,28 @@ void AggExprEmitter::withReturnValueSlot
  (RequiresDestruction && !Dest.getAddress().isValid());
 
   Address RetAddr = Address::invalid();
+
+  EHScopeStack::stable_iterator LifetimeEndBlock;
+  llvm::Value *LifetimeSizePtr = nullptr;
+  llvm::IntrinsicInst *LifetimeStartInst = nullptr;
   if (!UseTemp) {
 RetAddr = Dest.getAddress();
   } else {
 RetAddr = CGF.CreateMemTemp(RetTy);
 uint64_t Size =
 CGF.CGM.getDataLayout().getTypeAllocSize(CGF.ConvertTypeForMem(RetTy));
-if (llvm::Value *LifetimeSizePtr =
-CGF.EmitLifetimeStart(Size, RetAddr.getPointer()))
+LifetimeSizePtr = CGF.EmitLifetimeStart(Size, RetAddr.getPointer());
+if (LifetimeSizePtr) {
+  LifetimeStartInst =
+  cast(std::prev(Builder.GetInsertPoint()));
+  assert(LifetimeStartInst->getIntrinsicID() ==
+ llvm::Intrinsic::lifetime_start &&
+ "Last insertion wasn't a lifetime.start?");
+
   CGF.pushFullExprCleanup(
   NormalEHLifetimeMarker, RetAddr, LifetimeSizePtr);
+  LifetimeEndBlock = CGF.EHStack.stable_begin();
+}
   }
 
   RValue Src =
@@ -268,9 +281,18 @@ void AggExprEmitter::withReturnValueSlot
   if (RequiresDestruction)
 CGF.pushDestroy(RetTy.isDestructedType(), Src.getAggregateAddress(), 
RetTy);
 
-  if (UseTemp) {
-assert(Dest.getPointer() != Src.getAggregatePointer());
-EmitFinalDestCopy(E->getType(), Src);
+  if (!UseTemp)
+return;
+
+  assert(Dest.getPointer() != Src.getAggregatePointer());
+  EmitFinalDestCopy(E->getType(), Src);
+
+  if (!RequiresDestruction && LifetimeStartInst) {
+// If there's no dtor to run, the copy was the last use of our temporary.
+// Since we're not guaranteed to be in an ExprWithCleanups, clean up
+// eagerly.
+CGF.DeactivateCleanupBlock(LifetimeEndBlock, LifetimeStartInst);
+CGF.EmitLifetimeEnd(LifetimeSizePtr, RetAddr.getPointer());
   }
 }
 

Added: cfe/trunk/test/CodeGen/aggregate-assign-call.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/aggregate-assign-call.c?rev=327229&view=auto
==
--- cfe/trunk/test/CodeGen/aggregate-assign-call.c (added)
+++ cfe/trunk/test/CodeGen/aggregate-assign-call.c Sat Mar 10 15:06:31 2018
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O1 -S -emit-llvm -o - %s 
| FileCheck %s --check-prefix=O1
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O0 -S -emit-llvm -o - %s 
| FileCheck %s --check-prefix=O0
+//
+// Ensure that we place appropriate lifetime markers around indirectly returned
+// temporaries, and that the lifetime.ends appear in a timely manner.
+//
+// -O1 is used so lifetime markers actually get emitted.
+
+struct S {
+  int ns[40];
+};
+
+struct S foo(void);
+
+// CHECK-LABEL: define dso_local void @bar
+struct S bar() {
+  // O0-NOT: @llvm.lifetime.start
+  // O0-NOT: @llvm.lifetime.end
+
+  struct S r;
+  // O1: call void @llvm.lifetime.start.p0i8({{[^,]*}}, i8* nonnull 
%[[R_TMP:[^)]+]])
+
+  // O1: call void @llvm.lifetime.start.p0i8({{[^,]*}}, i8* nonnull 
%[[TMP1:[^)]+]])
+  // O1: call void @foo
+  r = foo();
+  // O1: call void @llvm.life

[PATCH] D44362: [clang] Change std::sort to llvm::sort in response to r327219

2018-03-10 Thread Mandeep Singh Grang via Phabricator via cfe-commits
mgrang created this revision.
mgrang added reviewers: rsmith, rnk, chandlerc.
mgrang added a project: clang.
Herald added a subscriber: klimek.

r327219 added wrappers to std::sort which randomly shuffle the container before 
sorting.
This will help in uncovering non-determinism caused due to undefined sorting
order of objects having the same key.

To make use of that infrastructure we need to invoke llvm::sort instead of 
std::sort.


Repository:
  rC Clang

https://reviews.llvm.org/D44362

Files:
  include/clang-c/Index.h
  include/clang/Basic/Attr.td
  include/clang/Serialization/ContinuousRangeMap.h
  lib/AST/ASTContext.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/VTableBuilder.cpp
  lib/ASTMatchers/Dynamic/Parser.cpp
  lib/Analysis/LiveVariables.cpp
  lib/Basic/VirtualFileSystem.cpp
  lib/CodeGen/CGVTables.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/TargetInfo.cpp
  lib/Driver/Driver.cpp
  lib/Format/FormatTokenLexer.cpp
  lib/Format/WhitespaceManager.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Frontend/DiagnosticRenderer.cpp
  lib/Sema/AnalysisBasedWarnings.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
  lib/StaticAnalyzer/Core/BugReporter.cpp
  lib/StaticAnalyzer/Core/CheckerRegistry.cpp
  lib/Tooling/ASTDiff/ASTDiff.cpp
  lib/Tooling/Core/Replacement.cpp
  tools/diagtool/DiagTool.cpp
  tools/libclang/CIndex.cpp
  unittests/Basic/VirtualFileSystemTest.cpp
  utils/TableGen/ClangAttrEmitter.cpp
  utils/TableGen/ClangDiagnosticsEmitter.cpp
  utils/TableGen/ClangOptionDocEmitter.cpp
  utils/TableGen/NeonEmitter.cpp

Index: utils/TableGen/NeonEmitter.cpp
===
--- utils/TableGen/NeonEmitter.cpp
+++ utils/TableGen/NeonEmitter.cpp
@@ -2007,7 +2007,7 @@
 }
   }
 
-  std::sort(NewTypeSpecs.begin(), NewTypeSpecs.end());
+  llvm::sort(NewTypeSpecs.begin(), NewTypeSpecs.end());
   NewTypeSpecs.erase(std::unique(NewTypeSpecs.begin(), NewTypeSpecs.end()),
 		 NewTypeSpecs.end());
   auto &Entry = IntrinsicMap[Name];
Index: utils/TableGen/ClangOptionDocEmitter.cpp
===
--- utils/TableGen/ClangOptionDocEmitter.cpp
+++ utils/TableGen/ClangOptionDocEmitter.cpp
@@ -111,25 +111,25 @@
 
   auto DocumentationForOption = [&](Record *R) -> DocumentedOption {
 auto &A = Aliases[R];
-std::sort(A.begin(), A.end(), CompareByName);
+llvm::sort(A.begin(), A.end(), CompareByName);
 return {R, std::move(A)};
   };
 
   std::function DocumentationForGroup =
   [&](Record *R) -> Documentation {
 Documentation D;
 
 auto &Groups = GroupsInGroup[R];
-std::sort(Groups.begin(), Groups.end(), CompareByLocation);
+llvm::sort(Groups.begin(), Groups.end(), CompareByLocation);
 for (Record *G : Groups) {
   D.Groups.emplace_back();
   D.Groups.back().Group = G;
   Documentation &Base = D.Groups.back();
   Base = DocumentationForGroup(G);
 }
 
 auto &Options = OptionsInGroup[R];
-std::sort(Options.begin(), Options.end(), CompareByName);
+llvm::sort(Options.begin(), Options.end(), CompareByName);
 for (Record *O : Options)
   D.Options.push_back(DocumentationForOption(O));
 
Index: utils/TableGen/ClangDiagnosticsEmitter.cpp
===
--- utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -207,9 +207,9 @@
   E = SortedGroups.end();
I != E; ++I) {
 MutableArrayRef GroupDiags = (*I)->DiagsInGroup;
-std::sort(GroupDiags.begin(), GroupDiags.end(), beforeThanCompare);
+llvm::sort(GroupDiags.begin(), GroupDiags.end(), beforeThanCompare);
   }
-  std::sort(SortedGroups.begin(), SortedGroups.end(), beforeThanCompareGroups);
+  llvm::sort(SortedGroups.begin(), SortedGroups.end(), beforeThanCompareGroups);
 
   // Warn about the same group being used anonymously in multiple places.
   for (SmallVectorImpl::const_iterator I = SortedGroups.begin(),
@@ -863,7 +863,7 @@
 Index.push_back(RecordIndexElement(R));
   }
 
-  std::sort(Index.begin(), Index.end(),
+  llvm::sort(Index.begin(), Index.end(),
 [](const RecordIndexElement &Lhs,
const RecordIndexElement &Rhs) { return Lhs.Name < Rhs.Name; });
 
@@ -1212,7 +1212,7 @@
   Records.getAllDerivedDefinitions("Diagnostic");
   std::vector DiagGroups =
   Records.getAllDerivedDefinitions("DiagGroup");
-  std::sort(DiagGroups.begin(), DiagGroups.end(), diagGroupBeforeByName);
+  llvm::sort(DiagGroups.begin(), DiagGroups.end(), diagGroupBeforeByName);
 
   DiagGroupParentMap DGParentMap(Records);
 
@@ -1231,9 +1231,9 @@
   DiagsInPed

[PATCH] D44362: [clang] Change std::sort to llvm::sort in response to r327219

2018-03-10 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: include/clang-c/Index.h:2133
* void abssort(float *x, unsigned N) {
-   *   std::sort(x, x + N,
+   *   llvm::sort(x, x + N,
* [](float a, float b) {

This shouldn't be changed.



Comment at: lib/AST/VTableBuilder.cpp:2109
+  llvm::sort(ThunksVector.begin(), ThunksVector.end(),
 [](const ThunkInfo &LHS, const ThunkInfo &RHS) {
 assert(LHS.Method == nullptr && RHS.Method == nullptr);

Reindent this (and other calls) please.


Repository:
  rC Clang

https://reviews.llvm.org/D44362



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