[PATCH] D34275: [analyzer] Re-implemente current virtual calls checker in a path-sensitive way

2017-08-22 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added a comment.

Thanks, works now! Apart from the minor comment on the hanging header file in 
the tests, this looks good and i have no further nits :)

//*summons @dcoughlin to have a look at English in the warning messages*//




Comment at: test/Analysis/virtualcall.cpp:15-21
+#if PUREONLY
+   // expected-warning-re@-2 ^}}Call to pure virtual function during 
construction}}
+   // expected-note-re@-3 ^}}Call to pure virtual function during 
construction}}
+#else 
+   // expected-warning-re@-5 ^}}Call to virtual function during 
construction}}
+   // expected-note-re@-6 ^}}Call to virtual function during 
construction}}
 #endif

I think it might be worth it to highlight that the function is pure virtual 
even in non-pure-only mode (if you have time for that).



Comment at: test/Analysis/virtualcall.cpp:137-141
-#include "virtualcall.h"
+class Y {
+public:
+  virtual void foobar();
+  void fooY() {
+F f1;
+foobar(); 
+#if !PUREONLY
+   // expected-warning-re@-2 ^}}Call to virtual function during 
construction}}
+   // expected-note-re@-3 ^}}Call to virtual function during 
construction}}
+#endif
+  }
+  Y() { fooY(); }
+#if !PUREONLY
+   // expected-note-re@-2 ^}}This constructor of an object of type 'Y' 
has not returned when the virtual method was called}}
+   // expected-note-re@-3 ^}}Calling 'Y::fooY'}}
+#endif
+};
 
-#define AS_SYSTEM
-#include "virtualcall.h"
-#undef AS_SYSTEM

There used to be a test case in this header; we should restore the test or 
remove the file if it's no longer relevant.


https://reviews.llvm.org/D34275



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


[PATCH] D36989: [clang-diff] Refactor stop-after command-line flag

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes accepted this revision.
johannes added a comment.
This revision is now accepted and ready to land.

Looks good, thanks!
You can remove StopAfterTopDown from the ComparisonOptions struct definition

I have a second option stop-after option coming up but I will use another 
boolean for it, it is simpler this way.


https://reviews.llvm.org/D36989



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


[PATCH] D36989: [clang-diff] Refactor stop-after command-line flag

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes requested changes to this revision.
johannes added a comment.
This revision now requires changes to proceed.

Oh wait I get linker errors with BUILD_SHARED_LIBS=1

`undefined reference to ClangDiffCategory` in ASTDiff


https://reviews.llvm.org/D36989



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


r311433 - [clang-diff] Use the relative name for NamedDecl

2017-08-22 Thread Johannes Altmanninger via cfe-commits
Author: krobelus
Date: Tue Aug 22 01:56:26 2017
New Revision: 311433

URL: http://llvm.org/viewvc/llvm-project?rev=311433&view=rev
Log:
[clang-diff] Use the relative name for NamedDecl

Summary:
If a node referring to a name is within a class or namespace, do not use
the full qualified name, but strip the namespace prefix.

Reviewers: arphaman, bkramer

Subscribers: klimek

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

Modified:
cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h
cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp
cfe/trunk/test/Tooling/clang-diff-ast.cpp
cfe/trunk/test/Tooling/clang-diff-basic.cpp
cfe/trunk/test/Tooling/clang-diff-html.test
cfe/trunk/test/Tooling/clang-diff-topdown.cpp

Modified: cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h?rev=311433&r1=311432&r2=311433&view=diff
==
--- cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h (original)
+++ cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h Tue Aug 22 01:56:26 2017
@@ -68,10 +68,10 @@ private:
 class SyntaxTree {
 public:
   /// Constructs a tree from a translation unit.
-  SyntaxTree(const ASTContext &AST);
+  SyntaxTree(ASTContext &AST);
   /// Constructs a tree from any AST node.
   template 
-  SyntaxTree(T *Node, const ASTContext &AST)
+  SyntaxTree(T *Node, ASTContext &AST)
   : TreeImpl(llvm::make_unique(this, Node, AST)) {}
   SyntaxTree(SyntaxTree &&Other) = default;
   ~SyntaxTree();

Modified: cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp?rev=311433&r1=311432&r2=311433&view=diff
==
--- cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp (original)
+++ cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp Tue Aug 22 01:56:26 2017
@@ -111,24 +111,22 @@ private:
 /// Represents the AST of a TranslationUnit.
 class SyntaxTree::Impl {
 public:
-  /// Constructs a tree from the entire translation unit.
-  Impl(SyntaxTree *Parent, const ASTContext &AST);
   /// Constructs a tree from an AST node.
-  Impl(SyntaxTree *Parent, Decl *N, const ASTContext &AST);
-  Impl(SyntaxTree *Parent, Stmt *N, const ASTContext &AST);
+  Impl(SyntaxTree *Parent, Decl *N, ASTContext &AST);
+  Impl(SyntaxTree *Parent, Stmt *N, ASTContext &AST);
   template 
   Impl(SyntaxTree *Parent,
typename std::enable_if::value, T>::type *Node,
-   const ASTContext &AST)
+   ASTContext &AST)
   : Impl(Parent, dyn_cast(Node), AST) {}
   template 
   Impl(SyntaxTree *Parent,
typename std::enable_if::value, T>::type *Node,
-   const ASTContext &AST)
+   ASTContext &AST)
   : Impl(Parent, dyn_cast(Node), AST) {}
 
   SyntaxTree *Parent;
-  const ASTContext *
+  ASTContext *
   std::vector Leaves;
   // Maps preorder indices to postorder ones.
   std::vector PostorderIds;
@@ -147,6 +145,10 @@ public:
   bool isInSubtree(NodeId Id, NodeId SubtreeRoot) const;
   int findPositionInParent(NodeId Id, bool Shifted = false) const;
 
+  std::string getRelativeName(const NamedDecl *ND,
+  const DeclContext *Context) const;
+  std::string getRelativeName(const NamedDecl *ND) const;
+
   std::string getNodeValue(NodeId Id) const;
   std::string getNodeValue(const Node &Node) const;
   std::string getDeclValue(const Decl *D) const;
@@ -270,7 +272,7 @@ struct PreorderVisitor : public Recursiv
 };
 } // end anonymous namespace
 
-SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, const ASTContext &AST)
+SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, ASTContext &AST)
 : Parent(Parent), AST(AST) {
   NodeCountVisitor NodeCounter(*this);
   NodeCounter.TraverseDecl(N);
@@ -280,7 +282,7 @@ SyntaxTree::Impl::Impl(SyntaxTree *Paren
   initTree();
 }
 
-SyntaxTree::Impl::Impl(SyntaxTree *Parent, Stmt *N, const ASTContext &AST)
+SyntaxTree::Impl::Impl(SyntaxTree *Parent, Stmt *N, ASTContext &AST)
 : Parent(Parent), AST(AST) {
   NodeCountVisitor NodeCounter(*this);
   NodeCounter.TraverseStmt(N);
@@ -365,6 +367,46 @@ int SyntaxTree::Impl::findPositionInPare
   llvm_unreachable("Node not found in parent's children.");
 }
 
+// Returns the qualified name of ND. If it is subordinate to Context,
+// then the prefix of the latter is removed from the returned value.
+std::string
+SyntaxTree::Impl::getRelativeName(const NamedDecl *ND,
+  const DeclContext *Context) const {
+  std::string ContextPrefix;
+  if (auto *Namespace = dyn_cast(Context))
+ContextPrefix = Namespace->getQualifiedNameAsString();
+  else if (auto *Record = dyn_cast(Context))
+ContextPrefix = Record->getQualifiedNameAsString();
+  else if (AST.getLangOpts().CPlusPlus11)
+if (auto *Tag = dyn_cast(Context))
+  ContextPrefix = Tag->getQualifiedNameAsString();
+  

r311434 - [clang-diff] Fix getRelativeName

2017-08-22 Thread Johannes Altmanninger via cfe-commits
Author: krobelus
Date: Tue Aug 22 01:59:13 2017
New Revision: 311434

URL: http://llvm.org/viewvc/llvm-project?rev=311434&view=rev
Log:
[clang-diff] Fix getRelativeName

Handle the case when DeclContext is null.

Modified:
cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp

Modified: cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp?rev=311434&r1=311433&r2=311434&view=diff
==
--- cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp (original)
+++ cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp Tue Aug 22 01:59:13 2017
@@ -372,7 +372,10 @@ int SyntaxTree::Impl::findPositionInPare
 std::string
 SyntaxTree::Impl::getRelativeName(const NamedDecl *ND,
   const DeclContext *Context) const {
+  std::string Val = ND->getQualifiedNameAsString();
   std::string ContextPrefix;
+  if (!Context)
+return Val;
   if (auto *Namespace = dyn_cast(Context))
 ContextPrefix = Namespace->getQualifiedNameAsString();
   else if (auto *Record = dyn_cast(Context))
@@ -380,7 +383,6 @@ SyntaxTree::Impl::getRelativeName(const
   else if (AST.getLangOpts().CPlusPlus11)
 if (auto *Tag = dyn_cast(Context))
   ContextPrefix = Tag->getQualifiedNameAsString();
-  std::string Val = ND->getQualifiedNameAsString();
   // Strip the qualifier, if Val refers to somthing in the current scope.
   // But leave one leading ':' in place, so that we know that this is a
   // relative path.
@@ -404,7 +406,7 @@ static const DeclContext *getEnclosingDe
   return D->getDeclContext();
 S = P.get();
   }
-  llvm_unreachable("Could not find Decl ancestor.");
+  return nullptr;
 }
 
 std::string SyntaxTree::Impl::getNodeValue(NodeId Id) const {


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


[PATCH] D36685: [clang-diff] HTML diff navigation

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes updated this revision to Diff 112126.
johannes added a comment.

some refactoring


https://reviews.llvm.org/D36685

Files:
  tools/clang-diff/ClangDiff.cpp


Index: tools/clang-diff/ClangDiff.cpp
===
--- tools/clang-diff/ClangDiff.cpp
+++ tools/clang-diff/ClangDiff.cpp
@@ -139,34 +139,81 @@
 highlightStack = []
 function clearHighlight() {
   while (highlightStack.length) {
-let [l, r] = highlightStack.pop()
+var [l, r] = highlightStack.pop()
 document.getElementById(l).style.backgroundColor = 'white'
-document.getElementById(r).style.backgroundColor = 'white'
+if (r[1] != '-')
+  document.getElementById(r).style.backgroundColor = 'white'
   }
 }
 function highlight(event) {
-  id = event.target['id']
+  var id = event.target['id']
   doHighlight(id)
 }
 function doHighlight(id) {
   clearHighlight()
   source = document.getElementById(id)
   if (!source.attributes['tid'])
 return
-  tid = source.attributes['tid'].value
-  target = document.getElementById(tid)
-  if (!target || source.parentElement && 
source.parentElement.classList.contains('code'))
+  var mapped = source
+  while (mapped && mapped.parentElement && 
mapped.attributes['tid'].value.substr(1) === '-1')
+mapped = mapped.parentElement
+  var tid = null, target = null
+  if (mapped) {
+tid = mapped.attributes['tid'].value
+target = document.getElementById(tid)
+  }
+  if (source.parentElement && source.parentElement.classList.contains('code'))
 return
-  source.style.backgroundColor = target.style.backgroundColor = 'lightgrey'
-  highlightStack.push([id, tid])
+  source.style.backgroundColor = 'lightgrey'
   source.scrollIntoView()
-  target.scrollIntoView()
+  if (target) {
+if (mapped === source)
+  target.style.backgroundColor = 'lightgrey'
+target.scrollIntoView()
+  }
+  highlightStack.push([id, tid])
   location.hash = '#' + id
 }
 function scrollToBoth() {
   doHighlight(location.hash.substr(1))
 }
+function changed(elem) {
+  return elem.classList.length == 0
+}
+function nextChangedNode(prefix, increment, number) {
+  do {
+number += increment
+var elem = document.getElementById(prefix + number)
+  } while(elem && !changed(elem))
+  return elem ? number : null
+}
+function handleKey(e) {
+  var down = e.code === "KeyJ"
+  var up = e.code === "KeyK"
+  if (!down && !up)
+return
+  var id = highlightStack[0] ? highlightStack[0][0] : 'R0'
+  var oldelem = document.getElementById(id)
+  var number = parseInt(id.substr(1))
+  var increment = down ? 1 : -1
+  var lastnumber = number
+  var prefix = id[0]
+  do {
+number = nextChangedNode(prefix, increment, number)
+var elem = document.getElementById(prefix + number)
+if (up && elem) {
+  while (elem.parentElement && changed(elem.parentElement))
+elem = elem.parentElement
+  number = elem.id.substr(1)
+}
+  } while ((down && id !== 'R0' && oldelem.contains(elem)))
+  if (!number)
+number = lastnumber
+  elem = document.getElementById(prefix + number)
+  doHighlight(prefix + number)
+}
 window.onload = scrollToBoth
+window.onkeydown = handleKey
 
 
 


Index: tools/clang-diff/ClangDiff.cpp
===
--- tools/clang-diff/ClangDiff.cpp
+++ tools/clang-diff/ClangDiff.cpp
@@ -139,34 +139,81 @@
 highlightStack = []
 function clearHighlight() {
   while (highlightStack.length) {
-let [l, r] = highlightStack.pop()
+var [l, r] = highlightStack.pop()
 document.getElementById(l).style.backgroundColor = 'white'
-document.getElementById(r).style.backgroundColor = 'white'
+if (r[1] != '-')
+  document.getElementById(r).style.backgroundColor = 'white'
   }
 }
 function highlight(event) {
-  id = event.target['id']
+  var id = event.target['id']
   doHighlight(id)
 }
 function doHighlight(id) {
   clearHighlight()
   source = document.getElementById(id)
   if (!source.attributes['tid'])
 return
-  tid = source.attributes['tid'].value
-  target = document.getElementById(tid)
-  if (!target || source.parentElement && source.parentElement.classList.contains('code'))
+  var mapped = source
+  while (mapped && mapped.parentElement && mapped.attributes['tid'].value.substr(1) === '-1')
+mapped = mapped.parentElement
+  var tid = null, target = null
+  if (mapped) {
+tid = mapped.attributes['tid'].value
+target = document.getElementById(tid)
+  }
+  if (source.parentElement && source.parentElement.classList.contains('code'))
 return
-  source.style.backgroundColor = target.style.backgroundColor = 'lightgrey'
-  highlightStack.push([id, tid])
+  source.style.backgroundColor = 'lightgrey'
   source.scrollIntoView()
-  target.scrollIntoView()
+  if (target) {
+if (mapped === source)
+  target.style.backgroundColor = 'lightgrey'
+target.scrollIntoView()
+  }
+  highlightStack.push([id, tid])
   location.hash = '#' + id
 }
 function s

[PATCH] D36686: [clang-diff] Add option to compare files across git revisions

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes updated this revision to Diff 112127.
johannes added a comment.

casing


https://reviews.llvm.org/D36686

Files:
  tools/clang-diff/ClangDiff.cpp

Index: tools/clang-diff/ClangDiff.cpp
===
--- tools/clang-diff/ClangDiff.cpp
+++ tools/clang-diff/ClangDiff.cpp
@@ -16,6 +16,7 @@
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Program.h"
 
 using namespace llvm;
 using namespace clang;
@@ -33,9 +34,9 @@
 cl::desc("Print the internal representation of the AST as JSON."),
 cl::init(false), cl::cat(ClangDiffCategory));
 
-static cl::opt
-PrintMatches("dump-matches", cl::desc("Print the matched nodes."),
- cl::init(false), cl::cat(ClangDiffCategory));
+static cl::opt PrintMatches("dump-matches",
+  cl::desc("Print the matched nodes."),
+  cl::init(false), cl::cat(ClangDiffCategory));
 
 static cl::opt HtmlDiff("html",
   cl::desc("Output a side-by-side diff in HTML."),
@@ -55,6 +56,12 @@
   cl::Optional, cl::init(""),
   cl::cat(ClangDiffCategory));
 
+static cl::opt
+GitRevision("git-rev",
+cl::desc("Compare a file between a revision range (..HEAD "
+ "is assumed if a single revision is given."),
+cl::Optional, cl::init(""), cl::cat(ClangDiffCategory));
+
 static cl::opt MaxSize("s", cl::desc(""), cl::Optional,
 cl::init(-1), cl::cat(ClangDiffCategory));
 
@@ -441,6 +448,19 @@
   }
 }
 
+std::string Exec(const char *Command) {
+  char Buffer[128];
+  std::string Result;
+  std::shared_ptr Pipe(popen(Command, "r"), pclose);
+  if (!Pipe)
+return Result;
+  while (!feof(Pipe.get())) {
+if (fgets(Buffer, 128, Pipe.get()) != nullptr)
+  Result += Buffer;
+  }
+  return Result;
+}
+
 int main(int argc, const char **argv) {
   std::string ErrorMessage;
   std::unique_ptr CommonCompilations =
@@ -476,13 +496,55 @@
 return 0;
   }
 
-  if (DestinationPath.empty()) {
+  if (DestinationPath.empty() && GitRevision.empty()) {
 llvm::errs() << "Error: Exactly two paths are required.\n";
 return 1;
   }
 
-  std::unique_ptr Src = getAST(CommonCompilations, SourcePath);
-  std::unique_ptr Dst = getAST(CommonCompilations, DestinationPath);
+  std::unique_ptr Src, Dst;
+
+  if (!GitRevision.empty()) {
+std::string Git;
+auto ErrorOrGit = llvm::sys::findProgramByName("git");
+if (!ErrorOrGit) {
+  llvm::errs() << "Error: Could not find git executable.\n";
+  return 1;
+}
+Git = ErrorOrGit.get();
+if (GitRevision.find("..") == std::string::npos)
+  GitRevision += "..HEAD";
+size_t Dots = GitRevision.find("..");
+GitRevision.replace(Dots, 2, "  ");
+GitRevision += " HEAD";
+std::string RevParseCommand = "git rev-parse " + GitRevision;
+std::string Revisions = Exec(RevParseCommand.data());
+std::transform(Revisions.begin(), Revisions.end(), Revisions.begin(),
+   [](char C) { return C == '\n' ? '\0' : C; });
+auto SrcRev = Revisions.data();
+size_t Offset = Revisions.find('\0') + 1;
+auto DstRev = Revisions.data() + Offset;
+auto UserRev = Revisions.data() + Revisions.find('\0', Offset) + 1;
+const char *CheckoutCommand[] = {"git", "checkout", nullptr, nullptr};
+auto Checkout = [&](const char *Rev) {
+  CheckoutCommand[2] = Rev;
+  if (llvm::sys::ExecuteAndWait(Git, CheckoutCommand)) {
+llvm::errs() << "Error: Failed to checkout " << Rev << "\n";
+return false;
+  }
+  return true;
+};
+if (!Checkout(SrcRev))
+  return 1;
+Src = getAST(CommonCompilations, SourcePath);
+if (!Checkout(DstRev))
+  return 1;
+Dst = getAST(CommonCompilations, SourcePath);
+Checkout(UserRev);
+  } else {
+Src = getAST(CommonCompilations, SourcePath);
+Dst = getAST(CommonCompilations, DestinationPath);
+  }
+
   if (!Src || !Dst)
 return 1;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36997: [clang-diff] Honor macros

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes created this revision.
Herald added a subscriber: klimek.

Nodes that are expanded from some macro are given a special
"Macro" kind instead of an ASTNodeKind. They are compared by
their textual value including arguments, before expansion.


https://reviews.llvm.org/D36997

Files:
  include/clang/Tooling/ASTDiff/ASTDiff.h
  lib/Tooling/ASTDiff/ASTDiff.cpp
  test/Tooling/Inputs/clang-diff-basic-src.cpp
  test/Tooling/clang-diff-ast.cpp
  test/Tooling/clang-diff-basic.cpp
  tools/clang-diff/ClangDiff.cpp

Index: tools/clang-diff/ClangDiff.cpp
===
--- tools/clang-diff/ClangDiff.cpp
+++ tools/clang-diff/ClangDiff.cpp
@@ -483,7 +483,7 @@
 std::unique_ptr AST = getAST(CommonCompilations, SourcePath);
 if (!AST)
   return 1;
-diff::SyntaxTree Tree(AST->getASTContext());
+diff::SyntaxTree Tree(*AST);
 if (ASTDump) {
   printTree(llvm::outs(), Tree);
   return 0;
@@ -561,8 +561,8 @@
   return 1;
 }
   }
-  diff::SyntaxTree SrcTree(Src->getASTContext());
-  diff::SyntaxTree DstTree(Dst->getASTContext());
+  diff::SyntaxTree SrcTree(*Src);
+  diff::SyntaxTree DstTree(*Dst);
   diff::ASTDiff Diff(SrcTree, DstTree, Options);
 
   if (HtmlDiff) {
Index: test/Tooling/clang-diff-basic.cpp
===
--- test/Tooling/clang-diff-basic.cpp
+++ test/Tooling/clang-diff-basic.cpp
@@ -53,5 +53,20 @@
 void f1() {{ (void) __func__;;; }}
 }
 
+// macros are always compared by their full textual value
+
+#define M1 return 1 + 1
+#define M2 return 2 * 2
+#define F(a, b) return a + b;
+
+int f2() {
+  // CHECK: Match Macro: M1{{.*}} to Macro: M1
+  M1;
+  // CHECK: Update Macro: M1{{.*}} to M2
+  M2;
+  // CHECK: Update Macro: F(1, 1){{.*}} to F(1, /*b=*/1)
+  F(1, /*b=*/1);
+}
+
 // CHECK: Delete AccessSpecDecl: public
 // CHECK: Delete CXXMethodDecl
Index: test/Tooling/clang-diff-ast.cpp
===
--- test/Tooling/clang-diff-ast.cpp
+++ test/Tooling/clang-diff-ast.cpp
@@ -66,12 +66,14 @@
 };
 
 #define M (void)1
-#define MA(a, b) (void)a, b
-// CHECK: FunctionDecl
-// CHECK-NEXT: CompoundStmt
+#define F(a, b) (void)a, b
 void macros() {
+  // CHECK: Macro: M(
   M;
-  MA(1, 2);
+  // two expressions, therefore it occurs twice
+  // CHECK-NEXT: Macro: F(1, 2)(
+  // CHECK-NEXT: Macro: F(1, 2)(
+  F(1, 2);
 }
 
 #ifndef GUARD
Index: test/Tooling/Inputs/clang-diff-basic-src.cpp
===
--- test/Tooling/Inputs/clang-diff-basic-src.cpp
+++ test/Tooling/Inputs/clang-diff-basic-src.cpp
@@ -31,3 +31,13 @@
 int um = 1 * 2 + 3;
 
 void f1() {{ (void) __func__;;; }}
+
+#define M1 return 1 + 1
+#define M2 return 1 + 2
+#define F(a, b) return a + b;
+
+int f2() {
+  M1;
+  M1;
+  F(1, 1);
+}
Index: lib/Tooling/ASTDiff/ASTDiff.cpp
===
--- lib/Tooling/ASTDiff/ASTDiff.cpp
+++ lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -120,21 +120,21 @@
 class SyntaxTree::Impl {
 public:
   /// Constructs a tree from an AST node.
-  Impl(SyntaxTree *Parent, Decl *N, ASTContext &AST);
-  Impl(SyntaxTree *Parent, Stmt *N, ASTContext &AST);
+  Impl(SyntaxTree *Parent, Decl *N, ASTUnit &AST);
+  Impl(SyntaxTree *Parent, Stmt *N, ASTUnit &AST);
   template 
   Impl(SyntaxTree *Parent,
typename std::enable_if::value, T>::type *Node,
-   ASTContext &AST)
+   ASTUnit &AST)
   : Impl(Parent, dyn_cast(Node), AST) {}
   template 
   Impl(SyntaxTree *Parent,
typename std::enable_if::value, T>::type *Node,
-   ASTContext &AST)
+   ASTUnit &AST)
   : Impl(Parent, dyn_cast(Node), AST) {}
 
   SyntaxTree *Parent;
-  ASTContext &AST;
+  ASTUnit &AST;
   std::vector Leaves;
   // Maps preorder indices to postorder ones.
   std::vector PostorderIds;
@@ -173,39 +173,57 @@
 static bool isSpecializedNodeExcluded(const Decl *D) { return D->isImplicit(); }
 static bool isSpecializedNodeExcluded(const Stmt *S) { return false; }
 
-template 
-static bool isNodeExcluded(const SourceManager &SrcMgr, T *N) {
+template  static bool isNodeExcluded(ASTUnit &AST, T *N) {
+  const SourceManager &SrcMgr = AST.getSourceManager();
   if (!N)
 return true;
   SourceLocation SLoc = N->getLocStart();
   if (SLoc.isValid()) {
 // Ignore everything from other files.
 if (!SrcMgr.isInMainFile(SLoc))
   return true;
-// Ignore macros.
-if (SLoc != SrcMgr.getSpellingLoc(SLoc))
+const Preprocessor &PP = AST.getPreprocessor();
+if (SLoc.isMacroID() && !PP.isAtStartOfMacroExpansion(SLoc))
   return true;
   }
   return isSpecializedNodeExcluded(N);
 }
 
+static SourceRange getSourceRange(const ASTUnit &AST, const DynTypedNode &DTN) {
+  const SourceManager &SrcMgr = AST.getSourceManager();
+  SourceRange Range = DTN.getSourceRange();
+  SourceLocation BeginLoc = Range.getBegin();
+  SourceLocation End

[PATCH] D36998: [AST] Make TraverseTemplateParameterListHelper public

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes created this revision.

This is useful for clients that want to create a visitor
that visits template parameters before visiting the declaration
that uses them.


https://reviews.llvm.org/D36998

Files:
  include/clang/AST/RecursiveASTVisitor.h


Index: include/clang/AST/RecursiveASTVisitor.h
===
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -497,10 +497,10 @@
   bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
 #include "clang/AST/DeclNodes.inc"
 
-private:
   // These are helper methods used by more than one Traverse* method.
   bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
 
+private:
   // Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
   template 
   bool TraverseDeclTemplateParameterLists(T *D);


Index: include/clang/AST/RecursiveASTVisitor.h
===
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -497,10 +497,10 @@
   bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
 #include "clang/AST/DeclNodes.inc"
 
-private:
   // These are helper methods used by more than one Traverse* method.
   bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
 
+private:
   // Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
   template 
   bool TraverseDeclTemplateParameterLists(T *D);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36999: [AST] Add DeclDataCollectors.inc

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes created this revision.

This adds some macros for collecting data from Decl nodes.
However, it is incomplete as its not always clear which data should be 
collected,
plus there are missing nodes. So this probably needs some tuning if it is useful
enough to get merged.


https://reviews.llvm.org/D36999

Files:
  lib/AST/DeclDataCollectors.inc
  unittests/AST/DataCollectionTest.cpp

Index: unittests/AST/DataCollectionTest.cpp
===
--- unittests/AST/DataCollectionTest.cpp
+++ unittests/AST/DataCollectionTest.cpp
@@ -57,7 +57,7 @@
   StmtHashMatch(llvm::MD5::MD5Result &Hash) : NumFound(0), Hash(Hash) {}
 
   void run(const MatchFinder::MatchResult &Result) override {
-const Stmt *S = Result.Nodes.getNodeAs("id");
+auto *S = Result.Nodes.getNodeAs("id");
 if (!S)
   return;
 ++NumFound;
@@ -80,7 +80,7 @@
   newFrontendActionFactory(&Finder));
   if (!runToolOnCode(Factory->create(), Code))
 return testing::AssertionFailure()
-   << "Parsing error in \"" << Code.str() << "\"";
+   << R"(Parsing error in ")" << Code.str() << R"(")";
   if (Hasher.NumFound == 0)
 return testing::AssertionFailure() << "Matcher didn't find any statements";
   if (Hasher.NumFound > 1)
Index: lib/AST/DeclDataCollectors.inc
===
--- /dev/null
+++ lib/AST/DeclDataCollectors.inc
@@ -0,0 +1,104 @@
+DEF_ADD_DATA(Decl, {
+  addData(D->getKind());
+  addData(data_collection::getMacroStack(D->getLocStart(), Context));
+  addData(data_collection::getMacroStack(D->getLocEnd(), Context));
+})
+
+DEF_ADD_DATA(NamedDecl, { addData(D->getQualifiedNameAsString()); })
+DEF_ADD_DATA(ValueDecl, { addData(D->getType()); })
+DEF_ADD_DATA(TypeDecl, {
+  if (auto *Type = D->getTypeForDecl())
+addData(Type->getCanonicalTypeInternal());
+})
+DEF_ADD_DATA(UsingDirectiveDecl,
+ { addData(D->getNominatedNamespace()->getName()); })
+DEF_ADD_DATA(UsingDecl, {
+  addData(D->isAccessDeclaration());
+  addData(D->hasTypename());
+})
+DEF_ADD_DATA(AccessSpecDecl, {
+  CharSourceRange Range(D->getSourceRange(), false);
+  addData(Lexer::getSourceText(Range, Context.getSourceManager(),
+   Context.getLangOpts()));
+})
+
+DEF_ADD_DATA(TemplateDecl, { addData(D->isConcept()); })
+DEF_ADD_DATA(BuiltinTemplateDecl, { addData(D->getBuiltinTemplateKind()); })
+DEF_ADD_DATA(TemplateTemplateParmDecl, {
+  addData(D->isParameterPack());
+  addData(D->isPackExpansion());
+  addData(D->isExpandedParameterPack());
+})
+DEF_ADD_DATA(RedeclarableTemplateDecl,
+ { addData(D->isMemberSpecialization()); })
+
+DEF_ADD_DATA(FriendDecl, {
+  if (D->getFriendDecl())
+addData(D->getFriendDecl()->getQualifiedNameAsString());
+})
+DEF_ADD_DATA(LinkageSpecDecl, {
+  addData(D->getLanguage());
+  addData(D->hasBraces());
+})
+DEF_ADD_DATA(LabelDecl, {
+  addData(D->isGnuLocal());
+  addData(D->isMSAsmLabel());
+  addData(D->isResolvedMSAsmLabel());
+})
+DEF_ADD_DATA(NamespaceAliasDecl,
+ { addData(D->getNamespace()->getQualifiedNameAsString()); })
+DEF_ADD_DATA(NamespaceDecl, {
+  addData(D->isAnonymousNamespace());
+  addData(D->isInline());
+})
+
+DEF_ADD_DATA(FunctionDecl, {
+  addData(D->isDefined());
+  addData(D->isThisDeclarationADefinition());
+  addData(D->doesThisDeclarationHaveABody());
+  addData(D->isVariadic());
+  addData(D->isVirtualAsWritten());
+  addData(D->isPure());
+  addData(D->isTrivial());
+  addData(D->isDefaulted());
+  addData(D->isExplicitlyDefaulted());
+  addData(D->hasImplicitReturnZero());
+  addData(D->isConstexpr());
+  addData(D->isDeleted());
+  addData(D->isMSVCRTEntryPoint());
+  addData(D->isNoReturn());
+  addData(D->hasSkippedBody());
+  addData(D->hasUnusedResultAttr());
+  addData(D->isInlineSpecified());
+  addData(D->isOutOfLine());
+  addData(D->getStorageClass());
+  addData(D->getLanguageLinkage());
+})
+DEF_ADD_DATA(CXXDeductionGuideDecl, { addData(D->isExplicitSpecified()); })
+DEF_ADD_DATA(CXXMethodDecl, {
+  addData(D->isStatic());
+  addData(D->isInstance());
+  addData(D->isConst());
+  addData(D->isVolatile());
+  addData(D->isVirtual());
+  addData(D->hasInlineBody());
+})
+DEF_ADD_DATA(CXXConversionDecl, { addData(D->isExplicitSpecified()); })
+DEF_ADD_DATA(VarDecl, {
+  addData(D->isStaticLocal());
+  addData(D->hasExternalStorage());
+  addData(D->getStorageDuration());
+  addData(D->getLanguageLinkage());
+  addData(D->isExternC());
+  addData(D->isInExternCContext());
+  addData(D->isInExternCXXContext());
+  addData(D->isOutOfLine());
+  addData(D->isFileVarDecl());
+  addData(D->getInitStyle());
+  addData(D->isInlineSpecified());
+  addData(D->isConstexpr());
+  addData(D->isInitCapture());
+})
+DEF_ADD_DATA(ImplicitParamDecl, { addData(D->getParameterKind()); })
+
+#undef DEF_ADD_DATA
___
cfe-commits mailing list
cfe-commits@lists.llvm.

[PATCH] D37000: [clang-diff] Remove NodeCountVisitor, NFC

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes created this revision.
Herald added a subscriber: klimek.

https://reviews.llvm.org/D37000

Files:
  lib/Tooling/ASTDiff/ASTDiff.cpp


Index: lib/Tooling/ASTDiff/ASTDiff.cpp
===
--- lib/Tooling/ASTDiff/ASTDiff.cpp
+++ lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -135,6 +135,8 @@
 
   SyntaxTree *Parent;
   ASTUnit &AST;
+  /// Nodes in preorder.
+  std::vector Nodes;
   std::vector Leaves;
   // Maps preorder indices to postorder ones.
   std::vector PostorderIds;
@@ -163,9 +165,6 @@
   std::string getStmtValue(const Stmt *S) const;
 
 private:
-  /// Nodes in preorder.
-  std::vector Nodes;
-
   void initTree();
   void setLeftMostDescendants();
 };
@@ -207,32 +206,6 @@
   return {SrcMgr.getExpansionLoc(BeginLoc), SrcMgr.getExpansionLoc(EndLoc)};
 }
 
