[PATCH] D85621: [clang] Allow DynTypedNode to store a TemplateArgumentLoc

2020-08-10 Thread Nathan Ridge via Phabricator via cfe-commits
nridge updated this revision to Diff 284264.
nridge added a comment.
Herald added a reviewer: jdoerfert.
Herald added a subscriber: sstefan1.

Run script to update AST matcher docs


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85621

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/AST/ASTTypeTraits.h
  clang/include/clang/ASTMatchers/ASTMatchFinder.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/lib/AST/ASTTypeTraits.cpp
  clang/lib/ASTMatchers/ASTMatchFinder.cpp
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -2637,6 +2637,19 @@
 std::make_unique>("x", 1)));
 }
 
+TEST(TemplateArgumentLoc, Matches) {
+  EXPECT_TRUE(matchAndVerifyResultTrue(
+  R"cpp(
+template  class C> class X {};
+class A {};
+const int B = 42;
+template  class C {};
+X x;
+  )cpp",
+  templateArgumentLoc().bind("x"),
+  std::make_unique>("x", 3)));
+}
+
 TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
   // Those matchers cover all the cases where an inner matcher is called
   // and there is not a 1:1 relationship between the match of the outer
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -734,6 +734,7 @@
 accessSpecDecl;
 const internal::VariadicAllOfMatcher cxxCtorInitializer;
 const internal::VariadicAllOfMatcher templateArgument;
+const internal::VariadicAllOfMatcher templateArgumentLoc;
 const internal::VariadicAllOfMatcher templateName;
 const internal::VariadicDynCastAllOfMatcher
 nonTypeTemplateParmDecl;
Index: clang/lib/ASTMatchers/ASTMatchFinder.cpp
===
--- clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -128,6 +128,9 @@
   traverse(*T);
 else if (const auto *C = DynNode.get())
   traverse(*C);
+else if (const TemplateArgumentLoc *TALoc =
+ DynNode.get())
+  traverse(*TALoc);
 // FIXME: Add other base types after adding tests.
 
 // It's OK to always overwrite the bound nodes, as if there was
@@ -224,6 +227,10 @@
 ScopedIncrement ScopedDepth(&CurrentDepth);
 return traverse(*CtorInit);
   }
+  bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL) {
+ScopedIncrement ScopedDepth(&CurrentDepth);
+return traverse(TAL);
+  }
   bool TraverseLambdaExpr(LambdaExpr *Node) {
 if (Finder->getASTContext().getParentMapContext().getTraversalKind() !=
 TK_IgnoreUnlessSpelledInSource)
@@ -304,6 +311,9 @@
 return VisitorBase::TraverseConstructorInitializer(
 const_cast(&CtorInit));
   }
+  bool baseTraverse(TemplateArgumentLoc TAL) {
+return VisitorBase::TraverseTemplateArgumentLoc(TAL);
+  }
 
   // Sets 'Matched' to true if 'Matcher' matches 'Node' and:
   //   0 < CurrentDepth <= MaxDepth.
@@ -447,6 +457,7 @@
   bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
   bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit);
+  bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL);
 
   // Matches children or descendants of 'Node' with 'BaseMatcher'.
   bool memoizedMatchesRecursively(const DynTypedNode &Node, ASTContext &Ctx,
@@ -557,6 +568,8 @@
   match(*N);
 } else if (auto *N = Node.get()) {
   match(*N);
+} else if (auto *N = Node.get()) {
+  match(*N);
 }
   }
 
@@ -680,6 +693,9 @@
   void matchDispatch(const CXXCtorInitializer *Node) {
 matchWithoutFilter(*Node, Matchers->CtorInit);
   }
+  void matchDispatch(const TemplateArgumentLoc *Node) {
+matchWithoutFilter(*Node, Matchers->TemplateArgumentLoc);
+  }
   void matchDispatch(const void *) { /* Do nothing. */ }
   /// @}
 
@@ -1035,6 +1051,11 @@
   CtorInit);
 }
 
+bool MatchASTVisitor::TraverseTemplateArgumentLoc(TemplateArgumentLoc Loc) {
+  match(Loc);
+  return RecursiveASTVisitor::TraverseTemplateArgumentLoc(Loc);
+}
+
 class MatchASTConsumer : public ASTConsumer {
 public:
   MatchASTConsumer(MatchFinder *Finder,
@@ -,6 +1132,12 @@
   Matchers.AllCallbacks.insert(Action);
 }
 
+void MatchFinder::addMatcher(const TemplateArgumentLocMatcher &NodeMatch,
+ MatchCallback *Action) {
+  Matchers.TemplateArgumentLoc.emplace_back(NodeMatch, Action);
+  Matchers.AllCallbacks.insert(Action);
+

[PATCH] D85621: [clang] Allow DynTypedNode to store a TemplateArgumentLoc

2020-08-10 Thread Nathan Ridge via Phabricator via cfe-commits
nridge added a comment.

In D85621#2205803 , @hokein wrote:

> Please run `clang/docs/tools/dump_ast_matchers.py` script to update the 
> `LibASTMatchersReference.html` file.

Done. Note, it looks like this script needs to be run with python 2. Should we 
document this somewhere?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85621

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


[clang] b1c7f84 - [clang] Allow DynTypedNode to store a TemplateArgumentLoc

2020-08-10 Thread Nathan Ridge via cfe-commits
Author: Nathan Ridge
Date: 2020-08-10T03:09:18-04:00
New Revision: b1c7f84643ffa63e72733b7089cea89723b82afc

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

LOG: [clang] Allow DynTypedNode to store a TemplateArgumentLoc

The patch also adds a templateArgumentLoc() AST matcher.

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

Added: 


Modified: 
clang/docs/LibASTMatchersReference.html
clang/include/clang/AST/ASTTypeTraits.h
clang/include/clang/ASTMatchers/ASTMatchFinder.h
clang/include/clang/ASTMatchers/ASTMatchers.h
clang/include/clang/ASTMatchers/ASTMatchersInternal.h
clang/lib/AST/ASTTypeTraits.cpp
clang/lib/ASTMatchers/ASTMatchFinder.cpp
clang/lib/ASTMatchers/ASTMatchersInternal.cpp
clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Removed: 




diff  --git a/clang/docs/LibASTMatchersReference.html 
b/clang/docs/LibASTMatchersReference.html
index 60ff6ffe6056..eb85e420e7e4 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -679,7 +679,8 @@ Node Matchers
   #pragma omp parallel default(firstprivate)
   #pragma omp parallel
 
-``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and 
``default(firstprivate)``.
+``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and
+``default(firstprivate)``
 
 
 
@@ -1625,6 +1626,17 @@ Node Matchers
 
 
 
+MatcherTemplateArgumentLoc>templateArgumentLocMatcherTemplateArgumentLoc>...
+Matches 
template arguments (with location info).
+
+Given
+  template  struct C {};
+  C c;
+templateArgumentLoc()
+  matches 'int' in C.
+
+
+
 MatcherTemplateArgument>templateArgumentMatcherTemplateArgument>...
 Matches template 
arguments.
 
@@ -3776,8 +3788,9 @@ Narrowing Matchers
 
 
 
-MatcherOMPDefaultClause>isNoneKind
-Matches if the OpenMP 
``default`` clause has ``none`` kind specified.
+MatcherOMPDefaultClause>isFirstPrivateKind
+Matches if the 
OpenMP ``default`` clause has ``firstprivate`` kind
+specified.
 
 Given
 
@@ -3786,12 +3799,13 @@ Narrowing Matchers
   #pragma omp parallel default(shared)
   #pragma omp parallel default(firstprivate)
 
-``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
+``ompDefaultClause(isFirstPrivateKind())`` matches only
+``default(firstprivate)``.
 
 
 
-MatcherOMPDefaultClause>isSharedKind
-Matches if the OpenMP 
``default`` clause has ``shared`` kind specified.
+MatcherOMPDefaultClause>isNoneKind
+Matches if the OpenMP 
``default`` clause has ``none`` kind specified.
 
 Given
 
@@ -3800,12 +3814,12 @@ Narrowing Matchers
   #pragma omp parallel default(shared)
   #pragma omp parallel default(firstprivate)
 
-``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``.
+``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
 
 
 
-MatcherOMPDefaultClause>isSharedKind
-Matches if the 
OpenMP ``default`` clause has ``firstprivate`` kind specified.
+MatcherOMPDefaultClause>isSharedKind
+Matches if the OpenMP 
``default`` clause has ``shared`` kind specified.
 
 Given
 
@@ -3814,7 +3828,7 @@ Narrowing Matchers
   #pragma omp parallel default(shared)
   #pragma omp parallel default(firstprivate)
 
-``ompDefaultClause(isFirstPrivateKind())`` matches only 
``default(firstprivate)``.
+``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``.
 
 
 

diff  --git a/clang/include/clang/AST/ASTTypeTraits.h 
b/clang/include/clang/AST/ASTTypeTraits.h
index 328b7bce6ba5..bd817b75bb84 100644
--- a/clang/include/clang/AST/ASTTypeTraits.h
+++ b/clang/include/clang/AST/ASTTypeTraits.h
@@ -132,6 +132,7 @@ class ASTNodeKind {
   enum NodeKindId {
 NKI_None,
 NKI_TemplateArgument,
+NKI_TemplateArgumentLoc,
 NKI_TemplateName,
 NKI_NestedNameSpecifierLoc,
 NKI_QualType,
@@ -191,6 +192,7 @@ class ASTNodeKind {
   };
 KIND_TO_KIND_ID(CXXCtorInitializer)
 KIND_TO_KIND_ID(TemplateArgument)
+KIND_TO_KIND_ID(TemplateArgumentLoc)
 KIND_TO_KIND_ID(TemplateName)
 KIND_TO_KIND_ID(NestedNameSpecifier)
 KIND_TO_KIND_ID(NestedNameS

[PATCH] D85621: [clang] Allow DynTypedNode to store a TemplateArgumentLoc

2020-08-10 Thread Nathan Ridge 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 rGb1c7f84643ff: [clang] Allow DynTypedNode to store a 
TemplateArgumentLoc (authored by nridge).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85621

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/AST/ASTTypeTraits.h
  clang/include/clang/ASTMatchers/ASTMatchFinder.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/lib/AST/ASTTypeTraits.cpp
  clang/lib/ASTMatchers/ASTMatchFinder.cpp
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -2637,6 +2637,19 @@
 std::make_unique>("x", 1)));
 }
 
+TEST(TemplateArgumentLoc, Matches) {
+  EXPECT_TRUE(matchAndVerifyResultTrue(
+  R"cpp(
+template  class C> class X {};
+class A {};
+const int B = 42;
+template  class C {};
+X x;
+  )cpp",
+  templateArgumentLoc().bind("x"),
+  std::make_unique>("x", 3)));
+}
+
 TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
   // Those matchers cover all the cases where an inner matcher is called
   // and there is not a 1:1 relationship between the match of the outer
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -734,6 +734,7 @@
 accessSpecDecl;
 const internal::VariadicAllOfMatcher cxxCtorInitializer;
 const internal::VariadicAllOfMatcher templateArgument;
+const internal::VariadicAllOfMatcher templateArgumentLoc;
 const internal::VariadicAllOfMatcher templateName;
 const internal::VariadicDynCastAllOfMatcher
 nonTypeTemplateParmDecl;
Index: clang/lib/ASTMatchers/ASTMatchFinder.cpp
===
--- clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -128,6 +128,9 @@
   traverse(*T);
 else if (const auto *C = DynNode.get())
   traverse(*C);
+else if (const TemplateArgumentLoc *TALoc =
+ DynNode.get())
+  traverse(*TALoc);
 // FIXME: Add other base types after adding tests.
 
 // It's OK to always overwrite the bound nodes, as if there was
@@ -224,6 +227,10 @@
 ScopedIncrement ScopedDepth(&CurrentDepth);
 return traverse(*CtorInit);
   }
+  bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL) {
+ScopedIncrement ScopedDepth(&CurrentDepth);
+return traverse(TAL);
+  }
   bool TraverseLambdaExpr(LambdaExpr *Node) {
 if (Finder->getASTContext().getParentMapContext().getTraversalKind() !=
 TK_IgnoreUnlessSpelledInSource)
@@ -304,6 +311,9 @@
 return VisitorBase::TraverseConstructorInitializer(
 const_cast(&CtorInit));
   }
+  bool baseTraverse(TemplateArgumentLoc TAL) {
+return VisitorBase::TraverseTemplateArgumentLoc(TAL);
+  }
 
   // Sets 'Matched' to true if 'Matcher' matches 'Node' and:
   //   0 < CurrentDepth <= MaxDepth.
@@ -447,6 +457,7 @@
   bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
   bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit);
+  bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL);
 
   // Matches children or descendants of 'Node' with 'BaseMatcher'.
   bool memoizedMatchesRecursively(const DynTypedNode &Node, ASTContext &Ctx,
@@ -557,6 +568,8 @@
   match(*N);
 } else if (auto *N = Node.get()) {
   match(*N);
+} else if (auto *N = Node.get()) {
+  match(*N);
 }
   }
 
@@ -680,6 +693,9 @@
   void matchDispatch(const CXXCtorInitializer *Node) {
 matchWithoutFilter(*Node, Matchers->CtorInit);
   }
+  void matchDispatch(const TemplateArgumentLoc *Node) {
+matchWithoutFilter(*Node, Matchers->TemplateArgumentLoc);
+  }
   void matchDispatch(const void *) { /* Do nothing. */ }
   /// @}
 
@@ -1035,6 +1051,11 @@
   CtorInit);
 }
 
+bool MatchASTVisitor::TraverseTemplateArgumentLoc(TemplateArgumentLoc Loc) {
+  match(Loc);
+  return RecursiveASTVisitor::TraverseTemplateArgumentLoc(Loc);
+}
+
 class MatchASTConsumer : public ASTConsumer {
 public:
   MatchASTConsumer(MatchFinder *Finder,
@@ -,6 +1132,12 @@
   Matchers.AllCallbacks.insert(Action);
 }
 
+void MatchFinder::addMatcher(const TemplateArgumentLocMatcher &NodeMatch,
+ MatchCallback *Action) {
+  Matchers.TemplateArgumentLoc.emplace_back(

[clang] 626d0f5 - [Concepts] Dump template arguments for immediately declared constraint.

2020-08-10 Thread Haojian Wu via cfe-commits
Author: Haojian Wu
Date: 2020-08-10T09:11:55+02:00
New Revision: 626d0f5818b223f04904c510eaa682db7a41c2dd

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

LOG: [Concepts] Dump template arguments for immediately declared constraint.

The template arguments were dumped as part of the TemplateTypeParmDecl, which
was incorrect.

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

Added: 


Modified: 
clang/include/clang/AST/ASTNodeTraverser.h
clang/lib/AST/TextNodeDumper.cpp
clang/test/AST/ast-dump-concepts.cpp

Removed: 




diff  --git a/clang/include/clang/AST/ASTNodeTraverser.h 
b/clang/include/clang/AST/ASTNodeTraverser.h
index 26656b7162b6..b0b1c152db05 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -543,9 +543,7 @@ class ASTNodeTraverser
 
   void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
 if (const auto *TC = D->getTypeConstraint())
-  if (TC->hasExplicitTemplateArgs())
-for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
-  dumpTemplateArgumentLoc(ArgLoc);
+  Visit(TC->getImmediatelyDeclaredConstraint());
 if (D->hasDefaultArgument())
   Visit(D->getDefaultArgument(), SourceRange(),
 D->getDefaultArgStorage().getInheritedFrom(),
@@ -574,6 +572,12 @@ class ASTNodeTraverser
 Visit(D->getConstraintExpr());
   }
 
+  void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *CSE) {
+if (CSE->hasExplicitTemplateArgs())
+  for (const auto &ArgLoc : CSE->getTemplateArgsAsWritten()->arguments())
+dumpTemplateArgumentLoc(ArgLoc);
+  }
+
   void VisitUsingShadowDecl(const UsingShadowDecl *D) {
 if (auto *TD = dyn_cast(D->getUnderlyingDecl()))
   Visit(TD->getTypeForDecl());

diff  --git a/clang/lib/AST/TextNodeDumper.cpp 
b/clang/lib/AST/TextNodeDumper.cpp
index 4aae63982542..47a7e431faf8 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1999,7 +1999,6 @@ void TextNodeDumper::VisitTemplateTypeParmDecl(const 
TemplateTypeParmDecl *D) {
   dumpBareDeclRef(TC->getFoundDecl());
   OS << ")";
 }
-AddChild([=] { Visit(TC->getImmediatelyDeclaredConstraint()); });
   } else if (D->wasDeclaredWithTypename())
 OS << " typename";
   else

diff  --git a/clang/test/AST/ast-dump-concepts.cpp 
b/clang/test/AST/ast-dump-concepts.cpp
index 630a953976fc..524ac0f65a06 100644
--- a/clang/test/AST/ast-dump-concepts.cpp
+++ b/clang/test/AST/ast-dump-concepts.cpp
@@ -15,8 +15,12 @@ concept binary_concept = true;
 template 
 struct Foo {
   // CHECK:  TemplateTypeParmDecl {{.*}} referenced Concept {{.*}} 
'binary_concept'
-  // CHECK-NEXT: |-ConceptSpecializationExpr {{.*}}  'bool' 
Concept {{.*}} 'binary_concept'
-  // CHECK-NEXT: `-TemplateArgument {{.*}} type 'int'
+  // CHECK-NEXT: `-ConceptSpecializationExpr {{.*}}  'bool' 
Concept {{.*}} 'binary_concept'
+  // CHECK-NEXT:   |-TemplateArgument {{.*}} type 'R'
+  // CHECK-NEXT:   | `-TemplateTypeParmType {{.*}} 'R'
+  // CHECK-NEXT:   |   `-TemplateTypeParm {{.*}} 'R'
+  // CHECK-NEXT:   `-TemplateArgument {{.*}} type 'int'
+  // CHECK-NEXT: `-BuiltinType {{.*}} 'int'
   template  R>
   Foo(R);
 
@@ -25,11 +29,11 @@ struct Foo {
   template 
   Foo(R);
 
-  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} 
Foo
+  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} Foo
   template 
   Foo(R, int) requires unary_concept;
 
-  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} 
Foo
+  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} Foo
   template 
   Foo(R, char) requires unary_concept {
   }



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


[PATCH] D85282: [Concepts] Dump template arguments for immediately declared constraint.

2020-08-10 Thread Haojian Wu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG626d0f5818b2: [Concepts] Dump template arguments for 
immediately declared constraint. (authored by hokein).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85282

Files:
  clang/include/clang/AST/ASTNodeTraverser.h
  clang/lib/AST/TextNodeDumper.cpp
  clang/test/AST/ast-dump-concepts.cpp


Index: clang/test/AST/ast-dump-concepts.cpp
===
--- clang/test/AST/ast-dump-concepts.cpp
+++ clang/test/AST/ast-dump-concepts.cpp
@@ -15,8 +15,12 @@
 template 
 struct Foo {
   // CHECK:  TemplateTypeParmDecl {{.*}} referenced Concept {{.*}} 
'binary_concept'
-  // CHECK-NEXT: |-ConceptSpecializationExpr {{.*}}  'bool' 
Concept {{.*}} 'binary_concept'
-  // CHECK-NEXT: `-TemplateArgument {{.*}} type 'int'
+  // CHECK-NEXT: `-ConceptSpecializationExpr {{.*}}  'bool' 
Concept {{.*}} 'binary_concept'
+  // CHECK-NEXT:   |-TemplateArgument {{.*}} type 'R'
+  // CHECK-NEXT:   | `-TemplateTypeParmType {{.*}} 'R'
+  // CHECK-NEXT:   |   `-TemplateTypeParm {{.*}} 'R'
+  // CHECK-NEXT:   `-TemplateArgument {{.*}} type 'int'
+  // CHECK-NEXT: `-BuiltinType {{.*}} 'int'
   template  R>
   Foo(R);
 
@@ -25,11 +29,11 @@
   template 
   Foo(R);
 
-  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} 
Foo
+  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} Foo
   template 
   Foo(R, int) requires unary_concept;
 
-  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} 
Foo
+  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} Foo
   template 
   Foo(R, char) requires unary_concept {
   }
Index: clang/lib/AST/TextNodeDumper.cpp
===
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -1999,7 +1999,6 @@
   dumpBareDeclRef(TC->getFoundDecl());
   OS << ")";
 }
-AddChild([=] { Visit(TC->getImmediatelyDeclaredConstraint()); });
   } else if (D->wasDeclaredWithTypename())
 OS << " typename";
   else
Index: clang/include/clang/AST/ASTNodeTraverser.h
===
--- clang/include/clang/AST/ASTNodeTraverser.h
+++ clang/include/clang/AST/ASTNodeTraverser.h
@@ -543,9 +543,7 @@
 
   void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
 if (const auto *TC = D->getTypeConstraint())
-  if (TC->hasExplicitTemplateArgs())
-for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
-  dumpTemplateArgumentLoc(ArgLoc);
+  Visit(TC->getImmediatelyDeclaredConstraint());
 if (D->hasDefaultArgument())
   Visit(D->getDefaultArgument(), SourceRange(),
 D->getDefaultArgStorage().getInheritedFrom(),
@@ -574,6 +572,12 @@
 Visit(D->getConstraintExpr());
   }
 
+  void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *CSE) {
+if (CSE->hasExplicitTemplateArgs())
+  for (const auto &ArgLoc : CSE->getTemplateArgsAsWritten()->arguments())
+dumpTemplateArgumentLoc(ArgLoc);
+  }
+
   void VisitUsingShadowDecl(const UsingShadowDecl *D) {
 if (auto *TD = dyn_cast(D->getUnderlyingDecl()))
   Visit(TD->getTypeForDecl());


Index: clang/test/AST/ast-dump-concepts.cpp
===
--- clang/test/AST/ast-dump-concepts.cpp
+++ clang/test/AST/ast-dump-concepts.cpp
@@ -15,8 +15,12 @@
 template 
 struct Foo {
   // CHECK:  TemplateTypeParmDecl {{.*}} referenced Concept {{.*}} 'binary_concept'
-  // CHECK-NEXT: |-ConceptSpecializationExpr {{.*}}  'bool' Concept {{.*}} 'binary_concept'
-  // CHECK-NEXT: `-TemplateArgument {{.*}} type 'int'
+  // CHECK-NEXT: `-ConceptSpecializationExpr {{.*}}  'bool' Concept {{.*}} 'binary_concept'
+  // CHECK-NEXT:   |-TemplateArgument {{.*}} type 'R'
+  // CHECK-NEXT:   | `-TemplateTypeParmType {{.*}} 'R'
+  // CHECK-NEXT:   |   `-TemplateTypeParm {{.*}} 'R'
+  // CHECK-NEXT:   `-TemplateArgument {{.*}} type 'int'
+  // CHECK-NEXT: `-BuiltinType {{.*}} 'int'
   template  R>
   Foo(R);
 
@@ -25,11 +29,11 @@
   template 
   Foo(R);
 
-  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} Foo
+  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} Foo
   template 
   Foo(R, int) requires unary_concept;
 
-  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} Foo
+  // CHECK:  FunctionTemplateDecl {{.*}}  {{.*}} Foo
   template 
   Foo(R, char) requires unary_concept {
   }
Index: clang/lib/AST/TextNodeDumper.cpp
===
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -1999,7 +1999,6 @@
   dumpBareDeclRef(TC->getFoundDecl());
   OS << ")";
 }
-AddChild([=] { Visit(TC->getImmediatelyDeclaredConstraint()); });
   } else if (D->wasDeclaredWithTypename())
 OS << " typename

[PATCH] D85523: [clang-tidy] Fix a crash in bugprone-not-null-terminated-result check when `__STDC_WANT_LIB_EXT1__` was undefined after definition.

2020-08-10 Thread Aleksandr Platonov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG5965fbf81b25: [clang-tidy] Fix a crash in 
bugprone-not-null-terminated-result check when… (authored by ArcsinX).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85523

Files:
  clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-undef-stdc-want-lib-ext1.c


Index: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-undef-stdc-want-lib-ext1.c
===
--- /dev/null
+++ 
clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-undef-stdc-want-lib-ext1.c
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
+// RUN: -- -std=c11 -I %S/Inputs/bugprone-not-null-terminated-result
+
+#include "not-null-terminated-result-c.h"
+
+#define __STDC_LIB_EXT1__ 1
+#define __STDC_WANT_LIB_EXT1__ 1
+#undef __STDC_WANT_LIB_EXT1__
+
+void f(const char *src) {
+  char dest[13];
+  memcpy_s(dest, 13, src, strlen(src) - 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 
'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: char dest[14];
+  // CHECK-FIXES-NEXT: strncpy_s(dest, 14, src, strlen(src) - 1);
+}
+
Index: clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
@@ -802,11 +802,14 @@
 while (It != PP->macro_end() && !AreSafeFunctionsWanted.hasValue()) {
   if (It->first->getName() == "__STDC_WANT_LIB_EXT1__") {
 const auto *MI = PP->getMacroInfo(It->first);
-const auto &T = MI->tokens().back();
-StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
-llvm::APInt IntValue;
-ValueStr.getAsInteger(10, IntValue);
-AreSafeFunctionsWanted = IntValue.getZExtValue();
+// PP->getMacroInfo() returns nullptr if macro has no definition.
+if (MI) {
+  const auto &T = MI->tokens().back();
+  StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
+  llvm::APInt IntValue;
+  ValueStr.getAsInteger(10, IntValue);
+  AreSafeFunctionsWanted = IntValue.getZExtValue();
+}
   }
 
   ++It;


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-undef-stdc-want-lib-ext1.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-undef-stdc-want-lib-ext1.c
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
+// RUN: -- -std=c11 -I %S/Inputs/bugprone-not-null-terminated-result
+
+#include "not-null-terminated-result-c.h"
+
+#define __STDC_LIB_EXT1__ 1
+#define __STDC_WANT_LIB_EXT1__ 1
+#undef __STDC_WANT_LIB_EXT1__
+
+void f(const char *src) {
+  char dest[13];
+  memcpy_s(dest, 13, src, strlen(src) - 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: char dest[14];
+  // CHECK-FIXES-NEXT: strncpy_s(dest, 14, src, strlen(src) - 1);
+}
+
Index: clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
@@ -802,11 +802,14 @@
 while (It != PP->macro_end() && !AreSafeFunctionsWanted.hasValue()) {
   if (It->first->getName() == "__STDC_WANT_LIB_EXT1__") {
 const auto *MI = PP->getMacroInfo(It->first);
-const auto &T = MI->tokens().back();
-StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
-llvm::APInt IntValue;
-ValueStr.getAsInteger(10, IntValue);
-AreSafeFunctionsWanted = IntValue.getZExtValue();
+// PP->getMacroInfo() returns nullptr if macro has no definition.
+if (MI) {
+  const auto &T = MI->tokens().back();
+  StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
+  llvm::APInt IntValue;
+  ValueStr.getAsInteger(10, IntValue);
+  AreSafeFunctionsWanted = IntValue.getZExtValue();
+}
   }
 
   ++It;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 5965fbf - [clang-tidy] Fix a crash in bugprone-not-null-terminated-result check when `__STDC_WANT_LIB_EXT1__` was undefined after definition.

2020-08-10 Thread Aleksandr Platonov via cfe-commits
Author: Aleksandr Platonov
Date: 2020-08-10T10:24:38+03:00
New Revision: 5965fbf81b25217c40b09b48bd808a8f4a5d4e89

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

LOG: [clang-tidy] Fix a crash in bugprone-not-null-terminated-result check when 
`__STDC_WANT_LIB_EXT1__` was undefined after definition.

PP->getMacroInfo() returns nullptr for undefined macro, so we need to check 
this return value before dereference.
Stack dump:
```
 #0 0x02185e6a llvm::sys::PrintStackTrace(llvm::raw_ostream&) 
(/llvm-project/build/bin/clang-tidy+0x2185e6a)
 #1 0x02183e8c llvm::sys::RunSignalHandlers() 
(/llvm-project/build/bin/clang-tidy+0x2183e8c)
 #2 0x02183ff3 SignalHandler(int) 
(/llvm-project/build/bin/clang-tidy+0x2183ff3)
 #3 0x7f37df9b1390 __restore_rt 
(/lib/x86_64-linux-gnu/libpthread.so.0+0x11390)
 #4 0x0052054e 
clang::tidy::bugprone::NotNullTerminatedResultCheck::check(clang::ast_matchers::MatchFinder::MatchResult
 const&) (/llvm-project/build/bin/clang-tidy+0x52054e)
```

Reviewed By: hokein

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

Added: 

clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-undef-stdc-want-lib-ext1.c

Modified: 
clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
index 269d69c1c124..7d484d777165 100644
--- a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
@@ -802,11 +802,14 @@ void NotNullTerminatedResultCheck::check(
 while (It != PP->macro_end() && !AreSafeFunctionsWanted.hasValue()) {
   if (It->first->getName() == "__STDC_WANT_LIB_EXT1__") {
 const auto *MI = PP->getMacroInfo(It->first);
-const auto &T = MI->tokens().back();
-StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
-llvm::APInt IntValue;
-ValueStr.getAsInteger(10, IntValue);
-AreSafeFunctionsWanted = IntValue.getZExtValue();
+// PP->getMacroInfo() returns nullptr if macro has no definition.
+if (MI) {
+  const auto &T = MI->tokens().back();
+  StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
+  llvm::APInt IntValue;
+  ValueStr.getAsInteger(10, IntValue);
+  AreSafeFunctionsWanted = IntValue.getZExtValue();
+}
   }
 
   ++It;

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-undef-stdc-want-lib-ext1.c
 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-undef-stdc-want-lib-ext1.c
new file mode 100644
index ..25e38800d28b
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-undef-stdc-want-lib-ext1.c
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
+// RUN: -- -std=c11 -I %S/Inputs/bugprone-not-null-terminated-result
+
+#include "not-null-terminated-result-c.h"
+
+#define __STDC_LIB_EXT1__ 1
+#define __STDC_WANT_LIB_EXT1__ 1
+#undef __STDC_WANT_LIB_EXT1__
+
+void f(const char *src) {
+  char dest[13];
+  memcpy_s(dest, 13, src, strlen(src) - 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 
'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: char dest[14];
+  // CHECK-FIXES-NEXT: strncpy_s(dest, 14, src, strlen(src) - 1);
+}
+



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


[PATCH] D85503: [clangd] Have template template arguments target their referenced template decl

2020-08-10 Thread Nathan Ridge via Phabricator via cfe-commits
nridge updated this revision to Diff 284271.
nridge added a comment.

Add Selection test

Also simplify the FindTarget test case a bit


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85503

Files:
  clang-tools-extra/clangd/FindTarget.cpp
  clang-tools-extra/clangd/Selection.cpp
  clang-tools-extra/clangd/unittests/FindTargetTests.cpp
  clang-tools-extra/clangd/unittests/SelectionTests.cpp


Index: clang-tools-extra/clangd/unittests/SelectionTests.cpp
===
--- clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -407,8 +407,16 @@
   s2[[-^>]]f();
 }
   )cpp",
-   "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
-  };
+   "DeclRefExpr"}, // DeclRefExpr to the "operator->" method.
+
+  // Template template argument.
+  {R"cpp(
+template  class Vector {};
+template  class Container> class A {};
+A<[[V^ector]]> a;
+  )cpp",
+   "TemplateArgumentLoc"}};
+
   for (const Case &C : Cases) {
 trace::TestTracer Tracer;
 Annotations Test(C.Code);
Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp
===
--- clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -376,6 +376,15 @@
{"template<> class Foo", Rel::TemplateInstantiation},
{"template  class Foo", Rel::TemplatePattern});
 
+  Code = R"cpp(
+// Template template argument.
+template struct Vector {};
+template  class Container>
+struct A {};
+A<[[Vector]]> a;
+  )cpp";
+  EXPECT_DECLS("TemplateArgumentLoc", {"template  struct Vector"});
+
   Flags.push_back("-std=c++17"); // for CTAD tests
 
   Code = R"cpp(
Index: clang-tools-extra/clangd/Selection.cpp
===
--- clang-tools-extra/clangd/Selection.cpp
+++ clang-tools-extra/clangd/Selection.cpp
@@ -479,6 +479,10 @@
   bool TraverseTypeLoc(TypeLoc X) {
 return traverseNode(&X, [&] { return Base::TraverseTypeLoc(X); });
   }
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &X) {
+return traverseNode(&X,
+[&] { return Base::TraverseTemplateArgumentLoc(X); });
+  }
   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc X) {
 return traverseNode(
 &X, [&] { return Base::TraverseNestedNameSpecifierLoc(X); });
Index: clang-tools-extra/clangd/FindTarget.cpp
===
--- clang-tools-extra/clangd/FindTarget.cpp
+++ clang-tools-extra/clangd/FindTarget.cpp
@@ -596,6 +596,19 @@
   add(CCI->getAnyMember(), Flags);
 // Constructor calls contain a TypeLoc node, so we don't handle them here.
   }
+
+  void add(const TemplateArgument &Arg, RelSet Flags) {
+// Only used for template template arguments.
+// For type and non-type template arguments, SelectionTree
+// will hit a more specific node (e.g. a TypeLoc or a
+// DeclRefExpr).
+if (Arg.getKind() == TemplateArgument::Template ||
+Arg.getKind() == TemplateArgument::TemplateExpansion) {
+  if (TemplateDecl *TD = Arg.getAsTemplate().getAsTemplateDecl()) {
+report(TD, Flags);
+  }
+}
+  }
 };
 
 } // namespace
@@ -619,6 +632,8 @@
 Finder.add(*QT, Flags);
   else if (const CXXCtorInitializer *CCI = N.get())
 Finder.add(CCI, Flags);
+  else if (const TemplateArgumentLoc *TAL = N.get())
+Finder.add(TAL->getArgument(), Flags);
 
   return Finder.takeDecls();
 }


Index: clang-tools-extra/clangd/unittests/SelectionTests.cpp
===
--- clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -407,8 +407,16 @@
   s2[[-^>]]f();
 }
   )cpp",
-   "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
-  };
+   "DeclRefExpr"}, // DeclRefExpr to the "operator->" method.
+
+  // Template template argument.
+  {R"cpp(
+template  class Vector {};
+template  class Container> class A {};
+A<[[V^ector]]> a;
+  )cpp",
+   "TemplateArgumentLoc"}};
+
   for (const Case &C : Cases) {
 trace::TestTracer Tracer;
 Annotations Test(C.Code);
Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp
===
--- clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -376,6 +376,15 @@
{"template<> class Foo", Rel::TemplateInstantiation},
{"template  class Foo", Rel::TemplatePattern});
 
+  Code = R"cpp(
+// Template template argument.
+

[PATCH] D85345: [BuildLibCalls] Add noundef to standard I/O functions

2020-08-10 Thread Juneyoung Lee via Phabricator via cfe-commits
aqjune added a comment.

In D85345#2205745 , @jdoerfert wrote:

> In D85345#2205712 , @aqjune wrote:
>
>> What about undef or poison is given to malloc? If it should raise UB, the 
>> size argument and returned pointer should be noundef.
>
> It is unclear to me if we want to forbid undef to be passed to malloc. It 
> makes practical sense but not from a semantic perspective.
> However, even if you pass undef you should not get undef back. So the return 
> should never be undef for sure. If it doesn, how could you ever deal with it, 
> given that a branch on the result would be UB :D

Makes sense and labeling the returned pointer of malloc as noundef will be 
useful in various places, e.g. proving safety of loop unswitching on 
`icmp(malloc(p), null)`.
Give me some time, because I'd like to play with this by implementing this on 
Alive2 and see how it goes when running unit tests.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85345

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


[PATCH] D85621: [clang] Allow DynTypedNode to store a TemplateArgumentLoc

2020-08-10 Thread Nathan James via Phabricator via cfe-commits
njames93 added a comment.

In D85621#2205856 , @nridge wrote:

> In D85621#2205803 , @hokein wrote:
>
>> Please run `clang/docs/tools/dump_ast_matchers.py` script to update the 
>> `LibASTMatchersReference.html` file.
>
> Done. Note, it looks like this script needs to be run with python 2. Should 
> we document this somewhere?

Given that python2 is EOL I think the correct course of action is to make it 
work with python3.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85621

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


[PATCH] D85431: [analyzer] Implement a new checker ThreadPrimitivesChecker

2020-08-10 Thread Denys Petrov via Phabricator via cfe-commits
ASDenysPetrov added inline comments.



Comment at: clang/lib/StaticAnalyzer/Checkers/ThreadPrimitivesChecker.cpp:46
+
+REGISTER_SET_WITH_PROGRAMSTATE(LockedMutexes, SVal)
+

vsavchenko wrote:
> vsavchenko wrote:
> > You should also cleanup and remove dead symbols from the set.
> Maybe `SymbolRef` is more suitable here?
>Maybe SymbolRef is more suitable here?
I'm afraid it's not. Sval keeps some data but this data 
See, getCXXThisVal returns SVal which is MemRegionVal, thus I can't cast it to 
SymbolVal and get SymbolRef.
But I would appreciate if you could tell me what other actionsI should do to 
get a correct SymbolRef.


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

https://reviews.llvm.org/D85431

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


[PATCH] D85440: [SyntaxTree] Implement `NNS` using the `List` base API

2020-08-10 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr2 added a comment.

LGTM after my comments are addressed.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85440

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


[PATCH] D85295: [SyntaxTree] Implement the List construct.

2020-08-10 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr2 accepted this revision.
gribozavr2 added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/include/clang/Tooling/Syntax/Tree.h:194
 
+/// A Tree that represents a syntactic list of elements.
+///

"""
A list of elements separated or terminated by a fixed token.

This type models the following grammar construct:
delimited-list(element, delimiter, termination, canBeEmpty)
"""



Comment at: clang/include/clang/Tooling/Syntax/Tree.h:249
+
+  /// Return whether *under valid code* the list can be empty.
+  ///

"Whether this list can be empty in syntactically and semantically correct code.

This list may be empty when the source code has errors even if canBeEmpty() 
returns true."



Comment at: clang/lib/Tooling/Syntax/Tree.cpp:367
+clang::tok::TokenKind syntax::List::getDelimiterTokenKind() {
+  llvm_unreachable("A list can have only elements and delimiters as 
children.");
+}

I think a better error message would say that there are no subclasses of List, 
so this method can't be called.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85295

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


[PATCH] D84781: [SyntaxTree] Use PointerUnion instead of inheritance for alternative clauses in NNS

2020-08-10 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr2 added a comment.

Seeing the API, I like the inheritance-based approach better. It seems more 
uniform.




Comment at: clang/lib/Tooling/Syntax/Nodes.cpp:219
+  syntax::EmptyNode *, syntax::Leaf *, syntax::DecltypeSpecifier *,
+  syntax::SimpleTemplateSpecifier *>::getFromOpaqueValue(firstChild());
+}

getFromOpaqueValue will not select the right alternative in the PointerUnion. 
You need to do case analysis through if-else-if based on the type of node 
returned by firstChild.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84781

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


[PATCH] D80514: [clang-tidy] modernize-use-trailing-return-type support for C++20 concepts and decltype

2020-08-10 Thread Bernhard Manfred Gruber via Phabricator via cfe-commits
bernhardmgruber added a comment.

Btw: what is the general rule for Phabricator reviews here when to tick the 
`Done` checkbox of a comment? What is the semantic of this checkbox? Is the 
ticked state the same for everyone?

Thank you for the help!




Comment at: 
clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp:430
+  AT->getKeyword() == AutoTypeKeyword::Auto &&
+  !hasAnyNestedLocalQualifiers(F->getDeclaredReturnType()))
+return;

aaron.ballman wrote:
> aaron.ballman wrote:
> > bernhardmgruber wrote:
> > > aaron.ballman wrote:
> > > > Why do we need to check that there aren't any nested local qualifiers?
> > > Because I would like the check to rewrite e.g. `const auto f();` into 
> > > `auto f() -> const auto;`. If I omit the check for nested local 
> > > qualifiers, then those kind of declarations would be skipped.
> > I'm still wondering about this.
> > Because I would like the check to rewrite e.g. const auto f(); into auto 
> > f() -> const auto;. If I omit the check for nested local qualifiers, then 
> > those kind of declarations would be skipped.
> 
> I don't think I understand why that's desirable though? What is it about the 
> qualifier that makes it worthwhile to repeat the type like that?
Thank you for insisting on that peculiarity! The choice is stylistically 
motivated to align function names:

```
auto f() -> int;
auto g() -> std::vector;
auto& h();
const auto k();
decltype(auto) l();
```
vs.
```
auto f() -> int;
auto g() -> std::vector;
auto h() -> auto&;
auto k() -> const auto; 
auto l() -> decltype(auto);
```

But judging from your response, this might be a surprise to users. Would you 
prefer having an option to enable/disable this behavior?



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/modernize-use-trailing-return-type.cpp:1
-// RUN: %check_clang_tidy -std=c++14,c++17 %s 
modernize-use-trailing-return-type %t -- -- -fdeclspec -fexceptions
+// RUN: %check_clang_tidy -std=c++14-or-later %s 
modernize-use-trailing-return-type %t -- -- -fdeclspec -fexceptions 
-DCOMMAND_LINE_INT=int
 // FIXME: Fix the checker to work in C++20 mode, it is performing a

riccibruno wrote:
> riccibruno wrote:
> > aaron.ballman wrote:
> > > bernhardmgruber wrote:
> > > > aaron.ballman wrote:
> > > > > The change to the language standard line makes me wonder if the fixme 
> > > > > below it is now stale, or if the test will fail in C++20 mode.
> > > > I just ran the tests again using `python .\check_clang_tidy.py 
> > > > -std=c++20 .\checkers\modernize-use-trailing-return-type.cpp 
> > > > modernize-use-trailing-return-type aa -- -- -DCOMMAND_LINE_INT=int` and 
> > > > I did not see mentioning of the use of an uninitialized variable. But I 
> > > > run on Windows, maybe the issue just surfaces on another OS? Is there a 
> > > > way to trigger the CI again?
> > > > 
> > > > I removed the FIXME in question in the hope the issue resolved itself.
> > > > But I run on Windows, maybe the issue just surfaces on another OS? Is 
> > > > there a way to trigger the CI again?
> > > 
> > > I also run on Windows so I can't easily test the behavior elsewhere for 
> > > you. The CI will get triggered on new patch uploads, but I still don't 
> > > always trust it. The bots are usually a more reliable source of CI truth 
> > > but we have no way to speculatively trigger all the bots.
> > I can run it for you with asan/msan.
> No warning with either asan or msan on x86-64 linux with clang 10.
Thank you @riccibruno for verifying that for me!


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

https://reviews.llvm.org/D80514

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


[PATCH] D84886: Create LoopNestPass

2020-08-10 Thread Ta-Wei Tu via Phabricator via cfe-commits
TaWeiTu added a comment.

Ping.

@ychen Thank you for your comment! I've added some unittests.  Please let me 
know if there's anything unclear about the intended usage.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84886

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


[PATCH] D84520: [Analyzer] Improve invalid dereference bug reporting in DereferenceChecker.

2020-08-10 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 284283.
balazske added a comment.

Preserve original error messages.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84520

Files:
  clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
  clang/test/Analysis/invalid-deref.c
  clang/test/Analysis/misc-ps-region-store.m

Index: clang/test/Analysis/misc-ps-region-store.m
===
--- clang/test/Analysis/misc-ps-region-store.m
+++ clang/test/Analysis/misc-ps-region-store.m
@@ -1157,7 +1157,7 @@
 struct list_pr8141 *
 pr8141 (void) {
   struct list_pr8141 *items;
-  for (;; items = ({ do { } while (0); items->tail; })) // expected-warning{{Dereference of undefined pointer value}}
+  for (;; items = ({ do { } while (0); items->tail; })) // expected-warning{{dereference of an undefined pointer value}}
 {
 }
 }
Index: clang/test/Analysis/invalid-deref.c
===
--- /dev/null
+++ clang/test/Analysis/invalid-deref.c
@@ -0,0 +1,32 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
+
+typedef unsigned uintptr_t;
+
+void f1() {
+  int *p;
+  *p = 0; // expected-warning{{Dereference of undefined pointer value}}
+}
+
+struct foo_struct {
+  int x;
+};
+
+int f2() {
+  struct foo_struct *p;
+
+  return p->x++; // expected-warning{{Access to field 'x' results in a dereference of an undefined pointer value (loaded from variable 'p')}}
+}
+
+int f3() {
+  char *x;
+  int i = 2;
+
+  return x[i + 1]; // expected-warning{{Array access (from variable 'x') results in an undefined pointer dereference}}
+}
+
+int f3_b() {
+  char *x;
+  int i = 2;
+
+  return x[i + 1]++; // expected-warning{{Array access (from variable 'x') results in an undefined pointer dereference}}
+}
Index: clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
@@ -30,11 +30,14 @@
 : public Checker< check::Location,
   check::Bind,
   EventDispatcher > {
+  enum DerefKind { NullPointer, UndefinedPointerValue };
+
   BugType BT_Null{this, "Dereference of null pointer", categories::MemoryError};
   BugType BT_Undef{this, "Dereference of undefined pointer value",
categories::MemoryError};
 
-  void reportBug(ProgramStateRef State, const Stmt *S, CheckerContext &C) const;
+  void reportBug(DerefKind K, ProgramStateRef State, const Stmt *S,
+ CheckerContext &C) const;
 
 public:
   void checkLocation(SVal location, bool isLoad, const Stmt* S,
@@ -117,8 +120,24 @@
   return false;
 }
 
-void DereferenceChecker::reportBug(ProgramStateRef State, const Stmt *S,
-   CheckerContext &C) const {
+void DereferenceChecker::reportBug(DerefKind K, ProgramStateRef State,
+   const Stmt *S, CheckerContext &C) const {
+  const BugType *BT = nullptr;
+  llvm::StringRef DerefStr1;
+  llvm::StringRef DerefStr2;
+  switch (K) {
+  case DerefKind::NullPointer:
+BT = &BT_Null;
+DerefStr1 = " results in a null pointer dereference";
+DerefStr2 = " results in a dereference of a null pointer";
+break;
+  case DerefKind::UndefinedPointerValue:
+BT = &BT_Undef;
+DerefStr1 = " results in an undefined pointer dereference";
+DerefStr2 = " results in a dereference of an undefined pointer value";
+break;
+  };
+
   // Generate an error node.
   ExplodedNode *N = C.generateErrorNode(State);
   if (!N)
@@ -135,7 +154,7 @@
 const ArraySubscriptExpr *AE = cast(S);
 AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(),
State.get(), N->getLocationContext());
-os << " results in a null pointer dereference";
+os << DerefStr1;
 break;
   }
   case Stmt::OMPArraySectionExprClass: {
@@ -143,11 +162,11 @@
 const OMPArraySectionExpr *AE = cast(S);
 AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(),
State.get(), N->getLocationContext());
-os << " results in a null pointer dereference";
+os << DerefStr1;
 break;
   }
   case Stmt::UnaryOperatorClass: {
-os << "Dereference of null pointer";
+os << BT->getDescription();
 const UnaryOperator *U = cast(S);
 AddDerefSource(os, Ranges, U->getSubExpr()->IgnoreParens(),
State.get(), N->getLocationContext(), true);
@@ -156,8 +175,7 @@
   case Stmt::MemberExprClass: {
 const MemberExpr *M = cast(S);
 if (M->isArrow() || isDeclRefExprToReference(M->getBase())) {
-  os << "Access to field '" << M->getMemberNameInfo()
- << "' results in a dereference of a null pointer";
+  os << "Access to field '" << M->getMemberNameInfo() << "'" << DerefStr

[PATCH] D84520: [Analyzer] Improve invalid dereference bug reporting in DereferenceChecker.

2020-08-10 Thread Balázs Kéri via Phabricator via cfe-commits
balazske marked an inline comment as done.
balazske added a comment.

Do the null pointer and invalid pointer dereference belong to the same checker, 
that is called //NullDereference//?




Comment at: clang/test/Analysis/misc-ps-region-store.m:1160
   struct list_pr8141 *items;
-  for (;; items = ({ do { } while (0); items->tail; })) // 
expected-warning{{Dereference of undefined pointer value}}
+  for (;; items = ({ do { } while (0); items->tail; })) // 
expected-warning{{dereference of an undefined pointer value}}
 {

Szelethus wrote:
> Is this the entire message? Because traditionally, analyzer warnings start 
> with an upper case and don't terminate.
Full message is:
`Access to field 'tail' results in a dereference of an undefined pointer value 
(loaded from variable 'items') [core.NullDereference]`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84520

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


[PATCH] D85439: [SyntaxTree] Expand support for `NestedNameSpecifier`

2020-08-10 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas updated this revision to Diff 284284.
eduucaldas added a comment.

Move to using inheritance


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85439

Files:
  clang/include/clang/AST/NestedNameSpecifier.h
  clang/lib/Tooling/Syntax/BuildTree.cpp
  clang/unittests/Tooling/Syntax/TreeTest.cpp

Index: clang/unittests/Tooling/Syntax/TreeTest.cpp
===
--- clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -2973,7 +2973,8 @@
 `-UsingNamespaceDirective
   |-using
   |-namespace
-  |-::
+  |-NestedNameSpecifier
+  | `-::
   |-ns
   `-;
 )txt"));
@@ -3002,8 +3003,10 @@
 | `-}
 `-UsingDeclaration
   |-using
-  |-ns
-  |-::
+  |-NestedNameSpecifier
+  | |-IdentifierNameSpecifier
+  | | `-ns
+  | `-::
   |-a
   `-;
 )txt"));
@@ -3207,11 +3210,13 @@
   |->
   `-SimpleDeclaration
 |-struct
-|-X
-|-<
-|-T
-|->
-|-::
+|-NestedNameSpecifier
+| |-SimpleTemplateNameSpecifier
+| | |-X
+| | |-<
+| | |-T
+| | `->
+| `-::
 |-Y
 |-{
 |-}
@@ -3245,15 +3250,19 @@
 |-{
 |-UsingDeclaration
 | |-using
-| |-T
-| |-::
+| |-NestedNameSpecifier
+| | |-IdentifierNameSpecifier
+| | | `-T
+| | `-::
 | |-foo
 | `-;
 |-UsingDeclaration
 | |-using
 | |-typename
-| |-T
-| |-::
+| |-NestedNameSpecifier
+| | |-IdentifierNameSpecifier
+| | | `-T
+| | `-::
 | |-bar
 | `-;
 |-}
Index: clang/lib/Tooling/Syntax/BuildTree.cpp
===
--- clang/lib/Tooling/Syntax/BuildTree.cpp
+++ clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -241,10 +241,24 @@
 assert(Added && "mapping added twice");
   }
 
+  void add(NestedNameSpecifierLoc From, syntax::Tree *To) {
+assert(To != nullptr);
+assert(From.hasQualifier());
+
+bool Added = NNSNodes.insert({From, To}).second;
+(void)Added;
+assert(Added && "mapping added twice");
+  }
+
   syntax::Tree *find(ASTPtr P) const { return Nodes.lookup(P); }
 
+  syntax::Tree *find(NestedNameSpecifierLoc P) const {
+return NNSNodes.lookup(P);
+  }
+
 private:
   llvm::DenseMap Nodes;
+  llvm::DenseMap NNSNodes;
 };
 } // namespace
 
@@ -281,16 +295,20 @@
 if (From)
   Mapping.add(From, New);
   }
+
   void foldNode(ArrayRef Range, syntax::Tree *New, TypeLoc L) {
 // FIXME: add mapping for TypeLocs
 foldNode(Range, New, nullptr);
   }
 
-  void foldNode(ArrayRef Range, syntax::Tree *New,
-NestedNameSpecifierLoc L) {
-// FIXME: add mapping for NestedNameSpecifierLoc
-foldNode(Range, New, nullptr);
+  void foldNode(llvm::ArrayRef Range, syntax::Tree *New,
+NestedNameSpecifierLoc From) {
+assert(New);
+Pending.foldChildren(Arena, Range, New);
+if (From)
+  Mapping.add(From, New);
   }
+
   /// Notifies that we should not consume trailing semicolon when computing
   /// token range of \p D.
   void noticeDeclWithoutSemicolon(Decl *D);
@@ -312,6 +330,8 @@
   void markChild(syntax::Node *N, NodeRole R);
   /// Set role for the syntax node matching \p N.
   void markChild(ASTPtr N, NodeRole R);
+  /// Set role for the syntax node matching \p N.
+  void markChild(NestedNameSpecifierLoc N, NodeRole R);
 
   /// Finish building the tree and consume the root node.
   syntax::TranslationUnit *finalize() && {
@@ -798,31 +818,31 @@
 return SR;
   }
 
-  syntax::NestedNameSpecifier *
-  BuildNestedNameSpecifier(const NestedNameSpecifierLoc &QualifierLoc) {
+  // To build syntax tree nodes for NestedNameSpecifierLoc we override Traverse
+  // instead of WalkUpFrom because we want to traverse the children ourselves
+  // and build a list instead of a nested tree of name specifier prefixes.
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc) {
 if (!QualifierLoc)
-  return nullptr;
+  return true;
 for (auto it = QualifierLoc; it; it = it.getPrefix()) {
-  assert(it.hasQualifier());
   auto *NS = BuildNameSpecifier(*it.getNestedNameSpecifier());
   assert(NS);
   if (!isa(NS))
 Builder.foldNode(Builder.getRange(getLocalSourceRange(it)).drop_back(),
- NS, it);
+ NS, nullptr);
   Builder.markChild(NS, syntax::NodeRole::NestedNameSpecifier_specifier);
   Builder.markChildToken(it.getEndLoc(),
  syntax::NodeRole::NestedNameSpecifier_delimiter);
 }
-auto *NNS = new (allocator()) syntax::NestedNameSpecifier;
-Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), NNS,
+Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()),
+ new (allocator()) syntax::NestedNameSpecifier,
  QualifierLoc);
-return NNS;
+return true;
   }

[PATCH] D85439: [SyntaxTree] Expand support for `NestedNameSpecifier`

2020-08-10 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas updated this revision to Diff 284285.
eduucaldas added a comment.

.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85439

Files:
  clang/include/clang/AST/NestedNameSpecifier.h
  clang/lib/Tooling/Syntax/BuildTree.cpp
  clang/unittests/Tooling/Syntax/TreeTest.cpp

Index: clang/unittests/Tooling/Syntax/TreeTest.cpp
===
--- clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -2973,7 +2973,8 @@
 `-UsingNamespaceDirective
   |-using
   |-namespace
-  |-::
+  |-NestedNameSpecifier
+  | `-::
   |-ns
   `-;
 )txt"));
@@ -3002,8 +3003,10 @@
 | `-}
 `-UsingDeclaration
   |-using
-  |-ns
-  |-::
+  |-NestedNameSpecifier
+  | |-IdentifierNameSpecifier
+  | | `-ns
+  | `-::
   |-a
   `-;
 )txt"));
@@ -3207,11 +3210,13 @@
   |->
   `-SimpleDeclaration
 |-struct
-|-X
-|-<
-|-T
-|->
-|-::
+|-NestedNameSpecifier
+| |-SimpleTemplateNameSpecifier
+| | |-X
+| | |-<
+| | |-T
+| | `->
+| `-::
 |-Y
 |-{
 |-}
@@ -3245,15 +3250,19 @@
 |-{
 |-UsingDeclaration
 | |-using
-| |-T
-| |-::
+| |-NestedNameSpecifier
+| | |-IdentifierNameSpecifier
+| | | `-T
+| | `-::
 | |-foo
 | `-;
 |-UsingDeclaration
 | |-using
 | |-typename
-| |-T
-| |-::
+| |-NestedNameSpecifier
+| | |-IdentifierNameSpecifier
+| | | `-T
+| | `-::
 | |-bar
 | `-;
 |-}
Index: clang/lib/Tooling/Syntax/BuildTree.cpp
===
--- clang/lib/Tooling/Syntax/BuildTree.cpp
+++ clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -241,10 +241,24 @@
 assert(Added && "mapping added twice");
   }
 
+  void add(NestedNameSpecifierLoc From, syntax::Tree *To) {
+assert(To != nullptr);
+assert(From.hasQualifier());
+
+bool Added = NNSNodes.insert({From, To}).second;
+(void)Added;
+assert(Added && "mapping added twice");
+  }
+
   syntax::Tree *find(ASTPtr P) const { return Nodes.lookup(P); }
 
+  syntax::Tree *find(NestedNameSpecifierLoc P) const {
+return NNSNodes.lookup(P);
+  }
+
 private:
   llvm::DenseMap Nodes;
+  llvm::DenseMap NNSNodes;
 };
 } // namespace
 
@@ -281,16 +295,20 @@
 if (From)
   Mapping.add(From, New);
   }
+
   void foldNode(ArrayRef Range, syntax::Tree *New, TypeLoc L) {
 // FIXME: add mapping for TypeLocs
 foldNode(Range, New, nullptr);
   }
 
-  void foldNode(ArrayRef Range, syntax::Tree *New,
-NestedNameSpecifierLoc L) {
-// FIXME: add mapping for NestedNameSpecifierLoc
-foldNode(Range, New, nullptr);
+  void foldNode(llvm::ArrayRef Range, syntax::Tree *New,
+NestedNameSpecifierLoc From) {
+assert(New);
+Pending.foldChildren(Arena, Range, New);
+if (From)
+  Mapping.add(From, New);
   }
+
   /// Notifies that we should not consume trailing semicolon when computing
   /// token range of \p D.
   void noticeDeclWithoutSemicolon(Decl *D);
@@ -312,6 +330,8 @@
   void markChild(syntax::Node *N, NodeRole R);
   /// Set role for the syntax node matching \p N.
   void markChild(ASTPtr N, NodeRole R);
+  /// Set role for the syntax node matching \p N.
+  void markChild(NestedNameSpecifierLoc N, NodeRole R);
 
   /// Finish building the tree and consume the root node.
   syntax::TranslationUnit *finalize() && {
@@ -744,45 +764,18 @@
 return true;
   }
 
-  syntax::NameSpecifier *BuildNameSpecifier(const NestedNameSpecifier &NNS) {
-switch (NNS.getKind()) {
-case NestedNameSpecifier::Global:
-  return new (allocator()) syntax::GlobalNameSpecifier;
-case NestedNameSpecifier::Namespace:
-case NestedNameSpecifier::NamespaceAlias:
-case NestedNameSpecifier::Identifier:
-  return new (allocator()) syntax::IdentifierNameSpecifier;
-case NestedNameSpecifier::TypeSpecWithTemplate:
-  return new (allocator()) syntax::SimpleTemplateNameSpecifier;
-case NestedNameSpecifier::TypeSpec: {
-  const auto *NNSType = NNS.getAsType();
-  assert(NNSType);
-  if (isa(NNSType))
-return new (allocator()) syntax::DecltypeNameSpecifier;
-  if (isa(
-  NNSType))
-return new (allocator()) syntax::SimpleTemplateNameSpecifier;
-  return new (allocator()) syntax::IdentifierNameSpecifier;
-}
-case NestedNameSpecifier::Super:
-  // FIXME: Support Microsoft's __super
-  llvm::report_fatal_error("We don't yet support the __super specifier",
-   true);
-}
-llvm_unreachable("Unhandled NestedNameSpecifier::SpecifierKind enum");
-  }
-
   // FIXME: Fix `NestedNameSpecifierLoc::getLocalSourceRange` for the
   // `DependentTemplateSpecializationType` case.
-  /// Given a nested-name-specifier return the range for the last name specifier
+  /// Given a nested-name-spe

[PATCH] D84005: Introduce ns_error_domain attribute.

2020-08-10 Thread Michael Forster via Phabricator via cfe-commits
MForster updated this revision to Diff 284286.
MForster added a comment.

Add an -ast-print test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84005

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/AST/ast-print-attr.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/ns_error_enum.m
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -329,6 +329,8 @@
 // empty string but are then recorded as a nullptr.
 OS << "\" << (get" << getUpperName() << "() ? get" << getUpperName()
<< "()->getName() : \"\") << \"";
+  else if (type == "VarDecl *")
+OS << "\" << get" << getUpperName() << "()->getName() << \"";
   else if (type == "TypeSourceInfo *")
 OS << "\" << get" << getUpperName() << "().getAsString() << \"";
   else if (type == "ParamIdx")
Index: clang/test/Sema/ns_error_enum.m
===
--- /dev/null
+++ clang/test/Sema/ns_error_enum.m
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -verify %s -x objective-c
+// RUN: %clang_cc1 -verify %s -x objective-c++
+
+
+#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+#define NS_ENUM(_type, _name) CF_ENUM(_type, _name)
+
+#define NS_ERROR_ENUM(_type, _name, _domain)  \
+  enum _name : _type _name; enum __attribute__((ns_error_domain(_domain))) _name : _type
+
+typedef NS_ENUM(unsigned, MyEnum) {
+  MyFirst,
+  MySecond,
+};
+
+typedef NS_ENUM(invalidType, MyInvalidEnum) {
+// expected-error@-1{{unknown type name 'invalidType'}}
+// expected-error@-2{{unknown type name 'invalidType'}}
+  MyFirstInvalid,
+  MySecondInvalid,
+};
+
+@interface NSString
+@end
+
+extern NSString *const MyErrorDomain;
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnum, MyErrorDomain) {
+	MyErrFirst,
+	MyErrSecond,
+};
+
+typedef NSString *const NsErrorDomain;
+extern NsErrorDomain MyTypedefErrorDomain;
+typedef NS_ERROR_ENUM(unsigned char, MyTypedefErrorEnum, MyTypedefErrorDomain) {
+  MyTypedefErrFirst,
+  MyTypedefErrSecond,
+};
+
+extern char *const WrongErrorDomainType;
+enum __attribute__((ns_error_domain(WrongErrorDomainType))) MyWrongErrorDomainType { MyWrongErrorDomain };
+// expected-error@-1{{domain argument 'WrongErrorDomainType' does not point to an NSString constant}}
+
+struct __attribute__((ns_error_domain(MyErrorDomain))) MyStructWithErrorDomain {};
+// expected-error@-1{{'ns_error_domain' attribute only applies to enums}}
+
+int __attribute__((ns_error_domain(MyErrorDomain))) NotTagDecl;
+  // expected-error@-1{{'ns_error_domain' attribute only applies to enums}}
+
+enum __attribute__((ns_error_domain())) NoArg { NoArgError };
+// expected-error@-1{{'ns_error_domain' attribute takes one argument}}
+
+enum __attribute__((ns_error_domain(MyErrorDomain, MyErrorDomain))) TwoArgs { TwoArgsError };
+// expected-error@-1{{'ns_error_domain' attribute takes one argument}}
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, InvalidDomain) {
+	// expected-error@-1{{use of undeclared identifier 'InvalidDomain'}}
+	MyErrFirstInvalid,
+	MyErrSecondInvalid,
+};
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, "domain-string");
+  // expected-error@-1{{domain argument does not refer to global constant}}
+
+void foo() {}
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalidFunction, foo);
+  // expected-error@-1{{domain argument 'foo' does not refer to global constant}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -80,6 +80,7 @@
 // CHECK-NEXT: MipsShortCall (SubjectMatchRule_function)
 // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method)
+// CHECK-NEXT: NSErrorDomain (SubjectMatchRule_enum)
 // CHECK-NEXT: Naked (SubjectMatchRule_function)
 // CHECK-NEXT: NoBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: NoCommon (SubjectMatchRule_variable)
Index: clang/test/AST/ast-print-attr.c
===
--- clang/test/AST/ast-print-attr.c
+++ clang/test/AST/ast-print-attr.c
@@ -15,3 +15,14 @@
 int fun_asm() asm("test");
 // CHECK: int var_asm asm("test");
 int var_asm asm("test");
+
+
+2@interface NSString
+@end
+
+extern NSString *const MyErrorDomain;
+// CHECK: enum __attribute__((ns_error_domain(MyErrorDomain))) MyErrorEnum {
+enum __attribut

[PATCH] D85439: [SyntaxTree] Expand support for `NestedNameSpecifier`

2020-08-10 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas marked 2 inline comments as done.
eduucaldas added a comment.

Now NNS are based on inheritance!




Comment at: clang/lib/Tooling/Syntax/BuildTree.cpp:849-850
+  const auto TL = NNSLoc.getTypeLoc().castAs();
+  if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(TL))
+return nullptr;
+  auto *NS = new (allocator()) syntax::DecltypeNameSpecifier;

Since we are overriding the TraverseNestedNameSpecifierLoc that previously 
fired TraverseTypeLoc we fire it when building a NameSpecifier.