-namespace {
-/// Counts the number of nodes that will be compared.
-struct NodeCountVisitor : public RecursiveASTVisitor {
-  int Count = 0;
-  const SyntaxTree::Impl &Tree;
-  NodeCountVisitor(const SyntaxTree::Impl &Tree) : Tree(Tree) {}
-  bool TraverseDecl(Decl *D) {
-if (isNodeExcluded(Tree.AST, D))
-  return true;
-++Count;
-RecursiveASTVisitor::TraverseDecl(D);
-return true;
-  }
-  bool TraverseStmt(Stmt *S) {
-if (S)
-  S = S->IgnoreImplicit();
-if (isNodeExcluded(Tree.AST, S))
-  return true;
-++Count;
-RecursiveASTVisitor::TraverseStmt(S);
-return true;
-  }
-  bool TraverseType(QualType T) { return true; }
-};
-} // end anonymous namespace
-
 namespace {
 // Sets Height, Parent and Children for each node.
 struct PreorderVisitor : public RecursiveASTVisitor {
@@ -244,6 +217,7 @@
 
   template  std::tuple PreTraverse(T *ASTNode) {
 NodeId MyId = Id;
+Tree.Nodes.emplace_back();
 Node &N = Tree.getMutableNode(MyId);
 N.Parent = Parent;
 N.Depth = Depth;
@@ -300,19 +274,13 @@
 
 SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, ASTUnit &AST)
 : Parent(Parent), AST(AST) {
-  NodeCountVisitor NodeCounter(*this);
-  NodeCounter.TraverseDecl(N);
-  Nodes.resize(NodeCounter.Count);
   PreorderVisitor PreorderWalker(*this);
   PreorderWalker.TraverseDecl(N);
   initTree();
 }
 
 SyntaxTree::Impl::Impl(SyntaxTree *Parent, Stmt *N, ASTUnit &AST)
 : Parent(Parent), AST(AST) {
-  NodeCountVisitor NodeCounter(*this);
-  NodeCounter.TraverseStmt(N);
-  Nodes.resize(NodeCounter.Count);
   PreorderVisitor PreorderWalker(*this);
   PreorderWalker.TraverseStmt(N);
   initTree();


Index: lib/Tooling/ASTDiff/ASTDiff.cpp
===
--- lib/Tooling/ASTDiff/ASTDiff.cpp
+++ lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -135,6 +135,8 @@
 
   SyntaxTree *Parent;
   ASTUnit &AST;
+  /// Nodes in preorder.
+  std::vector Nodes;
   std::vector Leaves;
   // Maps preorder indices to postorder ones.
   std::vector PostorderIds;
@@ -163,9 +165,6 @@
   std::string getStmtValue(const Stmt *S) const;
 
 private:
-  /// Nodes in preorder.
-  std::vector Nodes;
-
   void initTree();
   void setLeftMostDescendants();
 };
@@ -207,32 +206,6 @@
   return {SrcMgr.getExpansionLoc(BeginLoc), SrcMgr.getExpansionLoc(EndLoc)};
 }
 
-namespace {
-/// Counts the number of nodes that will be compared.
-struct NodeCountVisitor : public RecursiveASTVisitor {
-  int Count = 0;
-  const SyntaxTree::Impl &Tree;
-  NodeCountVisitor(const SyntaxTree::Impl &Tree) : Tree(Tree) {}
-  bool TraverseDecl(Decl *D) {
-if (isNodeExcluded(Tree.AST, D))
-  return true;
-++Count;
-RecursiveASTVisitor::TraverseDecl(D);
-return true;
-  }
-  bool TraverseStmt(Stmt *S) {
-if (S)
-  S = S->IgnoreImplicit();
-if (isNodeExcluded(Tree.AST, S))
-  return true;
-++Count;
-RecursiveASTVisitor::TraverseStmt(S);
-return true;
-  }
-  bool TraverseType(QualType T) { return true; }
-};
-} // end anonymous namespace
-
 namespace {
 // Sets Height, Parent and Children for each node.
 struct PreorderVisitor : public RecursiveASTVisitor {
@@ -244,6 +217,7 @@
 
   template  std::tuple PreTraverse(T *ASTNode) {
 NodeId MyId = Id;
+Tree.Nodes.emplace_back();
 Node &N = Tree.getMutableNode(MyId);
 N.Parent = Parent;
 N.Depth = Depth;
@@ -300,19 +274,13 @@
 
 SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, ASTUnit &AST)
 : Parent(Parent), AST(AST) {
-  NodeCountVisitor NodeCounter(*this);
-  NodeCounter.TraverseDecl(N);
-  Nodes.resize(NodeCounter.Count);
   PreorderVisitor PreorderWalker(*this);
   PreorderWalker.TraverseDecl(N);
   initTree();
 }
 
 SyntaxTree::Impl::Impl(SyntaxTree *Parent, Stmt *N, ASTUnit &AST)
 : Parent(Parent), AST(AST) {
-  NodeCountVisitor NodeCounter(*this);
-  NodeCounter.TraverseStmt(N);
-  Nodes.resize(NodeCounter.Count);
   PreorderVisitor PreorderWalker(*this);
   PreorderWalker.TraverseStmt(N);
   initTree();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailm

[PATCH] D37001: [clang-diff] Use data collectors for node comparison

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes created this revision.
Herald added a subscriber: klimek.

https://reviews.llvm.org/D37001

Files:
  lib/Tooling/ASTDiff/ASTDiff.cpp

Index: lib/Tooling/ASTDiff/ASTDiff.cpp
===
--- lib/Tooling/ASTDiff/ASTDiff.cpp
+++ lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -13,9 +13,13 @@
 
 #include "clang/Tooling/ASTDiff/ASTDiff.h"
 
+#include "clang/AST/DataCollection.h"
+#include "clang/AST/DeclVisitor.h"
 #include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/StmtVisitor.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/PriorityQueue.h"
+#include "llvm/Support/MD5.h"
 
 #include 
 #include 
@@ -116,9 +120,12 @@
   friend class ZhangShashaMatcher;
 };
 
+using HashType = std::array;
+
 /// Represents the AST of a TranslationUnit.
 class SyntaxTree::Impl {
 public:
+  Impl(SyntaxTree *Parent, ASTUnit &AST);
   /// Constructs a tree from an AST node.
   Impl(SyntaxTree *Parent, Decl *N, ASTUnit &AST);
   Impl(SyntaxTree *Parent, Stmt *N, ASTUnit &AST);
@@ -135,6 +142,7 @@
 
   SyntaxTree *Parent;
   ASTUnit &AST;
+  PrintingPolicy TypePP;
   /// Nodes in preorder.
   std::vector Nodes;
   std::vector Leaves;
@@ -164,6 +172,10 @@
   std::string getDeclValue(const Decl *D) const;
   std::string getStmtValue(const Stmt *S) const;
 
+  HashType hashNode(const Node &N) const;
+  HashType hashStmt(const Stmt *S) const;
+  HashType hashDecl(const Decl *D) const;
+
 private:
   void initTree();
   void setLeftMostDescendants();
@@ -272,15 +284,20 @@
 };
 } // end anonymous namespace
 
+SyntaxTree::Impl::Impl(SyntaxTree *Parent, ASTUnit &AST)
+: Parent(Parent), AST(AST), TypePP(AST.getLangOpts()) {
+  TypePP.AnonymousTagLocations = false;
+}
+
 SyntaxTree::Impl::Impl(SyntaxTree *Parent, Decl *N, ASTUnit &AST)
-: Parent(Parent), AST(AST) {
+: Impl(Parent, AST) {
   PreorderVisitor PreorderWalker(*this);
   PreorderWalker.TraverseDecl(N);
   initTree();
 }
 
 SyntaxTree::Impl::Impl(SyntaxTree *Parent, Stmt *N, ASTUnit &AST)
-: Parent(Parent), AST(AST) {
+: Impl(Parent, AST) {
   PreorderVisitor PreorderWalker(*this);
   PreorderWalker.TraverseStmt(N);
   initTree();
@@ -422,9 +439,6 @@
 
 std::string SyntaxTree::Impl::getDeclValue(const Decl *D) const {
   std::string Value;
-  PrintingPolicy TypePP(AST.getLangOpts());
-  TypePP.AnonymousTagLocations = false;
-
   if (auto *V = dyn_cast(D)) {
 Value += getRelativeName(V) + "(" + V->getType().getAsString(TypePP) + ")";
 if (auto *C = dyn_cast(D)) {
@@ -490,6 +504,92 @@
   return "";
 }
 
+class DataCollector : public ConstDeclVisitor,
+  public ConstStmtVisitor {
+  const SyntaxTree::Impl &Tree;
+  ASTContext &Context;
+  llvm::MD5 &DataConsumer;
+
+  void addData(const QualType &QT) { addData(QT.getAsString(Tree.TypePP)); }
+  template  void addData(T Data) {
+data_collection::addDataToConsumer(DataConsumer, Data);
+  }
+
+public:
+  DataCollector(const DynTypedNode &DTN, const SyntaxTree::Impl &Tree,
+llvm::MD5 &DataConsumer)
+  : Tree(Tree), Context(Tree.AST.getASTContext()),
+DataConsumer(DataConsumer) {
+if (auto *S = DTN.get())
+  ConstStmtVisitor::Visit(S);
+else if (auto *D = DTN.get())
+  ConstDeclVisitor::Visit(D);
+else
+  llvm_unreachable("Fatal: unhandled AST node.\n");
+  }
+
+#define DEF_ADD_DATA(CLASS, CODE)  \
+  template  Dummy Visit##CLASS(const CLASS *D) {   \
+CODE;  \
+ConstDeclVisitor::Visit##CLASS(D);  \
+  }
+
+#include "../../AST/DeclDataCollectors.inc"
+
+#define DEF_ADD_DATA(CLASS, CODE)  \
+  void Visit##CLASS(const CLASS *D) {  \
+CODE;  \
+ConstDeclVisitor::Visit##CLASS(D);  \
+  }
+
+  DEF_ADD_DATA(NamedDecl, { addData(Tree.getRelativeName(D)); })
+#undef DEF_ADD_DATA
+
+#define DEF_ADD_DATA(CLASS, CODE)  \
+  template  Dummy Visit##CLASS(const CLASS *S) {   \
+CODE;  \
+ConstStmtVisitor::Visit##CLASS(S);  \
+  }
+
+#include "../../AST/StmtDataCollectors.inc"
+
+#define DEF_ADD_DATA(CLASS, CODE)  \
+  void Visit##CLASS(const CLASS *S) {  \
+CODE;  \
+ConstStmtVisitor::Visit##CLASS(S);  \
+  }
+
+  // ignore differences of type, because they are not local
+  DEF_ADD_DATA(Expr, {})
+  DEF_ADD_DATA(DeclRefExpr, {
+addData(Tree.getRelativeName(S->getDecl(),
+ getEnclosingDeclConte

[PATCH] D37002: [clang-diff] Treat CXXCtorInitializer as a node

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes created this revision.
Herald added a subscriber: klimek.

https://reviews.llvm.org/D37002

Files:
  lib/Tooling/ASTDiff/ASTDiff.cpp
  test/Tooling/clang-diff-ast.cpp

Index: test/Tooling/clang-diff-ast.cpp
===
--- test/Tooling/clang-diff-ast.cpp
+++ test/Tooling/clang-diff-ast.cpp
@@ -54,14 +54,20 @@
   // CHECK: AccessSpecDecl: public(
 public:
   int not_initialized;
-  // All initialized members, bases and delegating initializers are are
-  // appended, separated by commas.
-  // CHECK: CXXConstructorDecl: :X(void (char, int){{( __attribute__\(\(thiscall\)\))?}})Base,:m,(
-  X(char c, int) : Base(), m(0) {
+  // CHECK: CXXConstructorDecl: :X(void (char, int){{( __attribute__\(\(thiscall\)\))?}})(
+  // CHECK-NEXT: ParmVarDecl: s(char)
+  // CHECK-NEXT: ParmVarDecl: (int)
+  // CHECK-NEXT: CXXCtorInitializer: Base
+  // CHECK-NEXT: CXXConstructExpr
+  // CHECK-NEXT: CXXCtorInitializer: m
+  // CHECK-NEXT: IntegerLiteral: 0
+  X(char s, int) : Base(), m(0) {
+// CHECK-NEXT: CompoundStmt
 // CHECK: MemberExpr: :m(
 int x = m;
   }
-  // CHECK: CXXConstructorDecl: :X(void (char){{( __attribute__\(\(thiscall\)\))?}})X,(
+  // CHECK: CXXConstructorDecl: :X(void (char){{( __attribute__\(\(thiscall\)\))?}})(
+  // CHECK: CXXCtorInitializer: X
   X(char s) : X(s, 4) {}
 };
 
Index: lib/Tooling/ASTDiff/ASTDiff.cpp
===
--- lib/Tooling/ASTDiff/ASTDiff.cpp
+++ lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -183,12 +183,15 @@
 
 static bool isSpecializedNodeExcluded(const Decl *D) { return D->isImplicit(); }
 static bool isSpecializedNodeExcluded(const Stmt *S) { return false; }
+static bool isSpecializedNodeExcluded(CXXCtorInitializer *I) {
+  return !I->isWritten();
+}
 
 template  static bool isNodeExcluded(ASTUnit &AST, T *N) {
   const SourceManager &SrcMgr = AST.getSourceManager();
   if (!N)
 return true;
-  SourceLocation SLoc = N->getLocStart();
+  SourceLocation SLoc = N->getSourceRange().getBegin();
   if (SLoc.isValid()) {
 // Ignore everything from other files.
 if (!SrcMgr.isInMainFile(SLoc))
@@ -281,6 +284,14 @@
 return true;
   }
   bool TraverseType(QualType T) { return true; }
+  bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
+if (isNodeExcluded(Tree.AST, Init))
+  return true;
+auto SavedState = PreTraverse(Init);
+RecursiveASTVisitor::TraverseConstructorInitializer(Init);
+PostTraverse(SavedState);
+return true;
+  }
 };
 } // end anonymous namespace
 
@@ -419,6 +430,17 @@
   return nullptr;
 }
 
+static std::string getInitializerValue(const CXXCtorInitializer *Init,
+   const PrintingPolicy &TypePP) {
+  if (Init->isAnyMemberInitializer())
+return Init->getAnyMember()->getName();
+  if (Init->isBaseInitializer())
+return QualType(Init->getBaseClass(), 0).getAsString(TypePP);
+  if (Init->isDelegatingInitializer())
+return Init->getTypeSourceInfo()->getType().getAsString(TypePP);
+  llvm_unreachable("Unknown initializer type");
+}
+
 std::string SyntaxTree::Impl::getNodeValue(NodeId Id) const {
   return getNodeValue(getNode(Id));
 }
@@ -434,31 +456,15 @@
 return getStmtValue(S);
   if (auto *D = DTN.get())
 return getDeclValue(D);
+  if (auto *Init = DTN.get())
+return getInitializerValue(Init, TypePP);
   llvm_unreachable("Fatal: unhandled AST node.\n");
 }
 
 std::string SyntaxTree::Impl::getDeclValue(const Decl *D) const {
   std::string Value;
-  if (auto *V = dyn_cast(D)) {
-Value += getRelativeName(V) + "(" + V->getType().getAsString(TypePP) + ")";
-if (auto *C = dyn_cast(D)) {
-  for (auto *Init : C->inits()) {
-if (!Init->isWritten())
-  continue;
-if (Init->isBaseInitializer()) {
-  Value += Init->getBaseClass()->getCanonicalTypeInternal().getAsString(
-  TypePP);
-} else if (Init->isDelegatingInitializer()) {
-  Value += C->getNameAsString();
-} else {
-  assert(Init->isAnyMemberInitializer());
-  Value += getRelativeName(Init->getMember());
-}
-Value += ",";
-  }
-}
-return Value;
-  }
+  if (auto *V = dyn_cast(D))
+return getRelativeName(V) + "(" + V->getType().getAsString(TypePP) + ")";
   if (auto *N = dyn_cast(D))
 Value += getRelativeName(N) + ";";
   if (auto *T = dyn_cast(D))
@@ -524,6 +530,8 @@
   ConstStmtVisitor::Visit(S);
 else if (auto *D = DTN.get())
   ConstDeclVisitor::Visit(D);
+else if (auto *Init = DTN.get())
+  addData(getInitializerValue(Init, Tree.TypePP));
 else
   llvm_unreachable("Fatal: unhandled AST node.\n");
   }
@@ -943,7 +951,8 @@
 NodeId Dst = M.getDst(Src);
 CommonDescendants += int(Dst.isValid() && T2.isInSubtree(Dst, Id2));
   }
-  // We need to subtract 1 to get the number of descendants excluding the root.
+  // We need to subtract 1 t

[PATCH] D37003: [clang-diff] Support templates

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes created this revision.
Herald added a subscriber: klimek.

TemplateName and TemplateArgument are recognised.


https://reviews.llvm.org/D37003

Files:
  lib/Tooling/ASTDiff/ASTDiff.cpp
  test/Tooling/Inputs/clang-diff-basic-src.cpp
  test/Tooling/clang-diff-ast.cpp
  test/Tooling/clang-diff-basic.cpp
  test/Tooling/clang-diff-html.test

Index: test/Tooling/clang-diff-html.test
===
--- test/Tooling/clang-diff-html.test
+++ test/Tooling/clang-diff-html.test
@@ -1,4 +1,4 @@
-// RUN: clang-diff -html %S/Inputs/clang-diff-basic-src.cpp %S/clang-diff-basic.cpp -- | FileCheck %s
+// RUN: clang-diff -html %S/Inputs/clang-diff-basic-src.cpp %S/clang-diff-basic.cpp -- -std=c++11 | FileCheck %s
 
 // CHECK: 
Index: test/Tooling/clang-diff-basic.cpp
===
--- test/Tooling/clang-diff-basic.cpp
+++ test/Tooling/clang-diff-basic.cpp
@@ -1,4 +1,4 @@
-// RUN: clang-diff -dump-matches %S/Inputs/clang-diff-basic-src.cpp %s -- | FileCheck %s
+// RUN: clang-diff -dump-matches %S/Inputs/clang-diff-basic-src.cpp %s -- -std=c++11 | FileCheck %s
 
 // CHECK: Match TranslationUnitDecl{{.*}} to TranslationUnitDecl
 // CHECK: Match NamespaceDecl: src{{.*}} to NamespaceDecl: dst
@@ -68,5 +68,18 @@
   F(1, /*b=*/1);
 }
 
+// CHECK: Update TemplateTypeParmDecl: T{{.*}} to Type
+template 
+U visit(Type &t) {
+  int x = t;
+  return U();
+}
+
+void tmp() {
+  long x;
+  // CHECK: Update TemplateArgument: int{{.*}} to long
+  visit(x);
+}
+
 // CHECK: Delete AccessSpecDecl: public
 // CHECK: Delete CXXMethodDecl
Index: test/Tooling/clang-diff-ast.cpp
===
--- test/Tooling/clang-diff-ast.cpp
+++ test/Tooling/clang-diff-ast.cpp
@@ -92,3 +92,16 @@
 // CHECK-NEXT: FunctionDecl: sentinel
 void sentinel();
 #endif
+
+// CHECK-NEXT: ClassTemplateDecl: C
+// CHECK-NEXT: TemplateTypeParmDecl
+// CHECK-NEXT: CXXRecordDecl
+template  class C {
+  // CHECK-NEXT: FieldDecl
+  T t;
+};
+
+// CHECK-NEXT: CXXRecordDecl
+// CHECK-NEXT: TemplateName
+// CHECK-NEXT: TemplateArgument
+class I : C {};
Index: test/Tooling/Inputs/clang-diff-basic-src.cpp
===
--- test/Tooling/Inputs/clang-diff-basic-src.cpp
+++ test/Tooling/Inputs/clang-diff-basic-src.cpp
@@ -41,3 +41,16 @@
   M1;
   F(1, 1);
 }
+
+template 
+U visit(T &t) {
+  int x = t;
+  return U();
+}
+
+void tmp() {
+  int x;
+  visit(x);
+}
+
+int x = 1;
Index: lib/Tooling/ASTDiff/ASTDiff.cpp
===
--- lib/Tooling/ASTDiff/ASTDiff.cpp
+++ lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -149,6 +149,7 @@
   // Maps preorder indices to postorder ones.
   std::vector PostorderIds;
   std::vector NodesBfs;
+  std::map TemplateArgumentLocations;
 
   int getSize() const { return Nodes.size(); }
   NodeId getRootId() const { return 0; }
@@ -186,6 +187,14 @@
 static bool isSpecializedNodeExcluded(CXXCtorInitializer *I) {
   return !I->isWritten();
 }
+static bool isSpecializedNodeExcluded(const TemplateArgumentLoc *S) {
+  return false;
+}
+
+static bool isNodeExcluded(ASTUnit &AST, TemplateName *Template) {
+  // TODO what if it is from another file
+  return false;
+}
 
 template  static bool isNodeExcluded(ASTUnit &AST, T *N) {
   const SourceManager &SrcMgr = AST.getSourceManager();
@@ -203,21 +212,16 @@
   return isSpecializedNodeExcluded(N);
 }
 
-static SourceRange getSourceRange(const ASTUnit &AST, const DynTypedNode &DTN) {
+static SourceRange getSourceExtent(const ASTUnit &AST, SourceRange Range) {
   const SourceManager &SrcMgr = AST.getSourceManager();
-  SourceRange Range = DTN.getSourceRange();
   SourceLocation BeginLoc = Range.getBegin();
   SourceLocation EndLoc;
   if (BeginLoc.isMacroID())
 EndLoc = SrcMgr.getExpansionRange(BeginLoc).second;
   else
 EndLoc = Range.getEnd();
   EndLoc = Lexer::getLocForEndOfToken(EndLoc, /*Offset=*/0, SrcMgr,
   AST.getLangOpts());
-  if (auto *ThisExpr = DTN.get()) {
-if (ThisExpr->isImplicit())
-  EndLoc = BeginLoc;
-  }
   return {SrcMgr.getExpansionLoc(BeginLoc), SrcMgr.getExpansionLoc(EndLoc)};
 }
 
@@ -230,13 +234,13 @@
 
   PreorderVisitor(SyntaxTree::Impl &Tree) : Tree(Tree) {}
 
-  template  std::tuple PreTraverse(T *ASTNode) {
+  template  std::tuple PreTraverse(const T &ASTNode) {
 NodeId MyId = Id;
 Tree.Nodes.emplace_back();
 Node &N = Tree.getMutableNode(MyId);
 N.Parent = Parent;
 N.Depth = Depth;
-N.ASTNode = DynTypedNode::create(*ASTNode);
+N.ASTNode = DynTypedNode::create(ASTNode);
 assert(!N.ASTNode.getNodeKind().isNone() &&
"Expected nodes to have a valid kind.");
 if (Parent.isValid()) {
@@ -268,7 +272,7 @@
   bool TraverseDecl(Decl *D) {
 if (isNodeExcluded(Tree.AST, D))
   return true;
-auto SavedState = PreTraverse(D);
+

[PATCH] D37004: [clang-diff] Fix the html output for CXXOperatorCallExpr

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes created this revision.
Herald added subscribers: mgorny, klimek.

The operator is always the first child of such an expression.
If it is an infix operator, we want to print the LHS first.


https://reviews.llvm.org/D37004

Files:
  test/Tooling/clang-diff-ast.cpp
  tools/clang-diff/CMakeLists.txt
  tools/clang-diff/ClangDiff.cpp


Index: tools/clang-diff/ClangDiff.cpp
===
--- tools/clang-diff/ClangDiff.cpp
+++ tools/clang-diff/ClangDiff.cpp
@@ -12,6 +12,7 @@
 //
 
//===--===//
 
+#include "clang/AST/ExprCXX.h"
 #include "clang/Tooling/ASTDiff/ASTDiff.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Tooling.h"
@@ -310,8 +311,17 @@
 OS << " class='" << getChangeKindAbbr(Node.Change) << "'";
   OS << ">";
 
-  for (diff::NodeId Child : Node.Children)
-Offset = printHtmlForNode(OS, Diff, Tree, IsLeft, Child, Offset);
+  const auto &Children = Node.Children;
+  auto *OpCall = Node.ASTNode.get();
+  if (OpCall && OpCall->isInfixBinaryOp()) {
+assert(Children.size() == 3 &&
+   "A Binary operator is supposed to have two arguments.");
+for (int I : {1, 0, 2})
+  Offset = printHtmlForNode(OS, Diff, Tree, IsLeft, Children[I], Offset);
+  } else {
+for (diff::NodeId Child : Children)
+  Offset = printHtmlForNode(OS, Diff, Tree, IsLeft, Child, Offset);
+  }
 
   for (; Offset < End; ++Offset)
 printHtml(OS, Code[Offset]);
Index: tools/clang-diff/CMakeLists.txt
===
--- tools/clang-diff/CMakeLists.txt
+++ tools/clang-diff/CMakeLists.txt
@@ -7,6 +7,7 @@
   )
 
 target_link_libraries(clang-diff
+  clangAST
   clangBasic
   clangFrontend
   clangTooling
Index: test/Tooling/clang-diff-ast.cpp
===
--- test/Tooling/clang-diff-ast.cpp
+++ test/Tooling/clang-diff-ast.cpp
@@ -39,7 +39,7 @@
 };
 
 // CHECK: CXXRecordDecl: X;X;(
-class X : Base {
+struct X : Base {
   int m;
   // CHECK: CXXMethodDecl: :foo(const char *(int)
   // CHECK: ParmVarDecl: i(int)(
@@ -105,3 +105,23 @@
 // CHECK-NEXT: TemplateName
 // CHECK-NEXT: TemplateArgument
 class I : C {};
+
+struct str {
+  str& operator+(const str&);
+} s1, s2, s3;
+
+// CHECK: CXXOperatorCallExpr
+// CHECK-NEXT: DeclRefExpr: str::operator+
+// CHECK-NEXT: CXXOperatorCallExpr
+// CHECK-NEXT: DeclRefExpr: str::operator+
+// CHECK-NEXT: DeclRefExpr: s1
+// CHECK-NEXT: DeclRefExpr: s2
+// CHECK-NEXT: DeclRefExpr: s3
+str x = s1 + s2 + s3;
+
+// CHECK: BinaryOperator: +
+// CHECK-NEXT: BinaryOperator: +
+// CHECK-NEXT: IntegerLiteral: 1
+// CHECK-NEXT: IntegerLiteral: 2
+// CHECK-NEXT: IntegerLiteral: 3
+int op = 1 + 2 + 3;


Index: tools/clang-diff/ClangDiff.cpp
===
--- tools/clang-diff/ClangDiff.cpp
+++ tools/clang-diff/ClangDiff.cpp
@@ -12,6 +12,7 @@
 //
 //===--===//
 
+#include "clang/AST/ExprCXX.h"
 #include "clang/Tooling/ASTDiff/ASTDiff.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Tooling.h"
@@ -310,8 +311,17 @@
 OS << " class='" << getChangeKindAbbr(Node.Change) << "'";
   OS << ">";
 
-  for (diff::NodeId Child : Node.Children)
-Offset = printHtmlForNode(OS, Diff, Tree, IsLeft, Child, Offset);
+  const auto &Children = Node.Children;
+  auto *OpCall = Node.ASTNode.get();
+  if (OpCall && OpCall->isInfixBinaryOp()) {
+assert(Children.size() == 3 &&
+   "A Binary operator is supposed to have two arguments.");
+for (int I : {1, 0, 2})
+  Offset = printHtmlForNode(OS, Diff, Tree, IsLeft, Children[I], Offset);
+  } else {
+for (diff::NodeId Child : Children)
+  Offset = printHtmlForNode(OS, Diff, Tree, IsLeft, Child, Offset);
+  }
 
   for (; Offset < End; ++Offset)
 printHtml(OS, Code[Offset]);
Index: tools/clang-diff/CMakeLists.txt
===
--- tools/clang-diff/CMakeLists.txt
+++ tools/clang-diff/CMakeLists.txt
@@ -7,6 +7,7 @@
   )
 
 target_link_libraries(clang-diff
+  clangAST
   clangBasic
   clangFrontend
   clangTooling
Index: test/Tooling/clang-diff-ast.cpp
===
--- test/Tooling/clang-diff-ast.cpp
+++ test/Tooling/clang-diff-ast.cpp
@@ -39,7 +39,7 @@
 };
 
 // CHECK: CXXRecordDecl: X;X;(
-class X : Base {
+struct X : Base {
   int m;
   // CHECK: CXXMethodDecl: :foo(const char *(int)
   // CHECK: ParmVarDecl: i(int)(
@@ -105,3 +105,23 @@
 // CHECK-NEXT: TemplateName
 // CHECK-NEXT: TemplateArgument
 class I : C {};
+
+struct str {
+  str& operator+(const str&);
+} s1, s2, s3;
+
+// CHECK: CXXOperatorCallExpr
+// CHECK-NEXT: DeclRefExpr: str::operator+
+// CHECK-NEXT: CXXOperatorCallExpr
+// CHECK-NEXT: DeclRefExpr: str::o

[clang-tools-extra] r311436 - [clangd] Updated ClangdServer comments. NFC.

2017-08-22 Thread Ilya Biryukov via cfe-commits
Author: ibiryukov
Date: Tue Aug 22 02:16:46 2017
New Revision: 311436

URL: http://llvm.org/viewvc/llvm-project?rev=311436&view=rev
Log:
[clangd] Updated ClangdServer comments. NFC.

Modified:
clang-tools-extra/trunk/clangd/ClangdServer.h

Modified: clang-tools-extra/trunk/clangd/ClangdServer.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=311436&r1=311435&r2=311436&view=diff
==
--- clang-tools-extra/trunk/clangd/ClangdServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.h Tue Aug 22 02:16:46 2017
@@ -169,20 +169,35 @@ private:
 };
 
 /// Provides API to manage ASTs for a collection of C++ files and request
-/// various language features(currently, only codeCompletion and async
-/// diagnostics for tracked files).
+/// various language features.
+/// Currently supports async diagnostics, code completion, formatting and goto
+/// definition.
 class ClangdServer {
 public:
-  /// Creates a new ClangdServer. To server parsing requests ClangdScheduler,
-  /// that spawns \p AsyncThreadsCount worker threads will be created (when \p
-  /// AsyncThreadsCount is 0, requests will be processed on the calling 
thread).
-  /// instance of parsing will be conducted via a vfs::FileSystem provided by 
\p
-  /// FSProvider. Results of code completion/diagnostics also include a tag,
-  /// that \p FSProvider returns along with the vfs::FileSystem. When \p
-  /// ResourceDir is set, it will be used to search for internal headers
-  /// (overriding defaults and -resource-dir compiler flag, if set). If \p
-  /// ResourceDir is None, ClangdServer will attempt to set it to a standard
-  /// location, obtained via CompilerInvocation::GetResourcePath.
+  /// Creates a new ClangdServer instance.
+  /// To process parsing requests asynchronously, ClangdServer will spawn \p
+  /// AsyncThreadsCount worker threads. However, if \p AsyncThreadsCount is 0,
+  /// all requests will be processed on the calling thread.
+  ///
+  /// ClangdServer uses \p FSProvider to get an instance of vfs::FileSystem for
+  /// each parsing request. Results of code completion and diagnostics also
+  /// include a tag, that \p FSProvider returns along with the vfs::FileSystem.
+  ///
+  /// The value of \p ResourceDir will be used to search for internal headers
+  /// (overriding defaults and -resource-dir compiler flag). If \p ResourceDir
+  /// is None, ClangdServer will call CompilerInvocation::GetResourcePath() to
+  /// obtain the standard resource directory.
+  ///
+  /// ClangdServer uses \p CDB to obtain compilation arguments for parsing. 
Note
+  /// that ClangdServer only obtains compilation arguments once for each newly
+  /// added file (i.e., when processing a first call to addDocument) and reuses
+  /// those arguments for subsequent reparses. However, ClangdServer will check
+  /// if compilation arguments changed on calls to forceReparse().
+  ///
+  /// After each parsing request finishes, ClangdServer reports diagnostics to
+  /// \p DiagConsumer. Note that a callback to \p DiagConsumer happens on a
+  /// worker thread. Therefore, instances of \p DiagConsumer must properly
+  /// synchronize access to shared state.
   ClangdServer(GlobalCompilationDatabase &CDB,
DiagnosticsConsumer &DiagConsumer,
FileSystemProvider &FSProvider, unsigned AsyncThreadsCount,


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


[PATCH] D37005: Add include/clang/Tooling/ASTDiff/ASTPatch.h

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes created this revision.
Herald added subscribers: mgorny, klimek.

This adds a functions to remove AST nodes.
It works for Decl, and for Stmt nodes that are children of a
CompoundStmt.

Sometimes it is not possible to remove a Decl from its context
despite DeclContext.containsDecl() returning true. Instead the program
crashes. An example for this is in the tests. So this might be a
bug although it may never occur under normal circumstances.


https://reviews.llvm.org/D37005

Files:
  include/clang/Tooling/ASTDiff/ASTPatch.h
  unittests/Tooling/ASTPatchTest.cpp
  unittests/Tooling/CMakeLists.txt

Index: unittests/Tooling/CMakeLists.txt
===
--- unittests/Tooling/CMakeLists.txt
+++ unittests/Tooling/CMakeLists.txt
@@ -11,6 +11,7 @@
 endif()
 
 add_clang_unittest(ToolingTests
+  ASTPatchTest.cpp
   CastExprTest.cpp
   CommentHandlerTest.cpp
   CompilationDatabaseTest.cpp
Index: unittests/Tooling/ASTPatchTest.cpp
===
--- /dev/null
+++ unittests/Tooling/ASTPatchTest.cpp
@@ -0,0 +1,64 @@
+//===- unittests/Tooling/ASTPatchTest.cpp -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/ASTDiff/ASTPatch.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace tooling;
+using namespace ast_matchers;
+
+namespace {
+template  struct DeleteMatch : public MatchFinder::MatchCallback {
+  unsigned NumFound = 0;
+  bool Success = true;
+
+  void run(const MatchFinder::MatchResult &Result) override {
+auto *Node = Result.Nodes.getNodeAs("id");
+if (!Node)
+  return;
+++NumFound;
+Success = Success && patch::remove(Node, *Result.Context);
+  }
+};
+} // end anonymous namespace
+
+template 
+static testing::AssertionResult
+isRemovalSuccessful(const NodeMatcher &StmtMatch, StringRef Code) {
+  DeleteMatch Deleter;
+  MatchFinder Finder;
+  Finder.addMatcher(StmtMatch, &Deleter);
+  std::unique_ptr Factory(
+  newFrontendActionFactory(&Finder));
+  if (!runToolOnCode(Factory->create(), Code))
+return testing::AssertionFailure()
+   << R"(Parsing error in ")" << Code.str() << R"(")";
+  if (Deleter.NumFound == 0)
+return testing::AssertionFailure() << "Matcher didn't find any statements";
+  return testing::AssertionResult(Deleter.Success);
+}
+
+TEST(ASTPatch, RemoveStmt) {
+  ASSERT_TRUE(isRemovalSuccessful(returnStmt().bind("id"),
+R"(void x(){ return;})"));
+}
+
+TEST(ASTPatch, RemoveDecl) {
+  ASSERT_TRUE(isRemovalSuccessful(varDecl().bind("id"),
+R"(int x = 0;)"));
+  ASSERT_TRUE(isRemovalSuccessful(functionTemplateDecl().bind("id"), R"(
+template  struct pred {};
+template  pred > swap();
+template  pred > swap();
+void swap();
+)"));
+}
Index: include/clang/Tooling/ASTDiff/ASTPatch.h
===
--- /dev/null
+++ include/clang/Tooling/ASTDiff/ASTPatch.h
@@ -0,0 +1,70 @@
+//===- ASTPatch.h - AST patching --*- C++ -*- -===//
+//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLING_ASTDIFF_ASTPATCH_H
+#define LLVM_CLANG_TOOLING_ASTDIFF_ASTPATCH_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTTypeTraits.h"
+
+using namespace clang;
+using namespace ast_type_traits;
+
+namespace clang {
+namespace patch {
+
+bool remove(Decl *D, ASTContext &Context) {
+  auto *Ctx = D->getLexicalDeclContext();
+  if (!Ctx->containsDecl(D))
+return false;
+  Ctx->removeDecl(D);
+  return true;
+}
+
+static bool removeFrom(Stmt *S, ASTContext &Context, DynTypedNode Parent) {
+  auto *ConstParentS = Parent.template get();
+  if (!ConstParentS)
+return false;
+  auto *ParentS = const_cast(ConstParentS);
+  if (auto *CS = dyn_cast(ParentS)) {
+std::vector Stmts(CS->child_begin(), CS->child_end());
+auto End = Stmts.end();
+Stmts.erase(std::remove(Stmts.begin(), Stmts.end(), S), Stmts.end());
+CS->setStmts(Context, Stmts);
+return Stmts.end() != End;
+  }
+  return false;
+}
+
+bool remove(Stmt *Node, ASTContext &Context) {
+  if (!Node)
+return false;
+  auto DTN = DynTypedNode::create(*Node);
+  const auto &Parents = Context.getParents(DTN);
+  if (Parents.empty())
+return false;
+  auto &Parent = Parents[0];
+  return removeFrom(Node, Context, Parent);

[PATCH] D36876: [IRGen] Evaluate constant static variables referenced through member expressions

2017-08-22 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman added inline comments.



Comment at: lib/CodeGen/CGExpr.cpp:1323
+  if (result.HasSideEffects && !AllowSideEffects) {
+assert(!isa(E) && "declrefs should not have side effects");
 return ConstantEmission();

rjmccall wrote:
> The side effects here are those associated with the initializer of the 
> referenced declaration, not the DRE itself.  Some expressions can be 
> constant-evaluated despite having side-effects because the side-effects occur 
> in an ignored operand, like the LHS of a comma or the base of a MemberExpr 
> that refers to a static member.
> 
> We can't allow side effects here because (1) we're not actually collecting 
> the side-effectful expressions to emit and (2) we'd need some permission from 
> the context to decide that we're allowed to do so anyway (with a lambda 
> capture, those side-effects have actually already been emitted, but I'm not 
> convinced that's always true).
> 
> On the other hand, I think we need to be able to emit MemberExprs to static 
> members as constants despite the presence of side-effects in their base 
> expressions, and I can't think of any reasonable way to do that except 
> actually making a temporary DeclRefExpr to try to constant-emit instead.
Thanks, I think I understand your explanation.

I will try using temporary a DRE instead when a static variable is used in a 
member expression. That means that the old integer field evaluation code will 
have to stay though.


Repository:
  rL LLVM

https://reviews.llvm.org/D36876



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


[PATCH] D34030: Fix the postorder visting of the ClassTemplateSpecializationDecl nodes in the RecursiveASTVisitor.

2017-08-22 Thread Peter Siket via Phabricator via cfe-commits
MontyKutyi added a comment.

Any further request on this?


https://reviews.llvm.org/D34030



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


[PATCH] D36954: [Sema] Update release notes with details of implicit scalar to vector conversions

2017-08-22 Thread Simon Dardis via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL311441: [Sema] Update release notes with details of implicit 
scalar to vector… (authored by sdardis).

Repository:
  rL LLVM

https://reviews.llvm.org/D36954

Files:
  cfe/branches/release_50/docs/ReleaseNotes.rst


Index: cfe/branches/release_50/docs/ReleaseNotes.rst
===
--- cfe/branches/release_50/docs/ReleaseNotes.rst
+++ cfe/branches/release_50/docs/ReleaseNotes.rst
@@ -116,7 +116,41 @@
 C Language Changes in Clang
 ---
 
-- ...
+- Added near complete support for implicit scalar to vector conversion, a GNU
+  C/C++ language extension. With this extension, the following code is
+  considered valid:
+
+.. code-block:: c
+
+typedef unsigned v4i32 __attribute__((vector_size(16)));
+
+v4i32 foo(v4i32 a) {
+  // Here 5 is implicitly casted to an unsigned value and replicated into a
+  // vector with as many elements as 'a'.
+  return a + 5;
+}
+
+The implicit conversion of a scalar value to a vector value--in the context of
+a vector expression--occurs when:
+
+- The type of the vector is that of a ``__attribute__((vector_size(size)))``
+  vector, not an OpenCL ``__attribute__((ext_vector_type(size)))`` vector type.
+
+- The scalar value can be casted to that of the vector element's type without
+  the loss of precision based on the type of the scalar and the type of the
+  vector's elements.
+
+- For compile time constant values, the above rule is weakened to consider the
+  value of the scalar constant rather than the constant's type.
+
+- Floating point constants with precise integral representations are not
+  implicitly converted to integer values, this is for compatability with GCC.
+
+
+Currently the basic integer and floating point types with the following
+operators are supported: ``+``, ``/``, ``-``, ``*``, ``%``, ``>``, ``<``,
+``>=``, ``<=``, ``==``, ``!=``, ``&``, ``|``, ``^`` and the corresponding
+assignment operators where applicable.
 
 ...
 
@@ -128,6 +162,10 @@
 C++ Language Changes in Clang
 -
 
+- As mentioned in `C Language Changes in Clang`_, Clang's support for
+  implicit scalar to vector conversions also applies to C++. Additionally
+  the following operators are also supported: ``&&`` and ``||``.
+
 ...
 
 C++1z Feature Support


Index: cfe/branches/release_50/docs/ReleaseNotes.rst
===
--- cfe/branches/release_50/docs/ReleaseNotes.rst
+++ cfe/branches/release_50/docs/ReleaseNotes.rst
@@ -116,7 +116,41 @@
 C Language Changes in Clang
 ---
 
-- ...
+- Added near complete support for implicit scalar to vector conversion, a GNU
+  C/C++ language extension. With this extension, the following code is
+  considered valid:
+
+.. code-block:: c
+
+typedef unsigned v4i32 __attribute__((vector_size(16)));
+
+v4i32 foo(v4i32 a) {
+  // Here 5 is implicitly casted to an unsigned value and replicated into a
+  // vector with as many elements as 'a'.
+  return a + 5;
+}
+
+The implicit conversion of a scalar value to a vector value--in the context of
+a vector expression--occurs when:
+
+- The type of the vector is that of a ``__attribute__((vector_size(size)))``
+  vector, not an OpenCL ``__attribute__((ext_vector_type(size)))`` vector type.
+
+- The scalar value can be casted to that of the vector element's type without
+  the loss of precision based on the type of the scalar and the type of the
+  vector's elements.
+
+- For compile time constant values, the above rule is weakened to consider the
+  value of the scalar constant rather than the constant's type.
+
+- Floating point constants with precise integral representations are not
+  implicitly converted to integer values, this is for compatability with GCC.
+
+
+Currently the basic integer and floating point types with the following
+operators are supported: ``+``, ``/``, ``-``, ``*``, ``%``, ``>``, ``<``,
+``>=``, ``<=``, ``==``, ``!=``, ``&``, ``|``, ``^`` and the corresponding
+assignment operators where applicable.
 
 ...
 
@@ -128,6 +162,10 @@
 C++ Language Changes in Clang
 -
 
+- As mentioned in `C Language Changes in Clang`_, Clang's support for
+  implicit scalar to vector conversions also applies to C++. Additionally
+  the following operators are also supported: ``&&`` and ``||``.
+
 ...
 
 C++1z Feature Support
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36954: [Sema] Update release notes with details of implicit scalar to vector conversions

2017-08-22 Thread Simon Dardis via Phabricator via cfe-commits
sdardis added a comment.

Thanks,
Simon


Repository:
  rL LLVM

https://reviews.llvm.org/D36954



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


r311442 - Fix templated type alias completion when using global completion cache

2017-08-22 Thread Erik Verbruggen via cfe-commits
Author: erikjv
Date: Tue Aug 22 03:25:48 2017
New Revision: 311442

URL: http://llvm.org/viewvc/llvm-project?rev=311442&view=rev
Log:
Fix templated type alias completion when using global completion cache

When we have enabled cache for global completions we did not have
diagnostics for Bar and could not complete Ba as in provided code
example.

template 
struct Foo { T member; };

template using Bar = Foo;

int main() {
Ba
}

Patch by Ivan Donchevskii!

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


Modified:
cfe/trunk/lib/Frontend/ASTUnit.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/test/Index/code-completion.cpp

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=311442&r1=311441&r2=311442&view=diff
==
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Tue Aug 22 03:25:48 2017
@@ -243,7 +243,8 @@ static unsigned getDeclShowContexts(cons
   
   uint64_t Contexts = 0;
   if (isa(ND) || isa(ND) || 
-  isa(ND) || isa(ND)) {
+  isa(ND) || isa(ND) ||
+  isa(ND)) {
 // Types can appear in these contexts.
 if (LangOpts.CPlusPlus || !isa(ND))
   Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel)

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=311442&r1=311441&r2=311442&view=diff
==
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Tue Aug 22 03:25:48 2017
@@ -198,9 +198,11 @@ Parser::ParseSingleDeclarationAfterTempl
 
   if (Tok.is(tok::kw_using)) {
 // FIXME: We should return the DeclGroup to the caller.
-ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
- prefixAttrs);
-return nullptr;
+auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, 
TemplateInfo, DeclEnd,
+ prefixAttrs);
+if (!usingDeclPtr)
+  return nullptr;
+return usingDeclPtr.get().getSingleDecl();
   }
 
   // Parse the declaration specifiers, stealing any diagnostics from
@@ -1023,8 +1025,8 @@ bool Parser::AnnotateTemplateIdToken(Tem
 ? OO_None
 : TemplateName.OperatorFunctionId.Operator;
 
-TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
-  SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
+TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
+  SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
   LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds);
 
 Tok.setAnnotationValue(TemplateId);

Modified: cfe/trunk/test/Index/code-completion.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/code-completion.cpp?rev=311442&r1=311441&r2=311442&view=diff
==
--- cfe/trunk/test/Index/code-completion.cpp (original)
+++ cfe/trunk/test/Index/code-completion.cpp Tue Aug 22 03:25:48 2017
@@ -37,6 +37,16 @@ Z::operator int() const {
   return 0;
 }
 
+template 
+struct Foo { T member; };
+
+template using Bar = Foo;
+
+void test_template_alias() {
+  // RUN: env CINDEXTEST_COMPLETION_CACHING=1 c-index-test 
-code-completion-at=%s:47:1 %s | FileCheck -check-prefix=CHECK-TEMPLATE-ALIAS %s
+
+}
+
 // CHECK-MEMBER: FieldDecl:{ResultType double}{TypedText member}
 // CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member}
 // CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member}
@@ -88,3 +98,5 @@ Z::operator int() const {
 // CHECK-EXPR-NEXT: Class name
 // CHECK-EXPR-NEXT: Nested name specifier
 // CHECK-EXPR-NEXT: Objective-C interface
+
+// CHECK-TEMPLATE-ALIAS: AliasTemplateDecl:{TypedText Bar}{LeftAngle 
<}{Placeholder typename T}{RightAngle >} (50)


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


[PATCH] D35355: Fix templated type alias completion when using global completion cache

2017-08-22 Thread Erik Verbruggen via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL311442: Fix templated type alias completion when using 
global completion cache (authored by erikjv).

Changed prior to commit:
  https://reviews.llvm.org/D35355?vs=109968&id=112144#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D35355

Files:
  cfe/trunk/lib/Frontend/ASTUnit.cpp
  cfe/trunk/lib/Parse/ParseTemplate.cpp
  cfe/trunk/test/Index/code-completion.cpp


Index: cfe/trunk/test/Index/code-completion.cpp
===
--- cfe/trunk/test/Index/code-completion.cpp
+++ cfe/trunk/test/Index/code-completion.cpp
@@ -37,6 +37,16 @@
   return 0;
 }
 
+template 
+struct Foo { T member; };
+
+template using Bar = Foo;
+
+void test_template_alias() {
+  // RUN: env CINDEXTEST_COMPLETION_CACHING=1 c-index-test 
-code-completion-at=%s:47:1 %s | FileCheck -check-prefix=CHECK-TEMPLATE-ALIAS %s
+
+}
+
 // CHECK-MEMBER: FieldDecl:{ResultType double}{TypedText member}
 // CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member}
 // CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member}
@@ -88,3 +98,5 @@
 // CHECK-EXPR-NEXT: Class name
 // CHECK-EXPR-NEXT: Nested name specifier
 // CHECK-EXPR-NEXT: Objective-C interface
+
+// CHECK-TEMPLATE-ALIAS: AliasTemplateDecl:{TypedText Bar}{LeftAngle 
<}{Placeholder typename T}{RightAngle >} (50)
Index: cfe/trunk/lib/Frontend/ASTUnit.cpp
===
--- cfe/trunk/lib/Frontend/ASTUnit.cpp
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp
@@ -243,7 +243,8 @@
   
   uint64_t Contexts = 0;
   if (isa(ND) || isa(ND) || 
-  isa(ND) || isa(ND)) {
+  isa(ND) || isa(ND) ||
+  isa(ND)) {
 // Types can appear in these contexts.
 if (LangOpts.CPlusPlus || !isa(ND))
   Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel)
Index: cfe/trunk/lib/Parse/ParseTemplate.cpp
===
--- cfe/trunk/lib/Parse/ParseTemplate.cpp
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp
@@ -198,9 +198,11 @@
 
   if (Tok.is(tok::kw_using)) {
 // FIXME: We should return the DeclGroup to the caller.
-ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
- prefixAttrs);
-return nullptr;
+auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, 
TemplateInfo, DeclEnd,
+ prefixAttrs);
+if (!usingDeclPtr)
+  return nullptr;
+return usingDeclPtr.get().getSingleDecl();
   }
 
   // Parse the declaration specifiers, stealing any diagnostics from
@@ -1023,8 +1025,8 @@
 ? OO_None
 : TemplateName.OperatorFunctionId.Operator;
 
-TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
-  SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
+TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
+  SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
   LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds);
 
 Tok.setAnnotationValue(TemplateId);


Index: cfe/trunk/test/Index/code-completion.cpp
===
--- cfe/trunk/test/Index/code-completion.cpp
+++ cfe/trunk/test/Index/code-completion.cpp
@@ -37,6 +37,16 @@
   return 0;
 }
 
+template 
+struct Foo { T member; };
+
+template using Bar = Foo;
+
+void test_template_alias() {
+  // RUN: env CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:47:1 %s | FileCheck -check-prefix=CHECK-TEMPLATE-ALIAS %s
+
+}
+
 // CHECK-MEMBER: FieldDecl:{ResultType double}{TypedText member}
 // CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member}
 // CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member}
@@ -88,3 +98,5 @@
 // CHECK-EXPR-NEXT: Class name
 // CHECK-EXPR-NEXT: Nested name specifier
 // CHECK-EXPR-NEXT: Objective-C interface
+
+// CHECK-TEMPLATE-ALIAS: AliasTemplateDecl:{TypedText Bar}{LeftAngle <}{Placeholder typename T}{RightAngle >} (50)
Index: cfe/trunk/lib/Frontend/ASTUnit.cpp
===
--- cfe/trunk/lib/Frontend/ASTUnit.cpp
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp
@@ -243,7 +243,8 @@
   
   uint64_t Contexts = 0;
   if (isa(ND) || isa(ND) || 
-  isa(ND) || isa(ND)) {
+  isa(ND) || isa(ND) ||
+  isa(ND)) {
 // Types can appear in these contexts.
 if (LangOpts.CPlusPlus || !isa(ND))
   Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel)
Index: cfe/trunk/lib/Parse/ParseTemplate.cpp
===
--- cfe/trunk/lib/Parse/ParseTemplate.cpp
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp
@@ -198,9 +198,11 @@
 
   if (Tok.is(tok::kw_using)) {
 // FIXME: We should return the DeclGroup to the caller.
-ParseUsingDirec

r311443 - [ObjC] Check written attributes only when synthesizing ambiguous property

2017-08-22 Thread Alex Lorenz via cfe-commits
Author: arphaman
Date: Tue Aug 22 03:38:07 2017
New Revision: 311443

URL: http://llvm.org/viewvc/llvm-project?rev=311443&view=rev
Log:
[ObjC] Check written attributes only when synthesizing ambiguous property

This commit fixes a bug introduced in r307903. The attribute ambiguity checker
that was introduced in r307903 checked all property attributes, which caused
errors for source-compatible properties, like:

@property (nonatomic, readonly) NSObject *prop;
@property (nonatomic, readwrite) NSObject *prop;

because the readwrite property would get implicit 'strong' attribute. The
ambiguity checker should be concerned about explicitly specified attributes
only.

rdar://33748089

Modified:
cfe/trunk/lib/Sema/SemaObjCProperty.cpp
cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=311443&r1=311442&r2=311443&view=diff
==
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Tue Aug 22 03:38:07 2017
@@ -872,7 +872,7 @@ SelectPropertyForSynthesisFromProtocols(
   }
 
   QualType RHSType = S.Context.getCanonicalType(Property->getType());
-  unsigned OriginalAttributes = Property->getPropertyAttributes();
+  unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();
   enum MismatchKind {
 IncompatibleType = 0,
 HasNoExpectedAttribute,
@@ -890,7 +890,7 @@ SelectPropertyForSynthesisFromProtocols(
   SmallVector Mismatches;
   for (ObjCPropertyDecl *Prop : Properties) {
 // Verify the property attributes.
-unsigned Attr = Prop->getPropertyAttributes();
+unsigned Attr = Prop->getPropertyAttributesAsWritten();
 if (Attr != OriginalAttributes) {
   auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName) {
 MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute

Modified: cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m?rev=311443&r1=311442&r2=311443&view=diff
==
--- cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m (original)
+++ cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m Tue Aug 22 03:38:07 2017
@@ -225,3 +225,30 @@ __attribute__((objc_root_class))
 @implementation TypeVsSetter
 @synthesize prop; // expected-note {{property synthesized here}}
 @end
+
+@protocol AutoStrongProp
+
+@property (nonatomic, readonly) NSObject *prop;
+
+@end
+
+@protocol AutoStrongProp_Internal 
+
+// This property gets the 'strong' attribute automatically.
+@property (nonatomic, readwrite) NSObject *prop;
+
+@end
+
+@interface SynthesizeWithImplicitStrongNoError : NSObject 
+@end
+
+@interface SynthesizeWithImplicitStrongNoError () 
+
+@end
+
+@implementation SynthesizeWithImplicitStrongNoError
+
+// no error, 'strong' is implicit in the 'readwrite' property.
+@synthesize prop = _prop;
+
+@end


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


[PATCH] D35271: Fix printing policy for AST context loaded from file

2017-08-22 Thread Johann KlƤhn via Phabricator via cfe-commits
jklaehn updated this revision to Diff 112139.
jklaehn added a reviewer: akyrtzi.
jklaehn added a comment.
Herald added a subscriber: mgorny.

Added regression test.


https://reviews.llvm.org/D35271

Files:
  lib/Frontend/ASTUnit.cpp
  unittests/Frontend/ASTUnitTest.cpp
  unittests/Frontend/CMakeLists.txt

Index: unittests/Frontend/CMakeLists.txt
===
--- unittests/Frontend/CMakeLists.txt
+++ unittests/Frontend/CMakeLists.txt
@@ -3,6 +3,7 @@
   )
 
 add_clang_unittest(FrontendTests
+  ASTUnitTest.cpp
   FrontendActionTest.cpp
   CodeGenActionTest.cpp
   )
Index: unittests/Frontend/ASTUnitTest.cpp
===
--- /dev/null
+++ unittests/Frontend/ASTUnitTest.cpp
@@ -0,0 +1,113 @@
+//===- unittests/Frontend/ASTUnitTest.cpp - ASTUnit tests -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include 
+
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/PCHContainerOperations.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+
+class ASTUnitTest : public ::testing::Test {
+  std::set TemporaryFiles;
+  std::string TestDir;
+
+public:
+  void SetUp() override {
+llvm::SmallString<256> Dir;
+ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("astunit-test", Dir));
+TestDir = Dir.str();
+  }
+
+  void TearDown() override {
+for (const std::string &Path : TemporaryFiles)
+  llvm::sys::fs::remove(Path);
+llvm::sys::fs::remove(TestDir);
+  }
+
+  void MarkTemporaryFile(std::string &Filename) {
+assert(!llvm::sys::path::is_absolute(Filename));
+llvm::SmallString<256> Path(TestDir);
+llvm::sys::path::append(Path, Filename);
+Filename = Path.str();
+TemporaryFiles.insert(Filename);
+llvm::sys::fs::create_directories(llvm::sys::path::parent_path(Filename));
+  }
+};
+
+TEST_F(ASTUnitTest, SaveLoadPreservesLangOptionsInPrintingPolicy) {
+  // Check that the printing policy is restored with the correct language
+  // options when loading an ASTUnit from a file.  To this end, an ASTUnit
+  // for a C++ translation unit is set up and written to a temporary file.
+
+  // By default `UseVoidForZeroParams` is true for non-C++ language options,
+  // thus we can check this field after loading the ASTUnit to deduce whether
+  // the correct (C++) language options were used when setting up the printing
+  // policy.
+
+  {
+PrintingPolicy PolicyWithDefaultLangOpt(LangOptions{});
+EXPECT_TRUE(PolicyWithDefaultLangOpt.UseVoidForZeroParams);
+  }
+
+  std::string FileName = "empty_file.cpp";
+  MarkTemporaryFile(FileName);
+  std::ofstream OS(FileName);
+  OS << "";
+  ASSERT_TRUE(OS.good());
+
+  const char* Args[] = {"clang", "-xc++", FileName.c_str()};
+
+  IntrusiveRefCntPtr Diags =
+  CompilerInstance::createDiagnostics(new DiagnosticOptions());
+
+  std::shared_ptr CInvok =
+  createInvocationFromCommandLine(Args, Diags);
+
+  if (!CInvok)
+FAIL() << "could not create compiler invocation";
+
+  IntrusiveRefCntPtr VFS(new vfs::InMemoryFileSystem);
+  VFS->addFile(FileName, 0, llvm::MemoryBuffer::getMemBuffer(""));
+  FileManager *FileMgr = new FileManager(FileSystemOptions(), VFS);
+  auto PCHContainerOps = std::make_shared();
+
+  std::unique_ptr AST = ASTUnit::LoadFromCompilerInvocation(
+  CInvok, PCHContainerOps, Diags, FileMgr);
+
+  if (!AST)
+FAIL() << "failed to create ASTUnit";
+
+  EXPECT_FALSE(AST->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
+
+  std::string Path = "printing_policy.ast";
+  MarkTemporaryFile(Path);
+  AST->Save(Path);
+
+  EXPECT_TRUE(llvm::sys::fs::exists(Path));
+
+  std::unique_ptr AU = ASTUnit::LoadFromASTFile(
+  Path, PCHContainerOps->getRawReader(), ASTUnit::LoadEverything, Diags,
+  FileSystemOptions(), /*UseDebugInfo=*/false);
+
+  if (!AU)
+FAIL() << "failed to load ASTUnit";
+
+  EXPECT_FALSE(AU->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
+}
+
+} // anonymous namespace
Index: lib/Frontend/ASTUnit.cpp
===
--- lib/Frontend/ASTUnit.cpp
+++ lib/Frontend/ASTUnit.cpp
@@ -542,6 +542,9 @@
 // Initialize the ASTContext
 Context->InitBuiltinTypes(*Target);
 
+// Adjust printing policy based on language options.
+Context->setPrintingPolicy(PrintingPolicy(LangOpt));
+
 // We didn't have access to the comment options when the ASTContext was
 // constructed, so register them now.
 Context->getCommentCommandTraits().registerComment

Re: r311443 - [ObjC] Check written attributes only when synthesizing ambiguous property

2017-08-22 Thread Alex L via cfe-commits
Hi Hans,

Can you please merge this into LLVM 5? It fixes a rather serious
Objective-C bug that I introduced just a couple of weeks before the branch.

Cheers,
Alex

On 22 August 2017 at 11:38, Alex Lorenz via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> Author: arphaman
> Date: Tue Aug 22 03:38:07 2017
> New Revision: 311443
>
> URL: http://llvm.org/viewvc/llvm-project?rev=311443&view=rev
> Log:
> [ObjC] Check written attributes only when synthesizing ambiguous property
>
> This commit fixes a bug introduced in r307903. The attribute ambiguity
> checker
> that was introduced in r307903 checked all property attributes, which
> caused
> errors for source-compatible properties, like:
>
> @property (nonatomic, readonly) NSObject *prop;
> @property (nonatomic, readwrite) NSObject *prop;
>
> because the readwrite property would get implicit 'strong' attribute. The
> ambiguity checker should be concerned about explicitly specified attributes
> only.
>
> rdar://33748089
>
> Modified:
> cfe/trunk/lib/Sema/SemaObjCProperty.cpp
> cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m
>
> Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaO
> bjCProperty.cpp?rev=311443&r1=311442&r2=311443&view=diff
> 
> ==
> --- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Tue Aug 22 03:38:07 2017
> @@ -872,7 +872,7 @@ SelectPropertyForSynthesisFromProtocols(
>}
>
>QualType RHSType = S.Context.getCanonicalType(Property->getType());
> -  unsigned OriginalAttributes = Property->getPropertyAttributes();
> +  unsigned OriginalAttributes = Property->getPropertyAttribute
> sAsWritten();
>enum MismatchKind {
>  IncompatibleType = 0,
>  HasNoExpectedAttribute,
> @@ -890,7 +890,7 @@ SelectPropertyForSynthesisFromProtocols(
>SmallVector Mismatches;
>for (ObjCPropertyDecl *Prop : Properties) {
>  // Verify the property attributes.
> -unsigned Attr = Prop->getPropertyAttributes();
> +unsigned Attr = Prop->getPropertyAttributesAsWritten();
>  if (Attr != OriginalAttributes) {
>auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName)
> {
>  MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute
>
> Modified: cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/
> arc-property-decl-attrs.m?rev=311443&r1=311442&r2=311443&view=diff
> 
> ==
> --- cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m (original)
> +++ cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m Tue Aug 22 03:38:07
> 2017
> @@ -225,3 +225,30 @@ __attribute__((objc_root_class))
>  @implementation TypeVsSetter
>  @synthesize prop; // expected-note {{property synthesized here}}
>  @end
> +
> +@protocol AutoStrongProp
> +
> +@property (nonatomic, readonly) NSObject *prop;
> +
> +@end
> +
> +@protocol AutoStrongProp_Internal 
> +
> +// This property gets the 'strong' attribute automatically.
> +@property (nonatomic, readwrite) NSObject *prop;
> +
> +@end
> +
> +@interface SynthesizeWithImplicitStrongNoError : NSObject
> 
> +@end
> +
> +@interface SynthesizeWithImplicitStrongNoError ()
> 
> +
> +@end
> +
> +@implementation SynthesizeWithImplicitStrongNoError
> +
> +// no error, 'strong' is implicit in the 'readwrite' property.
> +@synthesize prop = _prop;
> +
> +@end
>
>
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r311445 - Revert r311442 (Fix templated type alias completion when using global completion cache)

2017-08-22 Thread Erik Verbruggen via cfe-commits
Author: erikjv
Date: Tue Aug 22 03:54:40 2017
New Revision: 311445

URL: http://llvm.org/viewvc/llvm-project?rev=311445&view=rev
Log:
Revert r311442 (Fix templated type alias completion when using global 
completion cache)

Failing Tests (2):
Clang :: CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
Clang :: SemaCXX/alias-template.cpp


Modified:
cfe/trunk/lib/Frontend/ASTUnit.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/test/Index/code-completion.cpp

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=311445&r1=311444&r2=311445&view=diff
==
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Tue Aug 22 03:54:40 2017
@@ -243,8 +243,7 @@ static unsigned getDeclShowContexts(cons
   
   uint64_t Contexts = 0;
   if (isa(ND) || isa(ND) || 
-  isa(ND) || isa(ND) ||
-  isa(ND)) {
+  isa(ND) || isa(ND)) {
 // Types can appear in these contexts.
 if (LangOpts.CPlusPlus || !isa(ND))
   Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel)

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=311445&r1=311444&r2=311445&view=diff
==
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Tue Aug 22 03:54:40 2017
@@ -198,11 +198,9 @@ Parser::ParseSingleDeclarationAfterTempl
 
   if (Tok.is(tok::kw_using)) {
 // FIXME: We should return the DeclGroup to the caller.
-auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, 
TemplateInfo, DeclEnd,
- prefixAttrs);
-if (!usingDeclPtr)
-  return nullptr;
-return usingDeclPtr.get().getSingleDecl();
+ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
+ prefixAttrs);
+return nullptr;
   }
 
   // Parse the declaration specifiers, stealing any diagnostics from
@@ -1025,8 +1023,8 @@ bool Parser::AnnotateTemplateIdToken(Tem
 ? OO_None
 : TemplateName.OperatorFunctionId.Operator;
 
-TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
-  SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
+TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
+  SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
   LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds);
 
 Tok.setAnnotationValue(TemplateId);

Modified: cfe/trunk/test/Index/code-completion.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/code-completion.cpp?rev=311445&r1=311444&r2=311445&view=diff
==
--- cfe/trunk/test/Index/code-completion.cpp (original)
+++ cfe/trunk/test/Index/code-completion.cpp Tue Aug 22 03:54:40 2017
@@ -37,16 +37,6 @@ Z::operator int() const {
   return 0;
 }
 
-template 
-struct Foo { T member; };
-
-template using Bar = Foo;
-
-void test_template_alias() {
-  // RUN: env CINDEXTEST_COMPLETION_CACHING=1 c-index-test 
-code-completion-at=%s:47:1 %s | FileCheck -check-prefix=CHECK-TEMPLATE-ALIAS %s
-
-}
-
 // CHECK-MEMBER: FieldDecl:{ResultType double}{TypedText member}
 // CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member}
 // CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member}
@@ -98,5 +88,3 @@ void test_template_alias() {
 // CHECK-EXPR-NEXT: Class name
 // CHECK-EXPR-NEXT: Nested name specifier
 // CHECK-EXPR-NEXT: Objective-C interface
-
-// CHECK-TEMPLATE-ALIAS: AliasTemplateDecl:{TypedText Bar}{LeftAngle 
<}{Placeholder typename T}{RightAngle >} (50)


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


[PATCH] D36956: [clang-format] Emit absolute splits before lines for comments

2017-08-22 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir updated this revision to Diff 112147.
krasimir marked 3 inline comments as done.
krasimir added a comment.

- Address review comments


https://reviews.llvm.org/D36956

Files:
  lib/Format/BreakableToken.cpp
  unittests/Format/FormatTestComments.cpp


Index: unittests/Format/FormatTestComments.cpp
===
--- unittests/Format/FormatTestComments.cpp
+++ unittests/Format/FormatTestComments.cpp
@@ -2780,6 +2780,23 @@
"* long */",
getLLVMStyleWithColumns(20)));
 }
+
+TEST_F(FormatTestComments, NoCrush_Bug34236) {
+  // This is a test case from a crasher reported in:
+  // https://bugs.llvm.org/show_bug.cgi?id=34236
+  EXPECT_EQ(
+  R"(
+/**/ /*
+  *   a
+  * b c
+  * d*/)",
+  format(
+  R"(
+/**/ /*
+ *   a b
+ *   c d*/)",
+  getLLVMStyleWithColumns(80)));
+}
 } // end namespace
 } // end namespace format
 } // end namespace clang
Index: lib/Format/BreakableToken.cpp
===
--- lib/Format/BreakableToken.cpp
+++ lib/Format/BreakableToken.cpp
@@ -545,15 +545,18 @@
 }
 
 BreakableToken::Split BreakableBlockComment::getSplitBefore(
-unsigned LineIndex,
-unsigned PreviousEndColumn,
-unsigned ColumnLimit,
+unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit,
 llvm::Regex &CommentPragmasRegex) const {
   if (!mayReflow(LineIndex, CommentPragmasRegex))
 return Split(StringRef::npos, 0);
   StringRef TrimmedContent = Content[LineIndex].ltrim(Blanks);
-  return getReflowSplit(TrimmedContent, ReflowPrefix, PreviousEndColumn,
-ColumnLimit);
+  Split Result = getReflowSplit(TrimmedContent, ReflowPrefix, 
PreviousEndColumn,
+ColumnLimit);
+  // Result is relative to TrimmedContent. Adapt it relative to
+  // Content[LineIndex].
+  if (Result.first != StringRef::npos)
+Result.first += Content[LineIndex].size() - TrimmedContent.size();
+  return Result;
 }
 
 unsigned BreakableBlockComment::getReflownColumn(
@@ -633,17 +636,12 @@
 /*CurrentPrefix=*/ReflowPrefix, InPPDirective, /*Newlines=*/0,
 /*Spaces=*/0);
 // Check if we need to also insert a break at the whitespace range.
-// For this we first adapt the reflow split relative to the beginning of 
the
-// content.
 // Note that we don't need a penalty for this break, since it doesn't 
change
 // the total number of lines.
-Split BreakSplit = SplitBefore;
-BreakSplit.first += TrimmedContent.data() - Content[LineIndex].data();
 unsigned ReflownColumn =
 getReflownColumn(TrimmedContent, LineIndex, PreviousEndColumn);
-if (ReflownColumn > ColumnLimit) {
-  insertBreak(LineIndex, 0, BreakSplit, Whitespaces);
-}
+if (ReflownColumn > ColumnLimit)
+  insertBreak(LineIndex, 0, SplitBefore, Whitespaces);
 return;
   }
 


Index: unittests/Format/FormatTestComments.cpp
===
--- unittests/Format/FormatTestComments.cpp
+++ unittests/Format/FormatTestComments.cpp
@@ -2780,6 +2780,23 @@
"* long */",
getLLVMStyleWithColumns(20)));
 }
+
+TEST_F(FormatTestComments, NoCrush_Bug34236) {
+  // This is a test case from a crasher reported in:
+  // https://bugs.llvm.org/show_bug.cgi?id=34236
+  EXPECT_EQ(
+  R"(
+/**/ /*
+  *   a
+  * b c
+  * d*/)",
+  format(
+  R"(
+/**/ /*
+ *   a b
+ *   c d*/)",
+  getLLVMStyleWithColumns(80)));
+}
 } // end namespace
 } // end namespace format
 } // end namespace clang