Comment at: clang/unittests/Tooling/Syntax/TreeTest.cpp:1235
 | | | | |   |-(
-| | | | |   |-IdExpression
-| | | | |   | `-UnqualifiedId
-| | | | |   |   `-s
+| | | | |   |-s
 | | | | |   `-)

eduucaldas wrote:
> standard `TraverseNestedNameSpecifierLoc` fired `TraverseTypeLoc`, once we 
> override it we lost this. This will be fixed when refining the Node for 
> `DecltypeSpecifier`
This is no longer an issue, because we now fire TraverseTypeLoc in the case of 
DecltypeNameSpecifier


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85439

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


[PATCH] D83536: [clangd] Index refs to main-file symbols as well

2020-08-10 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/index/Background.h:143
+  std::function ContextProvider = nullptr,
+  bool CollectMainFileRefs = true);
   ~BackgroundIndex(); // Blocks while the current task finishes.

please set the default to false



Comment at: clang-tools-extra/clangd/index/FileIndex.cpp:219
+ const CanonicalIncludes &Includes,
+ bool CollectMainFileRefs) {
   std::vector DeclsToIndex(

we don't need the option here right? as `IsMainFileOnly` flag should always be 
false for symbols inside headers(preamble).



Comment at: clang-tools-extra/clangd/index/FileIndex.cpp:421
+void FileIndex::updateMain(PathRef Path, ParsedAST &AST,
+   bool CollectMainFileRefs) {
+  auto Contents = indexMainDecls(AST, CollectMainFileRefs);

i think we should rather put this option into `FileIndex` as a field (similar 
to `UseDex`) that way we could get rid of some plumbing



Comment at: clang-tools-extra/clangd/index/FileIndex.h:119
+  void updateMain(PathRef Path, ParsedAST &AST,
+  bool CollectMainFileRefs = true);
 

please drop the default


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83536

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


[PATCH] D84005: Introduce ns_error_domain attribute.

2020-08-10 Thread Michael Forster via Phabricator via cfe-commits
MForster updated this revision to Diff 284288.
MForster added a comment.

Fix mistake


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84005

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/AST/ast-print-attr.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/ns_error_enum.m
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -329,6 +329,8 @@
 // empty string but are then recorded as a nullptr.
 OS << "\" << (get" << getUpperName() << "() ? get" << getUpperName()
<< "()->getName() : \"\") << \"";
+  else if (type == "VarDecl *")
+OS << "\" << get" << getUpperName() << "()->getName() << \"";
   else if (type == "TypeSourceInfo *")
 OS << "\" << get" << getUpperName() << "().getAsString() << \"";
   else if (type == "ParamIdx")
Index: clang/test/Sema/ns_error_enum.m
===
--- /dev/null
+++ clang/test/Sema/ns_error_enum.m
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -verify %s -x objective-c
+// RUN: %clang_cc1 -verify %s -x objective-c++
+
+
+#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+#define NS_ENUM(_type, _name) CF_ENUM(_type, _name)
+
+#define NS_ERROR_ENUM(_type, _name, _domain)  \
+  enum _name : _type _name; enum __attribute__((ns_error_domain(_domain))) _name : _type
+
+typedef NS_ENUM(unsigned, MyEnum) {
+  MyFirst,
+  MySecond,
+};
+
+typedef NS_ENUM(invalidType, MyInvalidEnum) {
+// expected-error@-1{{unknown type name 'invalidType'}}
+// expected-error@-2{{unknown type name 'invalidType'}}
+  MyFirstInvalid,
+  MySecondInvalid,
+};
+
+@interface NSString
+@end
+
+extern NSString *const MyErrorDomain;
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnum, MyErrorDomain) {
+	MyErrFirst,
+	MyErrSecond,
+};
+
+typedef NSString *const NsErrorDomain;
+extern NsErrorDomain MyTypedefErrorDomain;
+typedef NS_ERROR_ENUM(unsigned char, MyTypedefErrorEnum, MyTypedefErrorDomain) {
+  MyTypedefErrFirst,
+  MyTypedefErrSecond,
+};
+
+extern char *const WrongErrorDomainType;
+enum __attribute__((ns_error_domain(WrongErrorDomainType))) MyWrongErrorDomainType { MyWrongErrorDomain };
+// expected-error@-1{{domain argument 'WrongErrorDomainType' does not point to an NSString constant}}
+
+struct __attribute__((ns_error_domain(MyErrorDomain))) MyStructWithErrorDomain {};
+// expected-error@-1{{'ns_error_domain' attribute only applies to enums}}
+
+int __attribute__((ns_error_domain(MyErrorDomain))) NotTagDecl;
+  // expected-error@-1{{'ns_error_domain' attribute only applies to enums}}
+
+enum __attribute__((ns_error_domain())) NoArg { NoArgError };
+// expected-error@-1{{'ns_error_domain' attribute takes one argument}}
+
+enum __attribute__((ns_error_domain(MyErrorDomain, MyErrorDomain))) TwoArgs { TwoArgsError };
+// expected-error@-1{{'ns_error_domain' attribute takes one argument}}
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, InvalidDomain) {
+	// expected-error@-1{{use of undeclared identifier 'InvalidDomain'}}
+	MyErrFirstInvalid,
+	MyErrSecondInvalid,
+};
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, "domain-string");
+  // expected-error@-1{{domain argument does not refer to global constant}}
+
+void foo() {}
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalidFunction, foo);
+  // expected-error@-1{{domain argument 'foo' does not refer to global constant}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -80,6 +80,7 @@
 // CHECK-NEXT: MipsShortCall (SubjectMatchRule_function)
 // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method)
+// CHECK-NEXT: NSErrorDomain (SubjectMatchRule_enum)
 // CHECK-NEXT: Naked (SubjectMatchRule_function)
 // CHECK-NEXT: NoBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: NoCommon (SubjectMatchRule_variable)
Index: clang/test/AST/ast-print-attr.c
===
--- clang/test/AST/ast-print-attr.c
+++ clang/test/AST/ast-print-attr.c
@@ -15,3 +15,14 @@
 int fun_asm() asm("test");
 // CHECK: int var_asm asm("test");
 int var_asm asm("test");
+
+
+@interface NSString
+@end
+
+extern NSString *const MyErrorDomain;
+// CHECK: enum __attribute__((ns_error_domain(MyErrorDomain))) MyErrorEnum {
+enum __attribute__((ns_erro

[PATCH] D84005: Introduce ns_error_domain attribute.

2020-08-10 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr2 accepted this revision.
gribozavr2 added inline comments.



Comment at: clang/test/AST/ast-print-attr.c:20
+
+2@interface NSString
+@end

Stray "2".




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84005

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


[PATCH] D84348: [SyntaxTree] Use simplified grammar rule for `NestedNameSpecifier` grammar nodes

2020-08-10 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas closed this revision.
eduucaldas added a comment.

commit hash 8abb5fb68f81b0e42d824bf080b1cef9a61559d6 



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84348

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


[PATCH] D85295: [SyntaxTree] Implement the List construct.

2020-08-10 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas updated this revision to Diff 284292.
eduucaldas marked 3 inline comments as done.
eduucaldas added a comment.

Answer code-review


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85295

Files:
  clang/include/clang/Tooling/Syntax/Nodes.h
  clang/include/clang/Tooling/Syntax/Tree.h
  clang/lib/Tooling/Syntax/Nodes.cpp
  clang/lib/Tooling/Syntax/Tree.cpp

Index: clang/lib/Tooling/Syntax/Tree.cpp
===
--- clang/lib/Tooling/Syntax/Tree.cpp
+++ clang/lib/Tooling/Syntax/Tree.cpp
@@ -268,3 +268,110 @@
   }
   return nullptr;
 }
+
+std::vector>
+syntax::List::getElementsAsNodesAndDelimiters() {
+  if (!firstChild())
+return {};
+
+  auto children = std::vector>();
+  syntax::Node *elementWithoutDelimiter = nullptr;
+  for (auto *C = firstChild(); C; C = C->nextSibling()) {
+switch (C->role()) {
+case syntax::NodeRole::List_element: {
+  if (elementWithoutDelimiter) {
+children.push_back({elementWithoutDelimiter, nullptr});
+  }
+  elementWithoutDelimiter = C;
+  break;
+}
+case syntax::NodeRole::List_delimiter: {
+  children.push_back({elementWithoutDelimiter, cast(C)});
+  elementWithoutDelimiter = nullptr;
+  break;
+}
+default:
+  llvm_unreachable(
+  "A list can have only elements and delimiters as children.");
+}
+  }
+
+  switch (getTerminationKind()) {
+  case syntax::List::TerminationKind::Separated: {
+children.push_back({elementWithoutDelimiter, nullptr});
+break;
+  }
+  case syntax::List::TerminationKind::Terminated:
+  case syntax::List::TerminationKind::MaybeTerminated: {
+if (elementWithoutDelimiter) {
+  children.push_back({elementWithoutDelimiter, nullptr});
+}
+break;
+  }
+  }
+
+  return children;
+}
+
+// Almost the same implementation of `getElementsAsNodesAndDelimiters` but
+// ignoring delimiters
+std::vector syntax::List::getElementsAsNodes() {
+  if (!firstChild())
+return {};
+
+  auto children = std::vector();
+  syntax::Node *elementWithoutDelimiter = nullptr;
+  for (auto *C = firstChild(); C; C = C->nextSibling()) {
+switch (C->role()) {
+case syntax::NodeRole::List_element: {
+  if (elementWithoutDelimiter) {
+children.push_back(elementWithoutDelimiter);
+  }
+  elementWithoutDelimiter = C;
+  break;
+}
+case syntax::NodeRole::List_delimiter: {
+  children.push_back(elementWithoutDelimiter);
+  elementWithoutDelimiter = nullptr;
+  break;
+}
+default:
+  llvm_unreachable("A list has only elements or delimiters.");
+}
+  }
+
+  switch (getTerminationKind()) {
+  case syntax::List::TerminationKind::Separated: {
+children.push_back(elementWithoutDelimiter);
+break;
+  }
+  case syntax::List::TerminationKind::Terminated:
+  case syntax::List::TerminationKind::MaybeTerminated: {
+if (elementWithoutDelimiter) {
+  children.push_back(elementWithoutDelimiter);
+}
+break;
+  }
+  }
+
+  return children;
+}
+
+// The methods below can't be implemented without information about the derived
+// list. These methods will be implemented by switching on the derived list's
+// `NodeKind`
+
+clang::tok::TokenKind syntax::List::getDelimiterTokenKind() {
+  llvm_unreachable("There are no subclasses of List, thus "
+   "getDelimiterTokenKind() cannot be called");
+}
+
+syntax::List::TerminationKind syntax::List::getTerminationKind() {
+  llvm_unreachable("There are no subclasses of List, thus getTerminationKind() "
+   "cannot be called");
+}
+
+bool syntax::List::canBeEmpty() {
+  llvm_unreachable(
+  "There are no subclasses of List, thus canBeEmpty() cannot be called");
+}
Index: clang/lib/Tooling/Syntax/Nodes.cpp
===
--- clang/lib/Tooling/Syntax/Nodes.cpp
+++ clang/lib/Tooling/Syntax/Nodes.cpp
@@ -144,6 +144,10 @@
 return OS << "ExternKeyword";
   case syntax::NodeRole::BodyStatement:
 return OS << "BodyStatement";
+  case syntax::NodeRole::List_element:
+return OS << "List_element";
+  case syntax::NodeRole::List_delimiter:
+return OS << "List_delimiter";
   case syntax::NodeRole::CaseStatement_value:
 return OS << "CaseStatement_value";
   case syntax::NodeRole::IfStatement_thenStatement:
Index: clang/include/clang/Tooling/Syntax/Tree.h
===
--- clang/include/clang/Tooling/Syntax/Tree.h
+++ clang/include/clang/Tooling/Syntax/Tree.h
@@ -191,6 +191,59 @@
   Node *FirstChild = nullptr;
 };
 
+/// A list of Elements separated or terminated by a fixed token.
+///
+/// This type models the following grammar construct:
+/// delimited-list(element, delimiter, termination, canBeEmpty)
+class List : public Tree {
+public:
+  template  struct ElementAndDelimiter {
+Element

[PATCH] D85295: [SyntaxTree] Implement the List construct.

2020-08-10 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas added inline comments.



Comment at: clang/include/clang/Tooling/Syntax/Tree.h:249
+
+  /// Return whether *under valid code* the list can be empty.
+  ///

gribozavr2 wrote:
> "Whether this list can be empty in syntactically and semantically correct 
> code.
> 
> This list may be empty when the source code has errors even if canBeEmpty() 
> returns true."
"...even if `canBeEmpty()` returns **false**"



Comment at: clang/lib/Tooling/Syntax/Tree.cpp:367
+clang::tok::TokenKind syntax::List::getDelimiterTokenKind() {
+  llvm_unreachable("A list can have only elements and delimiters as 
children.");
+}

gribozavr2 wrote:
> I think a better error message would say that there are no subclasses of 
> List, so this method can't be called.
Very sorry about that, this error was a copy-paste, I forgot to edit it


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85295

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


[PATCH] D80791: [AArch64] Generate .note.gnu.property based on module flags.

2020-08-10 Thread Momchil Velikov via Phabricator via cfe-commits
chill added a comment.

In D80791#2196598 , @nsz wrote:

> the assumption is that the intended branch protection is implied via cmdline 
> flags for the tu and function attributes are only used in source code for 
> some hack.

I don't share this assumption. I find it just as valid to control the PAC/BTI 
with things like:

  #ifdef ENABLE_BTI
  #define BTI_FUNC __attribute__((target("branch-protection=bti")))
  #else
  #define BTI_FUNC
  
  BTI_FUNC void foo() { ...
  BTI_FUNC int bar() { ...

without using any command-line option other than `-DENABLE_BTI=1`.


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

https://reviews.llvm.org/D80791

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


[PATCH] D85635: [clangd] Compute the interactive code range for semantic highlighting.

2020-08-10 Thread Haojian Wu via Phabricator via cfe-commits
hokein created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous.
Herald added a project: clang.
hokein requested review of this revision.
Herald added subscribers: MaskRay, ilya-biryukov.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85635

Files:
  clang-tools-extra/clangd/SemanticHighlighting.cpp
  clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

Index: clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
===
--- clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
+++ clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
@@ -79,7 +79,8 @@
 /// $Primitive[[int]] $Field[[a]] = 0;
 ///   };
 std::string annotate(llvm::StringRef Input,
- llvm::ArrayRef Tokens) {
+ llvm::ArrayRef Tokens,
+ size_t NextChar = 0) {
   assert(std::is_sorted(
   Tokens.begin(), Tokens.end(),
   [](const HighlightingToken &L, const HighlightingToken &R) {
@@ -87,18 +88,36 @@
   }));
 
   std::string Result;
-  unsigned NextChar = 0;
-  for (auto &T : Tokens) {
-unsigned StartOffset = llvm::cantFail(positionToOffset(Input, T.R.start));
-unsigned EndOffset = llvm::cantFail(positionToOffset(Input, T.R.end));
+  for (size_t I = 0; I < Tokens.size(); ++I) {
+const auto &Current = Tokens[I];
+unsigned StartOffset =
+llvm::cantFail(positionToOffset(Input, Current.R.start));
+assert(NextChar <= StartOffset && "Highlighting tokens must not overlap!");
+unsigned EndOffset = llvm::cantFail(positionToOffset(Input, Current.R.end));
 assert(StartOffset <= EndOffset);
-assert(NextChar <= StartOffset);
-
+const auto *End =
+llvm::find_if(llvm::makeArrayRef(Tokens.begin() + I + 1, Tokens.end()),
+  [&](const HighlightingToken &Next) {
+return Current.R.end <= Next.R.start;
+  });
+// Tokens whose ranges are contained by the Current range, we recursively
+// annotate them.
+auto ContainedTokens = llvm::makeArrayRef(Tokens.begin() + I + 1, End);
 Result += Input.substr(NextChar, StartOffset - NextChar);
-Result += std::string(
-llvm::formatv("${0}[[{1}]]", T.Kind,
-  Input.substr(StartOffset, EndOffset - StartOffset)));
+if (ContainedTokens.empty()) {
+  // No extra tokens contained by Current.
+  Result +=
+  llvm::formatv("${0}[[{1}]]", Current.Kind,
+Input.substr(StartOffset, EndOffset - StartOffset));
+  NextChar = EndOffset;
+  continue;
+}
+
+auto Annotated =
+annotate(Input.substr(0, EndOffset), ContainedTokens, StartOffset);
+Result += llvm::formatv("${0}[[{1}]]", Current.Kind, Annotated);
 NextChar = EndOffset;
+I += ContainedTokens.size();
   }
   Result += Input.substr(NextChar);
   return Result;
@@ -503,11 +522,11 @@
 
   #define $Macro[[test]]
   #undef $Macro[[test]]
-$InactiveCode[[]]  #ifdef $Macro[[test]]
-$InactiveCode[[]]  #endif
+$InactiveCode[[#ifdef $Macro[[test
+$InactiveCode[[#endif]]
 
-$InactiveCode[[]]  #if defined($Macro[[test]])
-$InactiveCode[[]]  #endif
+$InactiveCode[[#if defined($Macro[[test]])]]
+$InactiveCode[[#endif]]
 )cpp",
   R"cpp(
   struct $Class[[S]] {
@@ -614,8 +633,8 @@
   R"cpp(
   // Code in the preamble.
   // Inactive lines get an empty InactiveCode token at the beginning.
-$InactiveCode[[]]  #ifdef $Macro[[test]]
-$InactiveCode[[]]  #endif
+$InactiveCode[[#ifdef $Macro[[test
+$InactiveCode[[#endif]]
 
   // A declaration to cause the preamble to end.
   int $Variable[[EndPreamble]];
@@ -623,17 +642,17 @@
   // Code after the preamble.
   // Code inside inactive blocks does not get regular highlightings
   // because it's not part of the AST.
-$InactiveCode[[]]  #ifdef $Macro[[test]]
-$InactiveCode[[]]  int Inactive2;
-$InactiveCode[[]]  #endif
+$InactiveCode[[#ifdef $Macro[[test
+$InactiveCode[[int Inactive2;]]
+$InactiveCode[[#endif]]
 
   #ifndef $Macro[[test]]
   int $Variable[[Active1]];
   #endif
 
-$InactiveCode[[]]  #ifdef $Macro[[test]]
-$InactiveCode[[]]  int Inactive3;
-$InactiveCode[[]]  #else
+$InactiveCode[[#ifdef $Macro[[test
+$InactiveCode[[int Inactive3;]]
+$InactiveCode[[#else]]
   int $Variable[[Active2]];
   #endif
 )cpp",
Index: clang-tools-extra/clangd/SemanticHighlighting.cpp
===
--- clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -221,18 +221,27 @@
   // the end of the Tokens).
   TokRef = TokRef.drop_front(Conflicting.size());
 }
+const auto &SM = AST.getSourceManager();
+StringRef MainCode = SM.getBuffer(SM

[PATCH] D84520: [Analyzer] Improve invalid dereference bug reporting in DereferenceChecker.

2020-08-10 Thread Whisperity via Phabricator via cfe-commits
whisperity added a comment.

In D84520#2206077 , @balazske wrote:

> Do the null pointer and invalid pointer dereference belong to the same 
> checker, that is called //NullDereference//?

I think both SA and Tidy auto-appends the checker's name into the emitted 
diagnostic. However, @baloghadamsoftware did implement multiple checkers in the 
same translation unit, so maybe he knows where to override this.

(I can tell you where to override it in the context of Tidy, and it's horribly 
tricky and ugly...)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84520

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


[PATCH] D85525: [clang-tidy] Fix a crash in bugprone-not-null-terminated-result check when `__STDC_WANT_LIB_EXT1__` is not a literal.

2020-08-10 Thread Aleksandr Platonov via Phabricator via cfe-commits
ArcsinX updated this revision to Diff 284296.
ArcsinX added a comment.

- Rebase
- Add T.getLiteralData() check
- Newline


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85525

Files:
  clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c


Index: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c
===
--- /dev/null
+++ 
clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c
@@ -0,0 +1,16 @@
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
+// RUN: -- -std=c11 -I %S/Inputs/bugprone-not-null-terminated-result
+
+#include "not-null-terminated-result-c.h"
+
+#define __STDC_LIB_EXT1__ 1
+#define __STDC_WANT_LIB_EXT1__ ((unsigned)1)
+
+void f(const char *src) {
+  char dest[13];
+  memcpy_s(dest, 13, src, strlen(src) - 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 
'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: char dest[14];
+  // CHECK-FIXES-NEXT: strncpy_s(dest, 14, src, strlen(src) - 1);
+}
+
Index: clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
@@ -805,10 +805,12 @@
 // PP->getMacroInfo() returns nullptr if macro has no definition.
 if (MI) {
   const auto &T = MI->tokens().back();
-  StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
-  llvm::APInt IntValue;
-  ValueStr.getAsInteger(10, IntValue);
-  AreSafeFunctionsWanted = IntValue.getZExtValue();
+  if (T.isLiteral() && T.getLiteralData()) {
+StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
+llvm::APInt IntValue;
+ValueStr.getAsInteger(10, IntValue);
+AreSafeFunctionsWanted = IntValue.getZExtValue();
+  }
 }
   }
 


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c
@@ -0,0 +1,16 @@
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
+// RUN: -- -std=c11 -I %S/Inputs/bugprone-not-null-terminated-result
+
+#include "not-null-terminated-result-c.h"
+
+#define __STDC_LIB_EXT1__ 1
+#define __STDC_WANT_LIB_EXT1__ ((unsigned)1)
+
+void f(const char *src) {
+  char dest[13];
+  memcpy_s(dest, 13, src, strlen(src) - 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: char dest[14];
+  // CHECK-FIXES-NEXT: strncpy_s(dest, 14, src, strlen(src) - 1);
+}
+
Index: clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
@@ -805,10 +805,12 @@
 // PP->getMacroInfo() returns nullptr if macro has no definition.
 if (MI) {
   const auto &T = MI->tokens().back();
-  StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
-  llvm::APInt IntValue;
-  ValueStr.getAsInteger(10, IntValue);
-  AreSafeFunctionsWanted = IntValue.getZExtValue();
+  if (T.isLiteral() && T.getLiteralData()) {
+StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
+llvm::APInt IntValue;
+ValueStr.getAsInteger(10, IntValue);
+AreSafeFunctionsWanted = IntValue.getZExtValue();
+  }
 }
   }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] a90c78a - [SyntaxTree] Implement the List construct.

2020-08-10 Thread Eduardo Caldas via cfe-commits
Author: Eduardo Caldas
Date: 2020-08-10T10:32:28Z
New Revision: a90c78ac52615d256142ecd64fbedabb612dc73f

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

LOG: [SyntaxTree] Implement the List construct.

We defined a List construct to help with the implementation of list-like
grammar rules. This is a first implementation of this API.

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

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/include/clang/Tooling/Syntax/Tree.h
clang/lib/Tooling/Syntax/Nodes.cpp
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index 2273cb70307a..fc44076621d6 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -147,6 +147,8 @@ enum class NodeRole : uint8_t {
   /// statement, e.g. loop body for while, for, etc; inner statement for case,
   /// default, etc.
   BodyStatement,
+  List_element,
+  List_delimiter,
 
   // Roles specific to particular node kinds.
   OperatorExpression_operatorToken,

diff  --git a/clang/include/clang/Tooling/Syntax/Tree.h 
b/clang/include/clang/Tooling/Syntax/Tree.h
index d35bc6467bcc..fcd169cad3ec 100644
--- a/clang/include/clang/Tooling/Syntax/Tree.h
+++ b/clang/include/clang/Tooling/Syntax/Tree.h
@@ -191,6 +191,59 @@ class Tree : public Node {
   Node *FirstChild = nullptr;
 };
 
+/// A list of Elements separated or terminated by a fixed token.
+///
+/// This type models the following grammar construct:
+/// delimited-list(element, delimiter, termination, canBeEmpty)
+class List : public Tree {
+public:
+  template  struct ElementAndDelimiter {
+Element *element;
+Leaf *delimiter;
+  };
+
+  enum class TerminationKind {
+Terminated,
+MaybeTerminated,
+Separated,
+  };
+
+  using Tree::Tree;
+  /// Returns the elements and corresponding delimiters. Missing elements
+  /// and delimiters are represented as null pointers.
+  ///
+  /// For example, in a separated list:
+  /// "a, b, c" <=> [("a", ","), ("b", ","), ("c", null)]
+  /// "a, , c" <=> [("a", ","), (null, ","), ("c", ",)]
+  /// "a, b," <=> [("a", ","), ("b", ","), (null, null)]
+  ///
+  /// In a terminated or maybe-terminated list:
+  /// "a, b," <=> [("a", ","), ("b", ",")]
+  std::vector> getElementsAsNodesAndDelimiters();
+
+  /// Returns the elements of the list. Missing elements are represented
+  /// as null pointers in the same way as in the return value of
+  /// `getElementsAsNodesAndDelimiters()`.
+  std::vector getElementsAsNodes();
+
+  // These can't be implemented with the information we have!
+
+  /// Returns the appropriate delimiter for this list.
+  ///
+  /// Useful for discovering the correct delimiter to use when adding
+  /// elements to empty or one-element lists.
+  clang::tok::TokenKind getDelimiterTokenKind();
+
+  TerminationKind getTerminationKind();
+
+  /// Whether this list can be empty in syntactically and semantically correct
+  /// code.
+  ///
+  /// This list may be empty when the source code has errors even if
+  /// canBeEmpty() returns false.
+  bool canBeEmpty();
+};
+
 } // namespace syntax
 } // namespace clang
 

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index b5a4c50b2875..5e8deb668352 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -152,6 +152,10 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeRole 
R) {
 return OS << "TemplateKeyword";
   case syntax::NodeRole::BodyStatement:
 return OS << "BodyStatement";
+  case syntax::NodeRole::List_element:
+return OS << "List_element";
+  case syntax::NodeRole::List_delimiter:
+return OS << "List_delimiter";
   case syntax::NodeRole::CaseStatement_value:
 return OS << "CaseStatement_value";
   case syntax::NodeRole::IfStatement_thenStatement:

diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index 6f9ee40a89f2..6070d1603eb8 100644
--- a/clang/lib/Tooling/Syntax/Tree.cpp
+++ b/clang/lib/Tooling/Syntax/Tree.cpp
@@ -268,3 +268,110 @@ syntax::Node *syntax::Tree::findChild(NodeRole R) {
   }
   return nullptr;
 }
+
+std::vector>
+syntax::List::getElementsAsNodesAndDelimiters() {
+  if (!firstChild())
+return {};
+
+  auto children = std::vector>();
+  syntax::Node *elementWithoutDelimiter = nullptr;
+  for (auto *C = firstChild(); C; C = C->nextSibling()) {
+switch (C->role()) {
+case syntax::NodeRole::List_element: {
+  if (elementWithoutDelimiter) {
+children.push_back({elementWithoutDelimiter, nullptr});
+  }
+  elementWithoutDelimiter = C;
+  break;
+}
+case syntax::NodeRol

[PATCH] D85295: [SyntaxTree] Implement the List construct.

2020-08-10 Thread Eduardo Caldas 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 rGa90c78ac5261: [SyntaxTree] Implement the List construct. 
(authored by eduucaldas).

Changed prior to commit:
  https://reviews.llvm.org/D85295?vs=284292&id=284304#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85295

Files:
  clang/include/clang/Tooling/Syntax/Nodes.h
  clang/include/clang/Tooling/Syntax/Tree.h
  clang/lib/Tooling/Syntax/Nodes.cpp
  clang/lib/Tooling/Syntax/Tree.cpp

Index: clang/lib/Tooling/Syntax/Tree.cpp
===
--- clang/lib/Tooling/Syntax/Tree.cpp
+++ clang/lib/Tooling/Syntax/Tree.cpp
@@ -268,3 +268,110 @@
   }
   return nullptr;
 }
+
+std::vector>
+syntax::List::getElementsAsNodesAndDelimiters() {
+  if (!firstChild())
+return {};
+
+  auto children = std::vector>();
+  syntax::Node *elementWithoutDelimiter = nullptr;
+  for (auto *C = firstChild(); C; C = C->nextSibling()) {
+switch (C->role()) {
+case syntax::NodeRole::List_element: {
+  if (elementWithoutDelimiter) {
+children.push_back({elementWithoutDelimiter, nullptr});
+  }
+  elementWithoutDelimiter = C;
+  break;
+}
+case syntax::NodeRole::List_delimiter: {
+  children.push_back({elementWithoutDelimiter, cast(C)});
+  elementWithoutDelimiter = nullptr;
+  break;
+}
+default:
+  llvm_unreachable(
+  "A list can have only elements and delimiters as children.");
+}
+  }
+
+  switch (getTerminationKind()) {
+  case syntax::List::TerminationKind::Separated: {
+children.push_back({elementWithoutDelimiter, nullptr});
+break;
+  }
+  case syntax::List::TerminationKind::Terminated:
+  case syntax::List::TerminationKind::MaybeTerminated: {
+if (elementWithoutDelimiter) {
+  children.push_back({elementWithoutDelimiter, nullptr});
+}
+break;
+  }
+  }
+
+  return children;
+}
+
+// Almost the same implementation of `getElementsAsNodesAndDelimiters` but
+// ignoring delimiters
+std::vector syntax::List::getElementsAsNodes() {
+  if (!firstChild())
+return {};
+
+  auto children = std::vector();
+  syntax::Node *elementWithoutDelimiter = nullptr;
+  for (auto *C = firstChild(); C; C = C->nextSibling()) {
+switch (C->role()) {
+case syntax::NodeRole::List_element: {
+  if (elementWithoutDelimiter) {
+children.push_back(elementWithoutDelimiter);
+  }
+  elementWithoutDelimiter = C;
+  break;
+}
+case syntax::NodeRole::List_delimiter: {
+  children.push_back(elementWithoutDelimiter);
+  elementWithoutDelimiter = nullptr;
+  break;
+}
+default:
+  llvm_unreachable("A list has only elements or delimiters.");
+}
+  }
+
+  switch (getTerminationKind()) {
+  case syntax::List::TerminationKind::Separated: {
+children.push_back(elementWithoutDelimiter);
+break;
+  }
+  case syntax::List::TerminationKind::Terminated:
+  case syntax::List::TerminationKind::MaybeTerminated: {
+if (elementWithoutDelimiter) {
+  children.push_back(elementWithoutDelimiter);
+}
+break;
+  }
+  }
+
+  return children;
+}
+
+// The methods below can't be implemented without information about the derived
+// list. These methods will be implemented by switching on the derived list's
+// `NodeKind`
+
+clang::tok::TokenKind syntax::List::getDelimiterTokenKind() {
+  llvm_unreachable("There are no subclasses of List, thus "
+   "getDelimiterTokenKind() cannot be called");
+}
+
+syntax::List::TerminationKind syntax::List::getTerminationKind() {
+  llvm_unreachable("There are no subclasses of List, thus getTerminationKind() "
+   "cannot be called");
+}
+
+bool syntax::List::canBeEmpty() {
+  llvm_unreachable(
+  "There are no subclasses of List, thus canBeEmpty() cannot be called");
+}
Index: clang/lib/Tooling/Syntax/Nodes.cpp
===
--- clang/lib/Tooling/Syntax/Nodes.cpp
+++ clang/lib/Tooling/Syntax/Nodes.cpp
@@ -152,6 +152,10 @@
 return OS << "TemplateKeyword";
   case syntax::NodeRole::BodyStatement:
 return OS << "BodyStatement";
+  case syntax::NodeRole::List_element:
+return OS << "List_element";
+  case syntax::NodeRole::List_delimiter:
+return OS << "List_delimiter";
   case syntax::NodeRole::CaseStatement_value:
 return OS << "CaseStatement_value";
   case syntax::NodeRole::IfStatement_thenStatement:
Index: clang/include/clang/Tooling/Syntax/Tree.h
===
--- clang/include/clang/Tooling/Syntax/Tree.h
+++ clang/include/clang/Tooling/Syntax/Tree.h
@@ -191,6 +191,59 @@
   Node *FirstChild = nullptr;
 };
 
+/// A list of Elements separated or terminated by a fixed token.
+///
+/// This type models the following

[PATCH] D84846: [MC] Add support for generating missing GNU build notes

2020-08-10 Thread Timm Bäder via Phabricator via cfe-commits
tbaeder updated this revision to Diff 284308.
tbaeder added a comment.

Add a test that checks that clang accepts 
`-Wa,--generate-missing-build-notes=yes` and 
`-Wa,--generate-missing-build-notes=no`


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

https://reviews.llvm.org/D84846

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/Misc/generate-missing-build-notes.c
  clang/tools/driver/cc1as_main.cpp
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/lib/CodeGen/LLVMTargetMachine.cpp
  llvm/lib/MC/ELFObjectWriter.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCTargetOptions.cpp
  llvm/test/MC/ELF/build-notes.s
  llvm/tools/llvm-mc/llvm-mc.cpp

Index: llvm/tools/llvm-mc/llvm-mc.cpp
===
--- llvm/tools/llvm-mc/llvm-mc.cpp
+++ llvm/tools/llvm-mc/llvm-mc.cpp
@@ -172,6 +172,10 @@
 static cl::opt NoExecStack("no-exec-stack",
  cl::desc("File doesn't need an exec stack"));
 
+static cl::opt
+GenerateMissingBuildNotes("generate-missing-build-notes",
+  cl::desc("Generate missing GNU build notes"));
+
 enum ActionType {
   AC_AsLex,
   AC_Assemble,
@@ -378,6 +382,9 @@
   if (SaveTempLabels)
 Ctx.setAllowTemporaryLabels(false);
 
+  if (GenerateMissingBuildNotes)
+Ctx.setGenerateMissingBuildNotes(true);
+
   Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
   // Default to 4 for dwarf version.
   unsigned DwarfVersion = MCOptions.DwarfVersion ? MCOptions.DwarfVersion : 4;
Index: llvm/test/MC/ELF/build-notes.s
===
--- /dev/null
+++ llvm/test/MC/ELF/build-notes.s
@@ -0,0 +1,55 @@
+// RUN: llvm-mc --generate-missing-build-notes -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -r --section-relocations --hex-dump=.gnu.build.attributes - | FileCheck %s
+// RUN: llvm-mc --generate-missing-build-notes -filetype=obj -triple i386-pc-linux-gnu %s -o - | llvm-readobj -r --section-relocations --hex-dump=.gnu.build.attributes - | FileCheck %s --check-prefix=i386
+// RUN: llvm-mc --generate-missing-build-notes -filetype=obj -triple armeb-pc-linux-gnu %s -o - | llvm-readobj -r --section-relocations --hex-dump=.gnu.build.attributes - | FileCheck %s --check-prefix=armbe32
+
+.text
+.dc.l 1
+
+.section .text.unused,"ax"
+.space 1025
+
+.section .gnu.linkonce,"ax"
+.dc.l 3
+
+// CHECK:  Relocations [
+// CHECK-NEXT:   Section {{.*}} .rela.gnu.build.attributes {
+// CHECK-NEXT: 0x14 R_X86_64_64 .text 0x0
+// CHECK-NEXT: 0x1C R_X86_64_64 .text 0x4
+// CHECK-NEXT: 0x38 R_X86_64_64 .text.unused 0x0
+// CHECK-NEXT: 0x40 R_X86_64_64 .text.unused 0x401
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+// CHECK: Hex dump of section '.gnu.build.attributes':
+// CHECK-NEXT: 0x 0800 1000 0001 47412401 GA$.
+// CHECK-NEXT: 0x0010 33613200    3a2.
+// CHECK-NEXT: 0x0020  0800 1000 0001 
+// CHECK-NEXT: 0x0030 47412401 33613200   GA$.3a2.
+// CHECK-NEXT: 0x0040     
+
+// i386:  Relocations [
+// i386-NEXT:   Section {{.*}} .rel.gnu.build.attributes {
+// i386-NEXT: 0x14 R_386_32 .text 0x0
+// i386-NEXT: 0x18 R_386_32 .text 0x0
+// i386-NEXT: 0x30 R_386_32 .text.unused 0x0
+// i386-NEXT: 0x34 R_386_32 .text.unused 0x0
+// i386-NEXT:   }
+// i386-NEXT: ]
+// i386: Hex dump of section '.gnu.build.attributes':
+// i386-NEXT: 0x 0800 0800 0001 47412401 GA$.
+// i386-NEXT: 0x0010 33613200  0400 0800 3a2.
+// i386-NEXT: 0x0020 0800 0001 47412401 33613200 GA$.3a2.
+// i386-NEXT: 0x0030  0104   
+
+// armbe32:  Relocations [
+// armbe32-NEXT:   Section {{.*}} .rel.gnu.build.attributes {
+// armbe32-NEXT: 0x14 R_ARM_ABS32 .text 0x0
+// armbe32-NEXT: 0x18 R_ARM_ABS32 .text 0x0
+// armbe32-NEXT: 0x30 R_ARM_ABS32 .text.unused 0x0
+// armbe32-NEXT: 0x34 R_ARM_ABS32 .text.unused 0x0
+// armbe32-NEXT:   }
+// armbe32-NEXT: ]
+// armbe32: Hex dump of section '.gnu.build.attributes':
+// armbe32-NEXT: 0x 0008 0008 0100 47412401 GA$.
+// armbe32-NEXT: 0x0010 33613200  0004 0008 3a2.
+// armbe32-NEXT: 0x0020 0008 0100 47412401 33613200 GA$.3a2.
+// armbe32-NEXT: 0x0030  0401   
Index: llvm/lib/MC/MCTargetOptions.cpp
===
--- llvm/lib/MC/MCTargetOptions

[PATCH] D85439: [SyntaxTree] Expand support for `NestedNameSpecifier`

2020-08-10 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr2 accepted this revision.
gribozavr2 added inline comments.



Comment at: clang/include/clang/AST/NestedNameSpecifier.h:20
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT//DenseMapInfo.h"
 #include "llvm/ADT/FoldingSet.h"





Comment at: clang/include/clang/AST/NestedNameSpecifier.h:534
+// Define DenseMapInfo so that DeclarationNames can be used as keys
+// in DenseMap and DenseSets.
+template <> struct DenseMapInfo {

I'd suggest to remove the comment because it repeats the API (this is the only 
reason to define a DenseMapInfo specialization).



Comment at: clang/include/clang/AST/NestedNameSpecifier.h:539
+
+  static inline clang::NestedNameSpecifierLoc getEmptyKey() {
+return clang::NestedNameSpecifierLoc(FirstInfo::getEmptyKey(),

Inline is implied here.



Comment at: clang/include/clang/AST/NestedNameSpecifier.h:544
+
+  static inline clang::NestedNameSpecifierLoc getTombstoneKey() {
+return clang::NestedNameSpecifierLoc(FirstInfo::getTombstoneKey(),

Inline is implied here.



Comment at: clang/include/clang/AST/NestedNameSpecifier.h:550
+  static unsigned getHashValue(const clang::NestedNameSpecifierLoc &PairVal) {
+return detail::combineHashValue(
+FirstInfo::getHashValue(PairVal.getNestedNameSpecifier()),

Please use hash_combine instead of this internal API (see an example in 
`include/clang/Sema/Sema.h`).



Comment at: clang/lib/Tooling/Syntax/BuildTree.cpp:770
+  /// Given a nested-name-specifier return the range for the last name
+  /// specifier
   ///




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85439

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


[PATCH] D85637: [clangd] Fix the background index is not disabled when using remote-index.

2020-08-10 Thread Haojian Wu via Phabricator via cfe-commits
hokein created this revision.
hokein added a reviewer: kbobyrev.
Herald added subscribers: usaxena95, kadircet, arphaman, jkorous.
Herald added a project: clang.
hokein requested review of this revision.
Herald added subscribers: MaskRay, ilya-biryukov.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85637

Files:
  clang-tools-extra/clangd/tool/ClangdMain.cpp


Index: clang-tools-extra/clangd/tool/ClangdMain.cpp
===
--- clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -682,7 +682,6 @@
   if (!ResourceDir.empty())
 Opts.ResourceDir = ResourceDir;
   Opts.BuildDynamicSymbolIndex = EnableIndex;
-  Opts.BackgroundIndex = EnableBackgroundIndex;
   std::unique_ptr StaticIdx;
   std::future AsyncIndexLoad; // Block exit while loading the index.
   if (EnableIndex && !IndexFile.empty()) {
@@ -713,6 +712,7 @@
 }
   }
 #endif
+  Opts.BackgroundIndex = EnableBackgroundIndex;
   Opts.StaticIndex = StaticIdx.get();
   Opts.AsyncThreadsCount = WorkerThreadsCount;
   Opts.BuildRecoveryAST = RecoveryAST;


Index: clang-tools-extra/clangd/tool/ClangdMain.cpp
===
--- clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -682,7 +682,6 @@
   if (!ResourceDir.empty())
 Opts.ResourceDir = ResourceDir;
   Opts.BuildDynamicSymbolIndex = EnableIndex;
-  Opts.BackgroundIndex = EnableBackgroundIndex;
   std::unique_ptr StaticIdx;
   std::future AsyncIndexLoad; // Block exit while loading the index.
   if (EnableIndex && !IndexFile.empty()) {
@@ -713,6 +712,7 @@
 }
   }
 #endif
+  Opts.BackgroundIndex = EnableBackgroundIndex;
   Opts.StaticIndex = StaticIdx.get();
   Opts.AsyncThreadsCount = WorkerThreadsCount;
   Opts.BuildRecoveryAST = RecoveryAST;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D85337: [AMDGPU] gfx1031 target

2020-08-10 Thread James Henderson via Phabricator via cfe-commits
jhenderson added inline comments.



Comment at: llvm/tools/llvm-readobj/ELFDumper.cpp:1844
   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1030),
+  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_MACH_AMDGCN_GFX1031),
   LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_XNACK),

rampitec wrote:
> jhenderson wrote:
> > Where's the dedicated llvm-readobj test for this? Please add one. If there 
> > exists one for the other AMDGPU flags, extend that one, otherwise, it might 
> > be best to write one for the whole set at once.
> It is in the lvm/test/CodeGen/AMDGPU/elf-header-flags-mach.ll above along 
> with all other targets.
I emphasise "dedicated". llvm/test/CodeGen... is not the place for tests for 
llvm-readobj code. Such tests belong in llvm/test/tools/llvm-readobj.

To me, the CodeGen test looks like a test of the llc behaviour of generating 
the right value. It uses llvm-readobj, and therefore only incidentally tests 
the dumping behaviour. Imagine a situation where we decided to add support for 
this to llvm-objdump, and then somebody decides to switch the test over to 
using llvm-objdump to match (maybe it "looks better" that way). That would 
result in this code in llvm-readobj being untested.

My opinion, and one I think is shared with others who maintain llvm-readobj 
(amongst other things) is that you need direct testing for llvm-readobj 
behaviour within llvm-readobj tests to avoid such situations. This would 
therefore mean that this change needs two tests:

1) A test in llvm/test/tools/llvm-readobj/ELF which uses a process (e.g. 
yaml2obj) to create the ELF header with the required flag, to ensure the 
dumping behaviour is correct.
2) A test in llvm/test/CodeGen which tests that llc produces the right output 
value in the ELF header flags field (which of course would use llvm-readobj 
currently, but could use anything to verify).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85337

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


[PATCH] D85599: [Clang] Consider __builtin_trap() and __builtin_debugtrap() as terminator

2020-08-10 Thread Zhang Kang via Phabricator via cfe-commits
ZhangKang updated this revision to Diff 284250.
ZhangKang added a comment.

Fix the case.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85599

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/builtins-ppc.c
  clang/test/CodeGenCXX/vararg-non-pod.cpp
  compiler-rt/test/profile/gcov-__gcov_flush-terminate.c


Index: compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
===
--- compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
+++ compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
@@ -19,6 +19,6 @@
   __gcov_reset();  // CHECK-NEXT: 1: [[#@LINE]]:
   i = 42;  // CHECK-NEXT: 1: [[#@LINE]]:
   __builtin_trap();// CHECK-NEXT: 1: [[#@LINE]]:
-  i = 84;  // CHECK-NEXT: 1: [[#@LINE]]:
-  return 0;// CHECK-NEXT: 1: [[#@LINE]]:
+  i = 84;  // CHECK-NEXT: -: [[#@LINE]]:
+  return 0;// CHECK-NEXT: -: [[#@LINE]]:
 }
Index: clang/test/CodeGenCXX/vararg-non-pod.cpp
===
--- clang/test/CodeGenCXX/vararg-non-pod.cpp
+++ clang/test/CodeGenCXX/vararg-non-pod.cpp
@@ -12,5 +12,5 @@
 void test(X x) {
   // CHECK: call void @llvm.trap()
   vararg(x);
-  // CHECK: ret void
+  // CHECK: unreachable
 }
Index: clang/test/CodeGen/builtins-ppc.c
===
--- clang/test/CodeGen/builtins-ppc.c
+++ clang/test/CodeGen/builtins-ppc.c
@@ -27,3 +27,23 @@
   // CHECK: call double @llvm.ppc.setrnd(i32 %2)
   res = __builtin_setrnd(x);
 }
+
+void test_builtin_trap() {
+  volatile int i = 0;
+  __builtin_trap();
+  volatile int j = i;
+
+  // CHECK-LABEL: test_builtin_trap
+  // CHECK: call void @llvm.trap()
+  // CHECK: unreachable
+}
+
+void test_builtin_debugtrap() {
+  volatile int i = 0;
+  __builtin_debugtrap();
+  volatile int j = i;
+
+  // CHECK-LABEL: test_builtin_debugtrap
+  // CHECK: call void @llvm.debugtrap()
+  // CHECK: unreachable
+}
Index: clang/lib/CodeGen/CGBuiltin.cpp
===
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -2351,8 +2351,24 @@
 Function *F = CGM.getIntrinsic(Intrinsic::clear_cache);
 return RValue::get(Builder.CreateCall(F, {Begin, End}));
   }
-  case Builtin::BI__builtin_trap:
-return RValue::get(EmitTrapCall(Intrinsic::trap));
+  case Builtin::BI__builtin_trap: {
+RValue::get(EmitTrapCall(Intrinsic::trap));
+Builder.CreateUnreachable();
+
+// We do need to preserve an insertion point.
+EmitBlock(createBasicBlock("trap.cont"));
+
+return RValue::get(nullptr);
+  }
+  case Builtin::BI__builtin_debugtrap: {
+RValue::get(EmitTrapCall(Intrinsic::debugtrap));
+Builder.CreateUnreachable();
+
+// We do need to preserve an insertion point.
+EmitBlock(createBasicBlock("debugtrap.cont"));
+
+return RValue::get(nullptr);
+  }
   case Builtin::BI__debugbreak:
 return RValue::get(EmitTrapCall(Intrinsic::debugtrap));
   case Builtin::BI__builtin_unreachable: {


Index: compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
===
--- compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
+++ compiler-rt/test/profile/gcov-__gcov_flush-terminate.c
@@ -19,6 +19,6 @@
   __gcov_reset();  // CHECK-NEXT: 1: [[#@LINE]]:
   i = 42;  // CHECK-NEXT: 1: [[#@LINE]]:
   __builtin_trap();// CHECK-NEXT: 1: [[#@LINE]]:
-  i = 84;  // CHECK-NEXT: 1: [[#@LINE]]:
-  return 0;// CHECK-NEXT: 1: [[#@LINE]]:
+  i = 84;  // CHECK-NEXT: -: [[#@LINE]]:
+  return 0;// CHECK-NEXT: -: [[#@LINE]]:
 }
Index: clang/test/CodeGenCXX/vararg-non-pod.cpp
===
--- clang/test/CodeGenCXX/vararg-non-pod.cpp
+++ clang/test/CodeGenCXX/vararg-non-pod.cpp
@@ -12,5 +12,5 @@
 void test(X x) {
   // CHECK: call void @llvm.trap()
   vararg(x);
-  // CHECK: ret void
+  // CHECK: unreachable
 }
Index: clang/test/CodeGen/builtins-ppc.c
===
--- clang/test/CodeGen/builtins-ppc.c
+++ clang/test/CodeGen/builtins-ppc.c
@@ -27,3 +27,23 @@
   // CHECK: call double @llvm.ppc.setrnd(i32 %2)
   res = __builtin_setrnd(x);
 }
+
+void test_builtin_trap() {
+  volatile int i = 0;
+  __builtin_trap();
+  volatile int j = i;
+
+  // CHECK-LABEL: test_builtin_trap
+  // CHECK: call void @llvm.trap()
+  // CHECK: unreachable
+}
+
+void test_builtin_debugtrap() {
+  volatile int i = 0;
+  __builtin_debugtrap();
+  volatile int j = i;
+
+  // CHECK-LABEL: test_builtin_debugtrap
+

[PATCH] D85599: [Clang] Consider __builtin_trap() and __builtin_debugtrap() as terminator

2020-08-10 Thread Eli Friedman via Phabricator via cfe-commits
efriedma added a comment.

Fixing a MachineVerifier issue by patching clang is generally wrong; if the IR 
is valid, the backend should do something sane with it.  If the IR isn't valid, 
the IR Verifier should complain.

Here, I'd say the IR is valid; adding a special case to the IR rules here would 
be a pain.  So the right fix involves changing isel and/or the definitions of 
the the instructions in question.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85599

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


[PATCH] D85637: [clangd] Fix the background index is not disabled when using remote-index.

2020-08-10 Thread Kirill Bobyrev via Phabricator via cfe-commits
kbobyrev accepted this revision.
kbobyrev added a comment.
This revision is now accepted and ready to land.

Oh, thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85637

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


[clang-tools-extra] 3d2cf72 - [clangd] Fix the background index is not disabled when using remote-index.

2020-08-10 Thread Haojian Wu via cfe-commits
Author: Haojian Wu
Date: 2020-08-10T14:02:22+02:00
New Revision: 3d2cf72943295d167062b54e663e2f5236df2c5d

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

LOG: [clangd] Fix the background index is not disabled when using remote-index.

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

Added: 


Modified: 
clang-tools-extra/clangd/tool/ClangdMain.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp 
b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index daf87d11c384..484ece01b6c9 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -682,7 +682,6 @@ clangd accepts flags on the commandline, and in the 
CLANGD_FLAGS environment var
   if (!ResourceDir.empty())
 Opts.ResourceDir = ResourceDir;
   Opts.BuildDynamicSymbolIndex = EnableIndex;
-  Opts.BackgroundIndex = EnableBackgroundIndex;
   std::unique_ptr StaticIdx;
   std::future AsyncIndexLoad; // Block exit while loading the index.
   if (EnableIndex && !IndexFile.empty()) {
@@ -713,6 +712,7 @@ clangd accepts flags on the commandline, and in the 
CLANGD_FLAGS environment var
 }
   }
 #endif
+  Opts.BackgroundIndex = EnableBackgroundIndex;
   Opts.StaticIndex = StaticIdx.get();
   Opts.AsyncThreadsCount = WorkerThreadsCount;
   Opts.BuildRecoveryAST = RecoveryAST;



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


[PATCH] D85637: [clangd] Fix the background index is not disabled when using remote-index.

2020-08-10 Thread Haojian Wu 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 rG3d2cf7294329: [clangd] Fix the background index is not 
disabled when using remote-index. (authored by hokein).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85637

Files:
  clang-tools-extra/clangd/tool/ClangdMain.cpp


Index: clang-tools-extra/clangd/tool/ClangdMain.cpp
===
--- clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -682,7 +682,6 @@
   if (!ResourceDir.empty())
 Opts.ResourceDir = ResourceDir;
   Opts.BuildDynamicSymbolIndex = EnableIndex;
-  Opts.BackgroundIndex = EnableBackgroundIndex;
   std::unique_ptr StaticIdx;
   std::future AsyncIndexLoad; // Block exit while loading the index.
   if (EnableIndex && !IndexFile.empty()) {
@@ -713,6 +712,7 @@
 }
   }
 #endif
+  Opts.BackgroundIndex = EnableBackgroundIndex;
   Opts.StaticIndex = StaticIdx.get();
   Opts.AsyncThreadsCount = WorkerThreadsCount;
   Opts.BuildRecoveryAST = RecoveryAST;


Index: clang-tools-extra/clangd/tool/ClangdMain.cpp
===
--- clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -682,7 +682,6 @@
   if (!ResourceDir.empty())
 Opts.ResourceDir = ResourceDir;
   Opts.BuildDynamicSymbolIndex = EnableIndex;
-  Opts.BackgroundIndex = EnableBackgroundIndex;
   std::unique_ptr StaticIdx;
   std::future AsyncIndexLoad; // Block exit while loading the index.
   if (EnableIndex && !IndexFile.empty()) {
@@ -713,6 +712,7 @@
 }
   }
 #endif
+  Opts.BackgroundIndex = EnableBackgroundIndex;
   Opts.StaticIndex = StaticIdx.get();
   Opts.AsyncThreadsCount = WorkerThreadsCount;
   Opts.BuildRecoveryAST = RecoveryAST;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D85525: [clang-tidy] Fix a crash in bugprone-not-null-terminated-result check when `__STDC_WANT_LIB_EXT1__` is not a literal.

2020-08-10 Thread Aleksandr Platonov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGdcb8d3b72234: [clang-tidy] Fix a crash in 
bugprone-not-null-terminated-result check when… (authored by ArcsinX).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85525

Files:
  clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c


Index: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c
===
--- /dev/null
+++ 
clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c
@@ -0,0 +1,16 @@
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
+// RUN: -- -std=c11 -I %S/Inputs/bugprone-not-null-terminated-result
+
+#include "not-null-terminated-result-c.h"
+
+#define __STDC_LIB_EXT1__ 1
+#define __STDC_WANT_LIB_EXT1__ ((unsigned)1)
+
+void f(const char *src) {
+  char dest[13];
+  memcpy_s(dest, 13, src, strlen(src) - 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 
'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: char dest[14];
+  // CHECK-FIXES-NEXT: strncpy_s(dest, 14, src, strlen(src) - 1);
+}
+
Index: clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
@@ -805,10 +805,12 @@
 // PP->getMacroInfo() returns nullptr if macro has no definition.
 if (MI) {
   const auto &T = MI->tokens().back();
-  StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
-  llvm::APInt IntValue;
-  ValueStr.getAsInteger(10, IntValue);
-  AreSafeFunctionsWanted = IntValue.getZExtValue();
+  if (T.isLiteral() && T.getLiteralData()) {
+StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
+llvm::APInt IntValue;
+ValueStr.getAsInteger(10, IntValue);
+AreSafeFunctionsWanted = IntValue.getZExtValue();
+  }
 }
   }
 


Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c
@@ -0,0 +1,16 @@
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
+// RUN: -- -std=c11 -I %S/Inputs/bugprone-not-null-terminated-result
+
+#include "not-null-terminated-result-c.h"
+
+#define __STDC_LIB_EXT1__ 1
+#define __STDC_WANT_LIB_EXT1__ ((unsigned)1)
+
+void f(const char *src) {
+  char dest[13];
+  memcpy_s(dest, 13, src, strlen(src) - 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: char dest[14];
+  // CHECK-FIXES-NEXT: strncpy_s(dest, 14, src, strlen(src) - 1);
+}
+
Index: clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
===
--- clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
@@ -805,10 +805,12 @@
 // PP->getMacroInfo() returns nullptr if macro has no definition.
 if (MI) {
   const auto &T = MI->tokens().back();
-  StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
-  llvm::APInt IntValue;
-  ValueStr.getAsInteger(10, IntValue);
-  AreSafeFunctionsWanted = IntValue.getZExtValue();
+  if (T.isLiteral() && T.getLiteralData()) {
+StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
+llvm::APInt IntValue;
+ValueStr.getAsInteger(10, IntValue);
+AreSafeFunctionsWanted = IntValue.getZExtValue();
+  }
 }
   }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] dcb8d3b - [clang-tidy] Fix a crash in bugprone-not-null-terminated-result check when `__STDC_WANT_LIB_EXT1__` is not a literal.

2020-08-10 Thread Aleksandr Platonov via cfe-commits
Author: Aleksandr Platonov
Date: 2020-08-10T15:12:03+03:00
New Revision: dcb8d3b72234ea557df2af1141ad30bf1670a03a

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

LOG: [clang-tidy] Fix a crash in bugprone-not-null-terminated-result check when 
`__STDC_WANT_LIB_EXT1__` is not a literal.

If `__STDC_WANT_LIB_EXT1__` is not a literal (e.g. `#define 
__STDC_WANT_LIB_EXT1__ ((unsigned)1)`) bugprone-not-null-terminated-result 
check crashes.
Stack dump:
```
 #0 0x02185e6a llvm::sys::PrintStackTrace(llvm::raw_ostream&) 
(/llvm-project/build/bin/clang-tidy+0x2185e6a)
 #1 0x02183e8c llvm::sys::RunSignalHandlers() 
(/llvm-project/build/bin/clang-tidy+0x2183e8c)
 #2 0x02183ff3 SignalHandler(int) 
(/llvm-project/build/bin/clang-tidy+0x2183ff3)
 #3 0x7f08d91b1390 __restore_rt 
(/lib/x86_64-linux-gnu/libpthread.so.0+0x11390)
 #4 0x021338bb llvm::StringRef::getAsInteger(unsigned int, 
llvm::APInt&) const (/llvm-project/build/bin/clang-tidy+0x21338bb)
 #5 0x0052051c 