Index: lib/Format/BreakableToken.cpp
===
--- lib/Format/BreakableToken.cpp
+++ lib/Format/BreakableToken.cpp
@@ -545,15 +545,18 @@
 }
 
 BreakableToken::Split BreakableBlockComment::getSplitBefore(
-unsigned LineIndex,
-unsigned PreviousEndColumn,
-unsigned ColumnLimit,
+unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit,
 llvm::Regex &CommentPragmasRegex) const {
   if (!mayReflow(LineIndex, CommentPragmasRegex))
 return Split(StringRef::npos, 0);
   StringRef TrimmedContent = Content[LineIndex].ltrim(Blanks);

[PATCH] D36824: [mips] Rename getSupportedNanEncoding() to getIEEE754Standard() (NFC)

2017-08-22 Thread Aleksandar Beserminji via Phabricator via cfe-commits
abeserminji updated this revision to Diff 112150.
abeserminji added a comment.
Herald added a subscriber: arichardson.

Comment resolved.


Repository:
  rL LLVM

https://reviews.llvm.org/D36824

Files:
  lib/Basic/Targets/Mips.h
  lib/Driver/ToolChains/Arch/Mips.cpp
  lib/Driver/ToolChains/Arch/Mips.h

Index: lib/Driver/ToolChains/Arch/Mips.h
===
--- lib/Driver/ToolChains/Arch/Mips.h
+++ lib/Driver/ToolChains/Arch/Mips.h
@@ -24,15 +24,15 @@
 bool isMipsArch(llvm::Triple::ArchType Arch);
 
 namespace mips {
-typedef enum { NanLegacy = 1, Nan2008 = 2 } NanEncoding;
+typedef enum { Legacy = 1, Std2008 = 2 } IEEE754Standard;
 
 enum class FloatABI {
   Invalid,
   Soft,
   Hard,
 };
 
-NanEncoding getSupportedNanEncoding(StringRef &CPU);
+IEEE754Standard getIEEE754Standard(StringRef &CPU);
 bool hasCompactBranches(StringRef &CPU);
 void getMipsCPUAndABI(const llvm::opt::ArgList &Args,
   const llvm::Triple &Triple, StringRef &CPUName,
Index: lib/Driver/ToolChains/Arch/Mips.cpp
===
--- lib/Driver/ToolChains/Arch/Mips.cpp
+++ lib/Driver/ToolChains/Arch/Mips.cpp
@@ -265,14 +265,14 @@
   if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
 StringRef Val = StringRef(A->getValue());
 if (Val == "2008") {
-  if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008)
+  if (mips::getIEEE754Standard(CPUName) & mips::Std2008)
 Features.push_back("+nan2008");
   else {
 Features.push_back("-nan2008");
 D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
   }
 } else if (Val == "legacy") {
-  if (mips::getSupportedNanEncoding(CPUName) & mips::NanLegacy)
+  if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
 Features.push_back("-nan2008");
   else {
 Features.push_back("+nan2008");
@@ -323,27 +323,28 @@
   AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
 }
 
-mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) {
-  // Strictly speaking, mips32r2 and mips64r2 are NanLegacy-only since Nan2008
-  // was first introduced in Release 3. However, other compilers have
-  // traditionally allowed it for Release 2 so we should do the same.
-  return (NanEncoding)llvm::StringSwitch(CPU)
-  .Case("mips1", NanLegacy)
-  .Case("mips2", NanLegacy)
-  .Case("mips3", NanLegacy)
-  .Case("mips4", NanLegacy)
-  .Case("mips5", NanLegacy)
-  .Case("mips32", NanLegacy)
-  .Case("mips32r2", NanLegacy | Nan2008)
-  .Case("mips32r3", NanLegacy | Nan2008)
-  .Case("mips32r5", NanLegacy | Nan2008)
-  .Case("mips32r6", Nan2008)
-  .Case("mips64", NanLegacy)
-  .Case("mips64r2", NanLegacy | Nan2008)
-  .Case("mips64r3", NanLegacy | Nan2008)
-  .Case("mips64r5", NanLegacy | Nan2008)
-  .Case("mips64r6", Nan2008)
-  .Default(NanLegacy);
+mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
+  // Strictly speaking, mips32r2 and mips64r2 do not conform to the
+  // IEEE754-2008 standard. Support for this standard was first introduced
+  // in Release 3. However, other compilers have traditionally allowed it
+  // for Release 2 so we should do the same.
+  return (IEEE754Standard)llvm::StringSwitch(CPU)
+  .Case("mips1", Legacy)
+  .Case("mips2", Legacy)
+  .Case("mips3", Legacy)
+  .Case("mips4", Legacy)
+  .Case("mips5", Legacy)
+  .Case("mips32", Legacy)
+  .Case("mips32r2", Legacy | Std2008)
+  .Case("mips32r3", Legacy | Std2008)
+  .Case("mips32r5", Legacy | Std2008)
+  .Case("mips32r6", Std2008)
+  .Case("mips64", Legacy)
+  .Case("mips64r2", Legacy | Std2008)
+  .Case("mips64r3", Legacy | Std2008)
+  .Case("mips64r5", Legacy | Std2008)
+  .Case("mips64r6", Std2008)
+  .Default(Std2008);
 }
 
 bool mips::hasCompactBranches(StringRef &CPU) {
Index: lib/Basic/Targets/Mips.h
===
--- lib/Basic/Targets/Mips.h
+++ lib/Basic/Targets/Mips.h
@@ -77,7 +77,7 @@
 Triple.getOS() == llvm::Triple::OpenBSD;
   }
 
-  bool isNaN2008Default() const {
+  bool isIEEE754_2008Default() const {
 return CPU == "mips32r6" || CPU == "mips64r6";
   }
 
@@ -299,7 +299,7 @@
 DiagnosticsEngine &Diags) override {
 IsMips16 = false;
 IsMicromips = false;
-IsNan2008 = isNaN2008Default();
+IsNan2008 = isIEEE754_2008Default();
 IsSingleFloat = false;
 FloatABI = HardFloat;
 DspRev = NoDSP;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36876: [IRGen] Evaluate constant static variables referenced through member expressions

2017-08-22 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman updated this revision to Diff 112149.
arphaman added a comment.

Revert most of the changes and use temporary DREs as suggested by John.


Repository:
  rL LLVM

https://reviews.llvm.org/D36876

Files:
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprScalar.cpp
  test/CodeGenCXX/member-expr-references-variable.cpp

Index: test/CodeGenCXX/member-expr-references-variable.cpp
===
--- /dev/null
+++ test/CodeGenCXX/member-expr-references-variable.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Struct {
+   constexpr static const char *name = "foo";
+
+   constexpr static __complex float complexValue = 42.0;
+
+   Struct();
+   Struct(int x);
+};
+
+void use(int n, const char *c);
+
+Struct *getPtr();
+
+// CHECK: @[[STR:.*]] = private unnamed_addr constant [4 x i8] c"foo\00", align 1
+
+void scalarStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+  use(1, Struct::name);
+// CHECK: call void @_Z3useiPKc(i32 1, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+  Struct s;
+  use(2, s.name);
+// CHECK: call void @_Z3useiPKc(i32 2, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+  use(3, ptr->name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 3, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+  use(4, ref.name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 4, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+  use(5, Struct(2).name);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: call void @_Z3useiPKc(i32 5, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+  use(6, getPtr()->name);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: call void @_Z3useiPKc(i32 6, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+}
+
+void use(int n, __complex float v);
+
+void complexStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+  use(1, Struct::complexValue);
+// CHECK: store float 4.20e+01, float* %[[coerce0:.*]].{{.*}}, align 4
+// CHECK: store float 0.00e+00, float* %[[coerce0]].{{.*}}, align 4
+// CHECK: %[[cast0:.*]] = bitcast { float, float }* %[[coerce0]] to <2 x float>*
+// CHECK: %[[vector0:.*]] = load <2 x float>, <2 x float>* %[[cast0]], align 4
+// CHECK: call void @_Z3useiCf(i32 1, <2 x float> %[[vector0]])
+  Struct s;
+  use(2, s.complexValue);
+// CHECK: store float 4.20e+01, float* %[[coerce1:.*]].{{.*}}, align 4
+// CHECK: store float 0.00e+00, float* %[[coerce1]].{{.*}}, align 4
+// CHECK: %[[cast1:.*]] = bitcast { float, float }* %[[coerce1]] to <2 x float>*
+// CHECK: %[[vector1:.*]] = load <2 x float>, <2 x float>* %[[cast1]], align 4
+// CHECK: call void @_Z3useiCf(i32 2, <2 x float> %[[vector1]])
+  use(3, ptr->complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.20e+01, float* %[[coerce2:.*]].{{.*}}, align 4
+// CHECK: store float 0.00e+00, float* %[[coerce2]].{{.*}}, align 4
+// CHECK: %[[cast2:.*]] = bitcast { float, float }* %[[coerce2]] to <2 x float>*
+// CHECK: %[[vector2:.*]] = load <2 x float>, <2 x float>* %[[cast2]], align 4
+// CHECK: call void @_Z3useiCf(i32 3, <2 x float> %[[vector2]])
+  use(4, ref.complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.20e+01, float* %[[coerce3:.*]].{{.*}}, align 4
+// CHECK: store float 0.00e+00, float* %[[coerce3]].{{.*}}, align 4
+// CHECK: %[[cast3:.*]] = bitcast { float, float }* %[[coerce3]] to <2 x float>*
+// CHECK: %[[vector3:.*]] = load <2 x float>, <2 x float>* %[[cast3]], align 4
+// CHECK: call void @_Z3useiCf(i32 4, <2 x float> %[[vector3]])
+  use(5, Struct(2).complexValue);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: store float 4.20e+01, float* %[[coerce4:.*]].{{.*}}, align 4
+// CHECK: store float 0.00e+00, float* %[[coerce4]].{{.*}}, align 4
+// CHECK: %[[cast4:.*]] = bitcast { float, float }* %[[coerce4]] to <2 x float>*
+// CHECK: %[[vector4:.*]] = load <2 x float>, <2 x float>* %[[cast4]], align 4
+// CHECK: call void @_Z3useiCf(i32 5, <2 x float> %[[vector4]])
+  use(6, getPtr()->complexValue);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: store float 4.20e+01, float* %[[coerce5:.*]].{{.*}}, align 4
+// CHECK: store float 0.00e+00, float* %[[coerce5]].{{.*}}, align 4
+// CHECK: %[[cast5:.*]] = bitcast { float, float }* %[[coerce5]] to <2 x float>*
+// CHECK: %[[vector5:.*]] = load <2 x float>, <2 x float>* %[[cast5]], align 4
+// CHECK: call void @_Z3useiCf(i32 6, <2 x float> %[[vector5]])
+}
Index: lib/CodeGen/CGExprScalar.cpp
===

[PATCH] D36969: [Basic] Add a DiagnosticOr type

2017-08-22 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman added a comment.

In https://reviews.llvm.org/D36969#847803, @vsk wrote:

> Would it be more convenient to extend ErrorInfo instead of creating a new 
> diagnostic wrapper? E.g one benefit of passing around Expected's is that 
> there's some assurance the diagnostics will be reported.


Possibly, but one issue I found with ErrorInfo is that it gets harder to report 
diagnostics. E.g. with `DiagnosticOr` you will be able to write:

  DiagnosticOr<...> function(RefactoringOperation &Op) {
return Op.Diag(Loc, err::something) << "invalid";
  }

But with `Expected` you'll have to use something like:

  Expected<...> function(RefactoringOperation &Op) {
return llvm::make_error(Op.Diag(Loc, err::something) << 
"invalid");
  }

I don't think that the assurance about reporting these diagnostics is that 
important for my case. They will be consumed at most in 3 places 
(clang-refactor, clangd, and libclang) and clangd and it will obvious to the 
user if errors aren't getting reported.


Repository:
  rL LLVM

https://reviews.llvm.org/D36969



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


[PATCH] D36969: [Basic] Add a DiagnosticOr type

2017-08-22 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman added a comment.

In https://reviews.llvm.org/D36969#848518, @arphaman wrote:

> In https://reviews.llvm.org/D36969#847803, @vsk wrote:
>
> > Would it be more convenient to extend ErrorInfo instead of creating a new 
> > diagnostic wrapper? E.g one benefit of passing around Expected's is that 
> > there's some assurance the diagnostics will be reported.
>
>
> Possibly, but one issue I found with ErrorInfo is that it gets harder to 
> report diagnostics. E.g. with `DiagnosticOr` you will be able to write:
>
>   DiagnosticOr<...> function(RefactoringOperation &Op) {
> return Op.Diag(Loc, err::something) << "invalid";
>   }
>
>
> But with `Expected` you'll have to use something like:
>
>   Expected<...> function(RefactoringOperation &Op) {
> return llvm::make_error(Op.Diag(Loc, err::something) << 
> "invalid");
>   }
>
>
> I don't think that the assurance about reporting these diagnostics is that 
> important for my case. They will be consumed at most in 3 places 
> (clang-refactor, clangd, and libclang) and clangd and it will obvious to the 
> user if errors aren't getting reported.


Although I guess I could always change the approach completely and use variadic 
templates instead of `<<`, e.g.:

  template
  Error RefactoringOperation::error(SourceLocation Loc, unsigned DiagId, const 
T &... Arguments) {
return llvm::make_error(...);
  }
  
  DiagnosticOr<...> function(RefactoringOperation &Op) {
 return Op.error(Loc, diag::err_something, "invalid");
  }

I think I'll try that instead.


Repository:
  rL LLVM

https://reviews.llvm.org/D36969



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


[PATCH] D36614: [clang-format] Refine trailing comment detection

2017-08-22 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir marked an inline comment as done.
krasimir added inline comments.



Comment at: lib/Format/FormatToken.h:397
+ (!Previous ||
+  Previous->isOneOf(tok::comma, tok::equal, tok::l_brace) ||
+  Next->is(tok::r_brace;

djasper wrote:
> Is this list coming from existing tests?
Yes.



Comment at: unittests/Format/FormatTestComments.cpp:461
+
+  verifyFormat("const /** comment comment comment comment */\n"
+   "A = B;",

djasper wrote:
> I wonder whether instead we should just break the comment here, even if it is 
> not a trailing one. Violating the column limit also seems bad. What happens 
> if we do that (i.e. break non-trailing comments)?
Thanks! I've tried this approach here: https://reviews.llvm.org/D37007


https://reviews.llvm.org/D36614



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


[PATCH] D33672: [analyzer] INT50-CPP. Do not cast to an out-of-range enumeration checker

2017-08-22 Thread Endre Fülöp via Phabricator via cfe-commits
gamesh411 updated this revision to Diff 112154.
gamesh411 added a comment.

I have implemented the std::transform. The previous version used std::for_each 
because the iterator for enum declarations was not a random access iterator, 
but it turned out that I can solve this problem via std::distance. Thanks for 
sticking to your opinion on this one, because I could learn something new.

As for the type size checking problem: I have noticed that there is already a 
generic overflow checker, and that would detect the the 'assigning invalid 
value to an enum' problem. The only advantage of doing it here is that we could 
probably give a more specific error diagnostic (then again this could be done 
in the overflow checker as well). So in my opinion that concern belongs there, 
and this checker should nevertheless belong in the generic optin package, 
because of the c-style cast is also checked in it.


https://reviews.llvm.org/D33672

Files:
  include/clang/StaticAnalyzer/Checkers/Checkers.td
  lib/StaticAnalyzer/Checkers/CMakeLists.txt
  lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
  test/Analysis/enum-cast-out-of-range.cpp

Index: test/Analysis/enum-cast-out-of-range.cpp
===
--- /dev/null
+++ test/Analysis/enum-cast-out-of-range.cpp
@@ -0,0 +1,181 @@
+// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=alpha.cplusplus.EnumCastOutOfRange -verify %s
+
+enum unscoped_unspecified_t {
+  unscoped_unspecified_0 = -4,
+  unscoped_unspecified_1,
+  unscoped_unspecified_2 = 1,
+  unscoped_unspecified_3,
+  unscoped_unspecified_4 = 4
+};
+
+enum unscoped_specified_t : int {
+  unscoped_specified_0 = -4,
+  unscoped_specified_1,
+  unscoped_specified_2 = 1,
+  unscoped_specified_3,
+  unscoped_specified_4 = 4
+};
+
+enum class scoped_unspecified_t {
+  scoped_unspecified_0 = -4,
+  scoped_unspecified_1,
+  scoped_unspecified_2 = 1,
+  scoped_unspecified_3,
+  scoped_unspecified_4 = 4
+};
+
+enum class scoped_specified_t : int {
+  scoped_specified_0 = -4,
+  scoped_specified_1,
+  scoped_specified_2 = 1,
+  scoped_specified_3,
+  scoped_specified_4 = 4
+};
+
+void unscopedUnspecified() {
+  unscoped_unspecified_t InvalidBeforeRangeBegin = static_cast(-5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidNegativeValue1 = static_cast(-4); // OK.
+  unscoped_unspecified_t ValidNegativeValue2 = static_cast(-3); // OK.
+  unscoped_unspecified_t InvalidInsideRange1 = static_cast(-2); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t InvalidInsideRange2 = static_cast(-1); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t InvalidInsideRange3 = static_cast(0); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidPositiveValue1 = static_cast(1); // OK.
+  unscoped_unspecified_t ValidPositiveValue2 = static_cast(2); // OK.
+  unscoped_unspecified_t InvalidInsideRange4 = static_cast(3); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidPositiveValue3 = static_cast(4); // OK.
+  unscoped_unspecified_t InvalidAfterRangeEnd = static_cast(5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+}
+
+void unscopedSpecified() {
+  unscoped_specified_t InvalidBeforeRangeBegin = static_cast(-5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidNegativeValue1 = static_cast(-4); // OK.
+  unscoped_specified_t ValidNegativeValue2 = static_cast(-3); // OK.
+  unscoped_specified_t InvalidInsideRange1 = static_cast(-2); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t InvalidInsideRange2 = static_cast(-1); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t InvalidInsideRange3 = static_cast(0); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidPositiveValue1 = static_cast(1); // OK.
+  unscoped_specified_t ValidPositiveValue2 = static_cast(2); // OK.
+  unscoped_specified_t InvalidInsideRange4 = static_cast(3); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidPositiveValue3 = static_cast(4); // OK.
+  unscoped_specified_t InvalidAfterRangeEnd = static_cast(5); // expected-warning {{the value

[PATCH] D33672: [analyzer] INT50-CPP. Do not cast to an out-of-range enumeration checker

2017-08-22 Thread Endre Fülöp via Phabricator via cfe-commits
gamesh411 updated this revision to Diff 112156.

https://reviews.llvm.org/D33672

Files:
  include/clang/StaticAnalyzer/Checkers/Checkers.td
  lib/StaticAnalyzer/Checkers/CMakeLists.txt
  lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
  test/Analysis/enum-cast-out-of-range.cpp

Index: test/Analysis/enum-cast-out-of-range.cpp
===
--- /dev/null
+++ test/Analysis/enum-cast-out-of-range.cpp
@@ -0,0 +1,181 @@
+// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=alpha.cplusplus.EnumCastOutOfRange -verify %s
+
+enum unscoped_unspecified_t {
+  unscoped_unspecified_0 = -4,
+  unscoped_unspecified_1,
+  unscoped_unspecified_2 = 1,
+  unscoped_unspecified_3,
+  unscoped_unspecified_4 = 4
+};
+
+enum unscoped_specified_t : int {
+  unscoped_specified_0 = -4,
+  unscoped_specified_1,
+  unscoped_specified_2 = 1,
+  unscoped_specified_3,
+  unscoped_specified_4 = 4
+};
+
+enum class scoped_unspecified_t {
+  scoped_unspecified_0 = -4,
+  scoped_unspecified_1,
+  scoped_unspecified_2 = 1,
+  scoped_unspecified_3,
+  scoped_unspecified_4 = 4
+};
+
+enum class scoped_specified_t : int {
+  scoped_specified_0 = -4,
+  scoped_specified_1,
+  scoped_specified_2 = 1,
+  scoped_specified_3,
+  scoped_specified_4 = 4
+};
+
+void unscopedUnspecified() {
+  unscoped_unspecified_t InvalidBeforeRangeBegin = static_cast(-5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidNegativeValue1 = static_cast(-4); // OK.
+  unscoped_unspecified_t ValidNegativeValue2 = static_cast(-3); // OK.
+  unscoped_unspecified_t InvalidInsideRange1 = static_cast(-2); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t InvalidInsideRange2 = static_cast(-1); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t InvalidInsideRange3 = static_cast(0); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidPositiveValue1 = static_cast(1); // OK.
+  unscoped_unspecified_t ValidPositiveValue2 = static_cast(2); // OK.
+  unscoped_unspecified_t InvalidInsideRange4 = static_cast(3); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_unspecified_t ValidPositiveValue3 = static_cast(4); // OK.
+  unscoped_unspecified_t InvalidAfterRangeEnd = static_cast(5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+}
+
+void unscopedSpecified() {
+  unscoped_specified_t InvalidBeforeRangeBegin = static_cast(-5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidNegativeValue1 = static_cast(-4); // OK.
+  unscoped_specified_t ValidNegativeValue2 = static_cast(-3); // OK.
+  unscoped_specified_t InvalidInsideRange1 = static_cast(-2); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t InvalidInsideRange2 = static_cast(-1); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t InvalidInsideRange3 = static_cast(0); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidPositiveValue1 = static_cast(1); // OK.
+  unscoped_specified_t ValidPositiveValue2 = static_cast(2); // OK.
+  unscoped_specified_t InvalidInsideRange4 = static_cast(3); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  unscoped_specified_t ValidPositiveValue3 = static_cast(4); // OK.
+  unscoped_specified_t InvalidAfterRangeEnd = static_cast(5); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+}
+
+void scopedUnspecified() {
+  scoped_unspecified_t InvalidBeforeRangeBegin = static_cast(-5); // expected-warning{{the value provided to the cast expression is not in the valid range of values for the enum}}
+  scoped_unspecified_t ValidNegativeValue1 = static_cast(-4); // OK.
+  scoped_unspecified_t ValidNegativeValue2 = static_cast(-3); // OK.
+  scoped_unspecified_t InvalidInsideRange1 = static_cast(-2); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  scoped_unspecified_t InvalidInsideRange2 = static_cast(-1); // expected-warning {{the value provided to the cast expression is not in the valid range of values for the enum}}
+  scoped_unspecified_t InvalidInsideRange3 = static_cast(0); // expe

[PATCH] D33932: [clang-format] Add support for case-insensitive header matching and use it to improve support for LLVM-style include sorting.

2017-08-22 Thread Teodor MICU via Phabricator via cfe-commits
mteodor added a comment.

In https://reviews.llvm.org/D33932#793994, @djasper wrote:

> Just make clang-format always do this. I don't think anyone is relying on the 
> current behavior.


Well, someone did rely on **case sensitive** match. I thought //case 
insensitive// by default was just a Windows thing. Not anymore.

  - Regex:   '^"I[A-Z]+[a-z].*\.h"'
Priority:1

This rule became too greedy on latest revision. Now not only interfaces are 
prioritized but also all headers that start with [Ii].


Repository:
  rL LLVM

https://reviews.llvm.org/D33932



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


[PATCH] D36712: Emit section information for extern variables

2017-08-22 Thread Simon Dardis via Phabricator via cfe-commits
sdardis accepted this revision.
sdardis added a comment.
This revision is now accepted and ready to land.

I agree with @kparzysz here. If there is a mis-match between the declaration 
and definition, there are cases where undesirable behaviour (as such) will not 
occur depending on how the mismatch occurs.

One suggestion inline for the wording inline, the important part is making 
explicit

LGTM, anyone else have more comments?




Comment at: docs/LangRef.rst:582-584
+to be placed in and may have an optional explicit alignment specified. A 
+mismatch between section information in the variable declaration and its
+definition is undefined behavior. 

"If there is a mismatch between the explicit or inferred section information 
for the variable declaration and its definition the resulting behaviour is 
undefined."


https://reviews.llvm.org/D36712



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


[PATCH] D36712: Emit section information for extern variables

2017-08-22 Thread Simon Dardis via Phabricator via cfe-commits
sdardis added a comment.

> One suggestion inline for the wording inline, the important part is making 
> explicit

The important part is making explicit that section information for a variable 
can be explicit or inferred.


https://reviews.llvm.org/D36712



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


[PATCH] D37011: [clang-format] Fix lines regression in clang-format.py

2017-08-22 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir created this revision.

This patch fixes a regression after https://reviews.llvm.org/rL305665,
which updates the structure of the `lines` variable.


https://reviews.llvm.org/D37011

Files:
  tools/clang-format/clang-format.py


Index: tools/clang-format/clang-format.py
===
--- tools/clang-format/clang-format.py
+++ tools/clang-format/clang-format.py
@@ -62,7 +62,7 @@
 
   # Determine range to format.
   if vim.eval('exists("l:lines")') == '1':
-lines = vim.eval('l:lines')
+lines = ['-lines', vim.eval('l:lines')]
   elif vim.eval('exists("l:formatdiff")') == '1':
 with open(vim.current.buffer.name, 'r') as f:
   ondisk = f.read().splitlines();


Index: tools/clang-format/clang-format.py
===
--- tools/clang-format/clang-format.py
+++ tools/clang-format/clang-format.py
@@ -62,7 +62,7 @@
 
   # Determine range to format.
   if vim.eval('exists("l:lines")') == '1':
-lines = vim.eval('l:lines')
+lines = ['-lines', vim.eval('l:lines')]
   elif vim.eval('exists("l:formatdiff")') == '1':
 with open(vim.current.buffer.name, 'r') as f:
   ondisk = f.read().splitlines();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r311454 - [mips] Rename getSupportedNanEncoding() to getIEEE754Standard()

2017-08-22 Thread Petar Jovanovic via cfe-commits
Author: petarj
Date: Tue Aug 22 06:35:27 2017
New Revision: 311454

URL: http://llvm.org/viewvc/llvm-project?rev=311454&view=rev
Log:
[mips] Rename getSupportedNanEncoding() to getIEEE754Standard()

Rename the function getSupportedNanEncoding() to getIEEE754Standard(), since
this function will be used for non-nan related features.

Patch by Aleksandar Beserminji.

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


Modified:
cfe/trunk/lib/Basic/Targets/Mips.h
cfe/trunk/lib/Driver/ToolChains/Arch/Mips.cpp
cfe/trunk/lib/Driver/ToolChains/Arch/Mips.h

Modified: cfe/trunk/lib/Basic/Targets/Mips.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/Mips.h?rev=311454&r1=311453&r2=311454&view=diff
==
--- cfe/trunk/lib/Basic/Targets/Mips.h (original)
+++ cfe/trunk/lib/Basic/Targets/Mips.h Tue Aug 22 06:35:27 2017
@@ -77,7 +77,7 @@ public:
 Triple.getOS() == llvm::Triple::OpenBSD;
   }
 
-  bool isNaN2008Default() const {
+  bool isIEEE754_2008Default() const {
 return CPU == "mips32r6" || CPU == "mips64r6";
   }
 
@@ -299,7 +299,7 @@ public:
 DiagnosticsEngine &Diags) override {
 IsMips16 = false;
 IsMicromips = false;
-IsNan2008 = isNaN2008Default();
+IsNan2008 = isIEEE754_2008Default();
 IsSingleFloat = false;
 FloatABI = HardFloat;
 DspRev = NoDSP;

Modified: cfe/trunk/lib/Driver/ToolChains/Arch/Mips.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Arch/Mips.cpp?rev=311454&r1=311453&r2=311454&view=diff
==
--- cfe/trunk/lib/Driver/ToolChains/Arch/Mips.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/Arch/Mips.cpp Tue Aug 22 06:35:27 2017
@@ -265,14 +265,14 @@ void mips::getMIPSTargetFeatures(const D
   if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
 StringRef Val = StringRef(A->getValue());
 if (Val == "2008") {
-  if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008)
+  if (mips::getIEEE754Standard(CPUName) & mips::Std2008)
 Features.push_back("+nan2008");
   else {
 Features.push_back("-nan2008");
 D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
   }
 } else if (Val == "legacy") {
-  if (mips::getSupportedNanEncoding(CPUName) & mips::NanLegacy)
+  if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
 Features.push_back("-nan2008");
   else {
 Features.push_back("+nan2008");
@@ -323,27 +323,28 @@ void mips::getMIPSTargetFeatures(const D
   AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, 
"mt");
 }
 
-mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) {
-  // Strictly speaking, mips32r2 and mips64r2 are NanLegacy-only since Nan2008
-  // was first introduced in Release 3. However, other compilers have
-  // traditionally allowed it for Release 2 so we should do the same.
-  return (NanEncoding)llvm::StringSwitch(CPU)
-  .Case("mips1", NanLegacy)
-  .Case("mips2", NanLegacy)
-  .Case("mips3", NanLegacy)
-  .Case("mips4", NanLegacy)
-  .Case("mips5", NanLegacy)
-  .Case("mips32", NanLegacy)
-  .Case("mips32r2", NanLegacy | Nan2008)
-  .Case("mips32r3", NanLegacy | Nan2008)
-  .Case("mips32r5", NanLegacy | Nan2008)
-  .Case("mips32r6", Nan2008)
-  .Case("mips64", NanLegacy)
-  .Case("mips64r2", NanLegacy | Nan2008)
-  .Case("mips64r3", NanLegacy | Nan2008)
-  .Case("mips64r5", NanLegacy | Nan2008)
-  .Case("mips64r6", Nan2008)
-  .Default(NanLegacy);
+mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
+  // Strictly speaking, mips32r2 and mips64r2 do not conform to the
+  // IEEE754-2008 standard. Support for this standard was first introduced
+  // in Release 3. However, other compilers have traditionally allowed it
+  // for Release 2 so we should do the same.
+  return (IEEE754Standard)llvm::StringSwitch(CPU)
+  .Case("mips1", Legacy)
+  .Case("mips2", Legacy)
+  .Case("mips3", Legacy)
+  .Case("mips4", Legacy)
+  .Case("mips5", Legacy)
+  .Case("mips32", Legacy)
+  .Case("mips32r2", Legacy | Std2008)
+  .Case("mips32r3", Legacy | Std2008)
+  .Case("mips32r5", Legacy | Std2008)
+  .Case("mips32r6", Std2008)
+  .Case("mips64", Legacy)
+  .Case("mips64r2", Legacy | Std2008)
+  .Case("mips64r3", Legacy | Std2008)
+  .Case("mips64r5", Legacy | Std2008)
+  .Case("mips64r6", Std2008)
+  .Default(Std2008);
 }
 
 bool mips::hasCompactBranches(StringRef &CPU) {

Modified: cfe/trunk/lib/Driver/ToolChains/Arch/Mips.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Arch/Mips.h?rev=311454&r1=311453&r2=311454&view=diff
==
--- cfe/trunk/lib/Driver/ToolC

[PATCH] D36824: [mips] Rename getSupportedNanEncoding() to getIEEE754Standard() (NFC)

2017-08-22 Thread Petar Jovanovic via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL311454: [mips] Rename getSupportedNanEncoding() to 
getIEEE754Standard() (authored by petarj).

Changed prior to commit:
  https://reviews.llvm.org/D36824?vs=112150&id=112166#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D36824

Files:
  cfe/trunk/lib/Basic/Targets/Mips.h
  cfe/trunk/lib/Driver/ToolChains/Arch/Mips.cpp
  cfe/trunk/lib/Driver/ToolChains/Arch/Mips.h

Index: cfe/trunk/lib/Basic/Targets/Mips.h
===
--- cfe/trunk/lib/Basic/Targets/Mips.h
+++ cfe/trunk/lib/Basic/Targets/Mips.h
@@ -77,7 +77,7 @@
 Triple.getOS() == llvm::Triple::OpenBSD;
   }
 
-  bool isNaN2008Default() const {
+  bool isIEEE754_2008Default() const {
 return CPU == "mips32r6" || CPU == "mips64r6";
   }
 
@@ -299,7 +299,7 @@
 DiagnosticsEngine &Diags) override {
 IsMips16 = false;
 IsMicromips = false;
-IsNan2008 = isNaN2008Default();
+IsNan2008 = isIEEE754_2008Default();
 IsSingleFloat = false;
 FloatABI = HardFloat;
 DspRev = NoDSP;
Index: cfe/trunk/lib/Driver/ToolChains/Arch/Mips.h
===
--- cfe/trunk/lib/Driver/ToolChains/Arch/Mips.h
+++ cfe/trunk/lib/Driver/ToolChains/Arch/Mips.h
@@ -24,15 +24,15 @@
 bool isMipsArch(llvm::Triple::ArchType Arch);
 
 namespace mips {
-typedef enum { NanLegacy = 1, Nan2008 = 2 } NanEncoding;
+typedef enum { Legacy = 1, Std2008 = 2 } IEEE754Standard;
 
 enum class FloatABI {
   Invalid,
   Soft,
   Hard,
 };
 
-NanEncoding getSupportedNanEncoding(StringRef &CPU);
+IEEE754Standard getIEEE754Standard(StringRef &CPU);
 bool hasCompactBranches(StringRef &CPU);
 void getMipsCPUAndABI(const llvm::opt::ArgList &Args,
   const llvm::Triple &Triple, StringRef &CPUName,
Index: cfe/trunk/lib/Driver/ToolChains/Arch/Mips.cpp
===
--- cfe/trunk/lib/Driver/ToolChains/Arch/Mips.cpp
+++ cfe/trunk/lib/Driver/ToolChains/Arch/Mips.cpp
@@ -265,14 +265,14 @@
   if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
 StringRef Val = StringRef(A->getValue());
 if (Val == "2008") {
-  if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008)
+  if (mips::getIEEE754Standard(CPUName) & mips::Std2008)
 Features.push_back("+nan2008");
   else {
 Features.push_back("-nan2008");
 D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
   }
 } else if (Val == "legacy") {
-  if (mips::getSupportedNanEncoding(CPUName) & mips::NanLegacy)
+  if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
 Features.push_back("-nan2008");
   else {
 Features.push_back("+nan2008");
@@ -323,27 +323,28 @@
   AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
 }
 
-mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) {
-  // Strictly speaking, mips32r2 and mips64r2 are NanLegacy-only since Nan2008
-  // was first introduced in Release 3. However, other compilers have
-  // traditionally allowed it for Release 2 so we should do the same.
-  return (NanEncoding)llvm::StringSwitch(CPU)
-  .Case("mips1", NanLegacy)
-  .Case("mips2", NanLegacy)
-  .Case("mips3", NanLegacy)
-  .Case("mips4", NanLegacy)
-  .Case("mips5", NanLegacy)
-  .Case("mips32", NanLegacy)
-  .Case("mips32r2", NanLegacy | Nan2008)
-  .Case("mips32r3", NanLegacy | Nan2008)
-  .Case("mips32r5", NanLegacy | Nan2008)
-  .Case("mips32r6", Nan2008)
-  .Case("mips64", NanLegacy)
-  .Case("mips64r2", NanLegacy | Nan2008)
-  .Case("mips64r3", NanLegacy | Nan2008)
-  .Case("mips64r5", NanLegacy | Nan2008)
-  .Case("mips64r6", Nan2008)
-  .Default(NanLegacy);
+mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
+  // Strictly speaking, mips32r2 and mips64r2 do not conform to the
+  // IEEE754-2008 standard. Support for this standard was first introduced
+  // in Release 3. However, other compilers have traditionally allowed it
+  // for Release 2 so we should do the same.
+  return (IEEE754Standard)llvm::StringSwitch(CPU)
+  .Case("mips1", Legacy)
+  .Case("mips2", Legacy)
+  .Case("mips3", Legacy)
+  .Case("mips4", Legacy)
+  .Case("mips5", Legacy)
+  .Case("mips32", Legacy)
+  .Case("mips32r2", Legacy | Std2008)
+  .Case("mips32r3", Legacy | Std2008)
+  .Case("mips32r5", Legacy | Std2008)
+  .Case("mips32r6", Std2008)
+  .Case("mips64", Legacy)
+  .Case("mips64r2", Legacy | Std2008)
+  .Case("mips64r3", Legacy | Std2008)
+  .Case("mips64r5", Legacy | Std2008)
+  .Case("mips64r6", Std2008)
+  .Default(Std2008);
 }
 
 bool mips::hasCompactBranches(StringRef &CPU) {
___
cfe-commits mailing list
cfe-commits@li

[PATCH] D36969: [Basic] Add a DiagnosticError llvm::ErrorInfo subclass

2017-08-22 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman updated this revision to Diff 112169.
arphaman retitled this revision from "[Basic] Add a DiagnosticOr type" to 
"[Basic] Add a DiagnosticError llvm::ErrorInfo subclass".
arphaman edited the summary of this revision.
arphaman added a comment.

Use `ErrorInfo` subclass as suggested by Vedant.


Repository:
  rL LLVM

https://reviews.llvm.org/D36969

Files:
  include/clang/Basic/DiagnosticError.h
  lib/Basic/Diagnostic.cpp
  unittests/Basic/DiagnosticTest.cpp

Index: unittests/Basic/DiagnosticTest.cpp
===
--- unittests/Basic/DiagnosticTest.cpp
+++ unittests/Basic/DiagnosticTest.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticError.h"
 #include "clang/Basic/DiagnosticIDs.h"
 #include "gtest/gtest.h"
 
@@ -72,4 +73,27 @@
   }
 }
 
+TEST(DiagnosticTest, diagnosticError) {
+  DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions,
+  new IgnoringDiagConsumer());
+  PartialDiagnostic::StorageAllocator Alloc;
+  llvm::Expected> Value =
+  llvm::make_error(PartialDiagnosticAt(
+  SourceLocation(), PartialDiagnostic(diag::err_cannot_open_file, Alloc)
+<< "file"
+<< "error"));
+  EXPECT_TRUE(!Value);
+  PartialDiagnosticAt ErrDiag = PartialDiagnosticAt(
+  SourceLocation(), PartialDiagnostic(PartialDiagnostic::NullDiagnostic()));
+  llvm::handleAllErrors(Value.takeError(), [&](DiagnosticError &Err) {
+ErrDiag = std::move(Err.getDiagnostic());
+  });
+  EXPECT_EQ(ErrDiag.first, SourceLocation());
+  EXPECT_EQ(ErrDiag.second.getDiagID(), diag::err_cannot_open_file);
+
+  Value = std::make_pair(20, 1);
+  EXPECT_FALSE(!Value);
+  EXPECT_EQ(*Value, std::make_pair(20, 1));
+  EXPECT_EQ(Value->first, 20);
+}
 }
Index: lib/Basic/Diagnostic.cpp
===
--- lib/Basic/Diagnostic.cpp
+++ lib/Basic/Diagnostic.cpp
@@ -11,8 +11,9 @@
 //
 //===--===//
 
-#include "clang/Basic/CharInfo.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/DiagnosticError.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/PartialDiagnostic.h"
@@ -1050,3 +1051,5 @@
   llvm::CrashRecoveryContext::isRecoveringFromCrash()) &&
  "A partial is on the lam");
 }
+
+char DiagnosticError::ID;
Index: include/clang/Basic/DiagnosticError.h
===
--- /dev/null
+++ include/clang/Basic/DiagnosticError.h
@@ -0,0 +1,43 @@
+//===--- DiagnosticError.h - Diagnostic payload for llvm::Error -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H
+#define LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H
+
+#include "clang/Basic/PartialDiagnostic.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+
+/// \brief Carries a Clang disgnostic in an llvm::Error.
+///
+/// Users should emit the stored diagnostic using the DiagnosticsEngine.
+class DiagnosticError : public llvm::ErrorInfo {
+public:
+  DiagnosticError(PartialDiagnosticAt Diag) : Diag(std::move(Diag)) {}
+
+  void log(raw_ostream &OS) const override { OS << "clang diagnostic"; }
+
+  PartialDiagnosticAt &getDiagnostic() { return Diag; }
+  const PartialDiagnosticAt &getDiagnostic() const { return Diag; }
+
+  static char ID;
+
+private:
+  // Users are not expected to use error_code.
+  std::error_code convertToErrorCode() const override {
+return llvm::inconvertibleErrorCode();
+  }
+
+  PartialDiagnosticAt Diag;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTIC_ERROR_H
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37011: [clang-format] Fix lines regression in clang-format.py

2017-08-22 Thread Daniel Jasper via Phabricator via cfe-commits
djasper accepted this revision.
djasper added a comment.
This revision is now accepted and ready to land.

Thank you


https://reviews.llvm.org/D37011



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


[PATCH] D36782: [Bash-autocompletion] Add support for static analyzer flags

2017-08-22 Thread Raphael Isemann via Phabricator via cfe-commits
teemperor accepted this revision.
teemperor added a comment.
This revision is now accepted and ready to land.

Found one more minor comment typo. And could you do your changes to 
`OptParserEmitter.cpp` all in this patch? Because Rui/Me pointed out those 
things on this review, so this patch should also fix them IMHO :)

Otherwise this is good to go, nice work!




Comment at: llvm/include/llvm/Option/OptTable.h:152
+  ///  "foo, bar..", where foo and bar is the argument which the Option flag
+  //  takes
+  ///

`///` instead of `//`.


https://reviews.llvm.org/D36782



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


r311456 - [clang-format] Fix lines regression in clang-format.py

2017-08-22 Thread Krasimir Georgiev via cfe-commits
Author: krasimir
Date: Tue Aug 22 07:28:01 2017
New Revision: 311456

URL: http://llvm.org/viewvc/llvm-project?rev=311456&view=rev
Log:
[clang-format] Fix lines regression in clang-format.py

Summary:
This patch fixes a regression after https://reviews.llvm.org/rL305665,
which updates the structure of the `lines` variable.

Reviewers: djasper

Reviewed By: djasper

Subscribers: cfe-commits

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

Modified:
cfe/trunk/tools/clang-format/clang-format.py

Modified: cfe/trunk/tools/clang-format/clang-format.py
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/clang-format.py?rev=311456&r1=311455&r2=311456&view=diff
==
--- cfe/trunk/tools/clang-format/clang-format.py (original)
+++ cfe/trunk/tools/clang-format/clang-format.py Tue Aug 22 07:28:01 2017
@@ -62,7 +62,7 @@ def main():
 
   # Determine range to format.
   if vim.eval('exists("l:lines")') == '1':
-lines = vim.eval('l:lines')
+lines = ['-lines', vim.eval('l:lines')]
   elif vim.eval('exists("l:formatdiff")') == '1':
 with open(vim.current.buffer.name, 'r') as f:
   ondisk = f.read().splitlines();


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


[PATCH] D37011: [clang-format] Fix lines regression in clang-format.py

2017-08-22 Thread Krasimir Georgiev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL311456: [clang-format] Fix lines regression in 
clang-format.py (authored by krasimir).

Repository:
  rL LLVM

https://reviews.llvm.org/D37011

Files:
  cfe/trunk/tools/clang-format/clang-format.py


Index: cfe/trunk/tools/clang-format/clang-format.py
===
--- cfe/trunk/tools/clang-format/clang-format.py
+++ cfe/trunk/tools/clang-format/clang-format.py
@@ -62,7 +62,7 @@
 
   # Determine range to format.
   if vim.eval('exists("l:lines")') == '1':
-lines = vim.eval('l:lines')
+lines = ['-lines', vim.eval('l:lines')]
   elif vim.eval('exists("l:formatdiff")') == '1':
 with open(vim.current.buffer.name, 'r') as f:
   ondisk = f.read().splitlines();


Index: cfe/trunk/tools/clang-format/clang-format.py
===
--- cfe/trunk/tools/clang-format/clang-format.py
+++ cfe/trunk/tools/clang-format/clang-format.py
@@ -62,7 +62,7 @@
 
   # Determine range to format.
   if vim.eval('exists("l:lines")') == '1':
-lines = vim.eval('l:lines')
+lines = ['-lines', vim.eval('l:lines')]
   elif vim.eval('exists("l:formatdiff")') == '1':
 with open(vim.current.buffer.name, 'r') as f:
   ondisk = f.read().splitlines();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36712: Emit section information for extern variables

2017-08-22 Thread Elizabeth Andrews via Phabricator via cfe-commits
eandrews updated this revision to Diff 112172.
eandrews added a comment.

Updated the documentation to explicitly state that section information for a 
variable can be explicit or inferred.


https://reviews.llvm.org/D36712

Files:
  docs/LangRef.rst


Index: docs/LangRef.rst
===
--- docs/LangRef.rst
+++ docs/LangRef.rst
@@ -579,7 +579,9 @@
 case they don't have an initializer.
 
 Either global variable definitions or declarations may have an explicit section
-to be placed in and may have an optional explicit alignment specified.
+to be placed in and may have an optional explicit alignment specified. If 
there 
+is a mismatch between the explicit or inferred section information for the 
+variable declaration and its definition the resulting behavior is undefined. 
 
 A variable may be defined as a global ``constant``, which indicates that
 the contents of the variable will **never** be modified (enabling better
@@ -622,6 +624,12 @@
 Additionally, the global can placed in a comdat if the target has the necessary
 support.
 
+External declarations may have an explicit section specified. Section 
+information is retained in LLVM IR for targets that make use of this 
+information. Attaching section information to an external declaration is an 
+assertion that its definition is located in the specified section. If the 
+definition is located in a different section, the behavior is undefined.   
+
 By default, global initializers are optimized by assuming that global
 variables defined within the module are not modified from their
 initial values before the start of the global initializer. This is


Index: docs/LangRef.rst
===
--- docs/LangRef.rst
+++ docs/LangRef.rst
@@ -579,7 +579,9 @@
 case they don't have an initializer.
 
 Either global variable definitions or declarations may have an explicit section
-to be placed in and may have an optional explicit alignment specified.
+to be placed in and may have an optional explicit alignment specified. If there 
+is a mismatch between the explicit or inferred section information for the 
+variable declaration and its definition the resulting behavior is undefined. 
 
 A variable may be defined as a global ``constant``, which indicates that
 the contents of the variable will **never** be modified (enabling better
@@ -622,6 +624,12 @@
 Additionally, the global can placed in a comdat if the target has the necessary
 support.
 
+External declarations may have an explicit section specified. Section 
+information is retained in LLVM IR for targets that make use of this 
+information. Attaching section information to an external declaration is an 
+assertion that its definition is located in the specified section. If the 
+definition is located in a different section, the behavior is undefined.   
+
 By default, global initializers are optimized by assuming that global
 variables defined within the module are not modified from their
 initial values before the start of the global initializer. This is
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37007: [clang-format] Break non-trailing block comments

2017-08-22 Thread Daniel Jasper via Phabricator via cfe-commits
djasper accepted this revision.
djasper added a comment.
This revision is now accepted and ready to land.

If no tests break with this, lets just go for it. We can follow up and fix 
individual cases if we find undesired behavior.


https://reviews.llvm.org/D37007



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


r311457 - [clang-format] Break non-trailing block comments

2017-08-22 Thread Krasimir Georgiev via cfe-commits
Author: krasimir
Date: Tue Aug 22 07:40:05 2017
New Revision: 311457

URL: http://llvm.org/viewvc/llvm-project?rev=311457&view=rev
Log:
[clang-format] Break non-trailing block comments

Summary:
This patch is an alternative to https://reviews.llvm.org/D36614, by resolving a
non-idempotency issue by breaking non-trailing comments:

Consider formatting the following code with column limit at `V`:
```
V
const /* comment comment */ A = B;
```
The comment is not a trailing comment, breaking before it doesn't bring it under
the column limit. The formatter breaks after it, resulting in:

```
V
const /* comment comment */
A = B;
```
For a next reformat, the formatter considers the comment as a trailing comment,
so it is free to break it further, resulting in:

```
V
const /* comment
 comment */
A = B;
```
This patch improves the situation by directly producing the third case.

Reviewers: djasper

Reviewed By: djasper

Subscribers: cfe-commits, klimek

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

Modified:
cfe/trunk/lib/Format/ContinuationIndenter.cpp
cfe/trunk/unittests/Format/FormatTestComments.cpp

Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=311457&r1=311456&r2=311457&view=diff
==
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original)
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Tue Aug 22 07:40:05 2017
@@ -1282,7 +1282,7 @@ unsigned ContinuationIndenter::breakProt
   return 0;
 }
   } else if (Current.is(TT_BlockComment)) {
-if (!Current.isTrailingComment() || !Style.ReflowComments ||
+if (!Style.ReflowComments ||
 // If a comment token switches formatting, like
 // /* clang-format on */, we don't want to break it further,
 // but we may still want to adjust its indentation.

Modified: cfe/trunk/unittests/Format/FormatTestComments.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestComments.cpp?rev=311457&r1=311456&r2=311457&view=diff
==
--- cfe/trunk/unittests/Format/FormatTestComments.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestComments.cpp Tue Aug 22 07:40:05 2017
@@ -2780,6 +2780,22 @@ TEST_F(FormatTestComments, AlignsBlockCo
"* long */",
getLLVMStyleWithColumns(20)));
 }
+
+TEST_F(FormatTestComments, NonTrailingBlockComments) {
+  verifyFormat("const /** comment comment */ A = B;",
+   getLLVMStyleWithColumns(40));
+
+  verifyFormat("const /** comment comment comment */ A =\n"
+   "B;",
+   getLLVMStyleWithColumns(40));
+
+  EXPECT_EQ("const /** comment comment comment\n"
+" comment */\n"
+"A = B;",
+format("const /** comment comment comment comment */\n"
+   "A = B;",
+   getLLVMStyleWithColumns(40)));
+}
 } // end namespace
 } // end namespace format
 } // end namespace clang


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


[PATCH] D37007: [clang-format] Break non-trailing block comments

2017-08-22 Thread Krasimir Georgiev via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL311457: [clang-format] Break non-trailing block comments 
(authored by krasimir).

Repository:
  rL LLVM

https://reviews.llvm.org/D37007

Files:
  cfe/trunk/lib/Format/ContinuationIndenter.cpp
  cfe/trunk/unittests/Format/FormatTestComments.cpp


Index: cfe/trunk/lib/Format/ContinuationIndenter.cpp
===
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp
@@ -1282,7 +1282,7 @@
   return 0;
 }
   } else if (Current.is(TT_BlockComment)) {
-if (!Current.isTrailingComment() || !Style.ReflowComments ||
+if (!Style.ReflowComments ||
 // If a comment token switches formatting, like
 // /* clang-format on */, we don't want to break it further,
 // but we may still want to adjust its indentation.
Index: cfe/trunk/unittests/Format/FormatTestComments.cpp
===
--- cfe/trunk/unittests/Format/FormatTestComments.cpp
+++ cfe/trunk/unittests/Format/FormatTestComments.cpp
@@ -2780,6 +2780,22 @@
"* long */",
getLLVMStyleWithColumns(20)));
 }
+
+TEST_F(FormatTestComments, NonTrailingBlockComments) {
+  verifyFormat("const /** comment comment */ A = B;",
+   getLLVMStyleWithColumns(40));
+
+  verifyFormat("const /** comment comment comment */ A =\n"
+   "B;",
+   getLLVMStyleWithColumns(40));
+
+  EXPECT_EQ("const /** comment comment comment\n"
+" comment */\n"
+"A = B;",
+format("const /** comment comment comment comment */\n"
+   "A = B;",
+   getLLVMStyleWithColumns(40)));
+}
 } // end namespace
 } // end namespace format
 } // end namespace clang


Index: cfe/trunk/lib/Format/ContinuationIndenter.cpp
===
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp
@@ -1282,7 +1282,7 @@
   return 0;
 }
   } else if (Current.is(TT_BlockComment)) {
-if (!Current.isTrailingComment() || !Style.ReflowComments ||
+if (!Style.ReflowComments ||
 // If a comment token switches formatting, like
 // /* clang-format on */, we don't want to break it further,
 // but we may still want to adjust its indentation.
Index: cfe/trunk/unittests/Format/FormatTestComments.cpp
===
--- cfe/trunk/unittests/Format/FormatTestComments.cpp
+++ cfe/trunk/unittests/Format/FormatTestComments.cpp
@@ -2780,6 +2780,22 @@
"* long */",
getLLVMStyleWithColumns(20)));
 }
+
+TEST_F(FormatTestComments, NonTrailingBlockComments) {
+  verifyFormat("const /** comment comment */ A = B;",
+   getLLVMStyleWithColumns(40));
+
+  verifyFormat("const /** comment comment comment */ A =\n"
+   "B;",
+   getLLVMStyleWithColumns(40));
+
+  EXPECT_EQ("const /** comment comment comment\n"
+" comment */\n"
+"A = B;",
+format("const /** comment comment comment comment */\n"
+   "A = B;",
+   getLLVMStyleWithColumns(40)));
+}
 } // end namespace
 } // end namespace format
 } // end namespace clang
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36614: [clang-format] Refine trailing comment detection