clang::tidy::bugprone::NotNullTerminatedResultCheck::check(clang::ast_matchers::MatchFinder::MatchResult
 const&) (/llvm-project/build/bin/clang-tidy+0x52051c)
```

Reviewed By: hokein

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

Added: 

clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c

Modified: 
clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
index 7d484d777165..9a44ba2f58a5 100644
--- a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
@@ -805,10 +805,12 @@ void NotNullTerminatedResultCheck::check(
 // PP->getMacroInfo() returns nullptr if macro has no definition.
 if (MI) {
   const auto &T = MI->tokens().back();
-  StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
-  llvm::APInt IntValue;
-  ValueStr.getAsInteger(10, IntValue);
-  AreSafeFunctionsWanted = IntValue.getZExtValue();
+  if (T.isLiteral() && T.getLiteralData()) {
+StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());
+llvm::APInt IntValue;
+ValueStr.getAsInteger(10, IntValue);
+AreSafeFunctionsWanted = IntValue.getZExtValue();
+  }
 }
   }
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c
 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c
new file mode 100644
index ..bba807fb6e09
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone-not-null-terminated-result-stdc-want-lib-ext1-not-a-literal.c
@@ -0,0 +1,16 @@
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
+// RUN: -- -std=c11 -I %S/Inputs/bugprone-not-null-terminated-result
+
+#include "not-null-terminated-result-c.h"
+
+#define __STDC_LIB_EXT1__ 1
+#define __STDC_WANT_LIB_EXT1__ ((unsigned)1)
+
+void f(const char *src) {
+  char dest[13];
+  memcpy_s(dest, 13, src, strlen(src) - 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 
'memcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: char dest[14];
+  // CHECK-FIXES-NEXT: strncpy_s(dest, 14, src, strlen(src) - 1);
+}
+



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


[PATCH] D85440: [SyntaxTree] Implement `NNS` using the `List` base API

2020-08-10 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas updated this revision to Diff 284324.
eduucaldas added a comment.

Implement `canBeEmpty`, `getDelimiterToken`, `getTerminationKind` for 
`NestedNameSpecifier`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85440

Files:
  clang/include/clang/Tooling/Syntax/Nodes.h
  clang/lib/Tooling/Syntax/BuildTree.cpp
  clang/lib/Tooling/Syntax/Nodes.cpp
  clang/lib/Tooling/Syntax/Tree.cpp

Index: clang/lib/Tooling/Syntax/Tree.cpp
===
--- clang/lib/Tooling/Syntax/Tree.cpp
+++ clang/lib/Tooling/Syntax/Tree.cpp
@@ -357,21 +357,38 @@
   return children;
 }
 
-// The methods below can't be implemented without information about the derived
-// list. These methods will be implemented by switching on the derived list's
-// `NodeKind`
-
 clang::tok::TokenKind syntax::List::getDelimiterTokenKind() {
-  llvm_unreachable("There are no subclasses of List, thus "
-   "getDelimiterTokenKind() cannot be called");
+  switch (this->kind()) {
+  case NodeKind::NestedNameSpecifier: {
+return clang::tok::coloncolon;
+  }
+  default: {
+llvm_unreachable("This is not a subclass of List, thus "
+ "getDelimiterTokenKind() cannot be called");
+  }
+  }
 }
 
 syntax::List::TerminationKind syntax::List::getTerminationKind() {
-  llvm_unreachable("There are no subclasses of List, thus getTerminationKind() "
-   "cannot be called");
+  switch (this->kind()) {
+  case NodeKind::NestedNameSpecifier: {
+return TerminationKind::Terminated;
+  }
+  default: {
+llvm_unreachable("This is not a subclass of List, thus "
+ "getTerminationKind() cannot be called");
+  }
+  }
 }
 
 bool syntax::List::canBeEmpty() {
-  llvm_unreachable(
-  "There are no subclasses of List, thus canBeEmpty() cannot be called");
+  switch (this->kind()) {
+  case NodeKind::NestedNameSpecifier: {
+return false;
+  }
+  default: {
+llvm_unreachable("This is not a subclass of List, thus canBeEmpty() "
+ "cannot be called");
+  }
+  }
 }
Index: clang/lib/Tooling/Syntax/Nodes.cpp
===
--- clang/lib/Tooling/Syntax/Nodes.cpp
+++ clang/lib/Tooling/Syntax/Nodes.cpp
@@ -200,30 +200,32 @@
 return OS << "IdExpression_id";
   case syntax::NodeRole::IdExpression_qualifier:
 return OS << "IdExpression_qualifier";
-  case syntax::NodeRole::NestedNameSpecifier_specifier:
-return OS << "NestedNameSpecifier_specifier";
-  case syntax::NodeRole::NestedNameSpecifier_delimiter:
-return OS << "NestedNameSpecifier_delimiter";
   case syntax::NodeRole::ParenExpression_subExpression:
 return OS << "ParenExpression_subExpression";
   }
   llvm_unreachable("invalid role");
 }
 
-std::vector syntax::NestedNameSpecifier::delimiters() {
-  std::vector Children;
-  for (auto *C = firstChild(); C; C = C->nextSibling()) {
-assert(C->role() == syntax::NodeRole::NestedNameSpecifier_delimiter);
-Children.push_back(llvm::cast(C));
+// We could have an interator in list to not pay memory costs of temporary
+// vector
+std::vector syntax::NestedNameSpecifier::specifiers() {
+  auto specifiersAsNodes = getElementsAsNodes();
+  std::vector Children;
+  for (const auto &element : specifiersAsNodes) {
+Children.push_back(llvm::cast(element));
   }
   return Children;
 }
 
-std::vector syntax::NestedNameSpecifier::specifiers() {
-  std::vector Children;
-  for (auto *C = firstChild(); C; C = C->nextSibling()) {
-assert(C->role() == syntax::NodeRole::NestedNameSpecifier_specifier);
-Children.push_back(cast(C));
+std::vector>
+syntax::NestedNameSpecifier::specifiersAndDoubleColons() {
+  auto specifiersAsNodesAndDoubleColons = getElementsAsNodesAndDelimiters();
+  std::vector>
+  Children;
+  for (const auto &specifierAndDoubleColon : specifiersAsNodesAndDoubleColons) {
+Children.push_back(
+{llvm::cast(specifierAndDoubleColon.element),
+ specifierAndDoubleColon.delimiter});
   }
   return Children;
 }
Index: clang/lib/Tooling/Syntax/BuildTree.cpp
===
--- clang/lib/Tooling/Syntax/BuildTree.cpp
+++ clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -809,9 +809,8 @@
   if (!isa(NS))
 Builder.foldNode(Builder.getRange(getLocalSourceRange(it)).drop_back(),
  NS, it);
-  Builder.markChild(NS, syntax::NodeRole::NestedNameSpecifier_specifier);
-  Builder.markChildToken(it.getEndLoc(),
- syntax::NodeRole::NestedNameSpecifier_delimiter);
+  Builder.markChild(NS, syntax::NodeRole::List_element);
+  Builder.markChildToken(it.getEndLoc(), syntax::NodeRole::List_delimiter);
 }
 auto *NNS = new (allocator()) syntax::NestedNameSpecifier;
 Builder.foldNode(Builder.getRange(QualifierLoc.getSourceR

[PATCH] D85532: Correctly set CompilingPCH in PrecompilePreambleAction.

2020-08-10 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz updated this revision to Diff 284329.
adamcz marked 3 inline comments as done.
adamcz added a comment.

addressed review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85532

Files:
  clang-tools-extra/clangd/unittests/CMakeLists.txt
  clang-tools-extra/clangd/unittests/ModulesTests.cpp
  clang/lib/Frontend/PrecompiledPreamble.cpp
  clang/unittests/Frontend/ASTUnitTest.cpp

Index: clang/unittests/Frontend/ASTUnitTest.cpp
===
--- clang/unittests/Frontend/ASTUnitTest.cpp
+++ clang/unittests/Frontend/ASTUnitTest.cpp
@@ -13,6 +13,7 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/PCHContainerOperations.h"
+#include "clang/Lex/HeaderSearch.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ToolOutputFile.h"
@@ -111,4 +112,41 @@
 llvm::MemoryBuffer::MemoryBuffer_MMap);
 }
 
+TEST_F(ASTUnitTest, ModuleTextualHeader) {
+  llvm::IntrusiveRefCntPtr InMemoryFs =
+  new llvm::vfs::InMemoryFileSystem();
+  InMemoryFs->addFile("test.cpp", 0, llvm::MemoryBuffer::getMemBuffer(R"cpp(
+  #include "Textual.h"
+  void foo() {}
+)cpp"));
+  InMemoryFs->addFile("m.modulemap", 0, llvm::MemoryBuffer::getMemBuffer(R"cpp(
+  module M {
+module Textual {
+  textual header "Textual.h"
+}
+  }
+)cpp"));
+  InMemoryFs->addFile("Textual.h", 0, llvm::MemoryBuffer::getMemBuffer(R"cpp(
+  void foo();
+)cpp"));
+
+  const char *Args[] = {"clang", "test.cpp", "-fmodule-map-file=m.modulemap",
+"-fmodule-name=M"};
+  Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
+  CInvok = createInvocationFromCommandLine(Args, Diags);
+  ASSERT_TRUE(CInvok);
+
+  FileManager *FileMgr = new FileManager(FileSystemOptions(), InMemoryFs);
+  PCHContainerOps = std::make_shared();
+
+  auto AU = ASTUnit::LoadFromCompilerInvocation(
+  CInvok, PCHContainerOps, Diags, FileMgr, false, CaptureDiagsKind::None, 1,
+  TU_Complete, false, false, false);
+  auto File = AU->getFileManager().getFileRef("Textual.h", false, false);
+  assert(File);
+  // Verify that we do not crash here.
+  EXPECT_TRUE(AU->getPreprocessor().getHeaderSearchInfo().getExistingFileInfo(
+  &File->getFileEntry()));
+}
+
 } // anonymous namespace
Index: clang/lib/Frontend/PrecompiledPreamble.cpp
===
--- clang/lib/Frontend/PrecompiledPreamble.cpp
+++ clang/lib/Frontend/PrecompiledPreamble.cpp
@@ -208,6 +208,11 @@
 Callbacks.AfterPCHEmitted(Writer);
   }
 
+  bool BeginSourceFileAction(CompilerInstance &CI) override {
+assert(CI.getLangOpts().CompilingPCH);
+return ASTFrontendAction::BeginSourceFileAction(CI);
+  }
+
   bool shouldEraseOutputFiles() override { return !hasEmittedPreamblePCH(); }
   bool hasCodeCompletionSupport() const override { return false; }
   bool hasASTFileSupport() const override { return false; }
@@ -396,6 +401,8 @@
   auto PreambleDepCollector = std::make_shared();
   Clang->addDependencyCollector(PreambleDepCollector);
 
+  Clang->getLangOpts().CompilingPCH = true;
+
   // Remap the main source file to the preamble buffer.
   StringRef MainFilePath = FrontendOpts.Inputs[0].getFile();
   auto PreambleInputBuffer = llvm::MemoryBuffer::getMemBufferCopy(
Index: clang-tools-extra/clangd/unittests/ModulesTests.cpp
===
--- /dev/null
+++ clang-tools-extra/clangd/unittests/ModulesTests.cpp
@@ -0,0 +1,44 @@
+//===-- ModulesTests.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 "Annotations.h"
+#include "TestFS.h"
+#include "TestTU.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+#include 
+#include 
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TEST(Modules, TextualIncludeInPreamble) {
+  TestTU TU = TestTU::withCode(R"cpp(
+#include "Textual.h"
+
+void foo() {}
+)cpp");
+  TU.ExtraArgs.push_back("-fmodule-name=M");
+  TU.ExtraArgs.push_back("-fmodule-map-file=m.modulemap");
+  TU.AdditionalFiles["Textual.h"] = "void foo();";
+  TU.AdditionalFiles["m.modulemap"] = R"modulemap(
+module M {
+  module Textual {
+textual header "Textual.h"
+  }
+}
+)modulemap";
+  // Test that we do not crash.
+  TU.index();
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
Index: clang-tools-extra/clangd/unittests/CMakeLists.txt

[PATCH] D85532: Correctly set CompilingPCH in PrecompilePreambleAction.

2020-08-10 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz added inline comments.



Comment at: clang-tools-extra/clangd/unittests/ModulesTests.cpp:28
+)cpp");
+  TU.ExtraArgs.push_back("-fmodules");
+  TU.ExtraArgs.push_back("-fmodule-name=M");

kadircet wrote:
> this one is not needed right?
I suppose not.



Comment at: clang/lib/Frontend/PrecompiledPreamble.cpp:421
   StoreInMemory ? &Storage.asMemory().Data : nullptr, Callbacks));
   Callbacks.BeforeExecute(*Clang);
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))

kadircet wrote:
> anything operating on CompilerInstance before and including the callbacks 
> invoked here will see a broken LangOtps. Why not set it here (and maybe 
> assert in the override, or just not do anything at all)
I think we should at least assert() on this, so others don't waste as much time 
as I did looking for bugs like this. PrecompilePreambleAction is not usable 
with CompilingPCH = false.

I'm a bit conflicted on setting CompilingPCH outside of 
PrecompilePreambleAction, it makes it seem like you can change it somehow and 
it makes that Action class not self-contained (it requires that external bit 
that sets the options), but with assert it should be fine and it's essentially 
an internal detail of PrecompilePreamble class anyway.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85532

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


[PATCH] D85440: [SyntaxTree] Implement `NNS` using the `List` base API

2020-08-10 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr2 accepted this revision.
gribozavr2 added inline comments.



Comment at: clang/lib/Tooling/Syntax/Tree.cpp:362
+  switch (this->kind()) {
+  case NodeKind::NestedNameSpecifier: {
+return clang::tok::coloncolon;

Please drop the braces within 'case' unless you need them to create a new scope 
for a variable.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85440

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


[PATCH] D85016: [clang-format] Add space between method modifier and a tuple return type in C#

2020-08-10 Thread 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 rG5f104a809983: [clang-format] Add space between method 
modifier and a tuple return type in C# (authored by lbk, committed by Jonathan 
Coe ).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85016

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTestCSharp.cpp


Index: clang/unittests/Format/FormatTestCSharp.cpp
===
--- clang/unittests/Format/FormatTestCSharp.cpp
+++ clang/unittests/Format/FormatTestCSharp.cpp
@@ -777,6 +777,20 @@
   verifyFormat(R"(private float[ , ] Values;)", Style);
   verifyFormat(R"(string dirPath = args?[ 0 ];)", Style);
   verifyFormat(R"(char[ ,, ] rawCharArray = MakeCharacterGrid();)", Style);
+
+  // Method returning tuple
+  verifyFormat(R"(public (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(private (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(protected (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(virtual (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(extern (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(static (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(internal (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(abstract (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(sealed (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(override (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(async (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(unsafe (string name, int age) methodTuple() {})", Style);
 }
 
 TEST_F(FormatTestCSharp, CSharpNullableTypes) {
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3115,6 +3115,16 @@
Keywords.kw_lock))
 return Style.SpaceBeforeParens == FormatStyle::SBPO_ControlStatements 
||
spaceRequiredBeforeParens(Right);
+
+// space between method modifier and opening parenthesis of a tuple return
+// type
+if (Left.isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected,
+ tok::kw_virtual, tok::kw_extern, tok::kw_static,
+ Keywords.kw_internal, Keywords.kw_abstract,
+ Keywords.kw_sealed, Keywords.kw_override,
+ Keywords.kw_async, Keywords.kw_unsafe) &&
+Right.is(tok::l_paren))
+  return true;
   } else if (Style.Language == FormatStyle::LK_JavaScript) {
 if (Left.is(TT_JsFatArrow))
   return true;


Index: clang/unittests/Format/FormatTestCSharp.cpp
===
--- clang/unittests/Format/FormatTestCSharp.cpp
+++ clang/unittests/Format/FormatTestCSharp.cpp
@@ -777,6 +777,20 @@
   verifyFormat(R"(private float[ , ] Values;)", Style);
   verifyFormat(R"(string dirPath = args?[ 0 ];)", Style);
   verifyFormat(R"(char[ ,, ] rawCharArray = MakeCharacterGrid();)", Style);
+
+  // Method returning tuple
+  verifyFormat(R"(public (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(private (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(protected (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(virtual (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(extern (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(static (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(internal (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(abstract (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(sealed (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(override (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(async (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(unsafe (string name, int age) methodTuple() {})", Style);
 }
 
 TEST_F(FormatTestCSharp, CSharpNullableTypes) {
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3115,6 +3115,16 @@
Keywords.kw_lock))
 return Style.SpaceBeforeParens == FormatStyle::SBPO_ControlStatements ||
spaceRequiredBeforeParens(Right);
+
+// space between method modifier and opening parenthesis of a tuple return
+// type
+if (Left.isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected,
+ 

[clang] 5f104a8 - [clang-format] Add space between method modifier and a tuple return type in C#

2020-08-10 Thread Jonathan Coe via cfe-commits
Author: Łukasz Krawczyk
Date: 2020-08-10T14:00:33+01:00
New Revision: 5f104a809983aa3b90f75fb411a9c8472545d270

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

LOG: [clang-format] Add space between method modifier and a tuple return type 
in C#

"public (string name, int age) methodTuple() {}" is now properly spaced

Patch by lukaszkrawc...@google.com

Reviewed By: jbcoe, krasimir

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

Added: 


Modified: 
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTestCSharp.cpp

Removed: 




diff  --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index 6cbaf8a30812..11acb597aa40 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3115,6 +3115,16 @@ bool TokenAnnotator::spaceRequiredBefore(const 
AnnotatedLine &Line,
Keywords.kw_lock))
 return Style.SpaceBeforeParens == FormatStyle::SBPO_ControlStatements 
||
spaceRequiredBeforeParens(Right);
+
+// space between method modifier and opening parenthesis of a tuple return
+// type
+if (Left.isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected,
+ tok::kw_virtual, tok::kw_extern, tok::kw_static,
+ Keywords.kw_internal, Keywords.kw_abstract,
+ Keywords.kw_sealed, Keywords.kw_override,
+ Keywords.kw_async, Keywords.kw_unsafe) &&
+Right.is(tok::l_paren))
+  return true;
   } else if (Style.Language == FormatStyle::LK_JavaScript) {
 if (Left.is(TT_JsFatArrow))
   return true;

diff  --git a/clang/unittests/Format/FormatTestCSharp.cpp 
b/clang/unittests/Format/FormatTestCSharp.cpp
index a2c551e5c25e..ae4cdda1c845 100644
--- a/clang/unittests/Format/FormatTestCSharp.cpp
+++ b/clang/unittests/Format/FormatTestCSharp.cpp
@@ -777,6 +777,20 @@ foreach ((A a, B b) in someList) {
   verifyFormat(R"(private float[ , ] Values;)", Style);
   verifyFormat(R"(string dirPath = args?[ 0 ];)", Style);
   verifyFormat(R"(char[ ,, ] rawCharArray = MakeCharacterGrid();)", Style);
+
+  // Method returning tuple
+  verifyFormat(R"(public (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(private (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(protected (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(virtual (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(extern (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(static (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(internal (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(abstract (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(sealed (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(override (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(async (string name, int age) methodTuple() {})", Style);
+  verifyFormat(R"(unsafe (string name, int age) methodTuple() {})", Style);
 }
 
 TEST_F(FormatTestCSharp, CSharpNullableTypes) {



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


[PATCH] D84636: [RFC] Make the default LibCall implementations from compiler-rt builtins library more customizable

2020-08-10 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: compiler-rt/lib/builtins/arm-libcall-overrides.h:8
+//===--===//
+
+#define AEABI_RTABI __attribute__((__pcs__("aapcs")))

It looks like you're missing a header guard, is that intentional?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84636

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


[PATCH] D85532: Correctly set CompilingPCH in PrecompilePreambleAction.

2020-08-10 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

thanks, lgtm!




Comment at: clang/unittests/Frontend/ASTUnitTest.cpp:144
+  CInvok, PCHContainerOps, Diags, FileMgr, false, CaptureDiagsKind::None, 
1,
+  TU_Complete, false, false, false);
+  auto File = AU->getFileManager().getFileRef("Textual.h", false, false);

nit: `ASSRET_TRUE(AU);`



Comment at: clang/unittests/Frontend/ASTUnitTest.cpp:146
+  auto File = AU->getFileManager().getFileRef("Textual.h", false, false);
+  assert(File);
+  // Verify that we do not crash here.

ASSERT_TRUE again


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85532

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


[PATCH] D85645: [AST] Fix the CXXFoldExpr source range when parentheses range is invalid.

2020-08-10 Thread Haojian Wu via Phabricator via cfe-commits
hokein created this revision.
hokein added a reviewer: nridge.
Herald added a project: clang.
hokein requested review of this revision.

The CXXFoldExpr's range is invalid if the cxxfoldexpr is formed via the
Concept's TypeContraints (because the parentheses are not written in the
source code). We fallback to use the range from the pattern.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85645

Files:
  clang/include/clang/AST/ExprCXX.h
  clang/test/AST/ast-dump-concepts.cpp


Index: clang/test/AST/ast-dump-concepts.cpp
===
--- clang/test/AST/ast-dump-concepts.cpp
+++ clang/test/AST/ast-dump-concepts.cpp
@@ -12,6 +12,9 @@
 template 
 concept binary_concept = true;
 
+template 
+concept triple_concept = true;
+
 template 
 struct Foo {
   // CHECK:  TemplateTypeParmDecl {{.*}} referenced Concept {{.*}} 
'binary_concept'
@@ -37,4 +40,12 @@
   template 
   Foo(R, char) requires unary_concept {
   }
+
+  // CHECK: CXXFoldExpr {{.*}} 
+  template 
+  Foo();
+
+  // CHECK: CXXFoldExpr {{.*}} 
+  template ... Ts>
+  Foo();
 };
Index: clang/include/clang/AST/ExprCXX.h
===
--- clang/include/clang/AST/ExprCXX.h
+++ clang/include/clang/AST/ExprCXX.h
@@ -4575,9 +4575,17 @@
 return None;
   }
 
-  SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
+  SourceLocation getBeginLoc() const LLVM_READONLY {
+if (LParenLoc.isValid())
+  return LParenLoc;
+return getPattern()->getBeginLoc();
+  }
 
-  SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+  SourceLocation getEndLoc() const LLVM_READONLY {
+if (RParenLoc.isValid())
+  return RParenLoc;
+return getPattern()->getEndLoc();
+  }
 
   static bool classof(const Stmt *T) {
 return T->getStmtClass() == CXXFoldExprClass;


Index: clang/test/AST/ast-dump-concepts.cpp
===
--- clang/test/AST/ast-dump-concepts.cpp
+++ clang/test/AST/ast-dump-concepts.cpp
@@ -12,6 +12,9 @@
 template 
 concept binary_concept = true;
 
+template 
+concept triple_concept = true;
+
 template 
 struct Foo {
   // CHECK:  TemplateTypeParmDecl {{.*}} referenced Concept {{.*}} 'binary_concept'
@@ -37,4 +40,12 @@
   template 
   Foo(R, char) requires unary_concept {
   }
+
+  // CHECK: CXXFoldExpr {{.*}} 
+  template 
+  Foo();
+
+  // CHECK: CXXFoldExpr {{.*}} 
+  template ... Ts>
+  Foo();
 };
Index: clang/include/clang/AST/ExprCXX.h
===
--- clang/include/clang/AST/ExprCXX.h
+++ clang/include/clang/AST/ExprCXX.h
@@ -4575,9 +4575,17 @@
 return None;
   }
 
-  SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
+  SourceLocation getBeginLoc() const LLVM_READONLY {
+if (LParenLoc.isValid())
+  return LParenLoc;
+return getPattern()->getBeginLoc();
+  }
 
-  SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+  SourceLocation getEndLoc() const LLVM_READONLY {
+if (RParenLoc.isValid())
+  return RParenLoc;
+return getPattern()->getEndLoc();
+  }
 
   static bool classof(const Stmt *T) {
 return T->getStmtClass() == CXXFoldExprClass;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84602: [MSP430] Expose msp430_builtin calling convention to C code

2020-08-10 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a reviewer: echristo.
aaron.ballman added a subscriber: echristo.
aaron.ballman added a comment.

Adding @echristo for the debugging info question.

In D84602#2200274 , @atrosinenko wrote:

> I suspect there might be some terminology clash, so clarifying a bit just in 
> case.

Thank you for the explanations, they help!

> It was probably better to refer to these functions as //LibCalls// - 
> functions from the compiler support library (such as `libgcc`) such as 
> `__adddf3`. While there are `__popcount[sdt]i2` among them, most of the times 
> they are implicitly called when the high-level code performs division on 
> `__uint128`, for example. Unfortunately, they reside under 
> `compiler-rt/lib/builtins` - so that name was used... :) So, if I get it 
> right, you have proposed something like 
> `clang/include/clang/Basic/BuiltinsMips.def` and those are another kind of 
> builtins.

Ah! That explains my confusion -- I was indeed thinking of something like 
BuiltinMips.def and hadn't realized this was a different kind of builtin.

> The `CallingConv::MSP430_BUILTIN` was the name of a calling convention that 
> the MSP430 codegen of LLVM had to use //for a small subset of those support 
> functions//, as defined by MSP430 EABI. While it can be useful to add some 
> other CC for those functions for internal use by compiler-rt someday, now 
> there are only two CCs defined for MSP430 LibCalls: that "special convention" 
> for 13 functions only with two 64-bit arguments (including 64-bit integer 
> shifts) and the `CallingConv::C` for everything else both from the support 
> library and regular object files.
>
> Technically, these functions could probably be listed by names somewhere in 
> the backend code, completely detangling the upstreaming of MSP430 compiler-rt 
> port from D84602  (this one), D84605 
>  and, the most scary of them, D84636 
> . That may probably look a bit hackish, 
> though.

Given that these builtins are defined in source files rather than in a .td 
file, I agree that would be rather hackish and using syntax would be more 
appropriate.




Comment at: clang/lib/CodeGen/CGDebugInfo.cpp:1233
 return llvm::dwarf::DW_CC_LLVM_X86RegCall;
+  // TODO case CC_MSP430Builtin:
   }

aaron.ballman wrote:
> atrosinenko wrote:
> > aaron.ballman wrote:
> > > This is likely to cause -Werror failures because the switch won't be 
> > > fully covered. Are you planning to do this TODO as part of this patch, or 
> > > in a follow up?
> > > Are you planning to do this TODO as part of this patch, or in a follow up?
> > 
> > It depends on how large that change would be.
> > 
> > I first need to find out how such calling convention identifiers are issued 
> > (or maybe there already exist one from GCC). I see they are declared inside 
> > the `llvm/include/llvm/BinaryFormat/Dwarf.def`.
> > 
> I'm not certain how large the change would be (and I definitely don't insist 
> on a full implementation), but you should ensure the switch is fully covered 
> so that you don't break bots when the patch lands.
I still think this case needs some work to keep the bots happy. I would 
probably go with:
```
case CC_MSP430Builtin:
  // FIXME: Currently unsupported
  break;