2017-08-22 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir abandoned this revision.
krasimir marked an inline comment as done.
krasimir added a comment.

This was superseded by https://reviews.llvm.org/D37007.


https://reviews.llvm.org/D36614



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


[PATCH] D36951: [OpenCL][5.0.0 Release] Release notes for OpenCL in Clang

2017-08-22 Thread Anastasia Stulova via Phabricator via cfe-commits
Anastasia updated this revision to Diff 112175.
Anastasia added a comment.

Removed description of reverted fuctionality.


https://reviews.llvm.org/D36951

Files:
  docs/ReleaseNotes.rst


Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -122,7 +122,29 @@
 OpenCL C Language Changes in Clang
 --
 
-...
+Various bug fixes and improvements:
+-  Extended OpenCL-related Clang tests.
+-  Improved diagnostics across several areas: scoped address space
+   qualified variables, function pointers, atomics, type rank for overloading,
+   block captures, ``reserve_id_t``.
+-  Several address space related fixes for constant AS function scope 
variables,
+   IR generation, mangling of ``generic`` and alloca (post-fix from general 
Clang
+   refactoring of address spaces).
+-  Several improvements in extensions: fixed OpenCL version for 
``cl_khr_mipmap_image``,
+   added missing ``cl_khr_3d_image_writes``.
+-  Improvements in ``enqueue_kernel``, especially the implementation of 
``ndrange_t`` and blocks.
+-  OpenCL type related fixes: global samplers, the ``pipe_t`` size, internal 
type redefinition,
+   and type compatibility checking in ternary and other operations.
+-  The OpenCL header has been extended with missing extension guards, and 
direct mapping of ``as_type``
+   to ``__builtin_astype``.
+-  Fixed ``kernel_arg_type_qual`` and OpenCL/SPIR version in metadata.
+-  Added proper use of the kernel calling convention to various targets.
+
+The following new functionalities have been added:
+-  Added documentation on OpenCL to Clang user manual.
+-  Extended Clang builtins with required ``cl_khr_subgroups`` support.
+-  Add ``intel_reqd_sub_group_size`` attribute support.
+-  Added OpenCL types to ``CIndex``.
 
 OpenMP Support in Clang
 --


Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -122,7 +122,29 @@
 OpenCL C Language Changes in Clang
 --
 
-...
+Various bug fixes and improvements:
+-  Extended OpenCL-related Clang tests.
+-  Improved diagnostics across several areas: scoped address space
+   qualified variables, function pointers, atomics, type rank for overloading,
+   block captures, ``reserve_id_t``.
+-  Several address space related fixes for constant AS function scope variables,
+   IR generation, mangling of ``generic`` and alloca (post-fix from general Clang
+   refactoring of address spaces).
+-  Several improvements in extensions: fixed OpenCL version for ``cl_khr_mipmap_image``,
+   added missing ``cl_khr_3d_image_writes``.
+-  Improvements in ``enqueue_kernel``, especially the implementation of ``ndrange_t`` and blocks.
+-  OpenCL type related fixes: global samplers, the ``pipe_t`` size, internal type redefinition,
+   and type compatibility checking in ternary and other operations.
+-  The OpenCL header has been extended with missing extension guards, and direct mapping of ``as_type``
+   to ``__builtin_astype``.
+-  Fixed ``kernel_arg_type_qual`` and OpenCL/SPIR version in metadata.
+-  Added proper use of the kernel calling convention to various targets.
+
+The following new functionalities have been added:
+-  Added documentation on OpenCL to Clang user manual.
+-  Extended Clang builtins with required ``cl_khr_subgroups`` support.
+-  Add ``intel_reqd_sub_group_size`` attribute support.
+-  Added OpenCL types to ``CIndex``.
 
 OpenMP Support in Clang
 --
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36707: [CodeGen]Refactor CpuSupports/CPUIs Builtin Code Gen to better work with "target" implementation

2017-08-22 Thread Erich Keane via Phabricator via cfe-commits
erichkeane planned changes to this revision.
erichkeane added a comment.

I actually updated it a bit since then, so I'll hold off on committing until my 
replacement version is perfect, I'd prefer to stop churning.  Thanks for the 
review though Craig!


https://reviews.llvm.org/D36707



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


[PATCH] D36712: Emit section information for extern variables

2017-08-22 Thread Erich Keane via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL311459: Emit section information for extern variables 
(authored by erichkeane).

Changed prior to commit:
  https://reviews.llvm.org/D36712?vs=112172&id=112180#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D36712

Files:
  llvm/trunk/docs/LangRef.rst


Index: llvm/trunk/docs/LangRef.rst
===
--- llvm/trunk/docs/LangRef.rst
+++ llvm/trunk/docs/LangRef.rst
@@ -579,7 +579,9 @@
 case they don't have an initializer.
 
 Either global variable definitions or declarations may have an explicit section