```
But perhaps @echristo has opinions since this involves debugging information.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84602

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


[PATCH] D85528: [analyzer] Fix cast evaluation on scoped enums in ExprEngine

2020-08-10 Thread Whisperity via Phabricator via cfe-commits
whisperity added inline comments.



Comment at: clang/test/Analysis/z3-refute-enum-crash.cpp:5
+//
+// Requires z3 only for refutation. Works with both constraint managers.
+

You can have multiple `RUN` lines in the same test file, which will result in 
the tests potentially executed with multiple configuration.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85528

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


[PATCH] D80514: [clang-tidy] modernize-use-trailing-return-type support for C++20 concepts and decltype

2020-08-10 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

In D80514#2206019 , @bernhardmgruber 
wrote:

> Btw: what is the general rule for Phabricator reviews here when to tick the 
> `Done` checkbox of a comment? What is the semantic of this checkbox? Is the 
> ticked state the same for everyone?

I don't think we have any hard-and-fast rules for it and I suspect the ticked 
state differs from review to review. Personally, I appreciate when the person 
who was asked to do some work is the one to check the Done box signalling that 
they think it's done (whether it's an author fixing a comment from a reviewer 
or a reviewer answering a question from an author, etc). This tells me "hey, 
someone thinks this is done, go look at it and comment if you disagree." 
However, I am guessing others have a different workflow.

I don't think I have any further concerns with this patch, so LGTM.




Comment at: 
clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp:430
+  AT->getKeyword() == AutoTypeKeyword::Auto &&
+  !hasAnyNestedLocalQualifiers(F->getDeclaredReturnType()))
+return;

bernhardmgruber wrote:
> aaron.ballman wrote:
> > aaron.ballman wrote:
> > > bernhardmgruber wrote:
> > > > aaron.ballman wrote:
> > > > > Why do we need to check that there aren't any nested local qualifiers?
> > > > Because I would like the check to rewrite e.g. `const auto f();` into 
> > > > `auto f() -> const auto;`. If I omit the check for nested local 
> > > > qualifiers, then those kind of declarations would be skipped.
> > > I'm still wondering about this.
> > > Because I would like the check to rewrite e.g. const auto f(); into auto 
> > > f() -> const auto;. If I omit the check for nested local qualifiers, then 
> > > those kind of declarations would be skipped.
> > 
> > I don't think I understand why that's desirable though? What is it about 
> > the qualifier that makes it worthwhile to repeat the type like that?
> Thank you for insisting on that peculiarity! The choice is stylistically 
> motivated to align function names:
> 
> ```
> auto f() -> int;
> auto g() -> std::vector;
> auto& h();
> const auto k();
> decltype(auto) l();
> ```
> vs.
> ```
> auto f() -> int;
> auto g() -> std::vector;
> auto h() -> auto&;
> auto k() -> const auto; 
> auto l() -> decltype(auto);
> ```
> 
> But judging from your response, this might be a surprise to users. Would you 
> prefer having an option to enable/disable this behavior?
> But judging from your response, this might be a surprise to users. Would you 
> prefer having an option to enable/disable this behavior?

Maybe it will be, maybe it won't. :-D The reason I was surprised was because it 
feels like a formatting related choice rather than a modernization related 
choice. However, I've always struggled to understand the utility of this check 
(it's one I  disable in every .clang-tidy configuration file I can), so my 
reasoning may be flawed. I feel like the goal of this check isn't to format 
code nicely, it's to modernize to using a trailing return type where that adds 
clarity. But I don't think `auto& func()` changing into `auto func() -> auto&` 
adds clarity (I think it removes clarity because the second signature is 
strictly more complex than the first), and similar for qualifiers. However, I 
think the exact same thing about `int func()` changing into `auto func() -> 
int`.

Given that we document this function to rewrite all functions to a trailing 
return type signature, I guess the behavior you've proposed here is consistent 
with that goal and so I'm fine with it.


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

https://reviews.llvm.org/D80514

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


[PATCH] D82089: [clang-tidy] modernize-loop-convert reverse iteration support

2020-08-10 Thread Alexander Kornienko via Phabricator via cfe-commits
alexfh requested changes to this revision.
alexfh added a comment.
This revision now requires changes to proceed.

Thanks for the patch! Looks generally good. A few comments inline.




Comment at: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp:74-76
+static const char MakeReverseRangeFunction[] = "MakeReverseRangeFunction";
+static const char MakeReverseRangeHeader[] = "MakeReverseRangeHeader";
+static const char UseCxx20ReverseRanges[] = "UseCxx20ReverseRanges";

These are used in two places close together. I'd just use literals like for the 
other option names.



Comment at: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp:921
+&Descriptor.ContainerNeedsDereference,
+/*IsReverse*/ FixerKind == LFK_ReverseIterator);
   } else if (FixerKind == LFK_PseudoArray) {

`/*IsReverse=*/`



Comment at: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp:1003
+  IsEnabled = true;
+  Function = RangesMakeReverse.str();
+  Header = RangesMakeReverseHeader.str();

I'd just use string literals directly.



Comment at: 
clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp:1011-1015
+  if (Header.front() == '<' && Header.back() == '>') {
+IsSystemInclude = true;
+Header.pop_back();
+Header.erase(0, 1);
+  }

It looks like this should be a feature of the `IncludeInserter`. Not 
necessarily in this patch though. The `createIncludeInsertion` in other checks 
could be made a bit more self-descriptive too, e.g. this one in 
clang-tidy/modernize/MakeSmartPtrCheck.cpp:
```
  Diag << Inserter.createIncludeInsertion(
  FD, MakeSmartPtrFunctionHeader,
  /*IsAngled=*/MakeSmartPtrFunctionHeader == StdMemoryHeader);
```
could have angle brackets in `MakeSmartPtrFunctionHeader` instead of making a 
special case for `memory`.



Comment at: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.h:42-63
+
+  class ReverseRangeDetail {
+  public:
+ReverseRangeDetail(bool UseCxx20IfAvailable, std::string FunctionName,
+   std::string HeaderName, const LangOptions &LangOpts);
+
+bool isEnabled() const { return IsEnabled; }

This abstraction doesn't seem to give much benefit over placing all these 
fields into the `LoopConvertCheck` class. 



Comment at: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.h:58
+  private:
+bool IsEnabled{false};
+bool UseCxx20IfAvailable;

Use ` = false;` for initialization. It's more common in LLVM.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D82089

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


[PATCH] D84005: Introduce ns_error_domain attribute.

2020-08-10 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.

Continues to LGTM with your changes, but I did spot one tiny nit (no further 
reviews needed from me).




Comment at: clang/lib/Sema/SemaDeclAttr.cpp:5346
+  if (!isNSStringType(VD->getType(), S.Context)) {
+S.Diag(Loc, diag::err_nserrordomain_wrong_type) << DRE->getDecl();
+return;

Minor nit, you can pass `VD` instead of `DRE->getDecl()` here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84005

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


[PATCH] D85440: [SyntaxTree] Implement `NNS` using the `List` base API

2020-08-10 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas updated this revision to Diff 284342.
eduucaldas added a comment.

Answer comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85440

Files:
  clang/include/clang/Tooling/Syntax/Nodes.h
  clang/lib/Tooling/Syntax/BuildTree.cpp
  clang/lib/Tooling/Syntax/Nodes.cpp
  clang/lib/Tooling/Syntax/Tree.cpp

Index: clang/lib/Tooling/Syntax/Tree.cpp
===
--- clang/lib/Tooling/Syntax/Tree.cpp
+++ clang/lib/Tooling/Syntax/Tree.cpp
@@ -357,21 +357,32 @@
   return children;
 }
 
-// The methods below can't be implemented without information about the derived
-// list. These methods will be implemented by switching on the derived list's
-// `NodeKind`
-
 clang::tok::TokenKind syntax::List::getDelimiterTokenKind() {
-  llvm_unreachable("There are no subclasses of List, thus "
-   "getDelimiterTokenKind() cannot be called");
+  switch (this->kind()) {
+  case NodeKind::NestedNameSpecifier:
+return clang::tok::coloncolon;
+  default:
+llvm_unreachable("This is not a subclass of List, thus "
+ "getDelimiterTokenKind() cannot be called");
+  }
 }
 
 syntax::List::TerminationKind syntax::List::getTerminationKind() {
-  llvm_unreachable("There are no subclasses of List, thus getTerminationKind() "
-   "cannot be called");
+  switch (this->kind()) {
+  case NodeKind::NestedNameSpecifier:
+return TerminationKind::Terminated;
+  default:
+llvm_unreachable("This is not a subclass of List, thus "
+ "getTerminationKind() cannot be called");
+  }
 }
 
 bool syntax::List::canBeEmpty() {
-  llvm_unreachable(
-  "There are no subclasses of List, thus canBeEmpty() cannot be called");
+  switch (this->kind()) {
+  case NodeKind::NestedNameSpecifier:
+return false;
+  default:
+llvm_unreachable("This is not a subclass of List, thus canBeEmpty() "
+ "cannot be called");
+  }
 }
Index: clang/lib/Tooling/Syntax/Nodes.cpp
===
--- clang/lib/Tooling/Syntax/Nodes.cpp
+++ clang/lib/Tooling/Syntax/Nodes.cpp
@@ -200,30 +200,32 @@
 return OS << "IdExpression_id";
   case syntax::NodeRole::IdExpression_qualifier:
 return OS << "IdExpression_qualifier";
-  case syntax::NodeRole::NestedNameSpecifier_specifier:
-return OS << "NestedNameSpecifier_specifier";
-  case syntax::NodeRole::NestedNameSpecifier_delimiter:
-return OS << "NestedNameSpecifier_delimiter";
   case syntax::NodeRole::ParenExpression_subExpression:
 return OS << "ParenExpression_subExpression";
   }
   llvm_unreachable("invalid role");
 }
 
-std::vector syntax::NestedNameSpecifier::delimiters() {
-  std::vector Children;
-  for (auto *C = firstChild(); C; C = C->nextSibling()) {
-assert(C->role() == syntax::NodeRole::NestedNameSpecifier_delimiter);
-Children.push_back(llvm::cast(C));
+// We could have an interator in list to not pay memory costs of temporary
+// vector
+std::vector syntax::NestedNameSpecifier::specifiers() {
+  auto specifiersAsNodes = getElementsAsNodes();
+  std::vector Children;
+  for (const auto &element : specifiersAsNodes) {
+Children.push_back(llvm::cast(element));
   }
   return Children;
 }
 
-std::vector syntax::NestedNameSpecifier::specifiers() {
-  std::vector Children;
-  for (auto *C = firstChild(); C; C = C->nextSibling()) {
-assert(C->role() == syntax::NodeRole::NestedNameSpecifier_specifier);
-Children.push_back(cast(C));
+std::vector>
+syntax::NestedNameSpecifier::specifiersAndDoubleColons() {
+  auto specifiersAsNodesAndDoubleColons = getElementsAsNodesAndDelimiters();
+  std::vector>
+  Children;
+  for (const auto &specifierAndDoubleColon : specifiersAsNodesAndDoubleColons) {
+Children.push_back(
+{llvm::cast(specifierAndDoubleColon.element),
+ specifierAndDoubleColon.delimiter});
   }
   return Children;
 }
Index: clang/lib/Tooling/Syntax/BuildTree.cpp
===
--- clang/lib/Tooling/Syntax/BuildTree.cpp
+++ clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -809,9 +809,8 @@
   if (!isa(NS))
 Builder.foldNode(Builder.getRange(getLocalSourceRange(it)).drop_back(),
  NS, it);
-  Builder.markChild(NS, syntax::NodeRole::NestedNameSpecifier_specifier);
-  Builder.markChildToken(it.getEndLoc(),
- syntax::NodeRole::NestedNameSpecifier_delimiter);
+  Builder.markChild(NS, syntax::NodeRole::List_element);
+  Builder.markChildToken(it.getEndLoc(), syntax::NodeRole::List_delimiter);
 }
 auto *NNS = new (allocator()) syntax::NestedNameSpecifier;
 Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), NNS,
Index: clang/include/clang/Tooling/Syntax/Nodes.h
===

[PATCH] D85218: In clang-tidy base checks prevent anonymous functions from triggering assertions

2020-08-10 Thread David Truby via Phabricator via cfe-commits
DavidTruby accepted this revision.
DavidTruby added a comment.
This revision is now accepted and ready to land.

LGTM - please wait for someone more familiar with clang-tidy to review as well


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85218

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


[PATCH] D84005: Introduce ns_error_domain attribute.

2020-08-10 Thread Michael Forster via Phabricator via cfe-commits
MForster updated this revision to Diff 284343.
MForster marked an inline comment as done.
MForster added a comment.

Fix nit


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84005

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/AST/ast-print-attr.c
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/ns_error_enum.m
  clang/utils/TableGen/ClangAttrEmitter.cpp

Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -329,6 +329,8 @@
 // empty string but are then recorded as a nullptr.
 OS << "\" << (get" << getUpperName() << "() ? get" << getUpperName()
<< "()->getName() : \"\") << \"";
+  else if (type == "VarDecl *")
+OS << "\" << get" << getUpperName() << "()->getName() << \"";
   else if (type == "TypeSourceInfo *")
 OS << "\" << get" << getUpperName() << "().getAsString() << \"";
   else if (type == "ParamIdx")
Index: clang/test/Sema/ns_error_enum.m
===
--- /dev/null
+++ clang/test/Sema/ns_error_enum.m
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -verify %s -x objective-c
+// RUN: %clang_cc1 -verify %s -x objective-c++
+
+
+#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+#define NS_ENUM(_type, _name) CF_ENUM(_type, _name)
+
+#define NS_ERROR_ENUM(_type, _name, _domain)  \
+  enum _name : _type _name; enum __attribute__((ns_error_domain(_domain))) _name : _type
+
+typedef NS_ENUM(unsigned, MyEnum) {
+  MyFirst,
+  MySecond,
+};
+
+typedef NS_ENUM(invalidType, MyInvalidEnum) {
+// expected-error@-1{{unknown type name 'invalidType'}}
+// expected-error@-2{{unknown type name 'invalidType'}}
+  MyFirstInvalid,
+  MySecondInvalid,
+};
+
+@interface NSString
+@end
+
+extern NSString *const MyErrorDomain;
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnum, MyErrorDomain) {
+	MyErrFirst,
+	MyErrSecond,
+};
+
+typedef NSString *const NsErrorDomain;
+extern NsErrorDomain MyTypedefErrorDomain;
+typedef NS_ERROR_ENUM(unsigned char, MyTypedefErrorEnum, MyTypedefErrorDomain) {
+  MyTypedefErrFirst,
+  MyTypedefErrSecond,
+};
+
+extern char *const WrongErrorDomainType;
+enum __attribute__((ns_error_domain(WrongErrorDomainType))) MyWrongErrorDomainType { MyWrongErrorDomain };
+// expected-error@-1{{domain argument 'WrongErrorDomainType' does not point to an NSString constant}}
+
+struct __attribute__((ns_error_domain(MyErrorDomain))) MyStructWithErrorDomain {};
+// expected-error@-1{{'ns_error_domain' attribute only applies to enums}}
+
+int __attribute__((ns_error_domain(MyErrorDomain))) NotTagDecl;
+  // expected-error@-1{{'ns_error_domain' attribute only applies to enums}}
+
+enum __attribute__((ns_error_domain())) NoArg { NoArgError };
+// expected-error@-1{{'ns_error_domain' attribute takes one argument}}
+
+enum __attribute__((ns_error_domain(MyErrorDomain, MyErrorDomain))) TwoArgs { TwoArgsError };
+// expected-error@-1{{'ns_error_domain' attribute takes one argument}}
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, InvalidDomain) {
+	// expected-error@-1{{use of undeclared identifier 'InvalidDomain'}}
+	MyErrFirstInvalid,
+	MyErrSecondInvalid,
+};
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, "domain-string");
+  // expected-error@-1{{domain argument does not refer to global constant}}
+
+void foo() {}
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalidFunction, foo);
+  // expected-error@-1{{domain argument 'foo' does not refer to global constant}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -80,6 +80,7 @@
 // CHECK-NEXT: MipsShortCall (SubjectMatchRule_function)
 // CHECK-NEXT: NSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: NSConsumesSelf (SubjectMatchRule_objc_method)
+// CHECK-NEXT: NSErrorDomain (SubjectMatchRule_enum)
 // CHECK-NEXT: Naked (SubjectMatchRule_function)
 // CHECK-NEXT: NoBuiltin (SubjectMatchRule_function)
 // CHECK-NEXT: NoCommon (SubjectMatchRule_variable)
Index: clang/test/AST/ast-print-attr.c
===
--- clang/test/AST/ast-print-attr.c
+++ clang/test/AST/ast-print-attr.c
@@ -15,3 +15,14 @@
 int fun_asm() asm("test");
 // CHECK: int var_asm asm("test");
 int var_asm asm("test");
+
+
+@interface NSString
+@end
+
+extern NSString *const MyErrorDomain;
+// CHECK: enum __attribute__((ns_error_domain(MyErrorDomain))) MyE

[PATCH] D85440: [SyntaxTree] Implement `NNS` using the `List` base API

2020-08-10 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas updated this revision to Diff 284344.
eduucaldas added a comment.

lint


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85440

Files:
  clang/include/clang/Tooling/Syntax/Nodes.h
  clang/lib/Tooling/Syntax/BuildTree.cpp
  clang/lib/Tooling/Syntax/Nodes.cpp
  clang/lib/Tooling/Syntax/Tree.cpp

Index: clang/lib/Tooling/Syntax/Tree.cpp
===
--- clang/lib/Tooling/Syntax/Tree.cpp
+++ clang/lib/Tooling/Syntax/Tree.cpp
@@ -357,21 +357,32 @@
   return children;
 }
 
-// The methods below can't be implemented without information about the derived
-// list. These methods will be implemented by switching on the derived list's
-// `NodeKind`
-
 clang::tok::TokenKind syntax::List::getDelimiterTokenKind() {
-  llvm_unreachable("There are no subclasses of List, thus "
-   "getDelimiterTokenKind() cannot be called");
+  switch (this->kind()) {
+  case NodeKind::NestedNameSpecifier:
+return clang::tok::coloncolon;
+  default:
+llvm_unreachable("This is not a subclass of List, thus "
+ "getDelimiterTokenKind() cannot be called");
+  }
 }
 
 syntax::List::TerminationKind syntax::List::getTerminationKind() {
-  llvm_unreachable("There are no subclasses of List, thus getTerminationKind() "
-   "cannot be called");
+  switch (this->kind()) {
+  case NodeKind::NestedNameSpecifier:
+return TerminationKind::Terminated;
+  default:
+llvm_unreachable("This is not a subclass of List, thus "
+ "getTerminationKind() cannot be called");
+  }
 }
 
 bool syntax::List::canBeEmpty() {
-  llvm_unreachable(
-  "There are no subclasses of List, thus canBeEmpty() cannot be called");
+  switch (this->kind()) {
+  case NodeKind::NestedNameSpecifier:
+return false;
+  default:
+llvm_unreachable("This is not a subclass of List, thus canBeEmpty() "
+ "cannot be called");
+  }
 }
Index: clang/lib/Tooling/Syntax/Nodes.cpp
===
--- clang/lib/Tooling/Syntax/Nodes.cpp
+++ clang/lib/Tooling/Syntax/Nodes.cpp
@@ -200,30 +200,32 @@
 return OS << "IdExpression_id";
   case syntax::NodeRole::IdExpression_qualifier:
 return OS << "IdExpression_qualifier";
-  case syntax::NodeRole::NestedNameSpecifier_specifier:
-return OS << "NestedNameSpecifier_specifier";
-  case syntax::NodeRole::NestedNameSpecifier_delimiter:
-return OS << "NestedNameSpecifier_delimiter";
   case syntax::NodeRole::ParenExpression_subExpression:
 return OS << "ParenExpression_subExpression";
   }
   llvm_unreachable("invalid role");
 }
 
-std::vector syntax::NestedNameSpecifier::delimiters() {
-  std::vector Children;
-  for (auto *C = firstChild(); C; C = C->nextSibling()) {
-assert(C->role() == syntax::NodeRole::NestedNameSpecifier_delimiter);
-Children.push_back(llvm::cast(C));
+// We could have an interator in list to not pay memory costs of temporary
+// vector
+std::vector syntax::NestedNameSpecifier::specifiers() {
+  auto specifiersAsNodes = getElementsAsNodes();
+  std::vector Children;
+  for (const auto &element : specifiersAsNodes) {
+Children.push_back(llvm::cast(element));
   }
   return Children;
 }
 
-std::vector syntax::NestedNameSpecifier::specifiers() {
-  std::vector Children;
-  for (auto *C = firstChild(); C; C = C->nextSibling()) {
-assert(C->role() == syntax::NodeRole::NestedNameSpecifier_specifier);
-Children.push_back(cast(C));
+std::vector>
+syntax::NestedNameSpecifier::specifiersAndDoubleColons() {
+  auto specifiersAsNodesAndDoubleColons = getElementsAsNodesAndDelimiters();
+  std::vector>
+  Children;
+  for (const auto &specifierAndDoubleColon : specifiersAsNodesAndDoubleColons) {
+Children.push_back(
+{llvm::cast(specifierAndDoubleColon.element),
+ specifierAndDoubleColon.delimiter});
   }
   return Children;
 }
Index: clang/lib/Tooling/Syntax/BuildTree.cpp
===
--- clang/lib/Tooling/Syntax/BuildTree.cpp
+++ clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -809,9 +809,8 @@
   if (!isa(NS))
 Builder.foldNode(Builder.getRange(getLocalSourceRange(it)).drop_back(),
  NS, it);
-  Builder.markChild(NS, syntax::NodeRole::NestedNameSpecifier_specifier);
-  Builder.markChildToken(it.getEndLoc(),
- syntax::NodeRole::NestedNameSpecifier_delimiter);
+  Builder.markChild(NS, syntax::NodeRole::List_element);
+  Builder.markChildToken(it.getEndLoc(), syntax::NodeRole::List_delimiter);
 }
 auto *NNS = new (allocator()) syntax::NestedNameSpecifier;
 Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), NNS,
Index: clang/include/clang/Tooling/Syntax/Nodes.h
==

[clang] fdbd599 - [SyntaxTree] Implement `NestedNameSpecifier` using the `List` base API

2020-08-10 Thread Eduardo Caldas via cfe-commits
Author: Eduardo Caldas
Date: 2020-08-10T13:43:21Z
New Revision: fdbd5996533dad25f00687f27ce8e7a8b7573ba3

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

LOG: [SyntaxTree] Implement `NestedNameSpecifier` using the `List` base API

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Nodes.h
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/lib/Tooling/Syntax/Nodes.cpp
clang/lib/Tooling/Syntax/Tree.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index fc44076621d6..8e65fa1d8923 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -173,8 +173,6 @@ enum class NodeRole : uint8_t {
   ParametersAndQualifiers_trailingReturn,
   IdExpression_id,
   IdExpression_qualifier,
-  NestedNameSpecifier_specifier,
-  NestedNameSpecifier_delimiter,
   ParenExpression_subExpression
 };
 /// For debugging purposes.
@@ -262,14 +260,15 @@ class SimpleTemplateNameSpecifier final : public 
NameSpecifier {
 
 /// Models a `nested-name-specifier`. C++ [expr.prim.id.qual]
 /// e.g. the `std::vector::` in `std::vector::size`.
-class NestedNameSpecifier final : public Tree {
+class NestedNameSpecifier final : public List {
 public:
-  NestedNameSpecifier() : Tree(NodeKind::NestedNameSpecifier) {}
+  NestedNameSpecifier() : List(NodeKind::NestedNameSpecifier) {}
   static bool classof(const Node *N) {
 return N->kind() <= NodeKind::NestedNameSpecifier;
   }
   std::vector specifiers();
-  std::vector delimiters();
+  std::vector>
+  specifiersAndDoubleColons();
 };
 
 /// Models an `unqualified-id`. C++ [expr.prim.id.unqual]

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 4e76b3825b6f..76b86ac6424d 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -809,9 +809,8 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor {
   if (!isa(NS))
 Builder.foldNode(Builder.getRange(getLocalSourceRange(it)).drop_back(),
  NS, it);
-  Builder.markChild(NS, syntax::NodeRole::NestedNameSpecifier_specifier);
-  Builder.markChildToken(it.getEndLoc(),
- syntax::NodeRole::NestedNameSpecifier_delimiter);
+  Builder.markChild(NS, syntax::NodeRole::List_element);
+  Builder.markChildToken(it.getEndLoc(), syntax::NodeRole::List_delimiter);
 }
 auto *NNS = new (allocator()) syntax::NestedNameSpecifier;
 Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()), NNS,

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index 5e8deb668352..bf3c3108cb69 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -200,30 +200,32 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeRole 
R) {
 return OS << "IdExpression_id";
   case syntax::NodeRole::IdExpression_qualifier:
 return OS << "IdExpression_qualifier";
-  case syntax::NodeRole::NestedNameSpecifier_specifier:
-return OS << "NestedNameSpecifier_specifier";
-  case syntax::NodeRole::NestedNameSpecifier_delimiter:
-return OS << "NestedNameSpecifier_delimiter";
   case syntax::NodeRole::ParenExpression_subExpression:
 return OS << "ParenExpression_subExpression";
   }
   llvm_unreachable("invalid role");
 }
 
-std::vector syntax::NestedNameSpecifier::delimiters() {
-  std::vector Children;
-  for (auto *C = firstChild(); C; C = C->nextSibling()) {
-assert(C->role() == syntax::NodeRole::NestedNameSpecifier_delimiter);
-Children.push_back(llvm::cast(C));
+// We could have an interator in list to not pay memory costs of temporary
+// vector
+std::vector syntax::NestedNameSpecifier::specifiers() 
{
+  auto specifiersAsNodes = getElementsAsNodes();
+  std::vector Children;
+  for (const auto &element : specifiersAsNodes) {
+Children.push_back(llvm::cast(element));
   }
   return Children;
 }
 
-std::vector syntax::NestedNameSpecifier::specifiers() 
{
-  std::vector Children;
-  for (auto *C = firstChild(); C; C = C->nextSibling()) {
-assert(C->role() == syntax::NodeRole::NestedNameSpecifier_specifier);
-Children.push_back(cast(C));
+std::vector>
+syntax::NestedNameSpecifier::specifiersAndDoubleColons() {
+  auto specifiersAsNodesAndDoubleColons = getElementsAsNodesAndDelimiters();
+  std::vector>
+  Children;
+  for (const auto &specifierAndDoubleColon : specifiersAsNodesAndDoubleColons) 
{
+Children.push_back(
+{llvm::cast(specifierAndDoubleColon.element),
+ specifierAndDoubleColon.delimiter});
   }
   return Children;
 }

diff  --git a/clang/lib/Tooling/Syntax/Tree.cpp 
b/clang/lib/Tooling/Syntax/Tree.cpp
index 

[PATCH] D85091: [Sema, CodeGen] Implement [[likely]] and [[unlikely]] in IfStmt

2020-08-10 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

Thank you for starting the implementation work on these attributes!




Comment at: clang/include/clang/Basic/Attr.td:1288
+def Likely : StmtAttr {
+  let Spellings = [CXX11<"", "likely", 201803>];
+  let Documentation = [LikelihoodDocs];

Hmm, I'm on the fence about specifying `201803` for these attributes. Given 
that this is only the start of supporting the attribute, do we want to claim it 
already matches the standard's behavior? Or do we just want to return `1` to 
signify that we understand this attribute but we don't yet fully support it in 
common cases (such as on labels in switch statements, etc)?

As another question, should we consider adding a C2x spelling 
`[[clang::likely]]` and `[[clang::unlikely]]` to add this functionality to C?



Comment at: clang/include/clang/Basic/AttrDocs.td:1697
+It's not allowed to annotate a statement with both ``likely`` and
+``unlikely``.  It's not recommended to annotate both branches of an ``if``
+statement with an attribute.

Why? I would expect this to be reasonable code:
```
if (foo) [[likely]] {
  ...
} else if (bar) [[unlikely]] {
  ...
} else if (baz) [[likely]] {
  ...
} else {
  ...
}
```
Especially because I would expect this to be reasonable code:
```
switch (value) {
[[likely]] case 0: ... break;
[[unlikely]] case 1: ... break;
[[likely]] case 2: ... break;
[[unlikely]] default: ... break;
}
```
As motivating examples, consider a code generator that knows whether a 
particular branch is likely or not and it writes out the attribute on all 
branches. Or, something like this:
```
float rnd_value = get_super_random_number_between_zero_and_one();
if (rnd_value < .1) [[unlikely]] {
} else if (rnd_value > .9) [[unlikely]] {
} else [[likely]] {
}
```



Comment at: clang/include/clang/Basic/AttrDocs.td:1702
+
+At the moment the attribute is only implemented for an ``if`` statement.
+

We should document whether we silently accept the attribute in other locations 
and do nothing with it (I'm not keen on this approach because it surprises 
users) or that we loudly diagnose the attribute in situations that we don't 
support it in (I think this is a more user-friendly approach, but may require a 
separate warning flag).



Comment at: clang/include/clang/Basic/AttrDocs.td:1708
+
+  // compile with -Wimplicit-fallthrough
+  if (b) [[likely]] {

Why does `-Wimplicit-fallthrough` matter?



Comment at: clang/include/clang/Basic/DiagnosticGroups.td:659
 def IgnoredAttributes : DiagGroup<"ignored-attributes">;
+def LikelihoodAttributeIf : DiagGroup<"likelihood-attribute-if">;
 def Attributes : DiagGroup<"attributes", [UnknownAttributes,

Is this because you expect people will want to control diagnostics on `if` 
statements separate from diagnostics in other syntactic locations?



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:2399
 def err_repeat_attribute : Error<"%0 attribute cannot be repeated">;
+def err_attribute_compatibility : Error<
+  "incompatible attributes '%0' and '%1'">;

This isn't needed, we already have `err_attributes_are_not_compatible`.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:2401
+  "incompatible attributes '%0' and '%1'">;
+def note_attribute_compatibility_here : Note<
+  "attribute '%0' declarered here">;

We've already got `note_conflicting_attribute` for this as well.



Comment at: clang/lib/CodeGen/CGStmt.cpp:658
+  auto R = std::make_pair(false, false);
+  auto *AS = dyn_cast(Stmt);
+  if (!AS)

`const auto *`



Comment at: clang/lib/CodeGen/CGStmt.cpp:679-680
+
+  // The code doesn't protect against the same attribute on both branches.
+  // The frontend already issued a diagnostic.
+  std::pair LH = getLikelihood(Then);

I don't think the frontend should issue a diagnostic for that situation. I 
think codegen should handle chains appropriately instead as those seem 
plausible in reasonable code.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85091

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


[PATCH] D85431: [analyzer] Implement a new checker ThreadPrimitivesChecker

2020-08-10 Thread Denys Petrov via Phabricator via cfe-commits
ASDenysPetrov updated this revision to Diff 284353.
ASDenysPetrov added a comment.

Aded enum FuncIdKind to define function Ids.


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

https://reviews.llvm.org/D85431

Files:
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
  clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
  clang/lib/StaticAnalyzer/Checkers/ThreadPrimitivesChecker.cpp
  clang/test/Analysis/Checkers/ThreadPrimitivesChecker.cpp

Index: clang/test/Analysis/Checkers/ThreadPrimitivesChecker.cpp
===
--- /dev/null
+++ clang/test/Analysis/Checkers/ThreadPrimitivesChecker.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.ThreadPrimitives -verify %s
+
+namespace std {
+struct mutex {
+  void lock();
+  void unlock();
+};
+template 
+struct guard_lock {
+  T &t;
+  guard_lock(T &m) : t(m) {
+t.lock();
+  }
+  ~guard_lock() {
+t.unlock();
+  }
+};
+} // namespace std
+
+void correct_lock_unlock(std::mutex m) {
+  m.lock();
+  std::mutex *m2 = &m;
+  m2->unlock();
+}
+
+void correct_lock_unlock2(std::mutex m) {
+  m.lock();
+  std::mutex &m2 = m;
+  m2.unlock();
+}
+
+void correct_lock_unlock3(std::mutex m) {
+  m.lock();
+  m.unlock();
+}
+
+void correct_lock_unlock4(std::mutex m) {
+  std::guard_lock l(m);
+}
+
+void incorrect_lock_unlock(std::mutex m1, std::mutex m2) {
+  m1.lock();
+  m2.unlock(); // expected-warning{{unlock without lock}}
+}
+
+void incorrect_lock_unlock2(std::mutex m, bool b) {
+  m.lock();
+  if (b)
+m.unlock();
+}
+
+void unlock_without_lock(std::mutex m) {
+  m.unlock(); // expected-warning{{unlock without lock}}
+}
+
+void twice_lock(std::mutex m) {
+  m.lock();
+  m.lock(); // expected-warning{{lock more than once}}
+}
+
+void twice_lock2(std::mutex m) {
+  while (true)
+m.lock(); // expected-warning{{lock more than once}}
+}
Index: clang/lib/StaticAnalyzer/Checkers/ThreadPrimitivesChecker.cpp
===
--- /dev/null
+++ clang/lib/StaticAnalyzer/Checkers/ThreadPrimitivesChecker.cpp
@@ -0,0 +1,113 @@
+//=== ConversionChecker.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
+//
+//===--===//
+//
+// This checker finds STL thread primitives misuse.
+// - std::mutex::unlock without std::mutex::lock
+// - std::mutex::lock twice
+//
+//===--===//
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include 
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+
+enum FuncIdKind : uint8_t {
+  Undefined = 0,
+  Mutex_Lock,
+  Mutex_Unlock,
+};
+
+static const std::pair FuncMapping[]{
+{Mutex_Lock, {{"std", "mutex", "lock"}, 0, 0}},
+{Mutex_Unlock, {{"std", "mutex", "unlock"}, 0, 0}},
+};
+
+class ThreadPrimitivesChecker : public Checker {
+public:
+  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
+
+private:
+  BugType BT{this, "STL thread primitives misuse", "std::mutex misuse"};
+
+  FuncIdKind FindMutexLockOrUnlock(const CallEvent &Call,
+   CheckerContext &C) const;
+  void reportBug(CheckerContext &C, const char Msg[]) const;
+};
+
+} // namespace
+
+REGISTER_SET_WITH_PROGRAMSTATE(LockedMutexes, SVal)
+
+FuncIdKind
+ThreadPrimitivesChecker::FindMutexLockOrUnlock(const CallEvent &Call,
+   CheckerContext &C) const {
+  if (const auto *MCall = dyn_cast(&Call))
+for (auto &P : FuncMapping)
+  if (MCall->isCalled(P.second))
+return P.first;
+  return Undefined;
+}
+
+void ThreadPrimitivesChecker::checkPostCall(const CallEvent &Call,
+CheckerContext &C) const {
+  // Find mutex::lock or mutex::unlock functions.
+  FuncIdKind FuncId = FindMutexLockOrUnlock(Call, C);
+
+  if (FuncId == Undefined)
+return;
+
+  // We are sure about cast here, because mutex::lock/unlock met before.
+  const auto *MCall = cast(&Call);
+  SVal SymVal = MCall->getCXXThisVal();
+  SymVal.dump();
+  const bool LockFound = C.getState()->contains(SymVal);
+
+  switch (FuncId) {
+  case Mutex_Lock:
+if (LockFound) {
+  reportBug(C, "Call mutex::lock more than once.");
+} else {
+  ProgramState

[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-08-10 Thread Xiangling Liao via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6ef801aa6bc0: [AIX] Static init frontend recovery and 
backend support (authored by Xiangling_L).

Changed prior to commit:
  https://reviews.llvm.org/D84534?vs=283712&id=284355#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84534

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
  clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp
  clang/unittests/CodeGen/IncrementalProcessingTest.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll

Index: llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
@@ -0,0 +1,10 @@
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 655, void ()* @foo, i8* null }]
+
+define void @foo() {
+  ret void
+}
+
+; CHECK: LLVM ERROR: prioritized sinit and sterm functions are not yet supported
Index: llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
@@ -0,0 +1,10 @@
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff %s 2>&1 | FileCheck %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* null }]
+
+define internal void @foo() {
+  ret void
+}
+
+; CHECK: LLVM ERROR: cannot produce a unique identifier for this module based on strong external symbols
Index: llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
@@ -0,0 +1,12 @@
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@v = global i8 0
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* @v}]
+
+define void @foo() {
+  ret void
+}
+
+; CHECK: LLVM ERROR: associated data of XXStructor list is not yet supported on AIX
Index: llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
@@ -0,0 +1,60 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s
+
+@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @init1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @init2, i8* null }]
+@llvm.global_dtors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @destruct1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @destruct2, i8* null }]
+
+define i32 @extFunc() {
+entry:
+  ret i32 3
+}
+
+define internal void @init1() {
+  ret void
+}
+
+define internal void @destruct1() {
+  ret void
+}
+
+define internal void @init2() {
+  ret void
+}
+
+define internal void @destruct2() {
+  ret void
+}
+
+; CHECK:   .lglobl	init1[DS]
+; CHECK:   .lglobl	.init1
+; CHECK:   .csect init1[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @init1
+; CHECK: .init1:
+; CHECK: .__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	destruct1[DS]
+; CHECK:   .lglobl	.destruct1
+; CHECK:   .csect destruct1[DS]
+; CHECK: __sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @destruct1
+; CHECK: .destruct1:
+; CHECK: .__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	init2[DS]
+; CHECK:   .lglobl	.init2
+; CHECK:   .csect init2[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1: # @init2
+; CHECK: .init2:
+; CHECK: .__sinit8000_cla

[clang] 6ef801a - [AIX] Static init frontend recovery and backend support

2020-08-10 Thread Xiangling Liao via cfe-commits
Author: Xiangling Liao
Date: 2020-08-10T10:10:49-04:00
New Revision: 6ef801aa6bc01fc49a8e83ddb217470b5e2337dd

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

LOG: [AIX] Static init frontend recovery and backend support

On the frontend side, this patch recovers AIX static init implementation to
use the linkage type and function names Clang chooses for sinit related 
function.

On the backend side, this patch sets correct linkage and function names on 
aliases
created for sinit/sterm functions.

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

Added: 
clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll

Modified: 
clang/lib/CodeGen/CGDeclCXX.cpp
clang/lib/CodeGen/CodeGenModule.h
clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
clang/test/CodeGenCXX/aix-static-init.cpp
clang/unittests/CodeGen/IncrementalProcessingTest.cpp
llvm/include/llvm/CodeGen/AsmPrinter.h
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 4e941021daa3..bfefd7956157 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -21,7 +21,6 @@
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/MDBuilder.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Transforms/Utils/ModuleUtils.h"
 
 using namespace clang;
 using namespace CodeGen;
@@ -365,12 +364,9 @@ void CodeGenFunction::EmitCXXGuardedInitBranch(llvm::Value 
*NeedsInit,
 
 llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction(
 llvm::FunctionType *FTy, const Twine &Name, const CGFunctionInfo &FI,
-SourceLocation Loc, bool TLS, bool IsExternalLinkage) {
+SourceLocation Loc, bool TLS) {
   llvm::Function *Fn = llvm::Function::Create(
-  FTy,
-  IsExternalLinkage ? llvm::GlobalValue::ExternalLinkage
-: llvm::GlobalValue::InternalLinkage,
-  Name, &getModule());
+  FTy, llvm::GlobalValue::InternalLinkage, Name, &getModule());
 
   if (!getLangOpts().AppleKext && !TLS) {
 // Set the section if needed.
@@ -378,8 +374,7 @@ llvm::Function 
*CodeGenModule::CreateGlobalInitOrCleanUpFunction(
   Fn->setSection(Section);
   }
 
-  if (Fn->hasInternalLinkage())
-SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
+  SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
 
   Fn->setCallingConv(getRuntimeCC());
 
@@ -589,22 +584,10 @@ CodeGenModule::EmitCXXGlobalInitFunc() {
   if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty())
 return;
 
-  const bool UseSinitAndSterm = getCXXABI().useSinitAndSterm();
-  if (UseSinitAndSterm) {
-GlobalUniqueModuleId = getUniqueModuleId(&getModule());
-
-// FIXME: We need to figure out what to hash on or encode into the unique 
ID
-// we need.
-if (GlobalUniqueModuleId.compare("") == 0)
-  llvm::report_fatal_error(
-  "cannot produce a unique identifier for this module"
-  " based on strong external symbols");
-GlobalUniqueModuleId = GlobalUniqueModuleId.substr(1);
-  }
-
   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
   const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();
 
+  const bool UseSinitAndSterm = getCXXABI().useSinitAndSterm();
   // Create our global prioritized initialization function.
   if (!PrioritizedCXXGlobalInits.empty()) {
 assert(!UseSinitAndSterm && "Prioritized sinit and sterm functions are not"
@@ -644,24 +627,12 @@ CodeGenModule::EmitCXXGlobalInitFunc() {
   if (UseSinitAndSterm && CXXGlobalInits.empty())
 return;
 
-  // Create our global initialization function.
-  SmallString<128> FuncName;
-  bool IsExternalLinkage = false;
-  if (UseSinitAndSterm) {
-llvm::Twine("__sinit8000_clang_", GlobalUniqueModuleId)
-.toVector(FuncName);
-IsExternalLinkage = true;
-  } else {
-// Include the filename in the symbol name. Including "sub_" matches gcc
-// and makes sure these symbols appear lexicographically behind the symbols
-// with priority emitted above.
-llvm::Twine("_GLOBAL__sub_I_", getTransformedFileName(getModule()))
-.toVector(FuncName);
-  }
-
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.

[PATCH] D84226: [AST][RecoveryExpr] Support dependent binary operator in C for error recovery.

2020-08-10 Thread Haojian Wu via Phabricator via cfe-commits
hokein updated this revision to Diff 284358.
hokein added a comment.

- rebase;
- add comments for CreateDependentBinOp, and make it private based on Richard's 
comment;


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84226

Files:
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/AST/ast-dump-recovery.c
  clang/test/Sema/error-dependence.c

Index: clang/test/Sema/error-dependence.c
===
--- /dev/null
+++ clang/test/Sema/error-dependence.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -frecovery-ast -fno-recovery-ast-type -fc-dependence %s
+
+int call(int); // expected-note {{'call' declared here}}
+
+void test1(int s) {
+  // verify "assigning to 'int' from incompatible type ''" is
+  // not emitted.
+  s = call(); // expected-error {{too few arguments to function call}}
+}
Index: clang/test/AST/ast-dump-recovery.c
===
--- clang/test/AST/ast-dump-recovery.c
+++ clang/test/AST/ast-dump-recovery.c
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -fc-dependence -ast-dump %s | FileCheck -strict-whitespace %s
 
 int some_func(int);
 
@@ -42,11 +42,16 @@
 
 void test2() {
   int* ptr;
-  // FIXME: the top-level expr should be a binary operator.
-  // CHECK:  ImplicitCastExpr {{.*}} contains-errors 
-  // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors lvalue
-  // CHECK-NEXT:   |-DeclRefExpr {{.*}} 'ptr' 'int *'
-  // CHECK-NEXT:   `-RecoveryExpr {{.*}}
-  // CHECK-NEXT: `-DeclRefExpr {{.*}} 'some_func'
+  // CHECK: BinaryOperator {{.*}} contains-errors '='
+  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'ptr' 'int *'
+  // CHECK-NEXT: `-RecoveryExpr {{.*}}
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
   ptr = some_func(); // should not crash