-to be placed in and may have an optional explicit alignment specified.
+to be placed in and may have an optional explicit alignment specified. If 
there 
+is a mismatch between the explicit or inferred section information for the 
+variable declaration and its definition the resulting behavior is undefined. 
 
 A variable may be defined as a global ``constant``, which indicates that
 the contents of the variable will **never** be modified (enabling better
@@ -622,6 +624,12 @@
 Additionally, the global can placed in a comdat if the target has the necessary
 support.
 
+External declarations may have an explicit section specified. Section 
+information is retained in LLVM IR for targets that make use of this 
+information. Attaching section information to an external declaration is an 
+assertion that its definition is located in the specified section. If the 
+definition is located in a different section, the behavior is undefined.   
+
 By default, global initializers are optimized by assuming that global
 variables defined within the module are not modified from their
 initial values before the start of the global initializer. This is


Index: llvm/trunk/docs/LangRef.rst
===
--- llvm/trunk/docs/LangRef.rst
+++ llvm/trunk/docs/LangRef.rst
@@ -579,7 +579,9 @@
 case they don't have an initializer.
 
 Either global variable definitions or declarations may have an explicit section
-to be placed in and may have an optional explicit alignment specified.
+to be placed in and may have an optional explicit alignment specified. If there 
+is a mismatch between the explicit or inferred section information for the 
+variable declaration and its definition the resulting behavior is undefined. 
 
 A variable may be defined as a global ``constant``, which indicates that
 the contents of the variable will **never** be modified (enabling better
@@ -622,6 +624,12 @@
 Additionally, the global can placed in a comdat if the target has the necessary
 support.
 
+External declarations may have an explicit section specified. Section 
+information is retained in LLVM IR for targets that make use of this 
+information. Attaching section information to an external declaration is an 
+assertion that its definition is located in the specified section. If the 
+definition is located in a different section, the behavior is undefined.   
+
 By default, global initializers are optimized by assuming that global
 variables defined within the module are not modified from their
 initial values before the start of the global initializer. This is
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36487: Emit section information for extern variables.

2017-08-22 Thread Elizabeth Andrews via Phabricator via cfe-commits
eandrews added a comment.

LangRef has been updated and accepted. You can find it here - 
https://reviews.llvm.org/rL311459


https://reviews.llvm.org/D36487



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


[PATCH] D37014: [clang-tidy] Add a checker to remove useless intermediate variables before return statements with comparisons

2017-08-22 Thread Tristan Bourvon via Phabricator via cfe-commits
tbourvon added a comment.

Some more precisions I kept out of the revision body for clarity:

The checker contains a configuration option to set the maximum line length for 
the fixed return statement, so that we make sure this checker always 
contributes to improving readability and not the contrary.
The top-most non-trivial expression of the return statement has to be a 
comparison operator.

This checker tries to catch as many corner cases as possible. Most if not all 
of them are showcased in the tests, but the main ones are:

- It handles double variable declarations like this:

  auto Var1 = 1;
  auto Var2 = 2;
  return (Var1 < Var2);

so that the checker doesn't have to be run twice to fix these cases.

- It always preserves order of execution:

  auto Var = step1();
  return (step2() > Var);

will correctly be transformed into:

  return (step1() < step2()); // notice the comparison operator inversion



- It never duplicates code execution:

  auto Var = foo();
  return (Var == Var);

will not be matched.

I did not feel it was a good idea to include this in the user-facing checker 
documentation because it seems to me that the user of the checker does not need 
to worry about these exceptions as long as they are covered. The user should 
only be interested in the idea behind the checker and how it can help.


https://reviews.llvm.org/D37014



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


[PATCH] D37014: [clang-tidy] Add a checker to remove useless intermediate variables before return statements with comparisons

2017-08-22 Thread Tristan Bourvon via Phabricator via cfe-commits
tbourvon created this revision.
Herald added subscribers: xazax.hun, JDevlieghere, mgorny.

This patch adds a checker to detect patterns of the following form:

  auto IntermediateVar = foo();
  return (IntermediateVar == 1);

and suggests to turn them into:

  return (foo() == 1);

The reasoning behind this checker is that this kind of pattern is useless and 
lowers readability as long as the return statement remains rather short.
The idea of this checker was suggested to me by Sylvestre Ledru.


https://reviews.llvm.org/D37014

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tidy/readability/UselessIntermediateVarCheck.cpp
  clang-tidy/readability/UselessIntermediateVarCheck.h
  clang-tidy/utils/LexerUtils.cpp
  clang-tidy/utils/LexerUtils.h
  clang-tidy/utils/Matchers.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-useless-intermediate-var.rst
  test/clang-tidy/readability-useless-intermediate-var.cpp

Index: test/clang-tidy/readability-useless-intermediate-var.cpp
===
--- /dev/null
+++ test/clang-tidy/readability-useless-intermediate-var.cpp
@@ -0,0 +1,138 @@
+// RUN: %check_clang_tidy %s readability-useless-intermediate-var %t
+
+bool f() {
+  auto test = 1; // Test
+  // CHECK-FIXES: {{^}}  // Test{{$}}
+  return (test == 1);
+  // CHECK-FIXES: {{^}}  return (1 == 1);{{$}}
+  // CHECK-MESSAGES: :[[@LINE-4]]:8: warning: intermediate variable 'test' is useless [readability-useless-intermediate-var]
+  // CHECK-MESSAGES: :[[@LINE-3]]:11: note: because it is only used when returning the result of this comparison
+  // CHECK-MESSAGES: :[[@LINE-6]]:8: note: consider removing the variable declaration
+  // CHECK-MESSAGES: :[[@LINE-5]]:11: note: and directly using the variable initialization expression here
+}
+
+bool f2() {
+  auto test1 = 1; // Test1
+  // CHECK-FIXES: {{^}}  // Test1{{$}}
+  auto test2 = 2; // Test2
+  // CHECK-FIXES: {{^}}  // Test2{{$}}
+  return (test1 == test2);
+  // CHECK-FIXES: {{^}}  return (1 == 2);{{$}}
+  // CHECK-MESSAGES: :[[@LINE-6]]:8: warning: intermediate variable 'test1' is useless [readability-useless-intermediate-var]
+  // CHECK-MESSAGES: :[[@LINE-5]]:8: warning: and so is 'test2' [readability-useless-intermediate-var]
+  // CHECK-MESSAGES: :[[@LINE-4]]:11: note: because they are only used when returning the result of this comparison
+  // CHECK-MESSAGES: :[[@LINE-9]]:8: note: consider removing both this variable declaration
+  // CHECK-MESSAGES: :[[@LINE-8]]:8: note: and this one
+  // CHECK-MESSAGES: :[[@LINE-7]]:11: note: and directly using the variable initialization expressions here
+}
+
+bool f3() {
+  auto test1 = 1; // Test1
+  // CHECK-FIXES: {{^}}  // Test1{{$}}
+  auto test2 = 2; // Test2
+  return (test1 == 2);
+  // CHECK-FIXES: {{^}}  return (1 == 2);{{$}}
+  // CHECK-MESSAGES: :[[@LINE-5]]:8: warning: intermediate variable 'test1' is useless [readability-useless-intermediate-var]
+  // CHECK-MESSAGES: :[[@LINE-3]]:11: note: because it is only used when returning the result of this comparison
+  // CHECK-MESSAGES: :[[@LINE-7]]:8: note: consider removing the variable declaration
+  // CHECK-MESSAGES: :[[@LINE-5]]:11: note: and directly using the variable initialization expression here
+}
+
+bool f4() {
+  auto test1 = 1; // Test1
+  auto test2 = 2; // Test2
+  // CHECK-FIXES: {{^}}  // Test2{{$}}
+  return (test2 == 3);
+  // CHECK-FIXES: {{^}}  return (2 == 3);{{$}}
+  // CHECK-MESSAGES: :[[@LINE-4]]:8: warning: intermediate variable 'test2' is useless [readability-useless-intermediate-var]
+  // CHECK-MESSAGES: :[[@LINE-3]]:11: note: because it is only used when returning the result of this comparison
+  // CHECK-MESSAGES: :[[@LINE-6]]:8: note: consider removing the variable declaration
+  // CHECK-MESSAGES: :[[@LINE-5]]:11: note: and directly using the variable initialization expression here
+}
+
+bool f5() {
+  auto test1 = 1; // Test1
+  // CHECK-FIXES: {{^}}  // Test1{{$}}
+  auto test2 = 2; // Test2
+  return (2 == test1);
+  // CHECK-FIXES: {{^}}  return (1 == 2);{{$}}
+  // CHECK-MESSAGES: :[[@LINE-5]]:8: warning: intermediate variable 'test1' is useless [readability-useless-intermediate-var]
+  // CHECK-MESSAGES: :[[@LINE-3]]:16: note: because it is only used when returning the result of this comparison
+  // CHECK-MESSAGES: :[[@LINE-7]]:8: note: consider removing the variable declaration
+  // CHECK-MESSAGES: :[[@LINE-5]]:11: note: and directly using the variable initialization expression here
+}
+
+bool f6() {
+  auto test1 = 1; // Test1
+  auto test2 = 2; // Test2
+  // CHECK-FIXES: {{^}}  // Test2{{$}}
+  return (3 == test2);
+  // CHECK-FIXES: {{^}}  return (2 == 3);{{$}}
+  // CHECK-MESSAGES: :[[@LINE-4]]:8: warning: intermediate variable 'test2' is useless [readability-useless-intermediate-var]
+  // CHECK-MESSAGES: :[[@LINE-3]]:16: note: because it is only used when ret

Re: r311443 - [ObjC] Check written attributes only when synthesizing ambiguous property

2017-08-22 Thread Hans Wennborg via cfe-commits
Merged in r311464. Thanks!

On Tue, Aug 22, 2017 at 3:42 AM, Alex L  wrote:
> Hi Hans,
>
> Can you please merge this into LLVM 5? It fixes a rather serious Objective-C
> bug that I introduced just a couple of weeks before the branch.
>
> Cheers,
> Alex
>
>
> On 22 August 2017 at 11:38, Alex Lorenz via cfe-commits
>  wrote:
>>
>> Author: arphaman
>> Date: Tue Aug 22 03:38:07 2017
>> New Revision: 311443
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=311443&view=rev
>> Log:
>> [ObjC] Check written attributes only when synthesizing ambiguous property
>>
>> This commit fixes a bug introduced in r307903. The attribute ambiguity
>> checker
>> that was introduced in r307903 checked all property attributes, which
>> caused
>> errors for source-compatible properties, like:
>>
>> @property (nonatomic, readonly) NSObject *prop;
>> @property (nonatomic, readwrite) NSObject *prop;
>>
>> because the readwrite property would get implicit 'strong' attribute. The
>> ambiguity checker should be concerned about explicitly specified
>> attributes
>> only.
>>
>> rdar://33748089
>>
>> Modified:
>> cfe/trunk/lib/Sema/SemaObjCProperty.cpp
>> cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m
>>
>> Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=311443&r1=311442&r2=311443&view=diff
>>
>> ==
>> --- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Tue Aug 22 03:38:07 2017
>> @@ -872,7 +872,7 @@ SelectPropertyForSynthesisFromProtocols(
>>}
>>
>>QualType RHSType = S.Context.getCanonicalType(Property->getType());
>> -  unsigned OriginalAttributes = Property->getPropertyAttributes();
>> +  unsigned OriginalAttributes =
>> Property->getPropertyAttributesAsWritten();
>>enum MismatchKind {
>>  IncompatibleType = 0,
>>  HasNoExpectedAttribute,
>> @@ -890,7 +890,7 @@ SelectPropertyForSynthesisFromProtocols(
>>SmallVector Mismatches;
>>for (ObjCPropertyDecl *Prop : Properties) {
>>  // Verify the property attributes.
>> -unsigned Attr = Prop->getPropertyAttributes();
>> +unsigned Attr = Prop->getPropertyAttributesAsWritten();
>>  if (Attr != OriginalAttributes) {
>>auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName)
>> {
>>  MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute
>>
>> Modified: cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m?rev=311443&r1=311442&r2=311443&view=diff
>>
>> ==
>> --- cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m (original)
>> +++ cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m Tue Aug 22 03:38:07
>> 2017
>> @@ -225,3 +225,30 @@ __attribute__((objc_root_class))
>>  @implementation TypeVsSetter
>>  @synthesize prop; // expected-note {{property synthesized here}}
>>  @end
>> +
>> +@protocol AutoStrongProp
>> +
>> +@property (nonatomic, readonly) NSObject *prop;
>> +
>> +@end
>> +
>> +@protocol AutoStrongProp_Internal 
>> +
>> +// This property gets the 'strong' attribute automatically.
>> +@property (nonatomic, readwrite) NSObject *prop;
>> +
>> +@end
>> +
>> +@interface SynthesizeWithImplicitStrongNoError : NSObject
>> 
>> +@end
>> +
>> +@interface SynthesizeWithImplicitStrongNoError ()
>> 
>> +
>> +@end
>> +
>> +@implementation SynthesizeWithImplicitStrongNoError
>> +
>> +// no error, 'strong' is implicit in the 'readwrite' property.
>> +@synthesize prop = _prop;
>> +
>> +@end
>>
>>
>> ___
>> cfe-commits mailing list
>> cfe-commits@lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37014: [clang-tidy] Add a checker to remove useless intermediate variables before return statements with comparisons

2017-08-22 Thread Jonas Toth via Phabricator via cfe-commits
JonasToth added a comment.

Hi :)

I added my thoughts for the check. Many variables in your code could be 
`const`, i didn't mention all cases.




Comment at: clang-tidy/readability/UselessIntermediateVarCheck.cpp:24
+
+  auto directDeclRefExprLHS1 =
+// We match a direct declaration reference expression pointing

The matching expression can be `const auto`.
I would write the comment above the declaration, that the splitting does not 
occur (here and the next simpler matchers).

The local variables for matcher should have a capital letter as start -> 
s/directDeclRefExprLHS1/DirectDeclRefExpr/ here and elsewhere.



Comment at: clang-tidy/readability/UselessIntermediateVarCheck.cpp:62
+
+  auto hasVarDecl1 =
+// We match a single declaration which is a variable declaration,

here and elsewhere, is the indendation result of clang-format? Personally i 
like it, since it shows the structure, but there might be concerns since it 
probably does not match with the coding guideline.



Comment at: clang-tidy/readability/UselessIntermediateVarCheck.cpp:186
+const VarDecl *VarDecl1, const VarDecl *VarDecl2) {
+  diag(VarDecl1->getLocation(), "intermediate variable %0 is useless",
+   DiagnosticIDs::Warning)

The warning message sounds a little harsh/judging, and does not explain why the 
intermediate is useless. (the notes do which is ok i think).

Maybe go with `unnecessary intermediate variable %0`



Comment at: clang-tidy/readability/UselessIntermediateVarCheck.cpp:236
+  if (BinOpToReverse) {
+auto ReversedBinOpText =
+  BinaryOperator::getOpcodeStr(

`const auto` ?



Comment at: clang-tidy/readability/UselessIntermediateVarCheck.cpp:290
+// declaration.
+auto Init1TextOpt =
+  utils::lexer::getStmtText(Init1, Result.Context->getSourceManager());

some `const` is possible for this an the following variables.



Comment at: clang-tidy/readability/UselessIntermediateVarCheck.cpp:335
+  // operands of the binary operator to keep the same execution order.
+  auto LHSTextOpt =
+utils::lexer::getStmtText(BinOp->getLHS(), 
Result.Context->getSourceManager());

`const auto`?



Comment at: clang-tidy/readability/UselessIntermediateVarCheck.cpp:350
+// statement.
+bool HasVarRef1 = VarRefLHS1 || VarRefRHS1;
+bool HasVarRef2 = VarRefLHS2 || VarRefRHS2;

`const`



Comment at: clang-tidy/readability/UselessIntermediateVarCheck.h:29
+  : ClangTidyCheck(Name, Context),
+MaximumLineLength(Options.get("MaximumLineLength", 100)) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;

It would be nice, if there is a way to get this information from a clang-format 
file. 



Comment at: clang-tidy/readability/UselessIntermediateVarCheck.h:47
+  unsigned MaximumLineLength;
+  std::unordered_set CheckedDeclStmt;
+};

Maybe a SmallSet? the optimized datastructures from llvm would save dynamic 
memory allocations.



Comment at: clang-tidy/utils/Matchers.h:67
+  // We build a Control Flow Graph (CFG) from the parent statement.
+  std::unique_ptr StatementCFG
+  = CFG::buildCFG(nullptr, const_cast(Parent), &Finder->getASTContext(),

formatted? usually the `=` ends up on the same line



Comment at: docs/ReleaseNotes.rst:63
+
+  This new checker detects useless intermediate variables before return
+  statements that return the result of a simple comparison. This checker also

maybe "useless" should be replaced with "unnecessary". but thats only my 
opinion.



Comment at: docs/clang-tidy/checks/readability-useless-intermediate-var.rst:14
+
+  auto test = 1;
+  return (test == 2);

especially to avoid magic numbers, this kind of code could be more readable.



Comment at: test/clang-tidy/readability-useless-intermediate-var.cpp:1
+// RUN: %check_clang_tidy %s readability-useless-intermediate-var %t
+

the tests seem to be to less compared to the code volume of the check.

situations i think should be tested:

- initialization from a function, method call
- initialization with a lambda
```
const auto SomeVar = []() { /* super complicated stuff */ return Result; } ();
return SomeVar;
```
- template stuff -> proof that they work two, even thought it doesnt seem to be 
relevant, at least what i can see.
- what happens if a "temporary" is used as an argument for a function call?
```
const auto Var = std::sqrt(10);
return std::pow(Var, 10);
```
- proof that really long function calls (like STL Algorithm tends to be) are 
not inlined as well


https://reviews.llvm.org/D37014



___
cfe-commits m

[PATCH] D36848: [CodeGen] Use reentrant methods to time IR gen

2017-08-22 Thread Brian Gesiak via Phabricator via cfe-commits
modocache updated this revision to Diff 112187.
modocache retitled this revision from "[CodeGen] Use RefCntTimer to time IR 
generation" to "[CodeGen] Use reentrant methods to time IR gen".
modocache edited the summary of this revision.
modocache added a comment.

Use `startReentrantTimer` and `stopReentrantTimer`


https://reviews.llvm.org/D36848

Files:
  lib/CodeGen/CodeGenAction.cpp


Index: lib/CodeGen/CodeGenAction.cpp
===
--- lib/CodeGen/CodeGenAction.cpp
+++ lib/CodeGen/CodeGenAction.cpp
@@ -60,7 +60,6 @@
 ASTContext *Context;
 
 Timer LLVMIRGeneration;
-unsigned LLVMIRGenerationRefCount;
 
 /// True if we've finished generating IR. This prevents us from generating
 /// additional LLVM IR after emitting output in HandleTranslationUnit. This
@@ -90,7 +89,6 @@
   CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
   AsmOutStream(std::move(OS)), Context(nullptr),
   LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
-  LLVMIRGenerationRefCount(0),
   Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
 CodeGenOpts, C, CoverageInfo)),
   LinkModules(std::move(LinkModules)) {
@@ -113,33 +111,27 @@
   Context = &Ctx;
 
   if (llvm::TimePassesIsEnabled)
-LLVMIRGeneration.startTimer();
+LLVMIRGeneration.startReentrantTimer();
 
   Gen->Initialize(Ctx);
 
   if (llvm::TimePassesIsEnabled)
-LLVMIRGeneration.stopTimer();
+LLVMIRGeneration.stopReentrantTimer();
 }
 
 bool HandleTopLevelDecl(DeclGroupRef D) override {
   PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
  Context->getSourceManager(),
  "LLVM IR generation of declaration");
 
   // Recurse.
-  if (llvm::TimePassesIsEnabled) {
-LLVMIRGenerationRefCount += 1;
-if (LLVMIRGenerationRefCount == 1)
-  LLVMIRGeneration.startTimer();
-  }
+  if (llvm::TimePassesIsEnabled)
+LLVMIRGeneration.startReentrantTimer();
 
   Gen->HandleTopLevelDecl(D);
 
-  if (llvm::TimePassesIsEnabled) {
-LLVMIRGenerationRefCount -= 1;
-if (LLVMIRGenerationRefCount == 0)
-  LLVMIRGeneration.stopTimer();
-  }
+  if (llvm::TimePassesIsEnabled)
+LLVMIRGeneration.stopReentrantTimer();
 
   return true;
 }
@@ -149,12 +141,12 @@
  Context->getSourceManager(),
  "LLVM IR generation of inline function");
   if (llvm::TimePassesIsEnabled)
-LLVMIRGeneration.startTimer();
+LLVMIRGeneration.startReentrantTimer();
 
   Gen->HandleInlineFunctionDefinition(D);
 
   if (llvm::TimePassesIsEnabled)
-LLVMIRGeneration.stopTimer();
+LLVMIRGeneration.stopReentrantTimer();
 }
 
 void HandleInterestingDecl(DeclGroupRef D) override {
@@ -195,19 +187,13 @@
 void HandleTranslationUnit(ASTContext &C) override {
   {
 PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
-if (llvm::TimePassesIsEnabled) {
-  LLVMIRGenerationRefCount += 1;
-  if (LLVMIRGenerationRefCount == 1)
-LLVMIRGeneration.startTimer();
-}
+if (llvm::TimePassesIsEnabled)
+  LLVMIRGeneration.startReentrantTimer();
 
 Gen->HandleTranslationUnit(C);
 
-if (llvm::TimePassesIsEnabled) {
-  LLVMIRGenerationRefCount -= 1;
-  if (LLVMIRGenerationRefCount == 0)
-LLVMIRGeneration.stopTimer();
-}
+if (llvm::TimePassesIsEnabled)
+  LLVMIRGeneration.stopReentrantTimer();
 
IRGenFinished = true;
   }


Index: lib/CodeGen/CodeGenAction.cpp
===
--- lib/CodeGen/CodeGenAction.cpp
+++ lib/CodeGen/CodeGenAction.cpp
@@ -60,7 +60,6 @@
 ASTContext *Context;
 
 Timer LLVMIRGeneration;
-unsigned LLVMIRGenerationRefCount;
 
 /// True if we've finished generating IR. This prevents us from generating
 /// additional LLVM IR after emitting output in HandleTranslationUnit. This
@@ -90,7 +89,6 @@
   CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
   AsmOutStream(std::move(OS)), Context(nullptr),
   LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
-  LLVMIRGenerationRefCount(0),
   Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
 CodeGenOpts, C, CoverageInfo)),
   LinkModules(std::move(LinkModules)) {
@@ -113,33 +111,27 @@
   Context = &Ctx;
 
   if (llvm::TimePassesIsEnabled)
-LLVMIRGeneration.startTimer();
+LLVMIRGeneration.startReentrantTimer();
 
   Gen->Initialize(Ctx);
 
   if (llvm::TimePassesIsEnabled)
-

[PATCH] D36989: [clang-diff] Refactor stop-after command-line flag

2017-08-22 Thread Jacob Gravelle via Phabricator via cfe-commits
jgravelle-google added a comment.

If you have more stop-after options it'd probably be simpler to leave it as one 
field. I'll just rename it to "stop-diff-after" to avoid the name collision.


https://reviews.llvm.org/D36989



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


[PATCH] D36989: [clang-diff] Refactor stop-after command-line flag

2017-08-22 Thread Jacob Gravelle via Phabricator via cfe-commits
jgravelle-google updated this revision to Diff 112193.
jgravelle-google added a comment.

- Undo refactor, just change name


https://reviews.llvm.org/D36989

Files:
  test/Tooling/clang-diff-topdown.cpp
  tools/clang-diff/ClangDiff.cpp


Index: tools/clang-diff/ClangDiff.cpp
===
--- tools/clang-diff/ClangDiff.cpp
+++ tools/clang-diff/ClangDiff.cpp
@@ -50,7 +50,7 @@
 cl::Optional,
 cl::cat(ClangDiffCategory));
 
-static cl::opt StopAfter("stop-after",
+static cl::opt StopAfter("stop-diff-after",
   cl::desc(""),
   cl::Optional, cl::init(""),
   cl::cat(ClangDiffCategory));
Index: test/Tooling/clang-diff-topdown.cpp
===
--- test/Tooling/clang-diff-topdown.cpp
+++ test/Tooling/clang-diff-topdown.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -E %s > %t.src.cpp
 // RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST
-// RUN: clang-diff -dump-matches -stop-after=topdown %t.src.cpp %t.dst.cpp -- 
-std=c++11 | FileCheck %s
+// RUN: clang-diff -dump-matches -stop-diff-after=topdown %t.src.cpp 
%t.dst.cpp -- -std=c++11 | FileCheck %s
 //
 // Test the top-down matching of identical subtrees only.
 


Index: tools/clang-diff/ClangDiff.cpp
===
--- tools/clang-diff/ClangDiff.cpp
+++ tools/clang-diff/ClangDiff.cpp
@@ -50,7 +50,7 @@
 cl::Optional,
 cl::cat(ClangDiffCategory));
 
-static cl::opt StopAfter("stop-after",
+static cl::opt StopAfter("stop-diff-after",
   cl::desc(""),
   cl::Optional, cl::init(""),
   cl::cat(ClangDiffCategory));
Index: test/Tooling/clang-diff-topdown.cpp
===
--- test/Tooling/clang-diff-topdown.cpp
+++ test/Tooling/clang-diff-topdown.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -E %s > %t.src.cpp
 // RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST
-// RUN: clang-diff -dump-matches -stop-after=topdown %t.src.cpp %t.dst.cpp -- -std=c++11 | FileCheck %s
+// RUN: clang-diff -dump-matches -stop-diff-after=topdown %t.src.cpp %t.dst.cpp -- -std=c++11 | FileCheck %s
 //
 // Test the top-down matching of identical subtrees only.
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36989: [clang-diff] Refactor stop-after command-line flag

2017-08-22 Thread Johannes Altmanninger via Phabricator via cfe-commits
johannes added a comment.

In https://reviews.llvm.org/D36989#848835, @jgravelle-google wrote:

> If you have more stop-after options it'd probably be simpler to leave it as 
> one field. I'll just rename it to "stop-diff-after" to avoid the name 
> collision.


Ok, you can go ahead. Or, if I should do it let me know.


https://reviews.llvm.org/D36989



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


[PATCH] D16808: [MCU] PR26438: Fix assertion failure on function returning an empty struct or union

2017-08-22 Thread Alexander Kyte via Phabricator via cfe-commits
alexanderkyte added a comment.

This change is causing mono's native interop with C code compiled from clang to 
break. After some investigation, we're tracked bitcode differences between 
tests that fail versus not. When we upgrade the compiler to Xcode 8.3, we see 
that code generated to call functions returning empty structs will now generate 
code that crashes.

This seems to be us trying to pass arguments assuming that clang exhibits the 
same behavior it used to. It is easy enough for us to generate code for what 
clang does now, but that code would break if forced to interact with C compiled 
by gcc and older clangs.

Is there a way for callers of clang-emitted code to detect which ABI clang is 
going to use when returning an empty struct? This ABI change does not seem to 
admit backwards compatibility.

xcode73's clang -emit-llvm generates:

- define void @ret(%struct.AStruct* noalias sret %agg.result, i32 %a) #0 {

while xcode83's clang generates:

- define void @ret(i32) #0 {


Repository:
  rL LLVM

https://reviews.llvm.org/D16808



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


[PATCH] D36075: [refactor] Initial support for refactoring action rules

2017-08-22 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman added inline comments.



Comment at: 
include/clang/Tooling/Refactoring/RefactoringOperationController.h:19
+
+/// Encapsulates all of the possible state that an individual refactoring
+/// operation might have. Controls the process of initiation of refactoring

ioeric wrote:
> What are all the possible states, for example?
Bad comment. I think `inputs` is more descriptive.



Comment at: include/clang/Tooling/Refactoring/RefactoringResult.h:27
+
+  RefactoringResult(AtomicChange Change) : Kind(AtomicChanges) {
+Changes.push_back(std::move(Change));

alexshap wrote:
> explicit ?
Nah, it's more convenient to be able to return a single `AtomicChanges` without 
an explicit initializer I think.



Comment at: include/clang/Tooling/Refactoring/RefactoringResult.h:35
+
+  llvm::MutableArrayRef getChanges() {
+assert(getKind() == AtomicChanges &&

ioeric wrote:
> Do we expect the result changes to be modified? Why?
No, that was a workaround for a non-const member use. I'll use a const cast 
instead.



Comment at: include/clang/Tooling/Refactoring/SourceSelectionConstraints.h:35
+/// A custom selection requirement.
+class Requirement {
+  /// Subclasses must implement 'T evaluateSelection(SelectionConstraint) 
const'

ioeric wrote:
> It might worth explaining the relationship between this and the 
> `RequirementBase`. 
This class is not related to `RequirementBase` though. Were you talking about 
another class?


Repository:
  rL LLVM

https://reviews.llvm.org/D36075



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


[PATCH] D36075: [refactor] Initial support for refactoring action rules

2017-08-22 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman updated this revision to Diff 112195.
arphaman marked 7 inline comments as done.
arphaman added a comment.

- Split the header
- Remove DiagnosticOr in favour of Expected that will use a DiagnosticError 
that was proposed in the other patch.
- Address the other review comments


Repository:
  rL LLVM

https://reviews.llvm.org/D36075

Files:
  include/clang/Basic/LLVM.h
  include/clang/Tooling/Refactoring/AtomicChange.h
  include/clang/Tooling/Refactoring/EvaluateSourceSelectionConstraints.h
  include/clang/Tooling/Refactoring/RefactoringActionRule.h
  include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h
  include/clang/Tooling/Refactoring/RefactoringActionRuleRequirementsInternal.h
  include/clang/Tooling/Refactoring/RefactoringActionRules.h
  include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h
  include/clang/Tooling/Refactoring/RefactoringOperation.h
  include/clang/Tooling/Refactoring/RefactoringResult.h
  include/clang/Tooling/Refactoring/SourceSelectionConstraints.h
  unittests/Tooling/CMakeLists.txt
  unittests/Tooling/RefactoringActionRulesTest.cpp

Index: unittests/Tooling/RefactoringActionRulesTest.cpp
===
--- /dev/null
+++ unittests/Tooling/RefactoringActionRulesTest.cpp
@@ -0,0 +1,157 @@
+//===- unittest/Tooling/RefactoringTestActionRulesTest.cpp ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ReplacementTest.h"
+#include "RewriterTestContext.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Refactoring/RefactoringActionRules.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/Errc.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace tooling;
+using namespace refactoring_action_rules;
+
+namespace {
+
+class RefactoringActionRulesTest : public ::testing::Test {
+protected:
+  void SetUp() override {
+Context.Sources.setMainFileID(
+Context.createInMemoryFile("input.cpp", DefaultCode));
+  }
+
+  RewriterTestContext Context;
+  std::string DefaultCode = std::string(100, 'a');
+};
+
+TEST_F(RefactoringActionRulesTest, MyFirstRefactoringRule) {
+  auto ReplaceAWithB =
+  [](std::pair Selection)
+  -> Expected {
+const SourceManager &SM = Selection.first.getSources();
+SourceLocation Loc = Selection.first.getRange().getBegin().getLocWithOffset(
+Selection.second);
+AtomicChange Change(SM, Loc);
+llvm::Error E = Change.replace(SM, Loc, 1, "b");
+if (E)
+  return std::move(E);
+return Change;
+  };
+  class SelectionRequirement : public selection::Requirement {
+  public:
+std::pair
+evaluateSelection(selection::SourceSelectionRange Selection) const {
+  return std::make_pair(Selection, 20);
+}
+  };
+  auto Rule = createRefactoringRule(ReplaceAWithB,
+requiredSelection(SelectionRequirement()));
+
+  // When the requirements are satisifed, the rule's function must be invoked.
+  {
+RefactoringOperation Operation(Context.Sources);
+SourceLocation Cursor =
+Context.Sources.getLocForStartOfFile(Context.Sources.getMainFileID())
+.getLocWithOffset(10);
+Operation.setSelectionRange({Cursor, Cursor});
+
+Expected> ErrorOrResult =
+Rule->perform(Operation);
+ASSERT_FALSE(!ErrorOrResult);
+ASSERT_FALSE(!*ErrorOrResult);
+RefactoringResult Result = std::move(**ErrorOrResult);
+ASSERT_EQ(Result.getKind(), RefactoringResult::AtomicChanges);
+ASSERT_EQ(Result.getChanges().size(), 1u);
+std::string YAMLString =
+const_cast(Result.getChanges()[0]).toYAMLString();
+
+ASSERT_STREQ("---\n"
+ "Key: 'input.cpp:30'\n"
+ "FilePath:input.cpp\n"
+ "Error:   ''\n"
+ "InsertedHeaders: \n"
+ "RemovedHeaders:  \n"
+ "Replacements:\n" // Extra whitespace here!
+ "  - FilePath:input.cpp\n"
+ "Offset:  30\n"
+ "Length:  1\n"
+ "ReplacementText: b\n"
+ "...\n",
+ YAMLString.c_str());
+  }
+
+  // When one of the requirements is not satisfied, perform should return either
+  // None or a valid diagnostic.
+  {
+RefactoringOperation Operation(Context.Sources);
+Expected> ErrorOrResult =
+Rule->perform(Operation);
+
+ASSERT_FALSE(!ErrorOrResult);
+Optional Value = std::move(*ErrorOrResult);
+EXPECT_TRUE(!Value);
+  }
+}
+
+TEST_F(RefactoringActionRulesTest, ReturnError) {
+  Expected (*Func)(selection::SourceSelectionRange) =
+  [](selection::SourceSelectionRange) -

[PATCH] D34275: [analyzer] Re-implemente current virtual calls checker in a path-sensitive way

2017-08-22 Thread wangxin via Phabricator via cfe-commits
wangxindsb updated this revision to Diff 112196.
wangxindsb added a comment.

- Highlight pure virtual even in non-pure-only mode;
- Add change to the header.


https://reviews.llvm.org/D34275

Files:
  lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
  test/Analysis/virtualcall.cpp
  test/Analysis/virtualcall.h

Index: test/Analysis/virtualcall.h
===
--- test/Analysis/virtualcall.h
+++ test/Analysis/virtualcall.h
@@ -1,36 +1,14 @@
-#ifdef AS_SYSTEM
-#pragma clang system_header
-
-namespace system {
-  class A {
-  public:
-A() {
-  foo(); // no-warning
-}
-
-virtual int foo();
-  };
-}
-
-#else
-
 namespace header {
-  class A {
+  class Z {
   public:
-A() {
+Z() {
   foo();
 #if !PUREONLY
-#if INTERPROCEDURAL
-  // expected-warning-re@-3 ^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}}
-#else
-  // expected-warning-re@-5 ^}}Call to virtual function during construction will not dispatch to derived class}}
-#endif
+	// expected-warning-re@-2 ^}}Call to virtual function during construction}}
+	// expected-note-re@-3 ^}}This constructor of an object of type 'Z' has not returned when the virtual method was called}}
+	// expected-note-re@-4 ^}}Call to virtual function during construction}}	
 #endif
-
 }
-
 virtual int foo();
   };
 }
-
-#endif
Index: test/Analysis/virtualcall.cpp
===
--- test/Analysis/virtualcall.cpp
+++ test/Analysis/virtualcall.cpp
@@ -1,98 +1,83 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -verify -std=c++11 %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:Interprocedural=true -DINTERPROCEDURAL=1 -verify -std=c++11 %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:PureOnly=true -DPUREONLY=1 -verify -std=c++11 %s
-
-/* When INTERPROCEDURAL is set, we expect diagnostics in all functions reachable
-   from a constructor or destructor. If it is not set, we expect diagnostics
-   only in the constructor or destructor.
-
-   When PUREONLY is set, we expect diagnostics only for calls to pure virtual
-   functions not to non-pure virtual functions.
-*/
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-output=text -verify -std=c++11 %s
+
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:PureOnly=true -DPUREONLY=1 -analyzer-output=text -verify -std=c++11 %s
+
+#include "virtualcall.h"
 
 class A {
 public:
   A();
-  A(int i);
 
-  ~A() {};
-  
-  virtual int foo() = 0; // from Sema: expected-note {{'foo' declared here}}
+  ~A(){};
+
+  virtual int foo() = 0;
   virtual void bar() = 0;
   void f() {
 foo();
-#if INTERPROCEDURAL
-// expected-warning-re@-2 ^}}Call Path : foo <-- fCall to pure virtual function during construction has undefined behavior}}
-#endif
+	// expected-warning-re@-1 ^}}Call to pure virtual function during construction}}
+	// expected-note-re@-2 ^}}Call to pure virtual function during construction}}
   }
 };
 
 class B : public A {
 public:
-  B() {
-foo();
+  B() { // expected-note {{Calling default constructor for 'A'}}
+foo(); 
 #if !PUREONLY
-#if INTERPROCEDURAL
-// expected-warning-re@-3 ^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}}
-#else
-// expected-warning-re@-5 ^}}Call to virtual function during construction will not dispatch to derived class}}
+  	// expected-warning-re@-2 ^}}Call to virtual function during construction}}
+	// expected-note-re@-3 ^}}This constructor of an object of type 'B' has not returned when the virtual method was called}}
+  	// expected-note-re@-4 ^}}Call to virtual function during construction}}
 #endif
-#endif
-
   }
   ~B();
-  
+
   virtual int foo();
-  virtual void bar() { foo(); }
-#if INTERPROCEDURAL
-  // expected-warning-re@-2 ^}}Call Path : foo <-- barCall to virtual function during destruction will not dispatch to derived class}}
+  virtual void bar() {
+foo(); 
+#if !PUREONLY
+  	// expected-warning-re@-2 ^}}Call to virtual function during destruction}}
+  	// expected-note-re@-3 ^}}Call to virtual function during destruction}}
 #endif
+  } 
 };
 
-A::A() {
-  f();
-}
-
-A::A(int i) {
-  foo(); // From Sema: expected-warning {{call to pure virtual member function 'foo' has undefined behavior}}
-#if INTERPROCEDURAL
-  // expected-warning-re@-2 ^}}Call Path : fooCall to pure virtual function during construction has undefined behavior}}
-#else
-  // 

[PATCH] D35955: clang-format: Add preprocessor directive indentation

2017-08-22 Thread Daniel Jasper via Phabricator via cfe-commits
djasper added a comment.

Krasimir: Can you actually give this a round of review? I will also try to do 
so tomorrow.


https://reviews.llvm.org/D35955



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


r311474 - Test commit access.

2017-08-22 Thread Volodymyr Sapsai via cfe-commits
Author: vsapsai
Date: Tue Aug 22 10:39:25 2017
New Revision: 311474

URL: http://llvm.org/viewvc/llvm-project?rev=311474&view=rev
Log:
Test commit access.

Modified:
cfe/trunk/include/clang/Analysis/CloneDetection.h

Modified: cfe/trunk/include/clang/Analysis/CloneDetection.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CloneDetection.h?rev=311474&r1=311473&r2=311474&view=diff
==
--- cfe/trunk/include/clang/Analysis/CloneDetection.h (original)
+++ cfe/trunk/include/clang/Analysis/CloneDetection.h Tue Aug 22 10:39:25 2017
@@ -7,7 +7,7 @@
 //
 
//===--===//
 ///
-/// /file
+/// \file
 /// This file defines classes for searching and anlyzing source code clones.
 ///
 
//===--===//


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


[PATCH] D36969: [Basic] Add a DiagnosticError llvm::ErrorInfo subclass

2017-08-22 Thread Vedant Kumar via Phabricator via cfe-commits
vsk added a comment.

Nice! I'd like to get your thoughts on two candidate ergonomic changes:




Comment at: unittests/Basic/DiagnosticTest.cpp:81
+  llvm::Expected> Value =
+  llvm::make_error(PartialDiagnosticAt(
+  SourceLocation(), PartialDiagnostic(diag::err_cannot_open_file, 
Alloc)

It might be useful to add an Error-returning wrapper around PDA, e.g:
`static Error PartialDiagnosticAt::get(...)`



Comment at: unittests/Basic/DiagnosticTest.cpp:90
+ErrDiag = std::move(Err.getDiagnostic());
+  });
+  EXPECT_EQ(ErrDiag.first, SourceLocation());

Creating a null diagnostic before taking an error may become cumbersome. An 
alternative is to add a static helper in DiagnosticError:

```
static ParitalDiagnosticAt &DiagnosticError::take(Error E) {
  PartialDiagnosticAt *PDA = nullptr;
  handleAllErrors(std::move(E), [&](DE) { PDA = &DE.getDiagnostic(); });
  assert(PDA && "Expected a DiagnosticError");
  return *PDA;
}
```

This is more ergonomic, but the downside is that you lose some flexibility 
(what happens if there are two kinds of errors?, etc).

Another alternative is to switch to a callback-driven style (though that might 
require a lot of refactoring).


Repository:
  rL LLVM

https://reviews.llvm.org/D36969



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


r311476 - [clang-diff] Refactor stop-after command-line flag

2017-08-22 Thread Jacob Gravelle via cfe-commits
Author: jgravelle
Date: Tue Aug 22 10:42:44 2017
New Revision: 311476

URL: http://llvm.org/viewvc/llvm-project?rev=311476&view=rev
Log:
[clang-diff] Refactor stop-after command-line flag

Summary:
Rename stop-after to stop-diff-after. When building LLVM with
-DLLVM_BUILD_LLVM_DYLIB=ON, stop-after collides with the stop-after
already present in LLVM.

Reviewers: johannes, arphaman

Subscribers: klimek, aheejin, cfe-commits

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

Modified:
cfe/trunk/test/Tooling/clang-diff-topdown.cpp
cfe/trunk/tools/clang-diff/ClangDiff.cpp

Modified: cfe/trunk/test/Tooling/clang-diff-topdown.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-diff-topdown.cpp?rev=311476&r1=311475&r2=311476&view=diff
==
--- cfe/trunk/test/Tooling/clang-diff-topdown.cpp (original)
+++ cfe/trunk/test/Tooling/clang-diff-topdown.cpp Tue Aug 22 10:42:44 2017
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -E %s > %t.src.cpp
 // RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST
-// RUN: clang-diff -dump-matches -stop-after=topdown %t.src.cpp %t.dst.cpp -- 
-std=c++11 | FileCheck %s
+// RUN: clang-diff -dump-matches -stop-diff-after=topdown %t.src.cpp 
%t.dst.cpp -- -std=c++11 | FileCheck %s
 //
 // Test the top-down matching of identical subtrees only.
 

Modified: cfe/trunk/tools/clang-diff/ClangDiff.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-diff/ClangDiff.cpp?rev=311476&r1=311475&r2=311476&view=diff
==
--- cfe/trunk/tools/clang-diff/ClangDiff.cpp (original)
+++ cfe/trunk/tools/clang-diff/ClangDiff.cpp Tue Aug 22 10:42:44 2017
@@ -50,7 +50,7 @@ static cl::opt DestinationP
 cl::Optional,
 cl::cat(ClangDiffCategory));
 
-static cl::opt StopAfter("stop-after",
+static cl::opt StopAfter("stop-diff-after",
   cl::desc(""),
   cl::Optional, cl::init(""),
   cl::cat(ClangDiffCategory));


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


[PATCH] D36989: [clang-diff] Refactor stop-after command-line flag

2017-08-22 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL311476: [clang-diff] Refactor stop-after command-line flag 
(authored by jgravelle).

Repository:
  rL LLVM

https://reviews.llvm.org/D36989

Files:
  cfe/trunk/test/Tooling/clang-diff-topdown.cpp
  cfe/trunk/tools/clang-diff/ClangDiff.cpp


Index: cfe/trunk/test/Tooling/clang-diff-topdown.cpp
===
--- cfe/trunk/test/Tooling/clang-diff-topdown.cpp
+++ cfe/trunk/test/Tooling/clang-diff-topdown.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -E %s > %t.src.cpp
 // RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST
-// RUN: clang-diff -dump-matches -stop-after=topdown %t.src.cpp %t.dst.cpp -- 
-std=c++11 | FileCheck %s
+// RUN: clang-diff -dump-matches -stop-diff-after=topdown %t.src.cpp 
%t.dst.cpp -- -std=c++11 | FileCheck %s
 //
 // Test the top-down matching of identical subtrees only.
 
Index: cfe/trunk/tools/clang-diff/ClangDiff.cpp
===
--- cfe/trunk/tools/clang-diff/ClangDiff.cpp
+++ cfe/trunk/tools/clang-diff/ClangDiff.cpp
@@ -50,7 +50,7 @@
 cl::Optional,
 cl::cat(ClangDiffCategory));
 
-static cl::opt StopAfter("stop-after",
+static cl::opt StopAfter("stop-diff-after",
   cl::desc(""),
   cl::Optional, cl::init(""),
   cl::cat(ClangDiffCategory));


Index: cfe/trunk/test/Tooling/clang-diff-topdown.cpp
===
--- cfe/trunk/test/Tooling/clang-diff-topdown.cpp
+++ cfe/trunk/test/Tooling/clang-diff-topdown.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -E %s > %t.src.cpp
 // RUN: %clang_cc1 -E %s > %t.dst.cpp -DDEST
-// RUN: clang-diff -dump-matches -stop-after=topdown %t.src.cpp %t.dst.cpp -- -std=c++11 | FileCheck %s
+// RUN: clang-diff -dump-matches -stop-diff-after=topdown %t.src.cpp %t.dst.cpp -- -std=c++11 | FileCheck %s
 //
 // Test the top-down matching of identical subtrees only.
 
Index: cfe/trunk/tools/clang-diff/ClangDiff.cpp
===
--- cfe/trunk/tools/clang-diff/ClangDiff.cpp
+++ cfe/trunk/tools/clang-diff/ClangDiff.cpp
@@ -50,7 +50,7 @@
 cl::Optional,
 cl::cat(ClangDiffCategory));
 
-static cl::opt StopAfter("stop-after",
+static cl::opt StopAfter("stop-diff-after",
   cl::desc(""),
   cl::Optional, cl::init(""),
   cl::cat(ClangDiffCategory));
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r309226 - Headers: improve ARM EHABI coverage of unwind.h

2017-08-22 Thread Evgenii Stepanov via cfe-commits
As I understand, using compiler-rt as libgcc replacement on ARM is
currently broken because of this change, but I have not looked since
my last message.

On Mon, Aug 21, 2017 at 4:56 PM, Hans Wennborg  wrote:
> Is there something we need for 5.0.0 here?
>
> On Sat, Aug 12, 2017 at 9:58 PM, Saleem Abdulrasool
>  wrote:
>> Yeah, we should adjust that.  Technically, it is `_Unwind_Control_Block on
>> ARM EHABI.  However, _Unwind_Exception is aliased to that, which is why we
>> can use that in the personality routine.  We should adjust the sources for
>> the personality routine.
>>
>> On Fri, Aug 11, 2017 at 1:12 PM, Evgenii Stepanov
>>  wrote:
>>>
>>> Hi,
>>>
>>> I've noticed that the code in
>>> compiler-rt/lib/builtins/gcc_personality_v0.c refers to
>>> _Unwind_Exception as "struct _Unwind_Exception". With this change, it
>>> is not a struct anymore on ARM. Should that code be fixed, or is it a
>>> problem in this change?
>>>
>>> compiler-rt/lib/builtins/gcc_personality_v0.c:153:23: error:
>>> declaration of 'struct _Unwind_Exception' will not be visible outside
>>> of this function [-Werror,-Wvisibility]
>>> continueUnwind(struct _Unwind_Exception *exceptionObject,
>>>
>>> On Thu, Jul 27, 2017 at 9:46 AM, Hans Wennborg via cfe-commits
>>>  wrote:
>>> > Merged to 5.0 in r309290.
>>> >
>>> > On Wed, Jul 26, 2017 at 3:55 PM, Saleem Abdulrasool via cfe-commits
>>> >  wrote:
>>> >> Author: compnerd
>>> >> Date: Wed Jul 26 15:55:23 2017
>>> >> New Revision: 309226
>>> >>
>>> >> URL: http://llvm.org/viewvc/llvm-project?rev=309226&view=rev
>>> >> Log:
>>> >> Headers: improve ARM EHABI coverage of unwind.h
>>> >>
>>> >> Ensure that we define the `_Unwind_Control_Block` structure used on ARM
>>> >> EHABI targets.  This is needed for building libc++abi with the unwind.h
>>> >> from the resource dir.  A minor fallout of this is that we needed to
>>> >> create a typedef for _Unwind_Exception to work across ARM EHABI and
>>> >> non-EHABI targets.  The structure definitions here are based originally
>>> >> on the documentation from ARM under the "Exception Handling ABI for the
>>> >> ARMĀ® Architecture" Section 7.2.  They are then adjusted to more closely
>>> >> reflect the definition in libunwind from LLVM.  Those changes are
>>> >> compatible in layout but permit easier use in libc++abi and help
>>> >> maintain compatibility between libunwind and the compiler provided
>>> >> definition.
>>> >>
>>> >> Modified:
>>> >> cfe/trunk/lib/Headers/unwind.h
>>> >>
>>> >> Modified: cfe/trunk/lib/Headers/unwind.h
>>> >> URL:
>>> >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/unwind.h?rev=309226&r1=309225&r2=309226&view=diff
>>> >>
>>> >> ==
>>> >> --- cfe/trunk/lib/Headers/unwind.h (original)
>>> >> +++ cfe/trunk/lib/Headers/unwind.h Wed Jul 26 15:55:23 2017
>>> >> @@ -76,7 +76,13 @@ typedef intptr_t _sleb128_t;
>>> >>  typedef uintptr_t _uleb128_t;
>>> >>
>>> >>  struct _Unwind_Context;
>>> >> +#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) ||
>>> >> defined(__ARM_DWARF_EH___))
>>> >> +struct _Unwind_Control_Block;
>>> >> +typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */
>>> >> +#else
>>> >>  struct _Unwind_Exception;
>>> >> +typedef struct _Unwind_Exception _Unwind_Exception;
>>> >> +#endif
>>> >>  typedef enum {
>>> >>_URC_NO_REASON = 0,
>>> >>  #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
>>> >> @@ -109,8 +115,42 @@ typedef enum {
>>> >>  } _Unwind_Action;
>>> >>
>>> >>  typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code,
>>> >> - struct _Unwind_Exception
>>> >> *);
>>> >> + _Unwind_Exception *);
>>> >>
>>> >> +#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) ||
>>> >> defined(__ARM_DWARF_EH___))
>>> >> +typedef struct _Unwind_Control_Block _Unwind_Control_Block;
>>> >> +typedef uint32_t _Unwind_EHT_Header;
>>> >> +
>>> >> +struct _Unwind_Control_Block {
>>> >> +  uint64_t exception_class;
>>> >> +  void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block
>>> >> *);
>>> >> +  /* unwinder cache (private fields for the unwinder's use) */
>>> >> +  struct {
>>> >> +uint32_t reserved1; /* forced unwind stop function, 0 if not
>>> >> forced */
>>> >> +uint32_t reserved2; /* personality routine */
>>> >> +uint32_t reserved3; /* callsite */
>>> >> +uint32_t reserved4; /* forced unwind stop argument */
>>> >> +uint32_t reserved5;
>>> >> +  } unwinder_cache;
>>> >> +  /* propagation barrier cache (valid after phase 1) */
>>> >> +  struct {
>>> >> +uint32_t sp;
>>> >> +uint32_t bitpattern[5];
>>> >> +  } barrier_cache;
>>> >> +  /* cleanup cache (preserved over cleanup) */
>>> >> +  struct {
>>> >> +uint32_t bitpattern[4];
>>> >> +  } cleanup_cache;
>>> >> +  /* personality cache (for personality's benefit) */
>>> >> +  struct {
>>> >

r311479 - [OPENMP] Fix for PR34014: OpenMP 4.5: Target construct in static method

2017-08-22 Thread Alexey Bataev via cfe-commits
Author: abataev
Date: Tue Aug 22 10:54:52 2017
New Revision: 311479

URL: http://llvm.org/viewvc/llvm-project?rev=311479&view=rev
Log:
[OPENMP] Fix for PR34014: OpenMP 4.5: Target construct in static method
of class fails to map class static variable.

If the global variable is captured and it has several redeclarations,
sometimes it may lead to a compiler crash. Patch fixes this by working
only with canonical declarations.

Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/OpenMP/target_map_codegen.cpp

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=311479&r1=311478&r2=311479&view=diff
==
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Aug 22 10:54:52 2017
@@ -2300,6 +2300,7 @@ LValue CodeGenFunction::EmitDeclRefLValu
 
 // Check for captured variables.
 if (E->refersToEnclosingVariableOrCapture()) {
+  VD = VD->getCanonicalDecl();
   if (auto *FD = LambdaCaptureFields.lookup(VD))
 return EmitCapturedFieldLValue(*this, FD, CXXABIThisValue);
   else if (CapturedStmtInfo) {

Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=311479&r1=311478&r2=311479&view=diff
==
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Aug 22 10:54:52 2017
@@ -65,6 +65,8 @@ public:
 for (auto &C : CS->captures()) {
   if (C.capturesVariable() || C.capturesVariableByCopy()) {
 auto *VD = C.getCapturedVar();
+assert(VD == VD->getCanonicalDecl() &&
+"Canonical decl must be captured.");
 DeclRefExpr DRE(const_cast(VD),
 isCapturedVar(CGF, VD) ||
 (CGF.CapturedStmtInfo &&

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=311479&r1=311478&r2=311479&view=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Aug 22 10:54:52 2017
@@ -709,6 +709,7 @@ public:
llvm::function_ref PrivateGen) {
   assert(PerformCleanup && "adding private to dead scope");
 
+  LocalVD = LocalVD->getCanonicalDecl();
   // Only save it once.
   if (SavedLocals.count(LocalVD)) return false;
 
@@ -761,6 +762,7 @@ public:
 
 /// Checks if the global variable is captured in current function. 
 bool isGlobalVarCaptured(const VarDecl *VD) const {
+  VD = VD->getCanonicalDecl();
   return !VD->isLocalVarDeclOrParm() && CGF.LocalDeclMap.count(VD) > 0;
 }
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=311479&r1=311478&r2=311479&view=diff
==
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Aug 22 10:54:52 2017
@@ -14200,6 +14200,7 @@ bool Sema::tryCaptureVariable(
   bool IsGlobal = !Var->hasLocalStorage();
   if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedDecl(Var)))
 return true;
+  Var = Var->getCanonicalDecl();
 
   // Walk up the stack to determine whether we can capture the variable,
   // performing the "simple" checks that don't depend on type. We stop when

Modified: cfe/trunk/test/OpenMP/target_map_codegen.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_map_codegen.cpp?rev=311479&r1=311478&r2=311479&view=diff
==
--- cfe/trunk/test/OpenMP/target_map_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/target_map_codegen.cpp Tue Aug 22 10:54:52 2017
@@ -15,12 +15,30 @@
 // RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple 
i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | 
FileCheck %s  --check-prefix CK1 --check-prefix CK1-32
 #ifdef CK1
 
+class B {
+public:
+  static double VAR;
+  B() {
+  }
+
+  static void modify(int &res) {
+#pragma omp target map(tofrom \
+   : res)
+{
+  res = B::VAR;
+}
+  }
+};
+double B::VAR = 1.0;
+
 // CK1-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
 // Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_IS_FIRST = 288
 // CK1-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i32] [i32 288]
 
 // CK1-LABEL: implicit_maps_integer
 void implicit_maps_integer (int a){
+  // CK1: call void{{.*}}mod

r311480 - [Parser] Correct initalizer typos before lambda capture type is deduced.

2017-08-22 Thread Volodymyr Sapsai via cfe-commits
Author: vsapsai
Date: Tue Aug 22 10:55:19 2017
New Revision: 311480

URL: http://llvm.org/viewvc/llvm-project?rev=311480&view=rev
Log:
[Parser] Correct initalizer typos before lambda capture type is deduced.

This is the same assertion as in https://reviews.llvm.org/D25206 that is
triggered when RecordLayoutBuilder tries to compute the size of a field
(for capture "typo_boo" in the test case) whose type hasn't been
deduced.

The fix is to add CorrectDelayedTyposInExpr call to the cases when we
aren't disambiguating between an Obj-C message send and a lambda
expression.

rdar://problem/31760839

Reviewers: rsmith, ahatanak

Reviewed By: arphaman

Subscribers: cfe-commits

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

Modified:
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=311480&r1=311479&r2=311480&view=diff
==
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Aug 22 10:55:19 2017
@@ -966,6 +966,8 @@ Optional Parser::ParseLambdaIn
 // that would be an error.
 
 ParsedType InitCaptureType;
+if (!Init.isInvalid())
+  Init = Actions.CorrectDelayedTyposInExpr(Init.get());
 if (Init.isUsable()) {
   // Get the pointer and store it in an lvalue, so we can use it as an
   // out argument.

Modified: cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp?rev=311480&r1=311479&r2=311480&view=diff
==
--- cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp Tue Aug 22 10:55:19 2017
@@ -206,3 +206,11 @@ void test(double weight) {
   find(weight); // expected-note {{in instantiation of function template 
specialization}}
 }
 }
+
+namespace init_capture_undeclared_identifier {
+  auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}}
+
+  int typo_foo; // expected-note 2 {{'typo_foo' declared here}}
+  auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 
'typo_boo'; did you mean 'typo_foo'}}
+  auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 
'typo_boo'; did you mean 'typo_foo'}}
+}


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


[PATCH] D36853: [Parser] Correct initalizer typos before lambda capture type is deduced.

2017-08-22 Thread Volodymyr Sapsai via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL311480: [Parser] Correct initalizer typos before lambda 
capture type is deduced. (authored by vsapsai).

Changed prior to commit:
  https://reviews.llvm.org/D36853?vs=111716&id=112201#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D36853

Files:
  cfe/trunk/lib/Parse/ParseExprCXX.cpp
  cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp


Index: cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp
===
--- cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp
+++ cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp
@@ -206,3 +206,11 @@
   find(weight); // expected-note {{in instantiation of function template 
specialization}}
 }
 }
+
+namespace init_capture_undeclared_identifier {
+  auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}}
+
+  int typo_foo; // expected-note 2 {{'typo_foo' declared here}}
+  auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 
'typo_boo'; did you mean 'typo_foo'}}
+  auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 
'typo_boo'; did you mean 'typo_foo'}}
+}
Index: cfe/trunk/lib/Parse/ParseExprCXX.cpp
===
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp
@@ -966,6 +966,8 @@
 // that would be an error.
 
 ParsedType InitCaptureType;
+if (!Init.isInvalid())
+  Init = Actions.CorrectDelayedTyposInExpr(Init.get());
 if (Init.isUsable()) {
   // Get the pointer and store it in an lvalue, so we can use it as an
   // out argument.


Index: cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp
===
--- cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp
+++ cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp
@@ -206,3 +206,11 @@
   find(weight); // expected-note {{in instantiation of function template specialization}}
 }
 }
+
+namespace init_capture_undeclared_identifier {
+  auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}}
+
+  int typo_foo; // expected-note 2 {{'typo_foo' declared here}}
+  auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
+  auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
+}
Index: cfe/trunk/lib/Parse/ParseExprCXX.cpp
===
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp
@@ -966,6 +966,8 @@
 // that would be an error.
 
 ParsedType InitCaptureType;
+if (!Init.isInvalid())
+  Init = Actions.CorrectDelayedTyposInExpr(Init.get());
 if (Init.isUsable()) {
   // Get the pointer and store it in an lvalue, so we can use it as an
   // out argument.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r309226 - Headers: improve ARM EHABI coverage of unwind.h

2017-08-22 Thread Hans Wennborg via cfe-commits
Is there a bug filed? Since this was merged to 5.0.0, I'd like to know
if we broke something and if that is something that needs to be fixed.

On Tue, Aug 22, 2017 at 10:46 AM, Evgenii Stepanov
 wrote:
> As I understand, using compiler-rt as libgcc replacement on ARM is
> currently broken because of this change, but I have not looked since
> my last message.
>
> On Mon, Aug 21, 2017 at 4:56 PM, Hans Wennborg  wrote:
>> Is there something we need for 5.0.0 here?
>>
>> On Sat, Aug 12, 2017 at 9:58 PM, Saleem Abdulrasool
>>  wrote:
>>> Yeah, we should adjust that.  Technically, it is `_Unwind_Control_Block on
>>> ARM EHABI.  However, _Unwind_Exception is aliased to that, which is why we
>>> can use that in the personality routine.  We should adjust the sources for
>>> the personality routine.
>>>
>>> On Fri, Aug 11, 2017 at 1:12 PM, Evgenii Stepanov
>>>  wrote:

 Hi,

 I've noticed that the code in
 compiler-rt/lib/builtins/gcc_personality_v0.c refers to
 _Unwind_Exception as "struct _Unwind_Exception". With this change, it
 is not a struct anymore on ARM. Should that code be fixed, or is it a
 problem in this change?

 compiler-rt/lib/builtins/gcc_personality_v0.c:153:23: error:
 declaration of 'struct _Unwind_Exception' will not be visible outside
 of this function [-Werror,-Wvisibility]
 continueUnwind(struct _Unwind_Exception *exceptionObject,

 On Thu, Jul 27, 2017 at 9:46 AM, Hans Wennborg via cfe-commits
  wrote:
 > Merged to 5.0 in r309290.
 >
 > On Wed, Jul 26, 2017 at 3:55 PM, Saleem Abdulrasool via cfe-commits
 >  wrote:
 >> Author: compnerd
 >> Date: Wed Jul 26 15:55:23 2017
 >> New Revision: 309226
 >>
 >> URL: http://llvm.org/viewvc/llvm-project?rev=309226&view=rev
 >> Log:
 >> Headers: improve ARM EHABI coverage of unwind.h
 >>
 >> Ensure that we define the `_Unwind_Control_Block` structure used on ARM
 >> EHABI targets.  This is needed for building libc++abi with the unwind.h
 >> from the resource dir.  A minor fallout of this is that we needed to
 >> create a typedef for _Unwind_Exception to work across ARM EHABI and
 >> non-EHABI targets.  The structure definitions here are based originally
 >> on the documentation from ARM under the "Exception Handling ABI for the
 >> ARMĀ® Architecture" Section 7.2.  They are then adjusted to more closely
 >> reflect the definition in libunwind from LLVM.  Those changes are
 >> compatible in layout but permit easier use in libc++abi and help
 >> maintain compatibility between libunwind and the compiler provided
 >> definition.
 >>
 >> Modified:
 >> cfe/trunk/lib/Headers/unwind.h
 >>
 >> Modified: cfe/trunk/lib/Headers/unwind.h
 >> URL:
 >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/unwind.h?rev=309226&r1=309225&r2=309226&view=diff
 >>
 >> ==
 >> --- cfe/trunk/lib/Headers/unwind.h (original)
 >> +++ cfe/trunk/lib/Headers/unwind.h Wed Jul 26 15:55:23 2017
 >> @@ -76,7 +76,13 @@ typedef intptr_t _sleb128_t;
 >>  typedef uintptr_t _uleb128_t;
 >>
 >>  struct _Unwind_Context;
 >> +#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) ||
 >> defined(__ARM_DWARF_EH___))
 >> +struct _Unwind_Control_Block;
 >> +typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */
 >> +#else
 >>  struct _Unwind_Exception;
 >> +typedef struct _Unwind_Exception _Unwind_Exception;
 >> +#endif
 >>  typedef enum {
 >>_URC_NO_REASON = 0,
 >>  #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
 >> @@ -109,8 +115,42 @@ typedef enum {
 >>  } _Unwind_Action;
 >>
 >>  typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code,
 >> - struct _Unwind_Exception
 >> *);
 >> + _Unwind_Exception *);
 >>
 >> +#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) ||
 >> defined(__ARM_DWARF_EH___))
 >> +typedef struct _Unwind_Control_Block _Unwind_Control_Block;
 >> +typedef uint32_t _Unwind_EHT_Header;
 >> +
 >> +struct _Unwind_Control_Block {
 >> +  uint64_t exception_class;
 >> +  void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block
 >> *);
 >> +  /* unwinder cache (private fields for the unwinder's use) */
 >> +  struct {
 >> +uint32_t reserved1; /* forced unwind stop function, 0 if not
 >> forced */
 >> +uint32_t reserved2; /* personality routine */
 >> +uint32_t reserved3; /* callsite */
 >> +uint32_t reserved4; /* forced unwind stop argument */
 >> +uint32_t reserved5;
 >> +  } unwinder_cache;
 >> +  /* propagation barrier cache (valid after phase 1) */
 >> +  struc

[PATCH] D36678: [OpenCL] Do not use vararg in emitted functions for enqueue_kernel

2017-08-22 Thread Anastasia Stulova via Phabricator via cfe-commits
Anastasia added inline comments.



Comment at: test/CodeGenOpenCL/cl20-device-side-enqueue.cl:116
+  // B32: store i32 4, i32* %[[TMP3]], align 4
+  // B32: call i32 @__enqueue_kernel_vaargs(%opencl.queue_t{{.*}}* [[DEF_Q]], 
i32 [[FLAGS]], %struct.ndrange_t* [[NDR]]{{(.[0-9]+)?}}, i8 addrspace(4)* 
addrspacecast (i8 addrspace(1)* bitcast ({ i8**, i32, i32, i8*, 
%struct.__block_descriptor addrspace(2)* } addrspace(1)* 
@__block_literal_global{{(.[0-9]+)?}} to i8 addrspace(1)*) to i8 
addrspace(4)*), i32 3, i32* %[[TMP1]])
+  // B64: %[[TMP:.*]] = alloca [3 x i64]

You are not checking the arrays in the other calls too?


https://reviews.llvm.org/D36678



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


[PATCH] D35271: Fix printing policy for AST context loaded from file

2017-08-22 Thread Vedant Kumar via Phabricator via cfe-commits
vsk added a comment.

Thanks for adding the test! This is looking good.




Comment at: unittests/Frontend/ASTUnitTest.cpp:32
+llvm::SmallString<256> Dir;
+ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("astunit-test", Dir));
+TestDir = Dir.str();

If a directory isn't necessary to exercise the desired functionality, it'd be 
better to use createTemporaryFile() to open a temporary file descriptor, and 
then to use tool_output_file() to manage the descriptor's lifetime. 
Tool_output_file has logic to clean up files when a signal is received, etc.



Comment at: unittests/Frontend/ASTUnitTest.cpp:48
+TemporaryFiles.insert(Filename);
+llvm::sys::fs::create_directories(llvm::sys::path::parent_path(Filename));
+  }

It doesn't look like all of the directories which could be created here would 
be deleted? With any luck it'll be possible to use tool_output_file() to side 
step the issue.


https://reviews.llvm.org/D35271



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


[PATCH] D35955: clang-format: Add preprocessor directive indentation

2017-08-22 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir added inline comments.



Comment at: lib/Format/ContinuationIndenter.cpp:383
+   State.Line->Type == LT_ImportStatement) &&
+  Current.Previous->is(tok::hash) && State.FirstIndent > 0) {
+Spaces += State.FirstIndent;

You can replace `Current.Previous` with `Previous`. Also, I'd swap the checks a 
bit, like:
```
  if (Previous.is(tok::hash) && State.FirstIndent > 0 &&
  Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
  (State.Line->Type == LT_PreprocessorDirective ||
   State.Line->Type == LT_ImportStatement)) {
```
That way, the common case `Previous.is(tok::hash) == false` is handled quickly.



Comment at: lib/Format/ContinuationIndenter.cpp:387
+// hash. This causes second-level indents onward to have an extra space
+// after the tabs. We set the state to column 0 to avoid this misalignment.
+if (Style.UseTab != FormatStyle::UT_Never)

I don't understand this comment. Could you please give an example?



Comment at: lib/Format/UnwrappedLineParser.cpp:701
+  bool MaybeIncludeGuard = IfNDef;
+  for (auto& Line : Lines) {
+if (!Line.Tokens.front().Tok->is(tok::comment)) {

This can easily lead to a pretty bad runtime: consider a file starting with a 
few hundred lines of comments and having a few hundred `#ifdef`-s.

I'd say that after we do this MaybeIncludeGuard thing once, we don't repeat it 
again.

Also, lines could start with a block comment and continue with code:
```
/* small */ int ten = 10;
```



Comment at: lib/Format/UnwrappedLineParser.cpp:732
+  // then we count it as a real include guard and subtract one from every
+  // preprocessor indent.
+  unsigned TokenPosition = Tokens->getPosition();

Why do we need to subtract one from every preprocessor indent?



Comment at: lib/Format/UnwrappedLineParser.cpp:737
+for (auto& Line : Lines) {
+  if (Line.InPPDirective && Line.Level > 0)
+--Line.Level;

Wouldn't this also indent lines continuing macro definitions, as in:
```
#define A(x) int f(int x) { \
  return x; \
}
```



Comment at: lib/Format/UnwrappedLineParser.cpp:760
+  }
+  PPMaybeIncludeGuard = nullptr;
   nextToken();

Why do we reset `PPMaybeIncludeGuard` here?



Comment at: lib/Format/UnwrappedLineParser.cpp:770
   addUnwrappedLine();
-  Line->Level = 1;
+  ++Line->Level;
 

Why do we `++Line->Level` here?



Comment at: lib/Format/UnwrappedLineParser.cpp:787
   addUnwrappedLine();
+  PPMaybeIncludeGuard = nullptr;
 }

Why do we reset `PPMaybeIncludeGuard` here?



Comment at: lib/Format/UnwrappedLineParser.h:249
 
+  FormatToken *PPMaybeIncludeGuard;
+  bool FoundIncludeGuardStart;

Please add a comment for `PPMaybeIncludeGuard`: is it expected to point to the 
hash token of the `#ifdef`, or?


https://reviews.llvm.org/D35955



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


[PATCH] D35385: [Driver] Darwin: Link in the profile runtime archive first

2017-08-22 Thread Juergen Ributzka via Phabricator via cfe-commits
ributzka accepted this revision.
ributzka added a comment.
This revision is now accepted and ready to land.

Nice cleanup with the RuntimeLinkOptions enum. LGTM


https://reviews.llvm.org/D35385



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


Re: r311397 - [Driver][Darwin] Do not pass -munwind-table if -fno-excpetions is

2017-08-22 Thread Akira Hatanaka via cfe-commits
Hans, can this be merged to 5.0 too? This is a follow-up to r310006.

Thanks.

> On Aug 21, 2017, at 3:46 PM, Akira Hatanaka via cfe-commits 
>  wrote:
> 
> Author: ahatanak
> Date: Mon Aug 21 15:46:46 2017
> New Revision: 311397
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=311397&view=rev
> Log:
> [Driver][Darwin] Do not pass -munwind-table if -fno-excpetions is
> supplied.
> 
> With this change, -fno-exceptions disables unwind tables unless
> -funwind-tables is supplied too or the target is x86-64 (x86-64 requires
> emitting unwind tables).
> 
> rdar://problem/33934446
> 
> Modified:
>cfe/trunk/lib/Driver/ToolChains/Darwin.cpp
>cfe/trunk/test/Driver/clang-translation.c
> 
> Modified: cfe/trunk/lib/Driver/ToolChains/Darwin.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Darwin.cpp?rev=311397&r1=311396&r2=311397&view=diff
> ==
> --- cfe/trunk/lib/Driver/ToolChains/Darwin.cpp (original)
> +++ cfe/trunk/lib/Driver/ToolChains/Darwin.cpp Mon Aug 21 15:46:46 2017
> @@ -1845,7 +1845,12 @@ Darwin::TranslateArgs(const DerivedArgLi
> }
> 
> bool MachO::IsUnwindTablesDefault(const ArgList &Args) const {
> -  return !UseSjLjExceptions(Args);
> +  // Unwind tables are not emitted if -fno-exceptions is supplied (except 
> when
> +  // targeting x86_64).
> +  return getArch() == llvm::Triple::x86_64 ||
> + (!UseSjLjExceptions(Args) &&
> +  Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
> +   true));
> }
> 
> bool MachO::UseDwarfDebugFlags() const {
> 
> Modified: cfe/trunk/test/Driver/clang-translation.c
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/clang-translation.c?rev=311397&r1=311396&r2=311397&view=diff
> ==
> --- cfe/trunk/test/Driver/clang-translation.c (original)
> +++ cfe/trunk/test/Driver/clang-translation.c Mon Aug 21 15:46:46 2017
> @@ -73,6 +73,10 @@
> // RUN: FileCheck -check-prefix=ARM64-APPLE %s
> // ARM64-APPLE: -munwind-table
> 
> +// RUN: %clang -target arm64-apple-ios10 -fno-exceptions -### -S %s -arch 
> arm64 2>&1 | \
> +// RUN: FileCheck -check-prefix=ARM64-APPLE-EXCEP %s
> +// ARM64-APPLE-EXCEP-NOT: -munwind-table
> +
> // RUN: %clang -target armv7k-apple-watchos4.0 -### -S %s -arch armv7k 2>&1 | 
> \
> // RUN: FileCheck -check-prefix=ARMV7K-APPLE %s
> // ARMV7K-APPLE: -munwind-table
> 
> 
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

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


[PATCH] D36503: [libcxx] [test] Update for C++17 feature removals.

2017-08-22 Thread Stephan T. Lavavej via Phabricator via cfe-commits
STL_MSFT added a comment.

It's been two weeks - if there are no objections, I'd like to commit this soon. 
Thanks!


https://reviews.llvm.org/D36503



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


[PATCH] D36951: [OpenCL][5.0.0 Release] Release notes for OpenCL in Clang

2017-08-22 Thread Anastasia Stulova via Phabricator via cfe-commits
Anastasia closed this revision.
Anastasia added a comment.

Committed to release_50@311485


https://reviews.llvm.org/D36951



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


[PATCH] D36492: [time-report] Add preprocessor timer

2017-08-22 Thread Matthias Braun via Phabricator via cfe-commits
MatzeB added inline comments.



Comment at: lib/Lex/Preprocessor.cpp:746
 void Preprocessor::Lex(Token &Result) {
+  llvm::TimeRegion(PPOpts->getTimer());
+

modocache wrote:
> erik.pilkington wrote:
> > Doesn't this just start a timer and immediately end the timer? Shouldn't we 
> > do: `llvm::TimeRegion LexTime(PPOpts->getTimer())` so that the dtor gets 
> > called when this function returns and we track the time spent in this 
> > function?
> > 
> > Also: this is a pretty hot function, and it looks like TimeRegion does some 
> > non-trivial work if time is being tracked. Have you tried testing this on a 
> > big c++ file with and without this patch and seeing what the difference in 
> > compile time looks like?
> Ah, yes you're right! Sorry about that. Actually keeping the timer alive for 
> the duration of the method also reveals that the method is called 
> recursively, which causes an assert, because timers can't be started twice.
> 
> Another spot in Clang works around this with a "reference counted" timer: 
> https://github.com/llvm-mirror/clang/blob/6ac9c51ede0a50cca13dd4ac03562c036f7a3f48/lib/CodeGen/CodeGenAction.cpp#L130-L134.
>  I have a more generic version of this "reference counting timer" that I've 
> been using for some of the other timers I've been adding; maybe I'll use it 
> here as well.
FWIF: I share Eriks concerns about compiletime. Timers are enabled in optimized 
builds, and querying them is not free. So putting one into a function that is 
called a lot and is time critical seems like a bad idea (do benchmarking to 
prove or disprove this!).


https://reviews.llvm.org/D36492



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


[PATCH] D37014: [clang-tidy] Add a checker to remove useless intermediate variables before return statements with comparisons

2017-08-22 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: docs/ReleaseNotes.rst:60
 
+- New `readability-useless-intermediate-var
+  
`_
 check

Please place new checks in alphabetical order.



Comment at: docs/ReleaseNotes.rst:63
+
+  This new checker detects useless intermediate variables before return
+  statements that return the result of a simple comparison. This checker also

JonasToth wrote:
> maybe "useless" should be replaced with "unnecessary". but thats only my 
> opinion.
Checker -> check.
Please enclose return (in statement context) in ``.
Same for other places.


Repository:
  rL LLVM

https://reviews.llvm.org/D37014



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


[PATCH] D37023: [analyzer] Fix bugreporter::getDerefExpr() again.

2017-08-22 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ created this revision.

This patch continues work that was started in https://reviews.llvm.org/D32291.

Our `bugreporter::getDerefExpr()` API tries to find out what has been 
dereferenced. For example, if we have an lvalue expression `x->y.z` which 
causes a null dereference when dereferenced, the function returns lvalue `x->y` 
- the object from which the null pointer must have been loaded. Similarly, 
unwrapping lvalue `x->y` would result in `x`.

I believe i found a more correct way to implement it, namely to see where 
lvalue-to-rvalue casts are located in the expression. In our example, `x->y` is 
surrounded by an lvalue-to-rvalue cast, which indicates that we should not 
unwrap the expression further. And it is irrelevant whether the member 
expression is a dot or an arrow, or whether C++ `this->` or ObjC `self->` is 
written explicitly or assumed implicitly, or whether the expression or a 
sub-expression is a pointer or a reference (we used to look at these).

This patch refactors `getDerefExpr()` with this design in mind. Now the 
function must be much easier to understand, and also behave correctly.

Unwrapping of binary operators that caused the dereference (eg. `*x = 2` -> 
`*x`) was removed from `getDerefExpr()` because it contradicts its purpose and 
seems to have never actually been used (we should be receiving `*x` in this 
function instead in all cases).

Current implementation has the benefit of not crashing on the newly added test 
case. The crash was caused by the fact that the old `getDerefExpr()` was 
thinking that `self` was dereferenced, even though in fact it wasn't.

I should probably have a look at what else might have changed and add more test 
cases, because the old code was quite strange.


https://reviews.llvm.org/D37023

Files:
  lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
  test/Analysis/null-deref-path-notes.m

Index: test/Analysis/null-deref-path-notes.m
===
--- test/Analysis/null-deref-path-notes.m
+++ test/Analysis/null-deref-path-notes.m
@@ -50,6 +50,23 @@
   *p = 1; // expected-warning{{Dereference of null pointer}} expected-note{{Dereference of null pointer}}
 }
 
+@interface WithArrayPtr
+- (void) useArray;
+@end
+
+@implementation WithArrayPtr {
+@public int *p;
+}
+- (void)useArray {
+  p[1] = 2; // expected-warning{{Array access (via ivar 'p') results in a null pointer dereference}}
+// expected-note@-1{{Array access (via ivar 'p') results in a null pointer dereference}}
+}
+@end
+
+void testWithArrayPtr(WithArrayPtr *w) {
+  w->p = 0; // expected-note{{Null pointer value stored to 'p'}}
+  [w useArray]; // expected-note{{Calling 'useArray'}}
+}
 
 // CHECK:  diagnostics
 // CHECK-NEXT:  
@@ -801,4 +818,227 @@
 // CHECK-NEXT:file0
 // CHECK-NEXT:   
 // CHECK-NEXT:   
+// CHECK-NEXT:   
+// CHECK-NEXT:path
+// CHECK-NEXT:
+// CHECK-NEXT: 
+// CHECK-NEXT:  kindevent
+// CHECK-NEXT:  location
+// CHECK-NEXT:  
+// CHECK-NEXT:   line67
+// CHECK-NEXT:   col3
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  ranges
+// CHECK-NEXT:  
+// CHECK-NEXT:
+// CHECK-NEXT: 
+// CHECK-NEXT:  line67
+// CHECK-NEXT:  col3
+// CHECK-NEXT:  file0
+// CHECK-NEXT: 
+// CHECK-NEXT: 
+// CHECK-NEXT:  line67
+// CHECK-NEXT:  col10
+// CHECK-NEXT:  file0
+// CHECK-NEXT: 
+// CHECK-NEXT:
+// CHECK-NEXT:  
+// CHECK-NEXT:  depth0
+// CHECK-NEXT:  extended_message
+// CHECK-NEXT:  Null pointer value stored to 'p'
+// CHECK-NEXT:  message
+// CHECK-NEXT:  Null pointer value stored to 'p'
+// CHECK-NEXT: 
+// CHECK-NEXT: 
+// CHECK-NEXT:  kindcontrol
+// CHECK-NEXT:  edges
+// CHECK-NEXT:   
+// CHECK-NEXT:
+// CHECK-NEXT: start
+// CHECK-NEXT:  
+// CHECK-NEXT:   
+// CHECK-NEXT:line67
+// CHECK-NEXT:col3
+// CHECK-NEXT:file0
+// CHECK-NEXT:   
+// CHECK-NEXT:   
+// CHECK-NEXT:line67
+// CHECK-NEXT:col3
+// CHECK-NEXT:file0
+// CHECK-NEXT:   
+// CHECK-NEXT:  
+// CHECK-NEXT: end
+// CHECK-NEXT:  
+// CHECK-NEXT:   
+// CHECK-NEXT:line68
+// CHECK-NEXT:col3
+// CHECK-NEXT:file0
+// CHECK-NEXT:   
+// CHECK-NEXT:   
+// CHECK-NEXT:line68
+// CHECK-NEXT:col3
+// CHECK-NEXT:file0
+// CHECK-NEXT:   
+// CHECK-NEXT:  
+// CHECK-NEXT:
+// CHECK-NEXT:   
+// CHECK-NEXT: 
+// CHECK-NEXT: 
+// CHECK-NEXT:  kindevent
+// CHECK-NEXT:  location
+// CHECK-NEXT:  
+// CHECK-NEXT:   line68
+// CHECK-NEXT:   col3
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  ranges
+// CHECK-NEXT:  
+// CHECK-NEXT:  

[PATCH] D37014: [clang-tidy] Add a checker to remove useless intermediate variables before return statements with comparisons

2017-08-22 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added a comment.

Please add the following test: (and make sure that it does the right thing :))

  bool f_with_preproc_condition() {
auto test = 42;
assert(test == 42);
return test;
  }

I.e. if `-DNDEBUG` is present, variable is not needed, but if `-DNDEBUG` is 
*NOT* present...


Repository:
  rL LLVM

https://reviews.llvm.org/D37014



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


[PATCH] D37024: [libcxx] [test] Cleanup nullopt_t tests

2017-08-22 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter created this revision.

- Update specification text from N4387

- Delete `not_brace_initializable.fail.cpp`: it's redundant with 
`nullopt_t.fail.cpp`

- `is_empty` implies `is_class`

- `is_literal` is deprecated; directly verify that we can create a `nullopt_t` 
in a `constexpr` context


https://reviews.llvm.org/D37024

Files:
  test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp
  test/std/utilities/optional/optional.nullopt/nullopt_t.fail.cpp
  test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp

Index: test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
===
--- test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
+++ test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
@@ -11,33 +11,30 @@
 // 
 
 // struct nullopt_t{see below};
-// constexpr nullopt_t nullopt(unspecified);
+// inline constexpr nullopt_t nullopt(unspecified);
 
 // [optional.nullopt]/2:
-//   Type nullopt_t shall not have a default constructor or an initializer-list constructor.
-//   It shall not be an aggregate and shall be a literal type.
-//   Constant nullopt shall be initialized with an argument of literal type.
+//   Type nullopt_t shall not have a default constructor or an initializer-list
+//   constructor, and shall not be an aggregate.
 
 #include 
 #include 
 
-using std::optional;
 using std::nullopt_t;
 using std::nullopt;
 
-constexpr
-int
-test(const nullopt_t&)
+constexpr bool test()
 {
-return 3;
+nullopt_t foo{nullopt};
+(void)foo;
+return true;
 }
 
 int main()
 {
-static_assert(( std::is_class::value), "");
-static_assert(( std::is_empty::value), "");
-static_assert(( std::is_literal_type::value), "");
-static_assert((!std::is_default_constructible::value), "");
+static_assert(std::is_empty_v);
+static_assert(!std::is_default_constructible_v);
 
-static_assert(test(nullopt) == 3, "");
+static_assert(std::is_same_v);
+static_assert(test());
 }
Index: test/std/utilities/optional/optional.nullopt/nullopt_t.fail.cpp
===
--- test/std/utilities/optional/optional.nullopt/nullopt_t.fail.cpp
+++ test/std/utilities/optional/optional.nullopt/nullopt_t.fail.cpp
@@ -11,15 +11,13 @@
 // 
 
 // struct nullopt_t{see below};
-// constexpr nullopt_t nullopt(unspecified);
+// inline constexpr nullopt_t nullopt(unspecified);
 
 // [optional.nullopt]/2:
-//   Type nullopt_t shall not have a default constructor or an initializer-list constructor.
-//   It shall not be an aggregate and shall be a literal type.
-//   Constant nullopt shall be initialized with an argument of literal type.
+//   Type nullopt_t shall not have a default constructor or an initializer-list
+//   constructor, and shall not be an aggregate.
 
 #include 
-#include "test_macros.h"
 
 int main()
 {
Index: test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp
===
--- test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-//===--===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===--===//
-
-// UNSUPPORTED: c++98, c++03, c++11, c++14
-// 
-
-// struct nullopt_t{see below};
-
-#include 
-
-using std::optional;
-using std::nullopt_t;
-
-int main()
-{
-// I roughly interpret LWG2736 as "it shall not be possible to copy-list-initialize nullopt_t with an
-// empty braced-init-list."
-nullopt_t foo = {};
-}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r311487 - Revert "Revert "Revert "Revert "Fix LLVMgold plugin name/path for non-Linux.""""

2017-08-22 Thread Dan Albert via cfe-commits
Author: danalbert
Date: Tue Aug 22 14:05:01 2017
New Revision: 311487

URL: http://llvm.org/viewvc/llvm-project?rev=311487&view=rev
Log:
Revert "Revert "Revert "Revert "Fix LLVMgold plugin name/path for non-Linux.

With tests fixed for Windows style paths now that they are going
through path canonicalization.

Added:
cfe/trunk/test/Driver/lto-plugin-darwin.c
cfe/trunk/test/Driver/lto-plugin-linux.c
cfe/trunk/test/Driver/lto-plugin-windows.c
Modified:
cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp
cfe/trunk/test/Driver/freebsd.c
cfe/trunk/test/Driver/gold-lto.c
cfe/trunk/test/Driver/lto.c
cfe/trunk/test/Driver/thinlto.c

Modified: cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp?rev=311487&r1=311486&r2=311487&view=diff
==
--- cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp Tue Aug 22 14:05:01 2017
@@ -376,8 +376,20 @@ void tools::AddGoldPlugin(const ToolChai
   // as gold requires -plugin to come before any -plugin-opt that -Wl might
   // forward.
   CmdArgs.push_back("-plugin");
-  std::string Plugin =
-  ToolChain.getDriver().Dir + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold.so";
+
+#if defined(LLVM_ON_WIN32)
+  const char *Suffix = ".dll";
+#elif defined(__APPLE__)
+  const char *Suffix = ".dylib";
+#else
+  const char *Suffix = ".so";
+#endif
+
+  SmallString<1024> Plugin;
+  llvm::sys::path::native(Twine(ToolChain.getDriver().Dir) +
+  "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold" +
+  Suffix,
+  Plugin);
   CmdArgs.push_back(Args.MakeArgString(Plugin));
 
   // Try to pass driver level flags relevant to LTO code generation down to

Modified: cfe/trunk/test/Driver/freebsd.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/freebsd.c?rev=311487&r1=311486&r2=311487&view=diff
==
--- cfe/trunk/test/Driver/freebsd.c (original)
+++ cfe/trunk/test/Driver/freebsd.c Tue Aug 22 14:05:01 2017
@@ -127,7 +127,7 @@
 
 // RUN: %clang -target x86_64-pc-freebsd8 %s -### -flto 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-LTO %s
-// CHECK-LTO: ld{{.*}}" "-plugin{{.*}}LLVMgold.so
+// CHECK-LTO: ld{{.*}}" "-plugin{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}
 
 // RUN: %clang -target sparc-unknown-freebsd8 %s -### -fpic -no-integrated-as 
2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-SPARC-PIE %s

Modified: cfe/trunk/test/Driver/gold-lto.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/gold-lto.c?rev=311487&r1=311486&r2=311487&view=diff
==
--- cfe/trunk/test/Driver/gold-lto.c (original)
+++ cfe/trunk/test/Driver/gold-lto.c Tue Aug 22 14:05:01 2017
@@ -3,14 +3,14 @@
 // RUN: %clang -target x86_64-unknown-linux -### %t.o -flto 2>&1 \
 // RUN: -Wl,-plugin-opt=foo -O3 \
 // RUN: | FileCheck %s --check-prefix=CHECK-X86-64-BASIC
-// CHECK-X86-64-BASIC: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-X86-64-BASIC: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
 // CHECK-X86-64-BASIC: "-plugin-opt=O3"
 // CHECK-X86-64-BASIC: "-plugin-opt=foo"
 //
 // RUN: %clang -target x86_64-unknown-linux -### %t.o -flto 2>&1 \
 // RUN: -march=corei7 -Wl,-plugin-opt=foo -Ofast \
 // RUN: | FileCheck %s --check-prefix=CHECK-X86-64-COREI7
-// CHECK-X86-64-COREI7: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-X86-64-COREI7: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
 // CHECK-X86-64-COREI7: "-plugin-opt=mcpu=corei7"
 // CHECK-X86-64-COREI7: "-plugin-opt=O3"
 // CHECK-X86-64-COREI7: "-plugin-opt=foo"
@@ -18,11 +18,11 @@
 // RUN: %clang -target arm-unknown-linux -### %t.o -flto 2>&1 \
 // RUN: -march=armv7a -Wl,-plugin-opt=foo -O0 \
 // RUN: | FileCheck %s --check-prefix=CHECK-ARM-V7A
-// CHECK-ARM-V7A: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-ARM-V7A: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"
 // CHECK-ARM-V7A: "-plugin-opt=mcpu=generic"
 // CHECK-ARM-V7A: "-plugin-opt=O0"
 // CHECK-ARM-V7A: "-plugin-opt=foo"
 //
 // RUN: %clang -target i686-linux-android -### %t.o -flto 2>&1 \
 // RUN: | FileCheck %s --check-prefix=CHECK-X86-ANDROID
-// CHECK-X86-ANDROID: "-plugin" "{{.*}}/LLVMgold.so"
+// CHECK-X86-ANDROID: "-plugin" "{{.*}}{{[/\\]}}LLVMgold.{{dll|dylib|so}}"

Added: cfe/trunk/test/Driver/lto-plugin-darwin.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/lto-plugin-darwin.c?rev=311487&view=auto
==
--- cfe/trunk/test/Driver/lto-plugin-darwin.c (added)
+++ cfe/trunk/test/Driver/lto-plugin-darwin.c Tue Aug 22 14:05:01 2017
@@ -0,0 +1,6 @@
+// Check that Darwin uses LLVMgold.dylib.
+// REQUIRES: syste

[PATCH] D37025: [analyzer] Support more pointer arithmetic in bugreporter::getDerefExpr().

2017-08-22 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ created this revision.
Herald added a subscriber: eraman.

This patch adds support for a few more pointer arithmetic cases. For instance, 
when `p` is a null pointer, it would be possible to track that expressions like 
`*(++p) = 5` and `*(p + 2) = 5` are null pointer dereferences that are based on 
pointer `p`. The analyzer would later be able to display additional diagnostics 
to track where `p` has become null and why. I noticed these cases accidentally 
when i was working on https://reviews.llvm.org/D37023.


https://reviews.llvm.org/D37025

Files:
  lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
  test/Analysis/inlining/inline-defensive-checks.c
  test/Analysis/nullptr.cpp

Index: test/Analysis/nullptr.cpp
===
--- test/Analysis/nullptr.cpp
+++ test/Analysis/nullptr.cpp
@@ -1,11 +1,12 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-store region -analyzer-output=text -verify %s
 
 void clang_analyzer_eval(int);
 
 // test to see if nullptr is detected as a null pointer
 void foo1(void) {
-  char  *np = nullptr;
+  char  *np = nullptr; // expected-note{{'np' initialized to a null pointer value}}
   *np = 0;  // expected-warning{{Dereference of null pointer}}
+// expected-note@-1{{Dereference of null pointer}}
 }
 
 // check if comparing nullptr to nullptr is detected properly
@@ -23,10 +24,11 @@
   struct foo {
 int a, f;
   };
-  char *np = nullptr;
+  char *np = nullptr; // expected-note{{'np' initialized to a null pointer value}}
   // casting a nullptr to anything should be caught eventually
-  int *ip = &(((struct foo *)np)->f);
+  int *ip = &(((struct foo *)np)->f); // expected-note{{'ip' initialized to a null pointer value}}
   *ip = 0;  // expected-warning{{Dereference of null pointer}}
+// expected-note@-1{{Dereference of null pointer}}
   // should be error here too, but analysis gets stopped
 //  *np = 0;
 }
@@ -49,16 +51,31 @@
 }
 
 void zoo1() {
-  char **p = 0;
+  char **p = 0; // expected-note{{'p' initialized to a null pointer value}}
   delete *(p + 0); // expected-warning{{Dereference of null pointer}}
+   // expected-note@-1{{Dereference of null pointer}}
+}
+
+void zoo1backwards() {
+  char **p = 0; // expected-note{{'p' initialized to a null pointer value}}
+  delete *(0 + p); // expected-warning{{Dereference of null pointer}}
+   // expected-note@-1{{Dereference of null pointer}}
+}
+
+typedef __INTPTR_TYPE__ intptr_t;
+void zoo1multiply() {
+  char **p = 0; // FIXME-should-be-note:{{'p' initialized to a null pointer value}}
+  delete *((char **)((intptr_t)p * 2)); // expected-warning{{Dereference of null pointer}}
+   // expected-note@-1{{Dereference of null pointer}}
 }
 
 void zoo2() {
   int **a = 0;
-  int **b = 0;
+  int **b = 0; // expected-note{{'b' initialized to a null pointer value}}
   asm ("nop"
   :"=r"(*a)
   :"0"(*b) // expected-warning{{Dereference of null pointer}}
+   // expected-note@-1{{Dereference of null pointer}}
   );
 }
 
@@ -70,17 +87,19 @@
 int a;
   };
 
-  int *x = 0;
+  int *x = 0; // expected-note{{'x' initialized to a null pointer value}}
   return S(*x).a; // expected-warning{{Dereference of null pointer}}
+  // expected-note@-1{{Dereference of null pointer}}
 }
 
 int materializeTempExpr() {
-  int *n = 0;
+  int *n = 0; // expected-note{{'n' initialized to a null pointer value}}
   struct S {
 int a;
 S(int i): a(i) {}
   };
   const S &s = S(*n); // expected-warning{{Dereference of null pointer}}
+  // expected-note@-1{{Dereference of null pointer}}
   return s.a;
 }
 
@@ -98,33 +117,49 @@
 
 void invokeF(X* x) {
   x->f(); // expected-warning{{Called C++ object pointer is null}}
+  // expected-note@-1{{Called C++ object pointer is null}}
 }
 
 struct Type {
   decltype(nullptr) x;
 };
 
 void shouldNotCrash() {
-  decltype(nullptr) p;
-  if (getSymbol())
-invokeF(p); // expected-warning{{1st function call argument is an uninit}}
-  if (getSymbol())
-invokeF(nullptr);
-  if (getSymbol()) {
-X *x = Type().x;
+  decltype(nullptr) p; // expected-note{{'p' declared without an initial value}}
+  if (getSymbol()) // expected-note   {{Assuming the condition is false}}
+   // expected-note@-1{{Taking false branch}}
+   // expected-note@-2{{Assuming the condition is false}}
+   // expected-note@-3{{Taking false branch}}
+   // expected-note@-4{{Assuming the condition is true}}
+   // expected-note@-5{{Taking true branch}}
+invokeF(p); // expected-warning{{1st function call argument is an uninitialized value}}
+// expected

[PATCH] D37025: [analyzer] Support more pointer arithmetic in bugreporter::getDerefExpr().

2017-08-22 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added inline comments.



Comment at: test/Analysis/nullptr.cpp:54
 void zoo1() {
-  char **p = 0;
+  char **p = 0; // expected-note{{'p' initialized to a null pointer value}}
   delete *(p + 0); // expected-warning{{Dereference of null pointer}}

This note has been added by the patch. Other newly displayed notes in the old 
tests here have always been there, but just now got displayed.


https://reviews.llvm.org/D37025



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


[PATCH] D37024: [libcxx] [test] Cleanup nullopt_t tests

2017-08-22 Thread Stephan T. Lavavej via Phabricator via cfe-commits
STL_MSFT added a comment.

Otherwise, looks cromulent to me.




Comment at: test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp:38
 
-static_assert(test(nullopt) == 3, "");
+static_assert(std::is_same_v);
+static_assert(test());

You're saying `std::nullopt` but you already dragged it in.


https://reviews.llvm.org/D37024



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


[PATCH] D37024: [libcxx] [test] Cleanup nullopt_t tests

2017-08-22 Thread Casey Carter via Phabricator via cfe-commits
CaseyCarter updated this revision to Diff 112224.
CaseyCarter added a comment.

Don't unnecessarily fully qualify `std::nullopt`.


https://reviews.llvm.org/D37024

Files:
  test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp
  test/std/utilities/optional/optional.nullopt/nullopt_t.fail.cpp
  test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp

Index: test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
===
--- test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
+++ test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp
@@ -11,33 +11,30 @@
 // 
 
 // struct nullopt_t{see below};
-// constexpr nullopt_t nullopt(unspecified);
+// inline constexpr nullopt_t nullopt(unspecified);
 
 // [optional.nullopt]/2:
-//   Type nullopt_t shall not have a default constructor or an initializer-list constructor.
-//   It shall not be an aggregate and shall be a literal type.
-//   Constant nullopt shall be initialized with an argument of literal type.
+//   Type nullopt_t shall not have a default constructor or an initializer-list
+//   constructor, and shall not be an aggregate.
 
 #include 
 #include 
 
-using std::optional;
 using std::nullopt_t;
 using std::nullopt;
 
-constexpr
-int
-test(const nullopt_t&)
+constexpr bool test()
 {
-return 3;
+nullopt_t foo{nullopt};
+(void)foo;
+return true;
 }
 
 int main()
 {
-static_assert(( std::is_class::value), "");
-static_assert(( std::is_empty::value), "");
-static_assert(( std::is_literal_type::value), "");
-static_assert((!std::is_default_constructible::value), "");
+static_assert(std::is_empty_v);
+static_assert(!std::is_default_constructible_v);
 
-static_assert(test(nullopt) == 3, "");
+static_assert(std::is_same_v);
+static_assert(test());
 }
Index: test/std/utilities/optional/optional.nullopt/nullopt_t.fail.cpp
===
--- test/std/utilities/optional/optional.nullopt/nullopt_t.fail.cpp
+++ test/std/utilities/optional/optional.nullopt/nullopt_t.fail.cpp
@@ -11,15 +11,13 @@
 // 
 
 // struct nullopt_t{see below};
-// constexpr nullopt_t nullopt(unspecified);
+// inline constexpr nullopt_t nullopt(unspecified);
 
 // [optional.nullopt]/2:
-//   Type nullopt_t shall not have a default constructor or an initializer-list constructor.
-//   It shall not be an aggregate and shall be a literal type.
-//   Constant nullopt shall be initialized with an argument of literal type.
+//   Type nullopt_t shall not have a default constructor or an initializer-list
+//   constructor, and shall not be an aggregate.
 
 #include 
-#include "test_macros.h"
 
 int main()
 {
Index: test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp
===
--- test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-//===--===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===--===//
-
-// UNSUPPORTED: c++98, c++03, c++11, c++14
-// 
-
-// struct nullopt_t{see below};
-
-#include 
-
-using std::optional;
-using std::nullopt_t;
-
-int main()
-{
-// I roughly interpret LWG2736 as "it shall not be possible to copy-list-initialize nullopt_t with an
-// empty braced-init-list."
-nullopt_t foo = {};
-}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r311488 - Degeneralize more tests.

2017-08-22 Thread Dan Albert via cfe-commits
Author: danalbert
Date: Tue Aug 22 14:16:22 2017
New Revision: 311488

URL: http://llvm.org/viewvc/llvm-project?rev=311488&view=rev
Log:
Degeneralize more tests.

As before, not every platform supports LTO. Make sure the platform
we're targeting is one that supports it (regardless of the *host*
platform).

Modified:
cfe/trunk/test/Driver/lto-plugin-darwin.c
cfe/trunk/test/Driver/lto-plugin-linux.c
cfe/trunk/test/Driver/lto-plugin-windows.c

Modified: cfe/trunk/test/Driver/lto-plugin-darwin.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/lto-plugin-darwin.c?rev=311488&r1=311487&r2=311488&view=diff
==
--- cfe/trunk/test/Driver/lto-plugin-darwin.c (original)
+++ cfe/trunk/test/Driver/lto-plugin-darwin.c Tue Aug 22 14:16:22 2017
@@ -1,6 +1,6 @@
 // Check that Darwin uses LLVMgold.dylib.
 // REQUIRES: system-darwin
-// RUN: %clang -### %s -flto 2>&1 \
+// RUN: %clang -### %s -target x86_64-unknown-linux -flto 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-LTO-PLUGIN %s
 //
 // CHECK-LTO-PLUGIN: "-plugin" "{{.*}}/LLVMgold.dylib"

Modified: cfe/trunk/test/Driver/lto-plugin-linux.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/lto-plugin-linux.c?rev=311488&r1=311487&r2=311488&view=diff
==
--- cfe/trunk/test/Driver/lto-plugin-linux.c (original)
+++ cfe/trunk/test/Driver/lto-plugin-linux.c Tue Aug 22 14:16:22 2017
@@ -1,6 +1,6 @@
 // Check that non-Windows, non-Darwin OSs use LLVMgold.so.
 // REQUIRES: !system-darwin && !system-windows
-// RUN: %clang -### %s -flto 2>&1 \
+// RUN: %clang -### %s -target x86_64-unknown-linux -flto 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-LTO-PLUGIN %s
 //
 // CHECK-LTO-PLUGIN: "-plugin" "{{.*}}/LLVMgold.so"

Modified: cfe/trunk/test/Driver/lto-plugin-windows.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/lto-plugin-windows.c?rev=311488&r1=311487&r2=311488&view=diff
==
--- cfe/trunk/test/Driver/lto-plugin-windows.c (original)
+++ cfe/trunk/test/Driver/lto-plugin-windows.c Tue Aug 22 14:16:22 2017
@@ -1,6 +1,6 @@
 // Check that Windows uses LLVMgold.dll.
 // REQUIRES: system-windows
-// RUN: %clang -### %s -flto 2>&1 \
+// RUN: %clang -### %s -target x86_64-unknown-linux -flto 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-LTO-PLUGIN %s
 //
 // CHECK-LTO-PLUGIN: "-plugin" "{{.*}}\\LLVMgold.dll"


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


Re: [PATCH] D36914: Implement CFG construction for __try / __except / __leave.

2017-08-22 Thread Nico Weber via cfe-commits
rnk: ping :-)

On Mon, Aug 21, 2017 at 1:43 PM, Nico Weber via Phabricator via cfe-commits
 wrote:

> thakis added inline comments.
>
>
> 
> Comment at: lib/Analysis/CFG.cpp:448
> +BuildOpts(buildOpts), switchExclusivelyCovered(false),
> +switchCond(nullptr), cachedEntry(nullptr), lastLookup(nullptr) {}
>
> 
> (this is now a no-op and only a clang-formatting of the existing ctor
> code. I can omit this if you want.)
>
>
> https://reviews.llvm.org/D36914
>
>
>
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r309226 - Headers: improve ARM EHABI coverage of unwind.h

2017-08-22 Thread Evgenii Stepanov via cfe-commits
No. I don't have a easy way of reproducing this.

On Tue, Aug 22, 2017 at 11:10 AM, Hans Wennborg  wrote:
> Is there a bug filed? Since this was merged to 5.0.0, I'd like to know
> if we broke something and if that is something that needs to be fixed.
>
> On Tue, Aug 22, 2017 at 10:46 AM, Evgenii Stepanov
>  wrote:
>> As I understand, using compiler-rt as libgcc replacement on ARM is
>> currently broken because of this change, but I have not looked since
>> my last message.
>>
>> On Mon, Aug 21, 2017 at 4:56 PM, Hans Wennborg  wrote:
>>> Is there something we need for 5.0.0 here?
>>>
>>> On Sat, Aug 12, 2017 at 9:58 PM, Saleem Abdulrasool
>>>  wrote:
 Yeah, we should adjust that.  Technically, it is `_Unwind_Control_Block on
 ARM EHABI.  However, _Unwind_Exception is aliased to that, which is why we
 can use that in the personality routine.  We should adjust the sources for
 the personality routine.

 On Fri, Aug 11, 2017 at 1:12 PM, Evgenii Stepanov
  wrote:
>
> Hi,
>
> I've noticed that the code in
> compiler-rt/lib/builtins/gcc_personality_v0.c refers to
> _Unwind_Exception as "struct _Unwind_Exception". With this change, it
> is not a struct anymore on ARM. Should that code be fixed, or is it a
> problem in this change?
>
> compiler-rt/lib/builtins/gcc_personality_v0.c:153:23: error:
> declaration of 'struct _Unwind_Exception' will not be visible outside
> of this function [-Werror,-Wvisibility]
> continueUnwind(struct _Unwind_Exception *exceptionObject,
>
> On Thu, Jul 27, 2017 at 9:46 AM, Hans Wennborg via cfe-commits
>  wrote:
> > Merged to 5.0 in r309290.
> >
> > On Wed, Jul 26, 2017 at 3:55 PM, Saleem Abdulrasool via cfe-commits
> >  wrote:
> >> Author: compnerd
> >> Date: Wed Jul 26 15:55:23 2017
> >> New Revision: 309226
> >>
> >> URL: http://llvm.org/viewvc/llvm-project?rev=309226&view=rev
> >> Log:
> >> Headers: improve ARM EHABI coverage of unwind.h
> >>
> >> Ensure that we define the `_Unwind_Control_Block` structure used on ARM
> >> EHABI targets.  This is needed for building libc++abi with the unwind.h
> >> from the resource dir.  A minor fallout of this is that we needed to
> >> create a typedef for _Unwind_Exception to work across ARM EHABI and
> >> non-EHABI targets.  The structure definitions here are based originally
> >> on the documentation from ARM under the "Exception Handling ABI for the
> >> ARMĀ® Architecture" Section 7.2.  They are then adjusted to more closely
> >> reflect the definition in libunwind from LLVM.  Those changes are
> >> compatible in layout but permit easier use in libc++abi and help
> >> maintain compatibility between libunwind and the compiler provided
> >> definition.
> >>
> >> Modified:
> >> cfe/trunk/lib/Headers/unwind.h
> >>
> >> Modified: cfe/trunk/lib/Headers/unwind.h
> >> URL:
> >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/unwind.h?rev=309226&r1=309225&r2=309226&view=diff
> >>
> >> ==
> >> --- cfe/trunk/lib/Headers/unwind.h (original)
> >> +++ cfe/trunk/lib/Headers/unwind.h Wed Jul 26 15:55:23 2017
> >> @@ -76,7 +76,13 @@ typedef intptr_t _sleb128_t;
> >>  typedef uintptr_t _uleb128_t;
> >>
> >>  struct _Unwind_Context;
> >> +#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) ||
> >> defined(__ARM_DWARF_EH___))
> >> +struct _Unwind_Control_Block;
> >> +typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */
> >> +#else
> >>  struct _Unwind_Exception;
> >> +typedef struct _Unwind_Exception _Unwind_Exception;
> >> +#endif
> >>  typedef enum {
> >>_URC_NO_REASON = 0,
> >>  #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
> >> @@ -109,8 +115,42 @@ typedef enum {
> >>  } _Unwind_Action;
> >>
> >>  typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code,
> >> - struct _Unwind_Exception
> >> *);
> >> + _Unwind_Exception *);
> >>
> >> +#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) ||
> >> defined(__ARM_DWARF_EH___))
> >> +typedef struct _Unwind_Control_Block _Unwind_Control_Block;
> >> +typedef uint32_t _Unwind_EHT_Header;
> >> +
> >> +struct _Unwind_Control_Block {
> >> +  uint64_t exception_class;
> >> +  void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block
> >> *);
> >> +  /* unwinder cache (private fields for the unwinder's use) */
> >> +  struct {
> >> +uint32_t reserved1; /* forced unwind stop function, 0 if not
> >> forced */
> >> +uint32_t reserved2; /* personality routine */
> >> +uint32_t reserved3; /* cal

[PATCH] D36914: Implement CFG construction for __try / __except / __leave.

2017-08-22 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

Looks functionally correct




Comment at: test/Sema/warn-unreachable-ms.c:42
+  }
+}

Can we add a test to exercise that this builds the right CFG?
```
__try {
  __try {
f();
  } __except(1) {
__leave; // should exit outer try
  }
  __leave;
  f(); // expected-warning{{never be executed}}
} __except(1) {
}
```


https://reviews.llvm.org/D36914



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


Re: r311391 - [Driver] Recognize DevDiv internal builds of MSVC, with a different directory structure.

2017-08-22 Thread Hans Wennborg via cfe-commits
Merged to 5.0 in r311500.

On Mon, Aug 21, 2017 at 3:19 PM, Stephan T. Lavavej via cfe-commits
 wrote:
> Author: stl_msft
> Date: Mon Aug 21 15:19:33 2017
> New Revision: 311391
>
> URL: http://llvm.org/viewvc/llvm-project?rev=311391&view=rev
> Log:
> [Driver] Recognize DevDiv internal builds of MSVC, with a different directory 
> structure.
>
> This is a reasonably non-intrusive change, which I've verified
> works for both x86 and x64 DevDiv-internal builds.
>
> The idea is to change `bool IsVS2017OrNewer` into a 3-state
> `ToolsetLayout VSLayout`. Either a build is DevDiv-internal,
> released VS 2017 or newer, or released VS 2015 or older. When looking at
> the directory structure, if instead of `"VC"` we see `"x86ret"`, `"x86chk"`,
> `"amd64ret"`, or `"amd64chk"`, we recognize this as a DevDiv-internal build.
>
> After we get past the directory structure validation, we use this knowledge
> to regenerate paths appropriately. `llvmArchToDevDivInternalArch()` knows how
> we use `"i386"` subdirectories, and `MSVCToolChain::getSubDirectoryPath()`
> uses that. It also knows that DevDiv-internal builds have an `"inc"`
> subdirectory instead of `"include"`.
>
> This may still not be the "right" fix in any sense, but I believe that it's
> non-intrusive in the sense that if the special directory names aren't found,
> no codepaths are affected. (`ToolsetLayout::OlderVS` and
> `ToolsetLayout::VS2017OrNewer` correspond to `IsVS2017OrNewer` being `false`
> or `true`, respectively.) I searched for all references to `IsVS2017OrNewer`,
> which are places where Clang cares about VS's directory structure, and the
> only one that isn't being patched is some logic to deal with
> cross-compilation. I'm fine with that not working for DevDiv-internal builds
> for the moment (we typically test the native compilers), so I added a comment.
>
> Fixes D36860.
>
> Modified:
> cfe/trunk/lib/Driver/ToolChains/MSVC.cpp
> cfe/trunk/lib/Driver/ToolChains/MSVC.h
>
> Modified: cfe/trunk/lib/Driver/ToolChains/MSVC.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/MSVC.cpp?rev=311391&r1=311390&r2=311391&view=diff
> ==
> --- cfe/trunk/lib/Driver/ToolChains/MSVC.cpp (original)
> +++ cfe/trunk/lib/Driver/ToolChains/MSVC.cpp Mon Aug 21 15:19:33 2017
> @@ -76,7 +76,7 @@ static bool getSystemRegistryString(cons
>
>  // Check various environment variables to try and find a toolchain.
>  static bool findVCToolChainViaEnvironment(std::string &Path,
> -  bool &IsVS2017OrNewer) {
> +  MSVCToolChain::ToolsetLayout 
> &VSLayout) {
>// These variables are typically set by vcvarsall.bat
>// when launching a developer command prompt.
>if (llvm::Optional VCToolsInstallDir =
> @@ -84,7 +84,7 @@ static bool findVCToolChainViaEnvironmen
>  // This is only set by newer Visual Studios, and it leads straight to
>  // the toolchain directory.
>  Path = std::move(*VCToolsInstallDir);
> -IsVS2017OrNewer = true;
> +VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
>  return true;
>}
>if (llvm::Optional VCInstallDir =
> @@ -94,7 +94,7 @@ static bool findVCToolChainViaEnvironmen
>  // so this check has to appear second.
>  // In older Visual Studios, the VC directory is the toolchain.
>  Path = std::move(*VCInstallDir);
> -IsVS2017OrNewer = false;
> +VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
>  return true;
>}
>
> @@ -134,9 +134,16 @@ static bool findVCToolChainViaEnvironmen
>}
>if (IsBin) {
>  llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath);
> -if (llvm::sys::path::filename(ParentPath) == "VC") {
> +llvm::StringRef ParentFilename = 
> llvm::sys::path::filename(ParentPath);
> +if (ParentFilename == "VC") {
>Path = ParentPath;
> -  IsVS2017OrNewer = false;
> +  VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
> +  return true;
> +}
> +if (ParentFilename == "x86ret" || ParentFilename == "x86chk"
> +  || ParentFilename == "amd64ret" || ParentFilename == "amd64chk") {
> +  Path = ParentPath;
> +  VSLayout = MSVCToolChain::ToolsetLayout::DevDivInternal;
>return true;
>  }
>
> @@ -165,7 +172,7 @@ static bool findVCToolChainViaEnvironmen
>ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
>
>  Path = ToolChainPath;
> -IsVS2017OrNewer = true;
> +VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
>  return true;
>}
>
> @@ -181,7 +188,7 @@ static bool findVCToolChainViaEnvironmen
>  // This is the preferred way to discover new Visual Studios, as they're no
>  // longer listed in the registry.
>  static bool findVCToolChainViaSetupConfig(std::string &Path,
> - 

[PATCH] D35955: clang-format: Add preprocessor directive indentation

2017-08-22 Thread Erik Uhlmann via Phabricator via cfe-commits
euhlmann added inline comments.



Comment at: lib/Format/ContinuationIndenter.cpp:387
+// hash. This causes second-level indents onward to have an extra space
+// after the tabs. We set the state to column 0 to avoid this misalignment.
+if (Style.UseTab != FormatStyle::UT_Never)

krasimir wrote:
> I don't understand this comment. Could you please give an example?
When tabs are enabled, extra spaces would be added because of the column offset 
caused by the `#` token.
```
#if FOO
#if BAR
#define BAZ
#endif
#endif
```
Let me know if there's a better way to fix that.



Comment at: lib/Format/UnwrappedLineParser.cpp:732
+  // then we count it as a real include guard and subtract one from every
+  // preprocessor indent.
+  unsigned TokenPosition = Tokens->getPosition();

krasimir wrote:
> Why do we need to subtract one from every preprocessor indent?
This only knows for sure when something is an include guard at the end of the 
file. By that time, everything inside the include guard has already been 
indented one extra level since we didn't know about the guard yet, so it would 
look like
```
#ifndef FILE_H
#  define FILE_H
// ...
#  other directives
// ...
#endif
```
Subtracting one is the action taken when we decide that there's a valid include 
guard, so it looks like
```
#ifndef FILE_H
#define FILE_H
// ...
#other directives
// ...
#endif
```



Comment at: lib/Format/UnwrappedLineParser.cpp:760
+  }
+  PPMaybeIncludeGuard = nullptr;
   nextToken();

krasimir wrote:
> Why do we reset `PPMaybeIncludeGuard` here?
The idea is if there's any preprocessor lines between the #ifndef and the 
#define, it doesn't treat it as an include guard. This is the same reason for 
the other PPMaybeIncludeGuard reset.



Comment at: lib/Format/UnwrappedLineParser.cpp:770
   addUnwrappedLine();
-  Line->Level = 1;
+  ++Line->Level;
 

krasimir wrote:
> Why do we `++Line->Level` here?
This sets correct indent for multi-line macros, so they are indented one level 
more than the indent of the #define instead of always at level 1.


https://reviews.llvm.org/D35955



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


  1   2   >