+
+  int compoundOp;
+  // CHECK: CompoundAssignOperator {{.*}} '+='
+  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'compoundOp'
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
+  compoundOp += some_func();
 }
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -13303,18 +13303,8 @@
   // If either side is type-dependent, create an appropriate dependent
   // expression.
   if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
-if (Fns.empty()) {
-  // If there are no functions to store, just build a dependent
-  // BinaryOperator or CompoundAssignment.
-  if (Opc <= BO_Assign || Opc > BO_OrAssign)
-return BinaryOperator::Create(
-Context, Args[0], Args[1], Opc, Context.DependentTy, VK_RValue,
-OK_Ordinary, OpLoc, CurFPFeatureOverrides());
-  return CompoundAssignOperator::Create(
-  Context, Args[0], Args[1], Opc, Context.DependentTy, VK_LValue,
-  OK_Ordinary, OpLoc, CurFPFeatureOverrides(), Context.DependentTy,
-  Context.DependentTy);
-}
+if (Fns.empty())
+  return CreateDependentBinOp(OpLoc, Opc, Args[0], Args[1]);
 
 // FIXME: save results of ADL from here?
 CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13669,7 +13669,7 @@
 CorrectDelayedTyposInBinOp(Sema &S, BinaryOperatorKind Opc, Expr *LHSExpr,
Expr *RHSExpr) {
   ExprResult LHS = LHSExpr, RHS = RHSExpr;
-  if (!S.getLangOpts().CPlusPlus) {
+  if (!S.getLangOpts().CPlusPlus && !S.getLangOpts().CDependence) {
 // C cannot handle TypoExpr nodes on either side of a binop because it
 // doesn't handle dependent types properly, so make sure any TypoExprs have
 // been dealt with before checking the operands.
@@ -14247,6 +14247,19 @@
   return S.CreateOverloadedBinOp(OpLoc, Opc, Functions, LHS, RHS);
 }
 
+ExprResult Sema::CreateDependentBinOp(SourceLocation OpLoc,
+  BinaryOperatorKind Opc, Expr *LHS,
+  Expr *RHS) {
+  assert(LHS->isTypeDependent() || RHS->isTypeDependent());
+  if (Opc <= BO_Assign || Opc > BO_OrAssign)
+return BinaryOperator::Create(Context, LHS, RHS, Opc, Context.DependentTy,
+  VK_RValue, OK_Ordinary, OpLoc,
+  CurFPFeatureOv

[PATCH] D85315: [AIX][Clang][Driver] Generate reference to the C++ library on the link step

2020-08-10 Thread Shuhong Liu via Phabricator via cfe-commits
ShuhongL updated this revision to Diff 284357.
ShuhongL added a comment.

Fixed indent and updated error message.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85315

Files:
  clang/lib/Driver/ToolChains/AIX.cpp
  clang/lib/Driver/ToolChains/AIX.h
  clang/test/Driver/aix-ld.c

Index: clang/test/Driver/aix-ld.c
===
--- clang/test/Driver/aix-ld.c
+++ clang/test/Driver/aix-ld.c
@@ -15,6 +15,7 @@
 // CHECK-LD32: "-bpT:0x1000" "-bpD:0x2000"
 // CHECK-LD32: "[[SYSROOT]]/usr/lib{{/|}}crt0.o"
 // CHECK-LD32: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD32-NOT: "-lc++"
 // CHECK-LD32: "-lc"
 
 // Check powerpc64-ibm-aix7.1.0.0, 64-bit.
@@ -31,6 +32,7 @@
 // CHECK-LD64: "-bpT:0x1" "-bpD:0x11000"
 // CHECK-LD64: "[[SYSROOT]]/usr/lib{{/|}}crt0_64.o"
 // CHECK-LD64: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD64-NOT: "-lc++"
 // CHECK-LD64: "-lc"
 
 // Check powerpc-ibm-aix7.1.0.0, 32-bit. Enable POSIX thread support.
@@ -48,6 +50,7 @@
 // CHECK-LD32-PTHREAD: "-bpT:0x1000" "-bpD:0x2000"
 // CHECK-LD32-PTHREAD: "[[SYSROOT]]/usr/lib{{/|}}crt0.o"
 // CHECK-LD32-PTHREAD: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD32-PTHREAD-NOT: "-lc++"
 // CHECK-LD32-PTHREAD: "-lpthreads"
 // CHECK-LD32-PTHREAD: "-lc"
 
@@ -66,6 +69,7 @@
 // CHECK-LD64-PTHREAD: "-bpT:0x1" "-bpD:0x11000"
 // CHECK-LD64-PTHREAD: "[[SYSROOT]]/usr/lib{{/|}}crt0_64.o"
 // CHECK-LD64-PTHREAD: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD64-PTHREAD-NOT: "-lc++"
 // CHECK-LD64-PTHREAD: "-lpthreads"
 // CHECK-LD64-PTHREAD: "-lc"
 
@@ -84,6 +88,7 @@
 // CHECK-LD32-PROF: "-bpT:0x1000" "-bpD:0x2000"
 // CHECK-LD32-PROF: "[[SYSROOT]]/usr/lib{{/|}}mcrt0.o"
 // CHECK-LD32-PROF: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD32-PROF-NOT: "-lc++"
 // CHECK-LD32-PROF: "-lc"
 
 // Check powerpc64-ibm-aix7.1.0.0, 64-bit. Enable g-profiling.
@@ -101,6 +106,7 @@
 // CHECK-LD64-GPROF: "-bpT:0x1" "-bpD:0x11000"
 // CHECK-LD64-GPROF: "[[SYSROOT]]/usr/lib{{/|}}gcrt0_64.o"
 // CHECK-LD64-GPROF: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD64-GPROF-NOT: "-lc++"
 // CHECK-LD64-GPROF: "-lc"
 
 // Check powerpc-ibm-aix7.1.0.0, 32-bit. Static linking.
@@ -118,6 +124,7 @@
 // CHECK-LD32-STATIC: "-bpT:0x1000" "-bpD:0x2000"
 // CHECK-LD32-STATIC: "[[SYSROOT]]/usr/lib{{/|}}crt0.o"
 // CHECK-LD32-STATIC: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD32-STATIC-NOT: "-lc++"
 // CHECK-LD32-STATIC: "-lc"
 
 // Check powerpc-ibm-aix7.1.0.0, 32-bit. Library search path.
@@ -136,6 +143,7 @@
 // CHECK-LD32-LIBP: "[[SYSROOT]]/usr/lib{{/|}}crt0.o"
 // CHECK-LD32-LIBP: "-L[[SYSROOT]]/powerpc-ibm-aix7.1.0.0"
 // CHECK-LD32-LIBP: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD32-LIBP-NOT: "-lc++"
 // CHECK-LD32-LIBP: "-lc"
 
 // Check powerpc-ibm-aix7.1.0.0, 32-bit. nostdlib.
@@ -154,6 +162,7 @@
 // CHECK-LD32-NO-STD-LIB: "-bpT:0x1000" "-bpD:0x2000"
 // CHECK-LD32-NO-STD-LIB-NOT: "[[SYSROOT]]/usr/lib{{/|}}crt0.o"
 // CHECK-LD32-NO-STD-LIB: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD32-NO-STD-LIB-NOT: "-lc++"
 // CHECK-LD32-NO-STD-LIB-NOT: "-lpthreads"
 // CHECK-LD32-NO-STD-LIB-NOT: "-lc"
 
@@ -173,14 +182,15 @@
 // CHECK-LD64-NO-DEFAULT-LIBS: "-bpT:0x1" "-bpD:0x11000"
 // CHECK-LD64-NO-DEFAULT-LIBS: "[[SYSROOT]]/usr/lib{{/|}}crt0_64.o"
 // CHECK-LD64-NO-DEFAULT-LIBS: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD64-NO-DEFAULT-LIBS-NOT: "-lc++"
 // CHECK-LD64-NO-DEFAULT-LIBS-NOT: "-lpthreads"
 // CHECK-LD64-NO-DEFAULT-LIBS-NOT: "-lc"
 
 // Check powerpc-ibm-aix7.1.0.0, 32-bit. 'bcdtors' and argument order.
 // RUN: %clangxx -no-canonical-prefixes %s 2>&1 -### \
-// RUN:  -Wl,-bnocdtors \
-// RUN:  -target powerpc-ibm-aix7.1.0.0 \
-// RUN:  --sysroot %S/Inputs/aix_ppc_tree \
+// RUN:-Wl,-bnocdtors \
+// RUN:-target powerpc-ibm-aix7.1.0.0 \
+// RUN:--sysroot %S/Inputs/aix_ppc_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-LD32-CXX-ARG-ORDER %s
 // CHECK-LD32-CXX-ARG-ORDER: {{.*}}clang{{.*}}" "-cc1" "-triple" "powerpc-ibm-aix7.1.0.0"
 // CHECK-LD32-CXX-ARG-ORDER: "-isysroot" "[[SYSROOT:[^"]+]]"
@@ -192,3 +202,146 @@
 // CHECK-LD32-CXX-ARG-ORDER: "-bcdtors:all:0:s"
 // CHECK-LD32-CXX-ARG-ORDER: "-bnocdtors"
 // CHECK-LD32-CXX-ARG-ORDER-NOT: "-bcdtors:all:0:s"
+// CHECK-LD32-CXX-ARG-ORDER: "-lc++"
+// CHECK-LD32-CXX-ARG-ORDER: "-lc"
+
+// Check powerpc-ibm-aix7.1.0.0, 32-bit. lc++ and lc order.
+// RUN: %clangxx -no-canonical-prefixes %s 2>&1 -### \
+// RUN:-target powerpc-ibm-aix7.1.0.0 \
+// RUN:--sysroot %S/Inputs/aix_ppc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD32-CXX-ARG-LCXX %s
+// CHECK-LD32-CXX-ARG-LCXX: {{.*}}clang{{.*}}" "-cc1" "-triple" "powerpc-ibm-aix7.1

[PATCH] D80525: [clangd] Fix crash-bug in preamble indexing when using modules.

2020-08-10 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz updated this revision to Diff 284360.
adamcz marked 2 inline comments as done.
adamcz added a comment.

final(?) review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D80525

Files:
  clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
  clang-tools-extra/clangd/unittests/TestFS.h
  clang-tools-extra/clangd/unittests/TestTU.cpp
  clang-tools-extra/clangd/unittests/TestTU.h
  clang/lib/Index/IndexingAction.cpp

Index: clang/lib/Index/IndexingAction.cpp
===
--- clang/lib/Index/IndexingAction.cpp
+++ clang/lib/Index/IndexingAction.cpp
@@ -165,11 +165,20 @@
 static void indexPreprocessorMacros(const Preprocessor &PP,
 IndexDataConsumer &DataConsumer) {
   for (const auto &M : PP.macros())
-if (MacroDirective *MD = M.second.getLatest())
+if (MacroDirective *MD = M.second.getLatest()) {
+  auto *MI = MD->getMacroInfo();
+  // When using modules, it may happen that we find #undef of a macro that
+  // was defined in another module. In such case, MI may be nullptr, since
+  // we only look for macro definitions in the current TU. In that case,
+  // there is nothing to index.
+  if (!MI)
+continue;
+
   DataConsumer.handleMacroOccurrence(
   M.first, MD->getMacroInfo(),
   static_cast(index::SymbolRole::Definition),
   MD->getLocation());
+}
 }
 
 void index::indexASTUnit(ASTUnit &Unit, IndexDataConsumer &DataConsumer,
Index: clang-tools-extra/clangd/unittests/TestTU.h
===
--- clang-tools-extra/clangd/unittests/TestTU.h
+++ clang-tools-extra/clangd/unittests/TestTU.h
@@ -66,6 +66,14 @@
   // Simulate a header guard of the header (using an #import directive).
   bool ImplicitHeaderGuard = true;
 
+  // Whether to use overlay the TestFS over the real filesystem. This is
+  // required for use of modules.
+  // FIXME: Intercept the write of implicitly build module to disk and update
+  // TestFS with that content to avoid using real file system in tests.
+  // Please avoid using this for things other than implicit modules. The plan is
+  // to eliminate this option some day.
+  bool OverlayRealFileSystemForModules = false;
+
   // By default, build() will report Error diagnostics as GTest errors.
   // Suppress this behavior by adding an 'error-ok' comment to the code.
   ParsedAST build() const;
Index: clang-tools-extra/clangd/unittests/TestTU.cpp
===
--- clang-tools-extra/clangd/unittests/TestTU.cpp
+++ clang-tools-extra/clangd/unittests/TestTU.cpp
@@ -54,6 +54,8 @@
   Inputs.CompileCommand.Filename = FullFilename;
   Inputs.CompileCommand.Directory = testRoot();
   Inputs.Contents = Code;
+  if (OverlayRealFileSystemForModules)
+FS.OverlayRealFileSystem = true;
   Inputs.TFS = &FS;
   Inputs.Opts = ParseOptions();
   Inputs.Opts.BuildRecoveryAST = true;
Index: clang-tools-extra/clangd/unittests/TestFS.h
===
--- clang-tools-extra/clangd/unittests/TestFS.h
+++ clang-tools-extra/clangd/unittests/TestFS.h
@@ -34,12 +34,21 @@
 class MockFS : public ThreadsafeFS {
 public:
   IntrusiveRefCntPtr viewImpl() const override {
-return buildTestFS(Files, Timestamps);
+auto MemFS = buildTestFS(Files, Timestamps);
+if (!OverlayRealFileSystem)
+  return MemFS;
+llvm::IntrusiveRefCntPtr OverlayFileSystem =
+new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem());
+OverlayFileSystem->pushOverlay(MemFS);
+return OverlayFileSystem;
   }
 
   // If relative paths are used, they are resolved with testPath().
   llvm::StringMap Files;
   llvm::StringMap Timestamps;
+  // If true, real file system will be used as fallback for the in-memory one.
+  // This is useful for testing module support.
+  bool OverlayRealFileSystem = false;
 };
 
 // A Compilation database that returns a fixed set of compile flags.
Index: clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
===
--- clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
+++ clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
@@ -1520,6 +1520,31 @@
   EXPECT_THAT(Symbols,
   UnorderedElementsAre(AllOf(QName("X"), ForCodeCompletion(true;
 }
+
+// Regression test for a crash-bug we used to have.
+TEST_F(SymbolCollectorTest, UndefOfModuleMacro) {
+  auto TU = TestTU::withCode(R"cpp(#include "bar.h")cpp");
+  TU.AdditionalFiles["bar.h"] = R"cpp(
+#include "foo.h"
+#undef X
+)cpp";
+  TU.AdditionalFiles["foo.h"] = "#define X 1";
+  TU.AdditionalFiles["module.map"] = R"cpp(
+module foo {
+ header "foo.h"
+ export *
+   }
+   )cpp";
+  TU.ExtraArgs.push_b

[PATCH] D80525: [clangd] Fix crash-bug in preamble indexing when using modules.

2020-08-10 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz added inline comments.



Comment at: clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp:1523
+  TU.ExtraArgs.push_back("-fmodule-map-file=/module.map");
+  TU.OverlayRealFileSystem = true;
+

sammccall wrote:
> I'm a bit torn on this - this is obviously a bit messy (writing modules to 
> the real filesystem and exposing the whole FS to our test).
> It's not a huge thing and we could slap a FIXME on it, though you clearly 
> have to plumb it through a few layers.
> 
> I think the alternative is an explicit module build:
>  - subclass `clang::GenerateHeaderModuleAction`to override the output so it 
> ends up in a buffer
>  - add a method to TestTU like buildHeaderModule() that returns a 
> `std::string` containing the module content
>  - This test would have two TestTU instances, and the second looks something 
> like:
> ```
> TU2.AdditionalFiles["foo.pcm"] = TU1.buildHeaderModule();
> TU2.ExtraArgs = {"-fprebuild-module-path=.", "-std=c++20", "-fmodules"};
> TU2.HeaderCode = "import foo;\n#undef X";
> ```
> 
> I guess whether this is actually better probably depends on whether we're 
> likely to go in this direction (explicitly building and managing a module 
> cache ourselves) for modules. If we're likely to let clang implicitly build 
> modules and maybe just put the physical cache storage behind an abstraction, 
> maybe it's best to overlay the FS for now and rip this out later. If we're 
> going to do explicit module builds and schedule them ourselves, then starting 
> to experiment in that direction is useful, and there won't be an obvious time 
> to rip out the OverlayRealFileSystem feature.
> 
> I think all of which is to say feel free to land it in this form, or 
> experiment further.
> I think the OverlayRealFileSystem should maybe be `ExposeModuleCacheDir` or 
> something with a FIXME to come up with a better solution, though. It's not a 
> feature of TesttU we should be using for other purposes (without similar 
> careful consideration)
I think we should support implicit modules in general. It's a useful feature. 
This means we should be able to test it. While it might not matter for this 
particular fix, we need some implicit modules tests to prevent regressions.

We should also have explicit modules tests, of course. All of that is coming 
soon :-)

Ultimately, I think a proper solution is to either:
a. Support writing to disk in VFS, then implement that in InMemoryFS.
b. Create abstraction around writing implicitly compiled module to disk, 
intercept that in test and update the memory FS.

Both seem acceptable to me, although I haven't looked at details yet. I think 
for now, we should just accept the sad fact that some tests will write to disk. 
It should be easy to remove it later.

I added a FIXME and renamed to OverlayRealFilesystemForModules to make it clear 
it should not be used for anything else. Does that sound good to you?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D80525

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


[PATCH] D80031: [clang-format] [NFC] release note placed in the wrong location and other rst linting errors

2020-08-10 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: clang/docs/ReleaseNotes.rst:70
   motivating use case for these types is to limit 'bit' usage, these types 
don't
-  automatically promote to 'int' when operations are done between two 
``ExtInt(N)``
-  types, instead math occurs at the size of the largest ``ExtInt(N)`` type.
+  automatically promote to 'int' when operations are done between two
+  ``ExtInt(N)`` types, instead math occurs at the size of the largest

I think //int// should be highlighted too with double back-ticks.



Comment at: clang/docs/ReleaseNotes.rst:114
+  this occurs when the use of the ``extern`` keyword is neglected in the
+  declaration
   of a variable in a header file. In some cases, no specific translation unit

MyDeveloperDay wrote:
> Eugene.Zelenko wrote:
> > This and next line should be merged.
> I knew you'd be perfect to review this...
I'm happy to help!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D80031

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


[PATCH] D85025: [RecoveryExpr]WIP: Support dependence in C-only codepath

2020-08-10 Thread Haojian Wu via Phabricator via cfe-commits
hokein added a comment.

In D85025#2201042 , @rsmith wrote:

> Looks reasonable to me. I expect you'll find more places that need to learn 
> how to handle dependent types in C, but this looks like a solid start.

Thanks! Yeah, we'd need to a detailed plan to roll this out (similar to the 
recovery-ast in C++) to catch possibly-missing cases.

I'll address your comments in split patches. I think the next plan is be to 
move forward the code reviews, Sam agreed to review those and I'll add you in 
the Subscribers.




Comment at: clang/lib/AST/Expr.cpp:3757-3758
 case NPC_ValueDependentIsNull:
-  if (isTypeDependent() || getType()->isIntegralType(Ctx))
+  if ((!containsErrors() && isTypeDependent()) ||
+  getType()->isIntegralType(Ctx))
 return NPCK_ZeroExpression;

rsmith wrote:
> This change appears to be redundant: we handled all `containsErrors()` cases 
> before the `switch`.
oh, yeah, this is an oversight during the rebase.



Comment at: clang/lib/Sema/SemaExpr.cpp:14245-14247
+ExprResult Sema::CreateDependentBinOp(SourceLocation OpLoc,
+  BinaryOperatorKind Opc, Expr *LHS,
+  Expr *RHS) {

rsmith wrote:
> This function seems dangerous: in C++, we need to perform unqualified lookups 
> from the template definition context when creating a dependent binary 
> operator, and it's only correct to use this if such lookup found nothing.
> 
> Perhaps you could add something to the name of the function to indicate that 
> it should only be used when there are no unqualified lookup results?
good point, thanks! I added some comments about this method, and make it 
private to make it less mis-unused.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85025

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


[clang] b129c9d - Author: Shuhong Liu

2020-08-10 Thread Shuhong Liu via cfe-commits
Author: Shuhong Liu
Date: 2020-08-10T10:27:04-04:00
New Revision: b129c9d81aff8ece71eb29df1e5f31136a48c040

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

LOG: Author: Shuhong Liu 
Date:   Mon Aug 10 10:31:50 2020 +0300

[AIX][Clang][Driver] Generate reference to the C++ library on the link step

Have the linker find libc++ on its search path by adding -lc++.

Reviewed by: daltenty, hubert.reinterpretcast, stevewan

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

Added: 


Modified: 
clang/lib/Driver/ToolChains/AIX.cpp
clang/lib/Driver/ToolChains/AIX.h
clang/test/Driver/aix-ld.c

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/AIX.cpp 
b/clang/lib/Driver/ToolChains/AIX.cpp
index f9d8e18d6fd0..bc130a5557e9 100644
--- a/clang/lib/Driver/ToolChains/AIX.cpp
+++ b/clang/lib/Driver/ToolChains/AIX.cpp
@@ -141,6 +141,9 @@ void aix::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
 
+  if (getToolChain().ShouldLinkCXXStdlib(Args))
+getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
 // Support POSIX threads if "-pthreads" or "-pthread" is present.
 if (Args.hasArg(options::OPT_pthreads, options::OPT_pthread))
@@ -197,6 +200,23 @@ void AIX::AddClangSystemIncludeArgs(const ArgList 
&DriverArgs,
   addSystemInclude(DriverArgs, CC1Args, UP.str());
 }
 
+void AIX::AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs,
+  llvm::opt::ArgStringList &CC1Args) const {
+  switch (GetCXXStdlibType(DriverArgs)) {
+  case ToolChain::CST_Libcxx:
+CC1Args.push_back("-lc++");
+return;
+  case ToolChain::CST_Libstdcxx:
+llvm::report_fatal_error("linking libstdc++ unimplemented on AIX");
+  }
+
+  llvm_unreachable("Unexpected C++ library type; only libc++ is supported.");
+}
+
+ToolChain::CXXStdlibType AIX::GetDefaultCXXStdlibType() const {
+  return ToolChain::CST_Libcxx;
+}
+
 auto AIX::buildAssembler() const -> Tool * { return new aix::Assembler(*this); 
}
 
 auto AIX::buildLinker() const -> Tool * { return new aix::Linker(*this); }

diff  --git a/clang/lib/Driver/ToolChains/AIX.h 
b/clang/lib/Driver/ToolChains/AIX.h
index 942bb3cceb8a..f63b20da969e 100644
--- a/clang/lib/Driver/ToolChains/AIX.h
+++ b/clang/lib/Driver/ToolChains/AIX.h
@@ -67,6 +67,11 @@ class LLVM_LIBRARY_VISIBILITY AIX : public ToolChain {
   AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
 llvm::opt::ArgStringList &CC1Args) const override;
 
+  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+   llvm::opt::ArgStringList &CmdArgs) const override;
+
+  CXXStdlibType GetDefaultCXXStdlibType() const override;
+
 protected:
   Tool *buildAssembler() const override;
   Tool *buildLinker() const override;

diff  --git a/clang/test/Driver/aix-ld.c b/clang/test/Driver/aix-ld.c
index 59e35248af30..7b3710ca21ef 100644
--- a/clang/test/Driver/aix-ld.c
+++ b/clang/test/Driver/aix-ld.c
@@ -15,6 +15,7 @@
 // CHECK-LD32: "-bpT:0x1000" "-bpD:0x2000"
 // CHECK-LD32: "[[SYSROOT]]/usr/lib{{/|}}crt0.o"
 // CHECK-LD32: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD32-NOT: "-lc++"
 // CHECK-LD32: "-lc"
 
 // Check powerpc64-ibm-aix7.1.0.0, 64-bit.
@@ -31,6 +32,7 @@
 // CHECK-LD64: "-bpT:0x1" "-bpD:0x11000"
 // CHECK-LD64: "[[SYSROOT]]/usr/lib{{/|}}crt0_64.o"
 // CHECK-LD64: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD64-NOT: "-lc++"
 // CHECK-LD64: "-lc"
 
 // Check powerpc-ibm-aix7.1.0.0, 32-bit. Enable POSIX thread support.
@@ -48,6 +50,7 @@
 // CHECK-LD32-PTHREAD: "-bpT:0x1000" "-bpD:0x2000"
 // CHECK-LD32-PTHREAD: "[[SYSROOT]]/usr/lib{{/|}}crt0.o"
 // CHECK-LD32-PTHREAD: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD32-PTHREAD-NOT: "-lc++"
 // CHECK-LD32-PTHREAD: "-lpthreads"
 // CHECK-LD32-PTHREAD: "-lc"
 
@@ -66,6 +69,7 @@
 // CHECK-LD64-PTHREAD: "-bpT:0x1" "-bpD:0x11000"
 // CHECK-LD64-PTHREAD: "[[SYSROOT]]/usr/lib{{/|}}crt0_64.o"
 // CHECK-LD64-PTHREAD: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD64-PTHREAD-NOT: "-lc++"
 // CHECK-LD64-PTHREAD: "-lpthreads"
 // CHECK-LD64-PTHREAD: "-lc"
 
@@ -84,6 +88,7 @@
 // CHECK-LD32-PROF: "-bpT:0x1000" "-bpD:0x2000"
 // CHECK-LD32-PROF: "[[SYSROOT]]/usr/lib{{/|}}mcrt0.o"
 // CHECK-LD32-PROF: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD32-PROF-NOT: "-lc++"
 // CHECK-LD32-PROF: "-lc"
 
 // Check powerpc64-ibm-aix7.1.0.0, 64-bit. Enable g-profiling.
@@ -101,6 +106,7 @@
 // CHECK-LD64-GPROF: "-bpT:0x1" "-bpD:0x11000"
 // CHECK-LD64-GPROF: 

[PATCH] D84636: [RFC] Make the default LibCall implementations from compiler-rt builtins library more customizable

2020-08-10 Thread Anatoly Trosinenko via Phabricator via cfe-commits
atrosinenko added a comment.

Another note to myself: add `AUX_DECLS(__LibCallName)` to every generic 
implementation file. They were forgotten unintentionally.




Comment at: compiler-rt/lib/builtins/arm-libcall-overrides.h:8
+//===--===//
+
+#define AEABI_RTABI __attribute__((__pcs__("aapcs")))

aaron.ballman wrote:
> It looks like you're missing a header guard, is that intentional?
Thanks, there are files such as `libcall-set-defaults.inc` that is explicitly 
named `.inc` due to some specific requirements at which point it should be 
included. But this one definitely lacks a header guard. Another question is 
whether it lacks a guard to check whether we are really on ARM. But it would 
probably be better to have something like

```lang=cpp
#if !defined(__ARM_EABI__)
# error Do not include this header unless on ARM target.
#endif
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84636

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


[PATCH] D80525: [clangd] Fix crash-bug in preamble indexing when using modules.

2020-08-10 Thread Sam McCall via Phabricator via cfe-commits
sammccall accepted this revision.
sammccall added inline comments.



Comment at: clang-tools-extra/clangd/unittests/TestFS.h:51
+  // This is useful for testing module support.
+  bool OverlayRealFileSystem = false;
 };

also ForModules here?



Comment at: clang-tools-extra/clangd/unittests/TestTU.h:70
+  // Whether to use overlay the TestFS over the real filesystem. This is
+  // required for use of modules.
+  // FIXME: Intercept the write of implicitly build module to disk and update

nit: "of implicit modules, where the module file is written to disk and later 
read back"



Comment at: clang-tools-extra/clangd/unittests/TestTU.h:71
+  // required for use of modules.
+  // FIXME: Intercept the write of implicitly build module to disk and update
+  // TestFS with that content to avoid using real file system in tests.

nit: I'm not sure the (V)FS should be involved at all in the final test setup.
The way I see it, the module storage is basically a cache from (module name + 
validity-stuff) ==> bytes, and *reads* could be abstracted just like writes.
For tests this could just be an in-memory map of course, but I think even in 
production we'd benefit a bit from not having to express this map through the 
filesystem. (E.g the way it's versioned doesn't have much to do with the way 
versioned filesystems are)

Only actionable thing for now is to maybe tweak this comment slightly, but 
wanted to mention it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D80525

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


[PATCH] D85532: Correctly set CompilingPCH in PrecompilePreambleAction.

2020-08-10 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz updated this revision to Diff 284365.
adamcz marked an inline comment as done.
adamcz added a comment.

more review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85532

Files:
  clang-tools-extra/clangd/unittests/CMakeLists.txt
  clang-tools-extra/clangd/unittests/ModulesTests.cpp
  clang/lib/Frontend/PrecompiledPreamble.cpp
  clang/unittests/Frontend/ASTUnitTest.cpp

Index: clang/unittests/Frontend/ASTUnitTest.cpp
===
--- clang/unittests/Frontend/ASTUnitTest.cpp
+++ clang/unittests/Frontend/ASTUnitTest.cpp
@@ -13,6 +13,7 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/PCHContainerOperations.h"
+#include "clang/Lex/HeaderSearch.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ToolOutputFile.h"
@@ -111,4 +112,42 @@
 llvm::MemoryBuffer::MemoryBuffer_MMap);
 }
 
+TEST_F(ASTUnitTest, ModuleTextualHeader) {
+  llvm::IntrusiveRefCntPtr InMemoryFs =
+  new llvm::vfs::InMemoryFileSystem();
+  InMemoryFs->addFile("test.cpp", 0, llvm::MemoryBuffer::getMemBuffer(R"cpp(
+  #include "Textual.h"
+  void foo() {}
+)cpp"));
+  InMemoryFs->addFile("m.modulemap", 0, llvm::MemoryBuffer::getMemBuffer(R"cpp(
+  module M {
+module Textual {
+  textual header "Textual.h"
+}
+  }
+)cpp"));
+  InMemoryFs->addFile("Textual.h", 0, llvm::MemoryBuffer::getMemBuffer(R"cpp(
+  void foo();
+)cpp"));
+
+  const char *Args[] = {"clang", "test.cpp", "-fmodule-map-file=m.modulemap",
+"-fmodule-name=M"};
+  Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
+  CInvok = createInvocationFromCommandLine(Args, Diags);
+  ASSERT_TRUE(CInvok);
+
+  FileManager *FileMgr = new FileManager(FileSystemOptions(), InMemoryFs);
+  PCHContainerOps = std::make_shared();
+
+  auto AU = ASTUnit::LoadFromCompilerInvocation(
+  CInvok, PCHContainerOps, Diags, FileMgr, false, CaptureDiagsKind::None, 1,
+  TU_Complete, false, false, false);
+  ASSERT_TRUE(AU);
+  auto File = AU->getFileManager().getFileRef("Textual.h", false, false);
+  assert(File);
+  // Verify that we do not crash here.
+  EXPECT_TRUE(AU->getPreprocessor().getHeaderSearchInfo().getExistingFileInfo(
+  &File->getFileEntry()));
+}
+
 } // anonymous namespace
Index: clang/lib/Frontend/PrecompiledPreamble.cpp
===
--- clang/lib/Frontend/PrecompiledPreamble.cpp
+++ clang/lib/Frontend/PrecompiledPreamble.cpp
@@ -208,6 +208,11 @@
 Callbacks.AfterPCHEmitted(Writer);
   }
 
+  bool BeginSourceFileAction(CompilerInstance &CI) override {
+assert(CI.getLangOpts().CompilingPCH);
+return ASTFrontendAction::BeginSourceFileAction(CI);
+  }
+
   bool shouldEraseOutputFiles() override { return !hasEmittedPreamblePCH(); }
   bool hasCodeCompletionSupport() const override { return false; }
   bool hasASTFileSupport() const override { return false; }
@@ -396,6 +401,8 @@
   auto PreambleDepCollector = std::make_shared();
   Clang->addDependencyCollector(PreambleDepCollector);
 
+  Clang->getLangOpts().CompilingPCH = true;
+
   // Remap the main source file to the preamble buffer.
   StringRef MainFilePath = FrontendOpts.Inputs[0].getFile();
   auto PreambleInputBuffer = llvm::MemoryBuffer::getMemBufferCopy(
Index: clang-tools-extra/clangd/unittests/ModulesTests.cpp
===
--- /dev/null
+++ clang-tools-extra/clangd/unittests/ModulesTests.cpp
@@ -0,0 +1,44 @@
+//===-- ModulesTests.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 "Annotations.h"
+#include "TestFS.h"
+#include "TestTU.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+#include 
+#include 
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TEST(Modules, TextualIncludeInPreamble) {
+  TestTU TU = TestTU::withCode(R"cpp(
+#include "Textual.h"
+
+void foo() {}
+)cpp");
+  TU.ExtraArgs.push_back("-fmodule-name=M");
+  TU.ExtraArgs.push_back("-fmodule-map-file=m.modulemap");
+  TU.AdditionalFiles["Textual.h"] = "void foo();";
+  TU.AdditionalFiles["m.modulemap"] = R"modulemap(
+module M {
+  module Textual {
+textual header "Textual.h"
+  }
+}
+)modulemap";
+  // Test that we do not crash.
+  TU.index();
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
Index: clang-tools-extra/clangd/unittests/CMakeLists.txt
=

[PATCH] D85091: [Sema, CodeGen] Implement [[likely]] and [[unlikely]] in IfStmt

2020-08-10 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone added inline comments.



Comment at: clang/include/clang/Basic/AttrDocs.td:1697
+It's not allowed to annotate a statement with both ``likely`` and
+``unlikely``.  It's not recommended to annotate both branches of an ``if``
+statement with an attribute.

aaron.ballman wrote:
> Why? I would expect this to be reasonable code:
> ```
> if (foo) [[likely]] {
>   ...
> } else if (bar) [[unlikely]] {
>   ...
> } else if (baz) [[likely]] {
>   ...
> } else {
>   ...
> }
> ```
> Especially because I would expect this to be reasonable code:
> ```
> switch (value) {
> [[likely]] case 0: ... break;
> [[unlikely]] case 1: ... break;
> [[likely]] case 2: ... break;
> [[unlikely]] default: ... break;
> }
> ```
> As motivating examples, consider a code generator that knows whether a 
> particular branch is likely or not and it writes out the attribute on all 
> branches. Or, something like this:
> ```
> float rnd_value = get_super_random_number_between_zero_and_one();
> if (rnd_value < .1) [[unlikely]] {
> } else if (rnd_value > .9) [[unlikely]] {
> } else [[likely]] {
> }
> ```
Right, annotating both/multiple branches of a control statement should be 
perfectly fine. Even `if (x) [[likely]] { } else [[likely]] { }` should be 
perfectly okay as far as the code generator is concerned (and we should have a 
test for that); it's silly, but there's no reason to warn against it in the 
compiler docs.

Aaron, notice that `if (x) [[likely]] { } else if (y) [[likely]] { }` is not 
actually annotating "both" branches of any single `if`-statement. There you're 
annotating the true branch of an if (without annotating the else branch), and 
then annotating the true branch of another if (which doesn't have an else 
branch).

Mordante, in these docs, please document the "interesting" behavior of the 
standard attribute on labels — annotating a label is different from annotating 
the labeled statement itself. In particular,

[[likely]] case 1: case 2: foo(); break;
case 3: [[likely]] case 4: foo(); break;
case 5: case 6: [[likely]] foo(); break;

indicates that the likely cases are 1, 4, 5, and 6. (1 and 4 because their 
labels are annotated; 5 and 6 because their control flow passes through an 
annotated statement. Case 3's control flow passes through an annotated label, 
but that doesn't matter to the standard attribute.)



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:2402
+def note_attribute_compatibility_here : Note<
+  "attribute '%0' declarered here">;
+def warn_attribute_likelihood_if_duplicated : Warning<

Typo: /declarered/declared/



Comment at: clang/lib/Sema/SemaStmt.cpp:585
+  // Warn when both the true and false branch of an if statement have the same
+  // likelihood attribute. It's not prohibited, but makes no sense.
+  const LikelyAttr *Likely = nullptr;

I agree with Aaron, this doesn't deserve a warning. Or at least there should be 
some thought put into the "threat model." (Are we protecting against someone 
typoing `[[likely]]`/`[[likely]]` when they meant `[[likely]]`/`[[unlikely]]`? 
But they weren't supposed to annotate both branches in the first place...)



Comment at: clang/lib/Sema/SemaStmtAttr.cpp:349
+<< Unlikely->getSpelling() << Unlikely->getRange();
+
+return;

Nit: Remove this blank line, for parallelism with lines 358-359.



Comment at: clang/test/SemaCXX/attr-likelihood.cpp:101
+}
+#endif

I'd like to see a case like `if (x) [[likely]] i=1;` just to prove that it 
works on statements that aren't blocks or empty statements. (My understanding 
is that this should already work with your current patch.)

I'd like to see a case like `if (x) { [[likely]] i=1; }` to prove that it works 
on arbitrary statements. This //should// have the same effect as `if (x) 
[[likely]] { i=1; }`. My understanding is that your current patch doesn't get 
us there //yet//. If it's unclear how we'd get there by proceeding along your 
current trajectory, then I would question whether we want to commit to this 
trajectory at all, yet.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85091

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


[PATCH] D85532: Correctly set CompilingPCH in PrecompilePreambleAction.

2020-08-10 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz added inline comments.



Comment at: clang/unittests/Frontend/ASTUnitTest.cpp:146
+  auto File = AU->getFileManager().getFileRef("Textual.h", false, false);
+  assert(File);
+  // Verify that we do not crash here.

kadircet wrote:
> ASSERT_TRUE again
You can 't ASSERT_TRUE() on llvm::Expected, since operator bool() is not const. 
No idea why, but that's why it's assert()


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85532

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


Re: [clang] b129c9d - Author: Shuhong Liu

2020-08-10 Thread Hubert Tong via cfe-commits
@shuhong@ibm.com: I'm not sure what process you followed to commit
this, but the commit message does not seem right. It might make sense to
revert this and commit again with the proper message to make annotations
from `git blame` work better.

-- HT

On Mon, Aug 10, 2020 at 10:33 AM Shuhong Liu via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

>
> Author: Shuhong Liu
> Date: 2020-08-10T10:27:04-04:00
> New Revision: b129c9d81aff8ece71eb29df1e5f31136a48c040
>
> URL:
> https://github.com/llvm/llvm-project/commit/b129c9d81aff8ece71eb29df1e5f31136a48c040
> DIFF:
> https://github.com/llvm/llvm-project/commit/b129c9d81aff8ece71eb29df1e5f31136a48c040.diff
>
> LOG: Author: Shuhong Liu 
> Date:   Mon Aug 10 10:31:50 2020 +0300
>
> [AIX][Clang][Driver] Generate reference to the C++ library on the link
> step
>
> Have the linker find libc++ on its search path by adding -lc++.
>
> Reviewed by: daltenty, hubert.reinterpretcast, stevewan
>
> Differential Revision: https://reviews.llvm.org/D85315
>
> Added:
>
>
> Modified:
> clang/lib/Driver/ToolChains/AIX.cpp
> clang/lib/Driver/ToolChains/AIX.h
> clang/test/Driver/aix-ld.c
>
> Removed:
>
>
>
>
> 
> diff  --git a/clang/lib/Driver/ToolChains/AIX.cpp
> b/clang/lib/Driver/ToolChains/AIX.cpp
> index f9d8e18d6fd0..bc130a5557e9 100644
> --- a/clang/lib/Driver/ToolChains/AIX.cpp
> +++ b/clang/lib/Driver/ToolChains/AIX.cpp
> @@ -141,6 +141,9 @@ void aix::Linker::ConstructJob(Compilation &C, const
> JobAction &JA,
>Args.AddAllArgs(CmdArgs, options::OPT_L);
>ToolChain.AddFilePathLibArgs(Args, CmdArgs);
>
> +  if (getToolChain().ShouldLinkCXXStdlib(Args))
> +getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
> +
>if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
>  // Support POSIX threads if "-pthreads" or "-pthread" is present.
>  if (Args.hasArg(options::OPT_pthreads, options::OPT_pthread))
> @@ -197,6 +200,23 @@ void AIX::AddClangSystemIncludeArgs(const ArgList
> &DriverArgs,
>addSystemInclude(DriverArgs, CC1Args, UP.str());
>  }
>
> +void AIX::AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs,
> +  llvm::opt::ArgStringList &CC1Args) const {
> +  switch (GetCXXStdlibType(DriverArgs)) {
> +  case ToolChain::CST_Libcxx:
> +CC1Args.push_back("-lc++");
> +return;
> +  case ToolChain::CST_Libstdcxx:
> +llvm::report_fatal_error("linking libstdc++ unimplemented on AIX");
> +  }
> +
> +  llvm_unreachable("Unexpected C++ library type; only libc++ is
> supported.");
> +}
> +
> +ToolChain::CXXStdlibType AIX::GetDefaultCXXStdlibType() const {
> +  return ToolChain::CST_Libcxx;
> +}
> +
>  auto AIX::buildAssembler() const -> Tool * { return new
> aix::Assembler(*this); }
>
>  auto AIX::buildLinker() const -> Tool * { return new aix::Linker(*this); }
>
> diff  --git a/clang/lib/Driver/ToolChains/AIX.h
> b/clang/lib/Driver/ToolChains/AIX.h
> index 942bb3cceb8a..f63b20da969e 100644
> --- a/clang/lib/Driver/ToolChains/AIX.h
> +++ b/clang/lib/Driver/ToolChains/AIX.h
> @@ -67,6 +67,11 @@ class LLVM_LIBRARY_VISIBILITY AIX : public ToolChain {
>AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
>  llvm::opt::ArgStringList &CC1Args) const
> override;
>
> +  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
> +   llvm::opt::ArgStringList &CmdArgs) const
> override;
> +
> +  CXXStdlibType GetDefaultCXXStdlibType() const override;
> +
>  protected:
>Tool *buildAssembler() const override;
>Tool *buildLinker() const override;
>
> diff  --git a/clang/test/Driver/aix-ld.c b/clang/test/Driver/aix-ld.c
> index 59e35248af30..7b3710ca21ef 100644
> --- a/clang/test/Driver/aix-ld.c
> +++ b/clang/test/Driver/aix-ld.c
> @@ -15,6 +15,7 @@
>  // CHECK-LD32: "-bpT:0x1000" "-bpD:0x2000"
>  // CHECK-LD32: "[[SYSROOT]]/usr/lib{{/|}}crt0.o"
>  // CHECK-LD32: "-L[[SYSROOT]]/usr/lib"
> +// CHECK-LD32-NOT: "-lc++"
>  // CHECK-LD32: "-lc"
>
>  // Check powerpc64-ibm-aix7.1.0.0, 64-bit.
> @@ -31,6 +32,7 @@
>  // CHECK-LD64: "-bpT:0x1" "-bpD:0x11000"
>  // CHECK-LD64: "[[SYSROOT]]/usr/lib{{/|}}crt0_64.o"
>  // CHECK-LD64: "-L[[SYSROOT]]/usr/lib"
> +// CHECK-LD64-NOT: "-lc++"
>  // CHECK-LD64: "-lc"
>
>  // Check powerpc-ibm-aix7.1.0.0, 32-bit. Enable POSIX thread support.
> @@ -48,6 +50,7 @@
>  // CHECK-LD32-PTHREAD: "-bpT:0x1000" "-bpD:0x2000"
>  // CHECK-LD32-PTHREAD: "[[SYSROOT]]/usr/lib{{/|}}crt0.o"
>  // CHECK-LD32-PTHREAD: "-L[[SYSROOT]]/usr/lib"
> +// CHECK-LD32-PTHREAD-NOT: "-lc++"
>  // CHECK-LD32-PTHREAD: "-lpthreads"
>  // CHECK-LD32-PTHREAD: "-lc"
>
> @@ -66,6 +69,7 @@
>  // CHECK-LD64-PTHREAD: "-bpT:0x1" "-bpD:0x11000"
>  // CHECK-LD64-PTHREAD: "[[SYSROOT]]/usr/lib{{/|}}crt0_64.o"
>  // CHECK-LD64-PTHREAD:

[PATCH] D85613: [clang] Look through bindings when checking whether a default argument references a local entity.

2020-08-10 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 284364.
riccibruno marked 2 inline comments as done.
riccibruno edited the summary of this revision.
riccibruno added a comment.

Refer to the binding in the diagnostic.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85613

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp

Index: clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp
===
--- clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp
+++ clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp
@@ -1,5 +1,20 @@
 // RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
 
+namespace std {
+using size_t = decltype(sizeof(int));
+template  struct tuple_size;
+template  struct tuple_element;
+} // namespace std
+using size_t = std::size_t;
+
+struct E {};
+template  int get(E);
+
+namespace std {
+template <> struct tuple_size { static constexpr size_t value = 2; };
+template  struct tuple_element { using type = int; };
+}; // namespace std
+
 void h() {
   int i1 = 0;
   extern void h1(int x = i1);
@@ -22,10 +37,21 @@
   };
 
   extern void h6(int = i5);
-  // expected-error-re@-1 {{default argument references local variable '(unnamed variable of type (anonymous union at {{.*}}:20:3))' of enclosing function}}
+  // expected-error-re@-1 {{default argument references local variable '(unnamed variable of type (anonymous union at {{.*}}:35:3))' of enclosing function}}
+
+  struct S {
+int i, j;
+  };
+  auto [x, y] = S();
+
+  extern void h7(int = x); // expected-error {{default argument references local binding 'x'}}
 
-  struct S { int i; };
-  auto [x] = S();
+  auto [z, w] = E();
+  extern void h8a(int = sizeof(z)); // ok
+  extern void h8b(int = w); // expected-error {{default argument references local binding 'w'}}
 
-  extern void h7(int = x); // FIXME: reject
+  extern auto get_array()->int(&)[2];
+  auto [a0, a1] = get_array();
+  extern void h9a(int = sizeof(a0));
+  extern void h9b(int = a1); // expected-error {{default argument references local binding 'a1'}}
 }
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -86,6 +86,22 @@
 /// argument expression.
 bool CheckDefaultArgumentVisitor::VisitDeclRefExpr(const DeclRefExpr *DRE) {
   const NamedDecl *Decl = DRE->getDecl();
+
+  auto CheckAndDiagnoseLocalEntity = [&](const VarDecl *VD, unsigned DiagID,
+ const auto &... DiagArgs) -> bool {
+if (VD->isLocalVarDecl() && !DRE->isNonOdrUse()) {
+  auto DB = S.Diag(DRE->getBeginLoc(), DiagID);
+  // FIXME: Replace with a fold once we can use C++17.
+  int dummy[] = {(DB << DiagArgs, 0)...};
+  (void)dummy;
+
+  DB << DefaultArg->getSourceRange();
+  return true;
+}
+
+return false;
+  };
+
   if (const auto *Param = dyn_cast(Decl)) {
 // C++ [dcl.fct.default]p9:
 //   [...] parameters of a function shall not be used in default
@@ -111,10 +127,28 @@
 // C++20 [dcl.fct.default]p7 (DR as part of P0588R1, see also CWG 2346):
 //   Note: A local variable cannot be odr-used (6.3) in a default argument.
 //
-if (VDecl->isLocalVarDecl() && !DRE->isNonOdrUse())
-  return S.Diag(DRE->getBeginLoc(),
-diag::err_param_default_argument_references_local)
- << VDecl << DefaultArg->getSourceRange();
+if (CheckAndDiagnoseLocalEntity(
+VDecl, diag::err_param_default_argument_references_local,
+/*variable*/ 0, VDecl))
+  return true;
+
+  } else if (const auto *Binding = dyn_cast(Decl)) {
+// C++20 [basic.pre]p7:
+//   A local entity is [...] a structured binding whose corresponding
+//   variable is such an entity [...]
+//
+// C++20 [basic.def.odr]p9:
+//   A local entity (6.1) is odr-usable in a declarative region if [...]
+//
+// Note that this was not entirely clear in C++17 since [dcl.fct.default]p7
+// only prohibited local variables (a structured binding declaration
+// introduces identifiers as names).
+//
+const auto *VD = cast_or_null(Binding->getDecomposedDecl());
+if (VD && CheckAndDiagnoseLocalEntity(
+  VD, diag::err_param_default_argument_references_local,
+  /*binding*/ 1, Binding))
+  return true;
   }
 
   return false;
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3988,7 +3988,8 @@
 def err_param_default_argument_references_param : Error<
   "d

[PATCH] D84136: [clang] Fix visitation of ConceptSpecializationExpr in constrained-parameter

2020-08-10 Thread Haojian Wu via Phabricator via cfe-commits
hokein added inline comments.



Comment at: clang/include/clang/AST/RecursiveASTVisitor.h:1843
+  if (const auto *TC = D->getTypeConstraint()) {
+TRY_TO(TraverseStmt(TC->getImmediatelyDeclaredConstraint()));
 TRY_TO(TraverseConceptReference(*TC));

nridge wrote:
> hokein wrote:
> > nridge wrote:
> > > hokein wrote:
> > > > Looks like we may visit some nodes in `ConceptReference` twice:
> > > > -  getImmediatelyDeclaredConstraint returns a 
> > > > `ConceptSpecializationExpr` (most cases?) which is a subclass of 
> > > > `ConceptReference`;
> > > > - `TraverseStmt(ConceptSpecializationExpr*)` will dispatch to 
> > > > `TraverseConceptSpecializationExpr` which invokes 
> > > > `TraverseConceptReference` (see Line 2719);
> > > > 
> > > > 
> > > > It is sad that we don't have enough test coverage, could you write some 
> > > > tests in `clang/unittests/Tooling/RecursiveASTVisitorTests/`?
> > > It is true that there will be two calls to `TraverseConceptReference()`. 
> > > However, they are called on two different `ConceptReference` objects:
> > > 
> > >   * the call in `TraverseConceptSpecializationExpr` will visit the base 
> > > subobject of the `ConceptSpecializationExpr` (which inherits from 
> > > `ConceptReference`)
> > >   * the call in `TraverseTemplateTypeParmDecl` will visit the base 
> > > subobject of the `TypeConstraint` (which also inherits from 
> > > `ConceptReference`).
> > > 
> > > So, I think this is fine -- there are two distinct `ConceptReference` 
> > > objects in the AST, and with this patch we visit both of them.
> > I understand that they are two different `ConceptReference` objects, but 
> > they have members (`FoundDecl`, `ArgsAsWritten`) that may refer to the same 
> > AST nodes.
> > 
> > ```
> > template 
> > concept binary_concept = true;
> > struct Foo {};
> > 
> > template T> // the template argument Foo will be 
> > visited twice.
> > void k2();
> > ```
> > 
> > I'm not sure what's is the right approach here, I can see two options:
> > 
> > - traverse TC + immediately-declared-constraint expr, this seem to cause 
> > some ast nodes visited twice (maybe not a big deal?)
> > - just traverse immediately-declared-constraint expr, this seems not 
> > breaking any tests, but the immediately-declared-constraint expr could be 
> > nullptr (e.g. broken code, missing required template arguments); or the 
> > immediately-declared-constraint expr could be a `CXXFoldExpr`, which will 
> > make some members in `ConceptReference` not be visited;
> > 
> > @rsmith, do you have any idea about this?
> > 
> From clangd's point of view, it would be sufficient to visit the 
> immediately-declared-constraint-expr without visiting any of its descendants. 
> However, I'm not sure how to accomplish this using `RecursiveASTVisitor`. (I 
> think I'd want to call 
> `WalkUpFromXXX(TC->getImmediatelyDeclaredConstraint())`, where `XXX` is the 
> dynamic type of the immediately-delcared-constraint, but I don't know how to 
> dispatch to that dynamic type; `RecursiveASTVisitor` seems to be designed to 
> do the dispatch on `Traverse` calls, not `WalkUpFrom` calls).
Thinking more about this.

I'm aligned on the idea of only traversing the immediately declared constraint 
since the TypeContraint is a wrapper of it. The regression is that we'd not 
perform traversal if the immediately declared constraint is nullptr (this just 
happens for broken code). 

Fix ideas:
- build a recovery expression if we can't not build a immediately declared 
constraint due to the missing required template arguments etc;
- still traverse the TC if immediately declared constraint is nullptr;




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84136

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


[PATCH] D85532: Correctly set CompilingPCH in PrecompilePreambleAction.

2020-08-10 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz added inline comments.



Comment at: clang/unittests/Frontend/ASTUnitTest.cpp:146
+  auto File = AU->getFileManager().getFileRef("Textual.h", false, false);
+  assert(File);
+  // Verify that we do not crash here.

adamcz wrote:
> kadircet wrote:
> > ASSERT_TRUE again
> You can 't ASSERT_TRUE() on llvm::Expected, since operator bool() is not 
> const. No idea why, but that's why it's assert()
Nevermind, I do know why - because it changes the "checked" status, that makes 
sense. I guess we could make that mutable, but that seems out of scope for this 
change.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85532

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


[PATCH] D85613: [clang] Look through bindings when checking whether a default argument references a local entity.

2020-08-10 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added inline comments.



Comment at: clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p7.cpp:51
+  extern void h8a(int = sizeof(z)); // ok
+  extern void h8b(int = w); // expected-error {{default argument 
references local variable 'w'}}
 

rsmith wrote:
> The diagnostic in this case is inconsistent with the non-tuple-like cases. I 
> think this diagnostic is better; we should use the original `Decl` when 
> producing the diagnostic, not the decomposed variable.
Right, let's just refer to the binding in all cases.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85613

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


Re: [PATCH] D80791: [AArch64] Generate .note.gnu.property based on module flags.

2020-08-10 Thread Szabolcs Nagy via cfe-commits
The 08/10/2020 10:03, Momchil Velikov via Phabricator wrote:
> chill added a comment.
> 
> In D80791#2196598 , @nsz wrote:
> 
> > the assumption is that the intended branch protection is implied via 
> > cmdline flags for the tu and function attributes are only used in source 
> > code for some hack.
> 
> I don't share this assumption. I find it just as valid to control the PAC/BTI 
> with things like:
> 
>   #ifdef ENABLE_BTI
>   #define BTI_FUNC __attribute__((target("branch-protection=bti")))
>   #else
>   #define BTI_FUNC
>   
>   BTI_FUNC void foo() { ...
>   BTI_FUNC int bar() { ...
> 
> without using any command-line option other than `-DENABLE_BTI=1`.
> 

i think that cannot work.

the implementation is free to inject arbitrary code into
user code so if the user does not tell the implementation
that it wants the entire tu to be bti safe then non-bti
code can end up in there. (e.g. ctor of an instrumentation
that is not realated to any particular function with the
bti marking)

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

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


[clang] c7b683c - [PGO][CUDA][HIP] Skip generating profile on the device stub and wrong-side functions.

2020-08-10 Thread Michael Liao via cfe-commits
Author: Michael Liao
Date: 2020-08-10T11:01:46-04:00
New Revision: c7b683c126b849dab5c81e7deecfc1e61f8563a0

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

LOG: [PGO][CUDA][HIP] Skip generating profile on the device stub and wrong-side 
functions.

- Skip generating profile data on `__global__` function in the host
  compilation. It's a host-side stub function only and don't have
  profile instrumentation generated on the real function body. The extra
  profile data results in the malformed instrumentation profile data.
- Skip generating region mapping on functions in the wrong-side, i.e.,
  + For the device compilation, skip host-only functions; and,
  + For the host compilation, skip device-only functions (including
`__global__` functions.)
- As the device-side profiling is not ready yet, only host-side profile
  code generation is checked.

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

Added: 
clang/test/CodeGenCUDA/profile-coverage-mapping.cu

Modified: 
clang/lib/CodeGen/CodeGenPGO.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CodeGenPGO.cpp 
b/clang/lib/CodeGen/CodeGenPGO.cpp
index e810f608ab78..be3c50b99f30 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -773,6 +773,11 @@ void CodeGenPGO::assignRegionCounters(GlobalDecl GD, 
llvm::Function *Fn) {
   if (!D->hasBody())
 return;
 
+  // Skip CUDA/HIP kernel launch stub functions.
+  if (CGM.getLangOpts().CUDA && !CGM.getLangOpts().CUDAIsDevice &&
+  D->hasAttr())
+return;
+
   bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
   if (!InstrumentRegions && !PGOReader)
@@ -831,6 +836,18 @@ bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) {
   if (!D->getBody())
 return true;
 
+  // Skip host-only functions in the CUDA device compilation and device-only
+  // functions in the host compilation. Just roughly filter them out based on
+  // the function attributes. If there are effectively host-only or device-only
+  // ones, their coverage mapping may still be generated.
+  if (CGM.getLangOpts().CUDA &&
+  ((CGM.getLangOpts().CUDAIsDevice && !D->hasAttr() &&
+!D->hasAttr()) ||
+   (!CGM.getLangOpts().CUDAIsDevice &&
+(D->hasAttr() ||
+ (!D->hasAttr() && D->hasAttr())
+return true;
+
   // Don't map the functions in system headers.
   const auto &SM = CGM.getContext().getSourceManager();
   auto Loc = D->getBody()->getBeginLoc();

diff  --git a/clang/test/CodeGenCUDA/profile-coverage-mapping.cu 
b/clang/test/CodeGenCUDA/profile-coverage-mapping.cu
new file mode 100644
index ..5eae6f10e0ea
--- /dev/null
+++ b/clang/test/CodeGenCUDA/profile-coverage-mapping.cu
@@ -0,0 +1,20 @@
+// RUN: echo "GPU binary would be here" > %t
+// RUN: %clang_cc1 -fprofile-instrument=clang -triple x86_64-linux-gnu 
-target-sdk-version=8.0 -fcuda-include-gpubinary %t -emit-llvm -o - %s | 
FileCheck --check-prefix=PGOGEN %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -triple 
x86_64-linux-gnu -target-sdk-version=8.0 -fcuda-include-gpubinary %t -emit-llvm 
-o - %s | FileCheck --check-prefix=COVMAP %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping 
-dump-coverage-mapping -triple x86_64-linux-gnu -target-sdk-version=8.0 
-fcuda-include-gpubinary %t -emit-llvm-only -o - %s | FileCheck 
--check-prefix=MAPPING %s
+
+#include "Inputs/cuda.h"
+
+// PGOGEN-NOT: @__profn_{{.*kernel.*}} =
+// COVMAP-COUNT-2: section "__llvm_covfun", comdat
+// COVMAP-NOT: section "__llvm_covfun", comdat
+// MAPPING-NOT: {{.*dfn.*}}:
+// MAPPING-NOT: {{.*kernel.*}}:
+
+__device__ void dfn(int i) {}
+
+__global__ void kernel(int i) { dfn(i); }
+
+void host(void) {
+  kernel<<<1, 1>>>(1);
+}



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


[PATCH] D85276: [PGO][CUDA][HIP] Skip generating profile on the device stub and wrong-side functions.

2020-08-10 Thread Michael Liao 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 rGc7b683c126b8: [PGO][CUDA][HIP] Skip generating profile on 
the device stub and wrong-side… (authored by hliao).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85276

Files:
  clang/lib/CodeGen/CodeGenPGO.cpp
  clang/test/CodeGenCUDA/profile-coverage-mapping.cu


Index: clang/test/CodeGenCUDA/profile-coverage-mapping.cu
===
--- /dev/null
+++ clang/test/CodeGenCUDA/profile-coverage-mapping.cu
@@ -0,0 +1,20 @@
+// RUN: echo "GPU binary would be here" > %t
+// RUN: %clang_cc1 -fprofile-instrument=clang -triple x86_64-linux-gnu 
-target-sdk-version=8.0 -fcuda-include-gpubinary %t -emit-llvm -o - %s | 
FileCheck --check-prefix=PGOGEN %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -triple 
x86_64-linux-gnu -target-sdk-version=8.0 -fcuda-include-gpubinary %t -emit-llvm 
-o - %s | FileCheck --check-prefix=COVMAP %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping 
-dump-coverage-mapping -triple x86_64-linux-gnu -target-sdk-version=8.0 
-fcuda-include-gpubinary %t -emit-llvm-only -o - %s | FileCheck 
--check-prefix=MAPPING %s
+
+#include "Inputs/cuda.h"
+
+// PGOGEN-NOT: @__profn_{{.*kernel.*}} =
+// COVMAP-COUNT-2: section "__llvm_covfun", comdat
+// COVMAP-NOT: section "__llvm_covfun", comdat
+// MAPPING-NOT: {{.*dfn.*}}:
+// MAPPING-NOT: {{.*kernel.*}}:
+
+__device__ void dfn(int i) {}
+
+__global__ void kernel(int i) { dfn(i); }
+
+void host(void) {
+  kernel<<<1, 1>>>(1);
+}
Index: clang/lib/CodeGen/CodeGenPGO.cpp
===
--- clang/lib/CodeGen/CodeGenPGO.cpp
+++ clang/lib/CodeGen/CodeGenPGO.cpp
@@ -773,6 +773,11 @@
   if (!D->hasBody())
 return;
 
+  // Skip CUDA/HIP kernel launch stub functions.
+  if (CGM.getLangOpts().CUDA && !CGM.getLangOpts().CUDAIsDevice &&
+  D->hasAttr())
+return;
+
   bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
   if (!InstrumentRegions && !PGOReader)
@@ -831,6 +836,18 @@
   if (!D->getBody())
 return true;
 
+  // Skip host-only functions in the CUDA device compilation and device-only
+  // functions in the host compilation. Just roughly filter them out based on
+  // the function attributes. If there are effectively host-only or device-only
+  // ones, their coverage mapping may still be generated.
+  if (CGM.getLangOpts().CUDA &&
+  ((CGM.getLangOpts().CUDAIsDevice && !D->hasAttr() &&
+!D->hasAttr()) ||
+   (!CGM.getLangOpts().CUDAIsDevice &&
+(D->hasAttr() ||
+ (!D->hasAttr() && D->hasAttr())
+return true;
+
   // Don't map the functions in system headers.
   const auto &SM = CGM.getContext().getSourceManager();
   auto Loc = D->getBody()->getBeginLoc();


Index: clang/test/CodeGenCUDA/profile-coverage-mapping.cu
===
--- /dev/null
+++ clang/test/CodeGenCUDA/profile-coverage-mapping.cu
@@ -0,0 +1,20 @@
+// RUN: echo "GPU binary would be here" > %t
+// RUN: %clang_cc1 -fprofile-instrument=clang -triple x86_64-linux-gnu -target-sdk-version=8.0 -fcuda-include-gpubinary %t -emit-llvm -o - %s | FileCheck --check-prefix=PGOGEN %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -triple x86_64-linux-gnu -target-sdk-version=8.0 -fcuda-include-gpubinary %t -emit-llvm -o - %s | FileCheck --check-prefix=COVMAP %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -triple x86_64-linux-gnu -target-sdk-version=8.0 -fcuda-include-gpubinary %t -emit-llvm-only -o - %s | FileCheck --check-prefix=MAPPING %s
+
+#include "Inputs/cuda.h"
+
+// PGOGEN-NOT: @__profn_{{.*kernel.*}} =
+// COVMAP-COUNT-2: section "__llvm_covfun", comdat
+// COVMAP-NOT: section "__llvm_covfun", comdat
+// MAPPING-NOT: {{.*dfn.*}}:
+// MAPPING-NOT: {{.*kernel.*}}:
+
+__device__ void dfn(int i) {}
+
+__global__ void kernel(int i) { dfn(i); }
+
+void host(void) {
+  kernel<<<1, 1>>>(1);
+}
Index: clang/lib/CodeGen/CodeGenPGO.cpp
===
--- clang/lib/CodeGen/CodeGenPGO.cpp
+++ clang/lib/CodeGen/CodeGenPGO.cpp
@@ -773,6 +773,11 @@
   if (!D->hasBody())
 return;
 
+  // Skip CUDA/HIP kernel launch stub functions.
+  if (CGM.getLangOpts().CUDA && !CGM.getLangOpts().CUDAIsDevice &&
+  D->hasAttr())
+return;
+
   bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr();
   llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
   if (!InstrumentRegions && !PGOReader)
@@ -831,6 +836,18 @@
   if (!D->getBody())
 return true;
 
+  // Skip host-only functions in the CUDA device compilation and d

[PATCH] D85276: [PGO][CUDA][HIP] Skip generating profile on the device stub and wrong-side functions.

2020-08-10 Thread Michael Liao via Phabricator via cfe-commits
hliao added inline comments.



Comment at: clang/lib/CodeGen/CodeGenPGO.cpp:839-840
 
+  // Skip host-only functions in the CUDA device compilation and device-only
+  // functions in the host compilation.
+  if (CGM.getLangOpts().CUDA &&

tra wrote:
> hliao wrote:
> > tra wrote:
> > > hliao wrote:
> > > > tra wrote:
> > > > > We will still have around some functions that may never be used on 
> > > > > the host side (HD functions referenced from device code only).  I'm 
> > > > > not sure if that's a problem for profiling, though. I wonder if we 
> > > > > can somehow tie `skipRegionMappingForDecl` to whether we've actually 
> > > > > codegen'ed the function. 
> > > > Skipping wrong-side functions here just makes the report not confusing 
> > > > as these functions are not emitted at all and are supposed never 
> > > > running on the host/device side. If we still create the mapping for 
> > > > them, e.g., we may report they have 0 runs instead of reporting nothing 
> > > > (just like comments between function.) That looks a little bit 
> > > > confusing.
> > > > It seems the current PGO adds everything for coverage mapping and late 
> > > > prune them based on checks here. Just try to follow that logic to skip 
> > > > wrong-side functions. If we need to revise the original logic and 
> > > > generate coverage mapping for emitted functions only, the change here 
> > > > is unnecessary.
> > > I'd add a comment here that this 'filter' is just a rough best-effort 
> > > approximation that still allows some effectively device-only Decls 
> > > through.
> > > The output should still be correct, even though the functions will never 
> > > be used. Maybe add a TODO to deal with it if/when we know if the Decl was 
> > > codegen'ed.
> > > 
> > Add that comment. But, I tend to not deal that "effectively" 
> > host-only/device-only ones as that should be developers' responsibility to 
> > handle them. The additional zero coverage mapping may be useful as well. If 
> > a function is really device-only but is attributed with HD, the 0 coverage 
> > may help developers correcting them.
> It will be rather noisy in practice. A lot of code has either has been 
> written for NVCC or has to compile with it. NVCC does not have target 
> overloads, so sticking HD everywhere  is pretty much the only practical way 
> to do it in complicated enough C++ code.  Anything that uses Eigen or Thrust 
> will have tons of HD functions that are actually used only on one side. 
> 
Most HD interfaces in Eigen are designed to be used in both CPU and GPU. For 
GPU only ones, they are marked with `__device__` only. Thrust has a similar 
situation.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85276

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


[PATCH] D72705: [analyzer] Added new checker 'alpha.unix.ErrorReturn'.

2020-08-10 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 284375.
balazske marked an inline comment as done.
balazske added a comment.

- Renames.
- Changed behavior if function call is compared to returned value.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72705

Files:
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
  clang/lib/StaticAnalyzer/Checkers/ErrorReturnChecker.cpp
  clang/test/Analysis/Inputs/system-header-simulator.h
  clang/test/Analysis/error-return.c

Index: clang/test/Analysis/error-return.c
===
--- /dev/null
+++ clang/test/Analysis/error-return.c
@@ -0,0 +1,189 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.ErrorReturn -verify %s
+
+#include "Inputs/system-header-simulator.h"
+
+FILE *file();
+
+void test_EOFOrNeg_LT_Good() {
+  if (fputs("str", file()) < 0) {
+  }
+}
+
+void test_EOFOrNeg_LT_Bad() {
+  if (fputs("str", file()) < -1) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_GT_Good() {
+  if (fputs("str", file()) > -1) {
+  }
+}
+
+void test_EOFOrNeg_GT_Bad() {
+  if (fputs("str", file()) > 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_LE_Good() {
+  if (fputs("str", file()) <= -1) {
+  }
+}
+
+void test_EOFOrNeg_LE_Bad() {
+  if (fputs("str", file()) <= 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_GE_Good() {
+  if (fputs("str", file()) >= 0) {
+  }
+}
+
+void test_EOFOrNeg_GE_Bad() {
+  if (fputs("str", file()) >= -1) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_EQ_Good() {
+  if (fputs("str", file()) == -1) {
+  }
+}
+
+void test_EOFOrNeg_EQ_Bad() {
+  if (fputs("str", file()) == 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_NE_Good() {
+  if (fputs("str", file()) != -1) {
+  }
+}
+
+void test_EOFOrNeg_NE_Bad() {
+  if (fputs("str", file()) != 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_EQ_BadVal() {
+  if (fputs("str", file()) == -2) { // expected-warning{{Use of return value that was not checked}}
+  }
+  if (fputs("str", file()) == 1) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_VarAssign() {
+  int X = fputs("str", file());
+  if (X != 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_VarAssignInCond() {
+  int X;
+  if ((X = fputs("str", file())) != 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_VarAssign1() {
+  int X = fputs("str", file());
+  int Y = X;
+  if (Y != 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void badcheck(int X) {
+  if (X == 0) { } // expected-warning{{Use of return value that was not checked}}
+}
+
+void test_EOFOrNeg_Call() {
+  int X = fputs("str", file());
+  badcheck(X);
+}
+
+void test_EOFOrNeg_Syscall() {
+  int X = fputs("str", file());
+  fakeSystemHeaderCallIntVal(X); // expected-warning{{Use of return value that was not checked}}
+  fakeSystemHeaderCallIntVal(fputs("str", file())); // expected-warning{{Use of return value that was not checked}}
+}
+
+void test_EOFOrNeg_Use_LNot() {
+  int X = fputs("str", file());
+  if (!X) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_Use_Add() {
+  int X = fputs("str", file());
+  int Y = X + 1; // expected-warning{{Use of return value that was not checked}}
+}
+
+void test_EOFOrNeg_If() {
+  int X = fputs("str", file());
+  if (X) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_IfCond() {
+  if (fputs("str", file())) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_ForInit() {
+  for (fputs("str", file());;) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_ForCond() {
+  for (; fputs("str", file());) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_ForInc() {
+  for (;; fputs("str", file())) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_DoCond() {
+  do {
+  } while (fputs("str", file())); // expected-warning{{Use of return value that was not checked}}
+}
+
+void test_EOFOrNeg_WhileCond() {
+  while (fputs("str", file())) { // expected-warning{{Use of return value that was not checked}}
+  };
+}
+
+void unknown1(int);
+
+void test_EOFOrNeg_EscapeCall() {
+  int X = fputs("str", file());
+  unknown1(X);
+  int Y = X + 1;
+}
+
+int GlobalInt;
+
+void test_EOFOrNeg_EscapeGlobalAssign() {
+  GlobalInt = fputs("str", file());
+  

[PATCH] D80525: [clangd] Fix crash-bug in preamble indexing when using modules.

2020-08-10 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz updated this revision to Diff 284376.
adamcz marked 2 inline comments as done.
adamcz added a comment.

var rename, comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D80525

Files:
  clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
  clang-tools-extra/clangd/unittests/TestFS.h
  clang-tools-extra/clangd/unittests/TestTU.cpp
  clang-tools-extra/clangd/unittests/TestTU.h
  clang/lib/Index/IndexingAction.cpp

Index: clang/lib/Index/IndexingAction.cpp
===
--- clang/lib/Index/IndexingAction.cpp
+++ clang/lib/Index/IndexingAction.cpp
@@ -165,11 +165,20 @@
 static void indexPreprocessorMacros(const Preprocessor &PP,
 IndexDataConsumer &DataConsumer) {
   for (const auto &M : PP.macros())
-if (MacroDirective *MD = M.second.getLatest())
+if (MacroDirective *MD = M.second.getLatest()) {
+  auto *MI = MD->getMacroInfo();
+  // When using modules, it may happen that we find #undef of a macro that
+  // was defined in another module. In such case, MI may be nullptr, since
+  // we only look for macro definitions in the current TU. In that case,
+  // there is nothing to index.
+  if (!MI)
+continue;
+
   DataConsumer.handleMacroOccurrence(
   M.first, MD->getMacroInfo(),
   static_cast(index::SymbolRole::Definition),
   MD->getLocation());
+}
 }
 
 void index::indexASTUnit(ASTUnit &Unit, IndexDataConsumer &DataConsumer,
Index: clang-tools-extra/clangd/unittests/TestTU.h
===
--- clang-tools-extra/clangd/unittests/TestTU.h
+++ clang-tools-extra/clangd/unittests/TestTU.h
@@ -66,6 +66,16 @@
   // Simulate a header guard of the header (using an #import directive).
   bool ImplicitHeaderGuard = true;
 
+  // Whether to use overlay the TestFS over the real filesystem. This is
+  // required for use of implicit modules.where the module file is written to
+  // disk and later read back.
+  // FIXME: Change the way reading/writing modules work to allow us to keep them
+  // in memory across multiple clang invocations, at least in tests, to
+  // eliminate the need for real file system here.
+  // Please avoid using this for things other than implicit modules. The plan is
+  // to eliminate this option some day.
+  bool OverlayRealFileSystemForModules = false;
+
   // By default, build() will report Error diagnostics as GTest errors.
   // Suppress this behavior by adding an 'error-ok' comment to the code.
   ParsedAST build() const;
Index: clang-tools-extra/clangd/unittests/TestTU.cpp
===
--- clang-tools-extra/clangd/unittests/TestTU.cpp
+++ clang-tools-extra/clangd/unittests/TestTU.cpp
@@ -54,6 +54,8 @@
   Inputs.CompileCommand.Filename = FullFilename;
   Inputs.CompileCommand.Directory = testRoot();
   Inputs.Contents = Code;
+  if (OverlayRealFileSystemForModules)
+FS.OverlayRealFileSystemForModules = true;
   Inputs.TFS = &FS;
   Inputs.Opts = ParseOptions();
   Inputs.Opts.BuildRecoveryAST = true;
Index: clang-tools-extra/clangd/unittests/TestFS.h
===
--- clang-tools-extra/clangd/unittests/TestFS.h
+++ clang-tools-extra/clangd/unittests/TestFS.h
@@ -34,12 +34,21 @@
 class MockFS : public ThreadsafeFS {
 public:
   IntrusiveRefCntPtr viewImpl() const override {
-return buildTestFS(Files, Timestamps);
+auto MemFS = buildTestFS(Files, Timestamps);
+if (!OverlayRealFileSystemForModules)
+  return MemFS;
+llvm::IntrusiveRefCntPtr OverlayFileSystem =
+new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem());
+OverlayFileSystem->pushOverlay(MemFS);
+return OverlayFileSystem;
   }
 
   // If relative paths are used, they are resolved with testPath().
   llvm::StringMap Files;
   llvm::StringMap Timestamps;
+  // If true, real file system will be used as fallback for the in-memory one.
+  // This is useful for testing module support.
+  bool OverlayRealFileSystemForModules = false;
 };
 
 // A Compilation database that returns a fixed set of compile flags.
Index: clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
===
--- clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
+++ clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
@@ -1520,6 +1520,31 @@
   EXPECT_THAT(Symbols,
   UnorderedElementsAre(AllOf(QName("X"), ForCodeCompletion(true;
 }
+
+// Regression test for a crash-bug we used to have.
+TEST_F(SymbolCollectorTest, UndefOfModuleMacro) {
+  auto TU = TestTU::withCode(R"cpp(#include "bar.h")cpp");
+  TU.AdditionalFiles["bar.h"] = R"cpp(
+#include "foo.h"
+#undef X
+)cpp";
+  TU.AdditionalFiles["foo.h"

[PATCH] D80525: [clangd] Fix crash-bug in preamble indexing when using modules.

2020-08-10 Thread Adam Czachorowski via Phabricator via cfe-commits
adamcz added inline comments.



Comment at: clang-tools-extra/clangd/unittests/TestTU.h:71
+  // required for use of modules.
+  // FIXME: Intercept the write of implicitly build module to disk and update
+  // TestFS with that content to avoid using real file system in tests.

sammccall wrote:
> nit: I'm not sure the (V)FS should be involved at all in the final test setup.
> The way I see it, the module storage is basically a cache from (module name + 
> validity-stuff) ==> bytes, and *reads* could be abstracted just like writes.
> For tests this could just be an in-memory map of course, but I think even in 
> production we'd benefit a bit from not having to express this map through the 
> filesystem. (E.g the way it's versioned doesn't have much to do with the way 
> versioned filesystems are)
> 
> Only actionable thing for now is to maybe tweak this comment slightly, but 
> wanted to mention it.
Updated comment, is this better?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D80525

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


[PATCH] D85528: [analyzer] Fix cast evaluation on scoped enums in ExprEngine

2020-08-10 Thread Gábor Horváth via Phabricator via cfe-commits
xazax.hun added a comment.

In D85528#2205799 , @NoQ wrote:

> I expect at least one LIT test //without// `-analyzer-config 
> crosscheck-with-z3=true`

Agreed. I think the code snippet I proposed would be a great test to include 
with this revision.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85528

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


[PATCH] D85431: [analyzer] Implement a new checker ThreadPrimitivesChecker

2020-08-10 Thread Denys Petrov via Phabricator via cfe-commits
ASDenysPetrov updated this revision to Diff 284373.
ASDenysPetrov edited the summary of this revision.
ASDenysPetrov added a comment.

Added recursive_mutex support.

Please, look at a test file on TODOs. I want to cover those cases in the 
future. Could you advise me something on it?


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

https://reviews.llvm.org/D85431

Files:
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
  clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
  clang/lib/StaticAnalyzer/Checkers/ThreadPrimitivesChecker.cpp
  clang/test/Analysis/Checkers/ThreadPrimitivesChecker.cpp

Index: clang/test/Analysis/Checkers/ThreadPrimitivesChecker.cpp
===
--- /dev/null
+++ clang/test/Analysis/Checkers/ThreadPrimitivesChecker.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.ThreadPrimitives -verify %s
+
+namespace std {
+struct mutex {
+  void lock();
+  void unlock();
+};
+struct recursive_mutex {
+  void lock();
+  void unlock();
+};
+template 
+struct guard_lock {
+  T &t;
+  guard_lock(T &m) : t(m) {
+t.lock();
+  }
+  ~guard_lock() {
+t.unlock();
+  }
+};
+} // namespace std
+
+void correct_lock_unlock(std::mutex m) {
+  m.lock();
+  std::mutex *m2 = &m;
+  m2->unlock();
+}
+
+void correct_lock_unlock2(std::mutex m) {
+  m.lock();
+  std::mutex &m2 = m;
+  m2.unlock();
+}
+
+void correct_lock_unlock3(std::mutex m) {
+  m.lock();
+  m.unlock();
+}
+
+void correct_lock_unlock4(std::mutex m) {
+  std::guard_lock l(m);
+}
+
+void incorrect_lock_unlock(std::mutex m1, std::mutex m2, std::recursive_mutex rm1, std::recursive_mutex rm2) {
+  m1.lock();
+  m2.unlock(); // expected-warning{{unlock without lock}}
+  rm1.lock();
+  rm2.unlock(); // expected-warning{{unlock without lock}}
+}
+
+void lock_without_unlock(std::mutex m, bool b) {
+  m.lock();
+  if (b)
+m.unlock(); // TODO: Detect case when unlock is in one branch only.
+}
+
+// TODO: Detect lock without unlock at the end of the block.
+void lock_without_unlock(std::mutex m, std::recursive_mutex rm2) {
+  m.lock();
+  rm2.lock();
+}
+
+void unlock_without_lock(std::mutex m, std::recursive_mutex rm) {
+  m.unlock();  // expected-warning{{unlock without lock}}
+  rm.unlock(); // expected-warning{{unlock without lock}}
+}
+
+void twice_lock(std::mutex m, std::recursive_mutex rm) {
+  m.lock();
+  m.lock(); // expected-warning{{lock more than once}}
+
+  rm.lock();
+  rm.lock(); // OK
+}
+
+void twice_lock2(std::mutex m, std::recursive_mutex rm) {
+  while (true) {
+m.lock();  // expected-warning{{lock more than once}}
+rm.lock(); // OK
+  }
+}
Index: clang/lib/StaticAnalyzer/Checkers/ThreadPrimitivesChecker.cpp
===
--- /dev/null
+++ clang/lib/StaticAnalyzer/Checkers/ThreadPrimitivesChecker.cpp
@@ -0,0 +1,121 @@
+//=== ConversionChecker.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
+//
+//===--===//
+//
+// This checker finds STL thread primitives misuse.
+// - std::mutex::unlock without std::mutex::lock
+// - std::mutex::lock twice
+//
+//===--===//
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include 
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+
+enum FuncIdKind : uint8_t {
+  Undefined = 0,
+  Mutex_Lock,
+  Mutex_Unlock,
+  Recursive_Mutex_Lock,
+  Recursive_Mutex_Unlock,
+};
+
+static const std::pair FuncMapping[]{
+{Mutex_Lock, {{"std", "mutex", "lock"}, 0, 0}},
+{Mutex_Unlock, {{"std", "mutex", "unlock"}, 0, 0}},
+{Recursive_Mutex_Lock, {{"std", "recursive_mutex", "lock"}, 0, 0}},
+{Recursive_Mutex_Unlock, {{"std", "recursive_mutex", "unlock"}, 0, 0}},
+};
+
+class ThreadPrimitivesChecker : public Checker {
+public:
+  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
+
+private:
+  BugType BT{this, "STL thread primitives misuse", "std::mutex misuse"};
+
+  FuncIdKind FindMutexLockOrUnlock(const CallEvent &Call,
+   CheckerContext &C) const;
+  void reportBug(CheckerContext &C, const char Msg[]) const;
+};
+
+} // namespace
+
+REGISTER_SET_WITH_PROGRAMSTATE(LockedMutexes, SVal)
+
+FuncIdKind
+ThreadPrimitivesC

[PATCH] D85315: [AIX][Clang][Driver] Generate reference to the C++ library on the link step

2020-08-10 Thread Shuhong Liu via Phabricator via cfe-commits
ShuhongL closed this revision.
ShuhongL added a comment.

Landed by commit: rGb129c9d81aff8ece71eb29df1e5f31136a48c040 

(Sorry, I didn't properly align the tags in commit message and hence this 
revision was not automatically closed after landing to master. Will switch to 
Arc)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85315

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


[PATCH] D71726: Let clang atomic builtins fetch add/sub support floating point types

2020-08-10 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl added a comment.

ping


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

https://reviews.llvm.org/D71726

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


[PATCH] D85439: [SyntaxTree] Expand support for `NestedNameSpecifier`

2020-08-10 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas added a comment.

There are some refinements to do, to generate a complete syntax tree. Namely 
tag decltype-name-specifier and simple-template-specifier children with roles, 
to allow for accessors.




Comment at: clang/lib/Tooling/Syntax/BuildTree.cpp:838-842
+  // TODO: Build `SimpleTemplateNameSpecifier` children and implement
+  // accessors to them.
+  // Be aware, we cannot do that simply by calling `TraverseTypeLoc`,
+  // some `TypeLoc`s have inside them the previous name specifier and
+  // we want to treat them independently.

Let's generate the syntax tree for the nested-name-specifier:
```
T::template U::X::
```

`T` and `X` are just identifier-name-specifiers. They are easy.

`template U` however is a simple-template-name-specifier. 
```
simple-template-name-specifier :
  template_opt simple-template-id
```
We could generate it by traversing the corresponding semantic node. But this 
node is a `DependentTemplateSpecializationTypeLoc` and it covers `T::template 
U`. The traversal would then cover `T::` and thus generate a crash.

As such, we should treat simple-template-name-specifier in a less generic way.



Comment at: clang/lib/Tooling/Syntax/BuildTree.cpp:849-850
+  const auto TL = NNSLoc.getTypeLoc().castAs();
+  if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(TL))
+return nullptr;
+  auto *NS = new (allocator()) syntax::DecltypeNameSpecifier;

eduucaldas wrote:
> Since we are overriding the TraverseNestedNameSpecifierLoc that previously 
> fired TraverseTypeLoc we fire it when building a NameSpecifier.
As opposed to simple-template-name-specifier, we can here use a normal 
traversal to build the decltype-name-specifier because this specifier doesn't 
cross boundaries of name specifiers


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85439

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


[PATCH] D77062: [analyzer] Improve zero assumption in CStringChecke::assumeZero

2020-08-10 Thread Denys Petrov via Phabricator via cfe-commits
ASDenysPetrov added a comment.

@NoQ just one more ping. You accepted it and then I just revised it again. 
Could you, please, take a minute and look at it.
I'd close it with a great pleasure. It's been hanging too long.


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

https://reviews.llvm.org/D77062

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


[PATCH] D71767: [POC][SVE] Allow code generation for fixed length vectorised loops [Patch 2/2].

2020-08-10 Thread Paul Walker via Phabricator via cfe-commits
paulwalker-arm updated this revision to Diff 284380.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71767

Files:
  clang/lib/Driver/ToolChains/Clang.cpp
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
  llvm/lib/Target/AArch64/AArch64ISelLowering.h
  llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
  llvm/lib/Target/AArch64/SVEInstrFormats.td
  llvm/test/CodeGen/AArch64/sve-fixed-length-int-extends.ll

Index: llvm/test/CodeGen/AArch64/sve-fixed-length-int-extends.ll
===
--- /dev/null
+++ llvm/test/CodeGen/AArch64/sve-fixed-length-int-extends.ll
@@ -0,0 +1,373 @@
+; RUN: llc -aarch64-sve-vector-bits-min=128  -asm-verbose=0 < %s | FileCheck %s -check-prefix=NO_SVE
+; RUN: llc -aarch64-sve-vector-bits-min=256  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK
+; RUN: llc -aarch64-sve-vector-bits-min=384  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK
+; RUN: llc -aarch64-sve-vector-bits-min=512  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
+; RUN: llc -aarch64-sve-vector-bits-min=640  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
+; RUN: llc -aarch64-sve-vector-bits-min=768  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
+; RUN: llc -aarch64-sve-vector-bits-min=896  -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512
+; RUN: llc -aarch64-sve-vector-bits-min=1024 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
+; RUN: llc -aarch64-sve-vector-bits-min=1152 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
+; RUN: llc -aarch64-sve-vector-bits-min=1280 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
+; RUN: llc -aarch64-sve-vector-bits-min=1408 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
+; RUN: llc -aarch64-sve-vector-bits-min=1536 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
+; RUN: llc -aarch64-sve-vector-bits-min=1664 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
+; RUN: llc -aarch64-sve-vector-bits-min=1792 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
+; RUN: llc -aarch64-sve-vector-bits-min=1920 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024
+; RUN: llc -aarch64-sve-vector-bits-min=2048 -asm-verbose=0 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_512,VBITS_GE_1024,VBITS_GE_2048
+
+target triple = "aarch64-unknown-linux-gnu"
+
+; Don't use SVE when its registers are no bigger than NEON.
+; NO_SVE-NOT: z{0-9}
+
+;
+; sext i8 -> i16
+;
+
+define void @sext_v16i8_v16i16(<16 x i8> %a, <16 x i16>* %out) #0 {
+; CHECK-LABEL: sext_v16i8_v16i16:
+; CHECK: ptrue [[PG:p[0-9]+]].h, vl16
+; CHECK-NEXT: sunpklo [[A_HALFS:z[0-9]+]].h, z0.b
+; CHECK-NEXT: st1h { [[A_HALFS]].h }, [[PG]], [x0]
+; CHECK-NEXT: ret
+  %b = sext <16 x i8> %a to <16 x i16>
+  store <16 x i16>%b, <16 x i16>* %out
+  ret void
+}
+
+; NOTE: Extra 'add' is to prevent the extend being combined with the load.
+define void @sext_v32i8_v32i16(<32 x i8>* %in, <32 x i16>* %out) #0 {
+; CHECK-LABEL: sext_v32i8_v32i16:
+; VBITS_GE_512: add [[A_BYTES:z[0-9]+]].b, {{p[0-9]+}}/m, {{z[0-9]+}}.b, {{z[0-9]+}}.b
+; VBITS_GE_512-NEXT: sunpklo [[A_HALFS:z[0-9]+]].h, [[A_BYTES]].b
+; VBITS_GE_512-NEXT: ptrue [[PG:p[0-9]+]].h, vl32
+; VBITS_GE_512-NEXT: st1h { [[A_HALFS]].h }, [[PG]], [x1]
+; VBITS_GE_512-NEXT: ret
+  %a = load <32 x i8>, <32 x i8>* %in
+  %b = add <32 x i8> %a, %a
+  %c = sext <32 x i8> %b to <32 x i16>
+  store <32 x i16> %c, <32 x i16>* %out
+  ret void
+}
+
+define void @sext_v64i8_v64i16(<64 x i8>* %in, <64 x i16>* %out) #0 {
+; CHECK-LABEL: sext_v64i8_v64i16:
+; VBITS_GE_1024: add [[A_BYTES:z[0-9]+]].b, {{p[0-9]+}}/m, {{z[0-9]+}}.b, {{z[0-9]+}}.b
+; VBITS_GE_1024-NEXT: sunpklo [[A_HALFS:z[0-9]+]].h, [[A_BYTES]].b
+; VBITS_GE_1024-NEXT: ptrue [[PG:p[0-9]+]].h, vl64
+; VBITS_GE_1024-NEXT: st1h { [[A_HALFS]].h }, [[PG]], [x1]
+; VBITS_GE_1024-NEXT: ret
+  %a = load <64 x i8>, <64 x i8>* %in
+  %b = add <64 x i8> %a, %a
+  %c = sext <64 x i8> %b to <64 x i16>
+  store <64 x i16> %c, <64 x i16>* %out
+  ret void
+}
+
+define void @sext_v128i8_v128i16(<128 x i8>* %in, <128 x i16>* %out) #0 {
+; CHECK-LABEL: sext_v128i8_v128i16:
+; VBITS_GE_2048: add [[A_BYTES:z[0-9]+]].b, {{p[0-9]+}}/m, {{z[0-9]+}}.b, {{z[0-9]+}}.b
+; VBITS_GE_2048-NEXT: sunpklo [[A_HALFS:z[0-9]+]].h, [[A_BYTES]].b
+; VBITS_GE_2048-NEXT: ptrue [[PG:p[0-9]+]].h, vl128
+; VBITS_GE_2048-NEXT: st1h { [[A_HALFS]].h }, [[PG]], [x1]
+; VBITS_GE_2048-NEXT: ret
+  %a = load <128 x i8>, <128 x i8>* %in
+  %b = add <128 x i8> %a,

  1   2   3   >