[PATCH] D41224: [ThreadSafetyAnalysis] Fix isCapabilityExpr

2017-12-14 Thread Yi Kong via Phabricator via cfe-commits
kongyi created this revision.
kongyi added a reviewer: delesley.
kongyi added a project: clang.
Herald added a subscriber: cfe-commits.

There are many more expr types that can be a capability expr, like
CXXThisExpr, CallExpr, MemberExpr. Instead of enumerating all of them,
just check typeHasCapability for any type given, which is not expensive.

Also add & and * operators to allowed unary operators.


Repository:
  rC Clang

https://reviews.llvm.org/D41224

Files:
  lib/Sema/SemaDeclAttr.cpp
  test/Sema/attr-capabilities.cpp
  test/SemaCXX/warn-thread-safety-parsing.cpp


Index: test/SemaCXX/warn-thread-safety-parsing.cpp
===
--- test/SemaCXX/warn-thread-safety-parsing.cpp
+++ test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -351,7 +351,8 @@
 int gb_var_arg_6 GUARDED_BY(muRef);
 int gb_var_arg_7 GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());
 int gb_var_arg_8 GUARDED_BY(muPointer);
-
+int gb_var_arg_9 GUARDED_BY(!&mu1);
+int gb_var_arg_10 GUARDED_BY(!&*&mu1);
 
 // illegal attribute arguments
 int gb_var_arg_bad_1 GUARDED_BY(1); // \
Index: test/Sema/attr-capabilities.cpp
===
--- /dev/null
+++ test/Sema/attr-capabilities.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -verify %s
+
+class __attribute__((shared_capability("mutex"))) Mutex {
+ public:
+  void func1() __attribute__((assert_capability(this)));
+  void func2() __attribute__((assert_capability(!this)));
+
+  const Mutex& operator!() const { return *this; }
+};
+
+class NotACapability {
+ public:
+  void func1() __attribute__((assert_capability(this)));  // expected-warning 
{{'assert_capability' attribute requires arguments whose type is annotated with 
'capability' attribute; type here is 'NotACapability *'}}
+  void func2() __attribute__((assert_capability(!this)));  // expected-warning 
{{'assert_capability' attribute requires arguments whose type is annotated with 
'capability' attribute; type here is 'bool'}}
+
+  const NotACapability& operator!() const { return *this; }
+};
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -540,14 +540,13 @@
   // a DeclRefExpr is found, its type should be checked to determine whether it
   // is a capability or not.
 
-  if (const auto *E = dyn_cast(Ex))
-return typeHasCapability(S, E->getType());
-  else if (const auto *E = dyn_cast(Ex))
+  if (const auto *E = dyn_cast(Ex))
 return isCapabilityExpr(S, E->getSubExpr());
   else if (const auto *E = dyn_cast(Ex))
 return isCapabilityExpr(S, E->getSubExpr());
   else if (const auto *E = dyn_cast(Ex)) {
-if (E->getOpcode() == UO_LNot)
+if (E->getOpcode() == UO_LNot || E->getOpcode() == UO_AddrOf ||
+E->getOpcode() == UO_Deref)
   return isCapabilityExpr(S, E->getSubExpr());
 return false;
   } else if (const auto *E = dyn_cast(Ex)) {
@@ -557,7 +556,7 @@
 return false;
   }
 
-  return false;
+  return typeHasCapability(S, Ex->getType());
 }
 
 /// \brief Checks that all attribute arguments, starting from Sidx, resolve to


Index: test/SemaCXX/warn-thread-safety-parsing.cpp
===
--- test/SemaCXX/warn-thread-safety-parsing.cpp
+++ test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -351,7 +351,8 @@
 int gb_var_arg_6 GUARDED_BY(muRef);
 int gb_var_arg_7 GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());
 int gb_var_arg_8 GUARDED_BY(muPointer);
-
+int gb_var_arg_9 GUARDED_BY(!&mu1);
+int gb_var_arg_10 GUARDED_BY(!&*&mu1);
 
 // illegal attribute arguments
 int gb_var_arg_bad_1 GUARDED_BY(1); // \
Index: test/Sema/attr-capabilities.cpp
===
--- /dev/null
+++ test/Sema/attr-capabilities.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -verify %s
+
+class __attribute__((shared_capability("mutex"))) Mutex {
+ public:
+  void func1() __attribute__((assert_capability(this)));
+  void func2() __attribute__((assert_capability(!this)));
+
+  const Mutex& operator!() const { return *this; }
+};
+
+class NotACapability {
+ public:
+  void func1() __attribute__((assert_capability(this)));  // expected-warning {{'assert_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'NotACapability *'}}
+  void func2() __attribute__((assert_capability(!this)));  // expected-warning {{'assert_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'bool'}}
+
+  const NotACapability& operator!() const { return *this; }
+};
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -540,14 +540,13 @@
   // a DeclRefExpr is found, its type sho

[PATCH] D40548: [clangd] Symbol index interfaces and index-based code completion.

2017-12-14 Thread Sam McCall via Phabricator via cfe-commits
sammccall accepted this revision.
sammccall added a comment.
This revision is now accepted and ready to land.

Thanks for the split & refactoring! This looks nice. Just nits, plus some 
thoughts on the test.




Comment at: clangd/index/Index.cpp:11
 #include "Index.h"
-
+#include "clang/Sema/CodeCompleteConsumer.h"
 #include "llvm/Support/SHA1.h"

changes in this file can now be reverted I think



Comment at: clangd/index/Index.h:128
+  /// \brief Matches symbols in the index fuzzily and applies \p Callback on
+  /// each matched symbol.
+  ///

nit: "... before returning".

Just to be explicit that this is a synchronous API.



Comment at: clangd/index/Index.h:130
+  ///
+  /// Returns true if all candidates are matched.
+  virtual bool

This is a little vague - Returns true if the result list is complete, false if 
it was truncated due to MaxCandidateCount?

Might be clearer to invert it - Returns true if the result list was truncated - 
up to you.



Comment at: clangd/index/Index.h:132
+  virtual bool
+  fuzzyFind(const FuzzyFindRequest &Req,
+std::function Callback) const = 0;

context patch has landed, so this should now take const Context& as first 
parameter



Comment at: clangd/index/Index.h:136
+  // FIXME: add interfaces for more index use cases:
+  //  - Symbol getSymbolInfo(llvm::StringRef USR);
+  //  - getAllOccurrences(llvm::StringRef USR);

USRs will rather be SymbolIDs



Comment at: clangd/index/MemIndex.cpp:38
+  // Find all symbols that contain the query, igoring cases.
+  // FIXME: use better matching algorithm, e.g. fuzzy matcher.
+  if (StringRef(StringRef(Sym->QualifiedName).lower())

you can easily do this now - it shouldn't even be more lines of code.
Up to you of course.



Comment at: unittests/clangd/IndexTests.cpp:29
+
+struct CountedSymbolSlab {
+  CountedSymbolSlab() = delete;

nit: given the name, I actually think inheriting from Slab might be clearer.

Though I'm not sure we actually need this, see `weak_ptr` part of next comment.



Comment at: unittests/clangd/IndexTests.cpp:41
+
+class MemIndexTest : public ::testing::Test {
+protected:

This is a nice test, the one weakness I see is it's hard to read the cases in 
isolation as there's quite a lot of action-at-a-distance.
I think we can eliminate the base class without adding much boilerplate, which 
would make the tests more self-contained:
  - `Index` can be owned by the test
  - `match()` is good, but moving `Index.build()` call into the test, and 
accepting `Index` as a param means this interaction is more obvious and `match` 
can be a free function.
  - `CountedSymbolSlab` can more directly be replaced by a `weak_ptr`, which 
can tell you whether a `shared_ptr` is alive
  - `generateNumSymbols` (already) doesn't need to be a member. Having it 
optionally emit a weak_ptr to its return value would simplify the tests a 
little.

So MemIndexSymbolsRecycled would look something like

Index I;
std::weak_ptr> Symbols;
I.build(generateNumSymbols(0, 10), &Symbols);
EXPECT_THAT(match(I, Req), ElementsAre("7"));
EXPECT_FALSE(Symbols.expired());
I.build(generateNumSymbols(0,0));
EXPECT_TRUE(Symbols.expired());

WDYT?



Comment at: unittests/clangd/IndexTests.cpp:62
+  Slab->Slab.insert(symbol(std::to_string(i)));
+auto *Symbols = new std::vector();
+

This is a leak - the returned shared_ptr doesn't own this vector.

(I'm actually fine with this for simplicity if it's documented - but we might 
be running leak checkers that complain about it?)

In principle you need to make_shared a struct containing both the vector and 
the slab.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40548



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


[clang-tools-extra] r320678 - [clangd] Fix the unitttest build error on buildbot.

2017-12-14 Thread Haojian Wu via cfe-commits
Author: hokein
Date: Thu Dec 14 01:20:21 2017
New Revision: 320678

URL: http://llvm.org/viewvc/llvm-project?rev=320678&view=rev
Log:
[clangd] Fix the unitttest build error on buildbot.

Modified:
clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt

Modified: clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt?rev=320678&r1=320677&r2=320678&view=diff
==
--- clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt Thu Dec 14 01:20:21 
2017
@@ -25,6 +25,7 @@ target_link_libraries(ClangdTests
   clangDaemon
   clangFormat
   clangFrontend
+  clangIndex
   clangSema
   clangTooling
   clangToolingCore


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


[PATCH] D40488: [clangd] Implemented tracing using Context

2017-12-14 Thread Sam McCall via Phabricator via cfe-commits
sammccall accepted this revision.
sammccall added inline comments.
This revision is now accepted and ready to land.



Comment at: clangd/Trace.cpp:123
+  // Clone the context, so that the original Context can be moved.
+  this->Ctx.emplace(Ctx.clone());
+

This is a little unfortunate. Oh, well.



Comment at: clangd/Trace.h:42
+/// set up before calling any clangd-specific functions.
+class TracingSession {
+public:

hmm, `trace::TracingSession` seems redundant? Up to you


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40488



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


[PATCH] D41228: [ObjC] Enable __strong pointers in structs under ARC

2017-12-14 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak created this revision.
ahatanak added reviewers: rjmccall, doug.gregor, rsmith.
Herald added a subscriber: mgorny.

ObjectiveC ARC in C mode currently disallows having __strong and __weak 
pointers in structs. This patch takes the first step towards lifting that 
restriction. In order to properly manage the lifetimes of the objects owned by 
the structs, this patch modifies IRGen to synthesize special functions for 
structs with __strong pointers and call them when those structs have to be 
initialized, copied, and destructed similarly to what C++ special member 
functions of non-trivial classes do.

I plan to send a patch that allows __weak pointers in structs after this patch 
is committed.


https://reviews.llvm.org/D41228

Files:
  include/clang/AST/Decl.h
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/AST/ASTContext.cpp
  lib/AST/Decl.cpp
  lib/AST/Type.cpp
  lib/CodeGen/CGBlocks.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CGDeclCXX.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CMakeLists.txt
  lib/CodeGen/CodeGenCStruct.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExpr.cpp
  test/ARCMT/checking.m
  test/CodeGenObjC/strong-in-c-struct.m
  test/SemaObjC/arc-decls.m
  test/SemaObjC/arc-system-header.m
  test/SemaObjC/strong-in-c-struct.m

Index: test/SemaObjC/strong-in-c-struct.m
===
--- /dev/null
+++ test/SemaObjC/strong-in-c-struct.m
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks  -fobjc-runtime=ios-11.0 -fsyntax-only -verify %s
+
+typedef struct {
+  id a;
+} Strong;
+
+void callee_variadic(const char *, ...);
+
+void test_variadic(void) {
+  Strong t;
+  callee_variadic("s", t); // expected-error {{cannot pass non-trivial C object of type 'Strong' by value to variadic function}}
+}
+
+void test_jump0(int cond) {
+  switch (cond) {
+  case 0:
+;
+Strong x; // expected-note {{jump bypasses initialization of variable of non-trivial C struct type}}
+break;
+  case 1: // expected-error {{cannot jump from switch statement to this case label}}
+x.a = 0;
+break;
+  }
+}
+
+void test_jump1(void) {
+  static void *ips[] = { &&L0 };
+L0:  // expected-note {{possible target of indirect goto}}
+  ;
+  Strong x; // expected-note {{jump exits scope of variable with non-trivial destructor}}
+  goto *ips; // expected-error {{cannot jump}}
+}
+
+typedef void (^BlockTy)(void);
+void func(BlockTy);
+void func2(Strong);
+
+void test_block_scope0(int cond) {
+  Strong x; // expected-note {{jump enters lifetime of block which captures a C struct that is non-trivial to destroy}}
+  switch (cond) {
+  case 0:
+func(^{ func2(x); });
+break;
+  default: // expected-error {{cannot jump from switch statement to this case label}}
+break;
+  }
+}
+
+void test_block_scope1(void) {
+  static void *ips[] = { &&L0 };
+L0:  // expected-note {{possible target of indirect goto}}
+  ;
+  Strong x; // expected-note {{jump exits scope of variable with non-trivial destructor}} expected-note {{jump exits lifetime of block which captures a C struct that is non-trivial to destroy}}
+  func(^{ func2(x); });
+  goto *ips; // expected-error {{cannot jump}}
+}
Index: test/SemaObjC/arc-system-header.m
===
--- test/SemaObjC/arc-system-header.m
+++ test/SemaObjC/arc-system-header.m
@@ -23,8 +23,7 @@
 }
 
 void test5(struct Test5 *p) {
-  p->field = 0; // expected-error {{'field' is unavailable in ARC}}
-// expected-note@arc-system-header.h:25 {{field has non-trivial ownership qualification}}
+  p->field = 0;
 }
 
 id test6() {
@@ -49,8 +48,7 @@
 
 extern void doSomething(Test9 arg);
 void test9() {
-Test9 foo2 = {0, 0}; // expected-error {{'field' is unavailable in ARC}}
- // expected-note@arc-system-header.h:56 {{field has non-trivial ownership qualification}}
+Test9 foo2 = {0, 0};
 doSomething(foo2);
 }
 #endif
Index: test/SemaObjC/arc-decls.m
===
--- test/SemaObjC/arc-decls.m
+++ test/SemaObjC/arc-decls.m
@@ -3,7 +3,7 @@
 // rdar://8843524
 
 struct A {
-id x; // expected-error {{ARC forbids Objective-C objects in struct}}
+id x;
 };
 
 union u {
@@ -13,7 +13,7 @@
 @interface I {
struct A a; 
struct B {
-id y[10][20]; // expected-error {{ARC forbids Objective-C objects in struct}}
+id y[10][20];
 id z;
} b;
 
@@ -23,7 +23,7 @@
 
 // rdar://10260525
 struct r10260525 {
-  id (^block) (); // expected-error {{ARC forbids blocks in struct}}
+  id (^block) ();
 };
 
 struct S { 
Index: test/CodeGenObjC/strong-in-c-struct.m
===
--- /dev/null
+++ test/CodeGenObjC/strong-in-c-struct.m
@@ -0,0 +1,483

[PATCH] D41178: [clangd] Construct SymbolSlab from YAML format.

2017-12-14 Thread Haojian Wu via Phabricator via cfe-commits
hokein updated this revision to Diff 126909.
hokein marked 5 inline comments as done.
hokein added a comment.

Address the review comments.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41178

Files:
  clangd/CMakeLists.txt
  clangd/index/Index.cpp
  clangd/index/Index.h
  clangd/index/SymbolYAML.cpp
  clangd/index/SymbolYAML.h
  unittests/clangd/SymbolCollectorTests.cpp

Index: unittests/clangd/SymbolCollectorTests.cpp
===
--- unittests/clangd/SymbolCollectorTests.cpp
+++ unittests/clangd/SymbolCollectorTests.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include "index/SymbolCollector.h"
+#include "index/SymbolYAML.h"
 #include "clang/Index/IndexingAction.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
@@ -105,6 +106,49 @@
 QName("f1"), QName("f2")));
 }
 
+TEST_F(SymbolCollectorTest, YAMLConversions) {
+  const std::string YAML1 = R"(
+---
+ID: 057557CEBF6E6B2DD437FBF60CC58F352D1DF856
+QualifiedName:   'clang::Foo1'
+SymInfo:
+  Kind:Function
+  Lang:Cpp
+CanonicalDeclaration:
+  StartOffset: 0
+  EndOffset:   1
+  FilePath:/path/foo.h
+...
+)";
+  const std::string YAML2 = R"(
+---
+ID: 057557CEBF6E6B2DD437FBF60CC58F352D1DF858
+QualifiedName:   'clang::Foo2'
+SymInfo:
+  Kind:Function
+  Lang:Cpp
+CanonicalDeclaration:
+  StartOffset: 10
+  EndOffset:   12
+  FilePath:/path/foo.h
+...
+)";
+
+  auto Symbols1 = SymbolFromYAML(YAML1);
+  EXPECT_THAT(Symbols1,
+  UnorderedElementsAre(QName("clang::Foo1")));
+  auto Symbols2 = SymbolFromYAML(YAML2);
+  EXPECT_THAT(Symbols2,
+  UnorderedElementsAre(QName("clang::Foo2")));
+
+  std::string ConcatenatedYAML =
+  SymbolToYAML(Symbols1) + SymbolToYAML(Symbols2);
+  auto ConcatenatedSymbols = SymbolFromYAML(ConcatenatedYAML);
+  EXPECT_THAT(ConcatenatedSymbols,
+  UnorderedElementsAre(QName("clang::Foo1"),
+   QName("clang::Foo2")));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clangd/index/SymbolYAML.h
===
--- /dev/null
+++ clangd/index/SymbolYAML.h
@@ -0,0 +1,37 @@
+//===--- SymbolYAML.h *- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// SymbolYAML provides facilities to convert Symbol to YAML, and vice versa.
+// The YAML format of Symbol is designed for simplicity and experiment, but
+// isn't a suitable/efficient store.
+//
+// This is for **experimental** only. Don't use it in the production code.
+//
+//===-===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
+
+#include "Index.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace clangd {
+
+// Read symbols from a YAML-format string.
+SymbolSlab SymbolFromYAML(llvm::StringRef YAMLContent);
+
+// Convert symbols to a YAML-format string.
+// The YAML result is safe to concatenate if you have multiple symbol slabs.
+std::string SymbolToYAML(const SymbolSlab& Symbols);
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
Index: clangd/index/SymbolYAML.cpp
===
--- /dev/null
+++ clangd/index/SymbolYAML.cpp
@@ -0,0 +1,148 @@
+//===--- SymbolYAML.cpp --*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "SymbolYAML.h"
+
+#include "Index.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Errc.h"
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(clang::clangd::Symbol)
+
+namespace llvm {
+namespace yaml {
+
+using clang::clangd::Symbol;
+using clang::clangd::SymbolID;
+using clang::clangd::SymbolLocation;
+using clang::index::SymbolInfo;
+using clang::index::SymbolLanguage;
+using clang::index::SymbolKind;
+
+// Helper to (de)serialize the SymbolID. We serialize it as a hex string.
+struct NormalizedSymbolID {
+  NormalizedSymbolID(IO &) {}
+  NormalizedSymbolID(IO &, const SymbolID& ID) {
+llvm::raw_string_ostream OS(HexString);
+  

[PATCH] D41178: [clangd] Construct SymbolSlab from YAML format.

2017-12-14 Thread Haojian Wu via Phabricator via cfe-commits
hokein added a comment.

Thanks for the comments!




Comment at: clangd/index/SymbolFromYAML.cpp:32
+// supported in YAML I/O.
+struct NPArray {
+  NPArray(IO &) {}

sammccall wrote:
> what does NP stand for?
Ah, P is a typo here. N stands for Normalized. Renamed it to `NormalizedXXX`.



Comment at: clangd/index/SymbolFromYAML.cpp:44
+
+  std::vector Value;
+};

sammccall wrote:
> Nit: for readability, I suggest you encode as a hex string instead.
> 
> We don't yet have operator<< for SymbolID, but I think we should, and it 
> should be consistent.
> So preferably define `operator<<` for SymbolID, and use it here, rather than 
> just defining everything here.
Good idea. Done.



Comment at: clangd/index/SymbolFromYAML.h:1
+//===--- SymbolFromYAML.h *- 
C++-*-===//
+//

sammccall wrote:
> nit: `SymbolFromYAML.h` seems slightly off for the file, because you support 
> both conversions (and also multiple symbols)
> 
> Consider just `YAML.h`?
`YAML` seems too general. Named it `SymbolYAML` indicating the conversion 
between Symbol and YAML.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41178



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


[PATCH] D41179: [Sema] Diagnose template specializations with C linkage

2017-12-14 Thread Mikhail Maltsev via Phabricator via cfe-commits
miyuki updated this revision to Diff 126915.
miyuki added a comment.

Added a test for partial specialization.


https://reviews.llvm.org/D41179

Files:
  lib/Sema/SemaTemplate.cpp
  test/SemaTemplate/class-template-spec.cpp
  test/SemaTemplate/function-template-specialization.cpp


Index: test/SemaTemplate/function-template-specialization.cpp
===
--- test/SemaTemplate/function-template-specialization.cpp
+++ test/SemaTemplate/function-template-specialization.cpp
@@ -56,3 +56,8 @@
   template<>
   static void Bar(const long& input) {}  // expected-error{{explicit 
specialization of 'Bar' in class scope}}
 };
+
+template void f3(T) {}
+extern "C" { // expected-note {{extern "C" language linkage specification 
begins here}}
+  template<> void f3(int) {} // expected-error{{templates must have C++ 
linkage}}
+}
Index: test/SemaTemplate/class-template-spec.cpp
===
--- test/SemaTemplate/class-template-spec.cpp
+++ test/SemaTemplate/class-template-spec.cpp
@@ -235,3 +235,9 @@
   > struct S;
   template struct S {}; // expected-error {{non-type template 
argument specializes a template parameter with dependent type 'T'}}
 }
+
+template struct C {};
+extern "C" { // expected-note 2{{extern "C" language linkage specification 
begins here}}
+  template struct C {}; // expected-error{{templates must have 
C++ linkage}}
+  template<> struct C {}; // expected-error{{templates must have C++ 
linkage}}
+}
Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -7017,6 +7017,16 @@
 return true;
   }
 
+  // C++ [temp]p6:
+  //   A template, a template explicit specialization, and a class template
+  //   partial specialization shall not have C linkage.
+  if (S.CurContext->isExternCContext()) {
+S.Diag(Loc, diag::err_template_linkage);
+if (const LinkageSpecDecl *LSD = S.CurContext->getExternCContext())
+  S.Diag(LSD->getExternLoc(), diag::note_extern_c_begins_here);
+return true;
+  }
+
   // C++ [temp.expl.spec]p2:
   //   An explicit specialization shall be declared in the namespace
   //   of which the template is a member, or, for member templates, in


Index: test/SemaTemplate/function-template-specialization.cpp
===
--- test/SemaTemplate/function-template-specialization.cpp
+++ test/SemaTemplate/function-template-specialization.cpp
@@ -56,3 +56,8 @@
   template<>
   static void Bar(const long& input) {}  // expected-error{{explicit specialization of 'Bar' in class scope}}
 };
+
+template void f3(T) {}
+extern "C" { // expected-note {{extern "C" language linkage specification begins here}}
+  template<> void f3(int) {} // expected-error{{templates must have C++ linkage}}
+}
Index: test/SemaTemplate/class-template-spec.cpp
===
--- test/SemaTemplate/class-template-spec.cpp
+++ test/SemaTemplate/class-template-spec.cpp
@@ -235,3 +235,9 @@
   > struct S;
   template struct S {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'T'}}
 }
+
+template struct C {};
+extern "C" { // expected-note 2{{extern "C" language linkage specification begins here}}
+  template struct C {}; // expected-error{{templates must have C++ linkage}}
+  template<> struct C {}; // expected-error{{templates must have C++ linkage}}
+}
Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -7017,6 +7017,16 @@
 return true;
   }
 
+  // C++ [temp]p6:
+  //   A template, a template explicit specialization, and a class template
+  //   partial specialization shall not have C linkage.
+  if (S.CurContext->isExternCContext()) {
+S.Diag(Loc, diag::err_template_linkage);
+if (const LinkageSpecDecl *LSD = S.CurContext->getExternCContext())
+  S.Diag(LSD->getExternLoc(), diag::note_extern_c_begins_here);
+return true;
+  }
+
   // C++ [temp.expl.spec]p2:
   //   An explicit specialization shall be declared in the namespace
   //   of which the template is a member, or, for member templates, in
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39622: Fix type name generation in DWARF for template instantiations with enum types and template specializations

2017-12-14 Thread Anton via Phabricator via cfe-commits
xgsa added a comment.

In https://reviews.llvm.org/D39622#954585, @probinson wrote:

> Philosophically, mangled names and DWARF information serve different 
> purposes, and I don't think you will find one true solution where both of 
> them can yield the same name that everyone will be happy with.  Mangled names 
> exist to provide unique and reproducible identifiers for the "same" entity 
> across compilation units.  They are carefully specified (for example) to 
> allow a linker to associate a reference in one object file to a definition in 
> a different object file, and be guaranteed that the association is correct.  
> A demangled name is a necessarily context-free translation of the mangled 
> name into something that has a closer relationship to how a human would think 
> of or write the name of the thing, but isn't necessarily the only way to 
> write the name of the thing.
>
> DWARF names are (deliberately not carefully specified) strings that ought to 
> bear some relationship to how source code would name the thing, but you 
> probably don't want to attach semantic significance to those names.  This is 
> rather emphatically true for names containing template parameters.  Typedefs 
> (and their recent offspring, 'using' aliases) are your sworn enemy here.  
> Enums, as you have found, are also a problem.
>
> Basically, the type of an entity does not have a unique name, and trying to 
> coerce different representations of the type into having the same unique name 
> is a losing battle.


Thank you for clarification, Paul! Nevertheless, I suppose, showing actual type 
of a dynamic variable is very important for the projects, where RTTI is used. 
Moreover, it works properly in gcc+gdb pair, so I am extremely interested in 
fixing it in clang+lldb.

I understand that the suggested solution possibly does not cover all the cases, 
but it improves the situation and actually covers all the cases found by me (I 
have just rechecked -- typedefs/usings seems to work fine when displaying the 
real type of variable). If more cases are found in future, they could be fixed 
similarly too. Moreover, the debuggers already rely on the fact that the type 
name looks the same in RTTI and DWARF, and I suppose they have no choice, 
because there is no other source of information for them (or am I missing 
something?). Another advantage of this solution is that it doesn't require any 
format extension and will probably work out of the box in gdb and other 
debuggers. Moreover, I have just rechecked, gcc generates exactly the same type 
names in DWARF for examples in the description.

On the other hand, I understand the idea you have described, but I am not sure 
how to implement this lookup in another way. I suppose, we cannot extend RTTI 
with the debug type name (is it correct?). Thus, the only way I see is to add 
additional information about the mangled type name into DWARF. It could be 
either a separate section (like apple_types) or a special node for 
TAG_structure_type/TAG_class_type, which should be indexed into map for fast 
lookup. Anyway, this will be an extension to DWARF and will require special 
support in a debugger. Furthermore, such solution will be much complicated 
(still I don't mind working on it).

So what do you think? Is the suggested solution not full or not acceptable? Do 
you have other ideas how this feature should be implemented?

P.S. Should this question be raised in mailing list? And if yes, actually, in 
which ones (clang or lldb?), because it seems related to both clang and lldb?


https://reviews.llvm.org/D39622



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


[PATCH] D40548: [clangd] Symbol index interfaces and index-based code completion.

2017-12-14 Thread Eric Liu via Phabricator via cfe-commits
ioeric updated this revision to Diff 126916.
ioeric marked 7 inline comments as done.
ioeric added a comment.

- Address review comments


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40548

Files:
  clangd/CMakeLists.txt
  clangd/index/Index.h
  clangd/index/MemIndex.cpp
  clangd/index/MemIndex.h
  unittests/clangd/CMakeLists.txt
  unittests/clangd/IndexTests.cpp

Index: unittests/clangd/IndexTests.cpp
===
--- /dev/null
+++ unittests/clangd/IndexTests.cpp
@@ -0,0 +1,116 @@
+//===-- IndexTests.cpp  ---*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "index/Index.h"
+#include "index/MemIndex.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using testing::UnorderedElementsAre;
+
+namespace clang {
+namespace clangd {
+
+namespace {
+
+Symbol symbol(llvm::StringRef ID) {
+  Symbol Sym;
+  Sym.ID = SymbolID(ID);
+  Sym.QualifiedName = ID;
+  return Sym;
+}
+
+struct SlabAndPointers {
+  SymbolSlab Slab;
+  std::vector Pointers;
+};
+
+// Create a slab of symbols with IDs and names [Begin, End]. The life time of
+// the slab is managed by the returned shared pointer. If \p WeakSymbols is
+// provided, it will be pointed to the managed object in the returned shared
+// pointer.
+std::shared_ptr>
+generateNumSymbols(int Begin, int End,
+   std::weak_ptr *WeakSymbols = nullptr) {
+  auto Slab = std::make_shared();
+  if (WeakSymbols)
+*WeakSymbols = Slab;
+
+  for (int i = Begin; i <= End; i++)
+Slab->Slab.insert(symbol(std::to_string(i)));
+
+  for (const auto &Sym : Slab->Slab)
+Slab->Pointers.push_back(&Sym.second);
+
+  auto Symbols = std::shared_ptr>(std::move(Slab),
+  &Slab->Pointers);
+
+  return Symbols;
+}
+
+std::vector match(const SymbolIndex &I,
+   const FuzzyFindRequest &Req) {
+  std::vector Matches;
+  auto Ctx = Context::empty();
+  I.fuzzyFind(Ctx, Req,
+  [&](const Symbol &Sym) { Matches.push_back(Sym.QualifiedName); });
+  return Matches;
+}
+
+TEST(MemIndexTest, MemIndexSymbolsRecycled) {
+  MemIndex I;
+  std::weak_ptr Symbols;
+  I.build(generateNumSymbols(0, 10, &Symbols));
+  FuzzyFindRequest Req;
+  Req.Query = "7";
+  EXPECT_THAT(match(I, Req), UnorderedElementsAre("7"));
+
+  // Release old symbols.
+  I.build(generateNumSymbols(0, 0));
+  EXPECT_TRUE(Symbols.expired());
+}
+
+TEST(MemIndexTest, MemIndexMatchSubstring) {
+  MemIndex I;
+  I.build(generateNumSymbols(5, 25));
+  FuzzyFindRequest Req;
+  Req.Query = "5";
+  EXPECT_THAT(match(I, Req), UnorderedElementsAre("5", "15", "25"));
+}
+
+TEST(MemIndexTest, MemIndexDeduplicate) {
+  auto Symbols = generateNumSymbols(0, 10);
+
+  // Inject some duplicates and make sure we only match the same symbol once.
+  auto Sym = symbol("7");
+  Symbols->push_back(&Sym);
+  Symbols->push_back(&Sym);
+  Symbols->push_back(&Sym);
+
+  FuzzyFindRequest Req;
+  Req.Query = "7";
+  MemIndex I;
+  I.build(std::move(Symbols));
+  auto Matches = match(I, Req);
+  EXPECT_EQ(Matches.size(), 1u);
+}
+
+TEST(MemIndexTest, MemIndexLimitedNumMatches) {
+  MemIndex I;
+  I.build(generateNumSymbols(0, 100));
+  FuzzyFindRequest Req;
+  Req.Query = "5";
+  Req.MaxCandidateCount = 3;
+  auto Matches = match(I, Req);
+  EXPECT_EQ(Matches.size(), Req.MaxCandidateCount);
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
Index: unittests/clangd/CMakeLists.txt
===
--- unittests/clangd/CMakeLists.txt
+++ unittests/clangd/CMakeLists.txt
@@ -13,6 +13,7 @@
   CodeCompleteTests.cpp
   ContextTests.cpp
   FuzzyMatchTests.cpp
+  IndexTests.cpp
   JSONExprTests.cpp
   TestFS.cpp
   TraceTests.cpp
Index: clangd/index/MemIndex.h
===
--- /dev/null
+++ clangd/index/MemIndex.h
@@ -0,0 +1,41 @@
+//===--- MemIndex.h - Dynamic in-memory symbol index. -- 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_TOOLS_EXTRA_CLANGD_INDEX_MEMINDEX_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_MEMINDEX_H
+
+#include "Index.h"
+#include 
+
+namespace clang {
+namespace clangd {
+
+/// \brief This implements an index for a (relatively small) set of symbols that
+/// can be easily managed in memory.
+class MemIndex : public SymbolIndex {
+public:
+  /// \brief (Re-)Build index for `Symbols`. All symbol p

[PATCH] D40548: [clangd] Symbol index interfaces and index-based code completion.

2017-12-14 Thread Eric Liu via Phabricator via cfe-commits
ioeric updated this revision to Diff 126917.
ioeric marked an inline comment as done.
ioeric added a comment.

- Fix comment for fuzzyFind


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40548

Files:
  clangd/CMakeLists.txt
  clangd/index/Index.h
  clangd/index/MemIndex.cpp
  clangd/index/MemIndex.h
  unittests/clangd/CMakeLists.txt
  unittests/clangd/IndexTests.cpp

Index: unittests/clangd/IndexTests.cpp
===
--- /dev/null
+++ unittests/clangd/IndexTests.cpp
@@ -0,0 +1,116 @@
+//===-- IndexTests.cpp  ---*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "index/Index.h"
+#include "index/MemIndex.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using testing::UnorderedElementsAre;
+
+namespace clang {
+namespace clangd {
+
+namespace {
+
+Symbol symbol(llvm::StringRef ID) {
+  Symbol Sym;
+  Sym.ID = SymbolID(ID);
+  Sym.QualifiedName = ID;
+  return Sym;
+}
+
+struct SlabAndPointers {
+  SymbolSlab Slab;
+  std::vector Pointers;
+};
+
+// Create a slab of symbols with IDs and names [Begin, End]. The life time of
+// the slab is managed by the returned shared pointer. If \p WeakSymbols is
+// provided, it will be pointed to the managed object in the returned shared
+// pointer.
+std::shared_ptr>
+generateNumSymbols(int Begin, int End,
+   std::weak_ptr *WeakSymbols = nullptr) {
+  auto Slab = std::make_shared();
+  if (WeakSymbols)
+*WeakSymbols = Slab;
+
+  for (int i = Begin; i <= End; i++)
+Slab->Slab.insert(symbol(std::to_string(i)));
+
+  for (const auto &Sym : Slab->Slab)
+Slab->Pointers.push_back(&Sym.second);
+
+  auto Symbols = std::shared_ptr>(std::move(Slab),
+  &Slab->Pointers);
+
+  return Symbols;
+}
+
+std::vector match(const SymbolIndex &I,
+   const FuzzyFindRequest &Req) {
+  std::vector Matches;
+  auto Ctx = Context::empty();
+  I.fuzzyFind(Ctx, Req,
+  [&](const Symbol &Sym) { Matches.push_back(Sym.QualifiedName); });
+  return Matches;
+}
+
+TEST(MemIndexTest, MemIndexSymbolsRecycled) {
+  MemIndex I;
+  std::weak_ptr Symbols;
+  I.build(generateNumSymbols(0, 10, &Symbols));
+  FuzzyFindRequest Req;
+  Req.Query = "7";
+  EXPECT_THAT(match(I, Req), UnorderedElementsAre("7"));
+
+  // Release old symbols.
+  I.build(generateNumSymbols(0, 0));
+  EXPECT_TRUE(Symbols.expired());
+}
+
+TEST(MemIndexTest, MemIndexMatchSubstring) {
+  MemIndex I;
+  I.build(generateNumSymbols(5, 25));
+  FuzzyFindRequest Req;
+  Req.Query = "5";
+  EXPECT_THAT(match(I, Req), UnorderedElementsAre("5", "15", "25"));
+}
+
+TEST(MemIndexTest, MemIndexDeduplicate) {
+  auto Symbols = generateNumSymbols(0, 10);
+
+  // Inject some duplicates and make sure we only match the same symbol once.
+  auto Sym = symbol("7");
+  Symbols->push_back(&Sym);
+  Symbols->push_back(&Sym);
+  Symbols->push_back(&Sym);
+
+  FuzzyFindRequest Req;
+  Req.Query = "7";
+  MemIndex I;
+  I.build(std::move(Symbols));
+  auto Matches = match(I, Req);
+  EXPECT_EQ(Matches.size(), 1u);
+}
+
+TEST(MemIndexTest, MemIndexLimitedNumMatches) {
+  MemIndex I;
+  I.build(generateNumSymbols(0, 100));
+  FuzzyFindRequest Req;
+  Req.Query = "5";
+  Req.MaxCandidateCount = 3;
+  auto Matches = match(I, Req);
+  EXPECT_EQ(Matches.size(), Req.MaxCandidateCount);
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
Index: unittests/clangd/CMakeLists.txt
===
--- unittests/clangd/CMakeLists.txt
+++ unittests/clangd/CMakeLists.txt
@@ -13,6 +13,7 @@
   CodeCompleteTests.cpp
   ContextTests.cpp
   FuzzyMatchTests.cpp
+  IndexTests.cpp
   JSONExprTests.cpp
   TestFS.cpp
   TraceTests.cpp
Index: clangd/index/MemIndex.h
===
--- /dev/null
+++ clangd/index/MemIndex.h
@@ -0,0 +1,41 @@
+//===--- MemIndex.h - Dynamic in-memory symbol index. -- 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_TOOLS_EXTRA_CLANGD_INDEX_MEMINDEX_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_MEMINDEX_H
+
+#include "Index.h"
+#include 
+
+namespace clang {
+namespace clangd {
+
+/// \brief This implements an index for a (relatively small) set of symbols that
+/// can be easily managed in memory.
+class MemIndex : public SymbolIndex {
+public:
+  /// \brief (Re-)Build index for `Symbols`. All symbol

Re: Status of CET support? (Re: [PATCH] D40224:...)

2017-12-14 Thread Pavel Chupin via cfe-commits
Hi Kostya,
Long time no see. :)
I would estimate that everything (glibc, kernel, loader, simulator)
should be available approx. February 2018 as soon as implementation
finished and tested on our side.
CET is enabled already in GCC, glibc branch with CET is available
(https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/hjl/cet/master)
and will be upstreamed as soon as kernel upstream progress made.

On Wed, Nov 29, 2017 at 8:41 AM, Ben Simhon, Oren
 wrote:
> Hi Kostya,
>
>
>
> Sorry for the detailed response.
>
> I forwarded your questions to GCC team who are also adding CET support for
> Glibc / Linux Kernel / Loader.
>
>
>
> I also talked to the simulations team to understand their timeline.
>
> They will contact this mailing list with detailed answers.
>
>
>
> There are few more patches to complete LLVM Compiler support.
>
> I will appreciate your help in reviewing some of them:
>
> https://reviews.llvm.org/D40482
>
> https://reviews.llvm.org/D40478
>
>
>
> Thanks,
>
> Oren
>
>
>
> From: Kostya Serebryany [mailto:k...@google.com]
> Sent: Tuesday, November 28, 2017 01:46
> Cc: Ben Simhon, Oren ; pavel.v.chu...@gmail.com;
> Keane, Erich ; Justin Bogner ;
> ablik...@gmail.com; Reid Kleckner ; Craig Topper
> ; cfe-commits ; Evgeniy
> Stepanov ; Peter Collingbourne ; Sahita,
> Ravi ; Zuckerman, Michael
> 
> Subject: Status of CET support? (Re: [PATCH] D40224:...)
>
>
>
> Hi,
>
>
>
> I see these patches for the CET support in LLVM -- great!
>
> Could you please also tell us
>
>   * what's the status of the Linux Kernel and Glibc support for CET?
>
>   * how we can start evaluating the hardware feature (simulators, etc)?
>
>
>
> Thanks!
>
>
>
> --kcc
>
>
>
>
>
> On Sun, Nov 26, 2017 at 4:35 AM, Phabricator via Phabricator via cfe-commits
>  wrote:
>
> This revision was automatically updated to reflect the committed changes.
> Closed by commit rL318995: Control-Flow Enforcement Technology - Shadow
> Stack and Indirect Branch Tracking… (authored by orenb).
>
> Changed prior to commit:
>   https://reviews.llvm.org/D40224?vs=123937&id=124287#toc
>
> Repository:
>   rL LLVM
>
> https://reviews.llvm.org/D40224
>
> Files:
>   cfe/trunk/include/clang/Basic/BuiltinsX86.def
>   cfe/trunk/include/clang/Basic/BuiltinsX86_64.def
>   cfe/trunk/include/clang/Driver/Options.td
>   cfe/trunk/lib/Basic/Targets/X86.cpp
>   cfe/trunk/lib/Basic/Targets/X86.h
>   cfe/trunk/lib/Headers/CMakeLists.txt
>   cfe/trunk/lib/Headers/cetintrin.h
>   cfe/trunk/lib/Headers/immintrin.h
>   cfe/trunk/test/CodeGen/builtins-x86.c
>   cfe/trunk/test/CodeGen/cetintrin.c
>   cfe/trunk/test/Driver/x86-target-features.c
>   cfe/trunk/test/Preprocessor/x86_target_features.c
>
>
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
>
> -
> Intel Israel (74) Limited
>
> This e-mail and any attachments may contain confidential material for
> the sole use of the intended recipient(s). Any review or distribution
> by others is strictly prohibited. If you are not the intended
> recipient, please contact the sender and delete all copies.



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


[PATCH] D41178: [clangd] Construct SymbolSlab from YAML format.

2017-12-14 Thread Sam McCall via Phabricator via cfe-commits
sammccall accepted this revision.
sammccall added inline comments.
This revision is now accepted and ready to land.



Comment at: clangd/index/Index.h:17
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/YAMLTraits.h"
 

This isn't needed anymore (if you remove the friend below)



Comment at: clangd/index/Index.h:57
   }
+  friend struct llvm::yaml::MappingTraits;
+  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,

I think this no longer needs to be a friend.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41178



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


[PATCH] D40548: [clangd] Symbol index interfaces and index-based code completion.

2017-12-14 Thread Sam McCall via Phabricator via cfe-commits
sammccall accepted this revision.
sammccall added inline comments.



Comment at: unittests/clangd/IndexTests.cpp:29
+
+struct SlabAndPointers {
+  SymbolSlab Slab;

this could be local to generateNumSymbols, up to you



Comment at: unittests/clangd/IndexTests.cpp:51
+
+  auto Symbols = std::shared_ptr>(std::move(Slab),
+  &Slab->Pointers);

nit: just return? (you can skip spelling out the shared_ptr type with {}, I 
think)



Comment at: unittests/clangd/IndexTests.cpp:73
+  EXPECT_THAT(match(I, Req), UnorderedElementsAre("7"));
+
+  // Release old symbols.

assert symbols is not expired here?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40548



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


[PATCH] D40548: [clangd] Symbol index interfaces and index-based code completion.

2017-12-14 Thread Eric Liu via Phabricator via cfe-commits
ioeric updated this revision to Diff 126919.
ioeric marked 3 inline comments as done.
ioeric added a comment.

- Address more comments. # I am going to land it now.
- Merge remote-tracking branch 'origin/master' into index


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40548

Files:
  clangd/CMakeLists.txt
  clangd/index/Index.h
  clangd/index/MemIndex.cpp
  clangd/index/MemIndex.h
  unittests/clangd/CMakeLists.txt
  unittests/clangd/IndexTests.cpp

Index: unittests/clangd/IndexTests.cpp
===
--- /dev/null
+++ unittests/clangd/IndexTests.cpp
@@ -0,0 +1,114 @@
+//===-- IndexTests.cpp  ---*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "index/Index.h"
+#include "index/MemIndex.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using testing::UnorderedElementsAre;
+
+namespace clang {
+namespace clangd {
+
+namespace {
+
+Symbol symbol(llvm::StringRef ID) {
+  Symbol Sym;
+  Sym.ID = SymbolID(ID);
+  Sym.QualifiedName = ID;
+  return Sym;
+}
+
+struct SlabAndPointers {
+  SymbolSlab Slab;
+  std::vector Pointers;
+};
+
+// Create a slab of symbols with IDs and names [Begin, End]. The life time of
+// the slab is managed by the returned shared pointer. If \p WeakSymbols is
+// provided, it will be pointed to the managed object in the returned shared
+// pointer.
+std::shared_ptr>
+generateNumSymbols(int Begin, int End,
+   std::weak_ptr *WeakSymbols = nullptr) {
+  auto Slab = std::make_shared();
+  if (WeakSymbols)
+*WeakSymbols = Slab;
+
+  for (int i = Begin; i <= End; i++)
+Slab->Slab.insert(symbol(std::to_string(i)));
+
+  for (const auto &Sym : Slab->Slab)
+Slab->Pointers.push_back(&Sym.second);
+
+  return {std::move(Slab), &Slab->Pointers};
+}
+
+std::vector match(const SymbolIndex &I,
+   const FuzzyFindRequest &Req) {
+  std::vector Matches;
+  auto Ctx = Context::empty();
+  I.fuzzyFind(Ctx, Req,
+  [&](const Symbol &Sym) { Matches.push_back(Sym.QualifiedName); });
+  return Matches;
+}
+
+TEST(MemIndexTest, MemIndexSymbolsRecycled) {
+  MemIndex I;
+  std::weak_ptr Symbols;
+  I.build(generateNumSymbols(0, 10, &Symbols));
+  FuzzyFindRequest Req;
+  Req.Query = "7";
+  EXPECT_THAT(match(I, Req), UnorderedElementsAre("7"));
+
+  EXPECT_FALSE(Symbols.expired());
+  // Release old symbols.
+  I.build(generateNumSymbols(0, 0));
+  EXPECT_TRUE(Symbols.expired());
+}
+
+TEST(MemIndexTest, MemIndexMatchSubstring) {
+  MemIndex I;
+  I.build(generateNumSymbols(5, 25));
+  FuzzyFindRequest Req;
+  Req.Query = "5";
+  EXPECT_THAT(match(I, Req), UnorderedElementsAre("5", "15", "25"));
+}
+
+TEST(MemIndexTest, MemIndexDeduplicate) {
+  auto Symbols = generateNumSymbols(0, 10);
+
+  // Inject some duplicates and make sure we only match the same symbol once.
+  auto Sym = symbol("7");
+  Symbols->push_back(&Sym);
+  Symbols->push_back(&Sym);
+  Symbols->push_back(&Sym);
+
+  FuzzyFindRequest Req;
+  Req.Query = "7";
+  MemIndex I;
+  I.build(std::move(Symbols));
+  auto Matches = match(I, Req);
+  EXPECT_EQ(Matches.size(), 1u);
+}
+
+TEST(MemIndexTest, MemIndexLimitedNumMatches) {
+  MemIndex I;
+  I.build(generateNumSymbols(0, 100));
+  FuzzyFindRequest Req;
+  Req.Query = "5";
+  Req.MaxCandidateCount = 3;
+  auto Matches = match(I, Req);
+  EXPECT_EQ(Matches.size(), Req.MaxCandidateCount);
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
Index: unittests/clangd/CMakeLists.txt
===
--- unittests/clangd/CMakeLists.txt
+++ unittests/clangd/CMakeLists.txt
@@ -13,6 +13,7 @@
   CodeCompleteTests.cpp
   ContextTests.cpp
   FuzzyMatchTests.cpp
+  IndexTests.cpp
   JSONExprTests.cpp
   TestFS.cpp
   TraceTests.cpp
Index: clangd/index/MemIndex.h
===
--- /dev/null
+++ clangd/index/MemIndex.h
@@ -0,0 +1,41 @@
+//===--- MemIndex.h - Dynamic in-memory symbol index. -- 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_TOOLS_EXTRA_CLANGD_INDEX_MEMINDEX_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_MEMINDEX_H
+
+#include "Index.h"
+#include 
+
+namespace clang {
+namespace clangd {
+
+/// \brief This implements an index for a (relatively small) set of symbols that
+/// can be easily managed in memory.
+class MemIndex : public SymbolIndex {
+public:
+  /// \brief (Re-)Build index for `Symbols`

[PATCH] D40284: [Sema] Improve diagnostics for template arg deduction

2017-12-14 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

I would prefer that we make the more-invasive fix, and make each error case 
within template argument deduction set all the deduction failure information. 
(Consider factoring out the error setup into helper functions too.) The current 
approach is a maintenance problem in addition to creating incorrect 
diagnostics, as it makes it very hard to see what parameters are actually 
intended to be provided with each of the different forms of deduction failure.


https://reviews.llvm.org/D40284



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


[clang-tools-extra] r320688 - [clangd] Symbol index interfaces and an in-memory index implementation.

2017-12-14 Thread Eric Liu via cfe-commits
Author: ioeric
Date: Thu Dec 14 03:25:49 2017
New Revision: 320688

URL: http://llvm.org/viewvc/llvm-project?rev=320688&view=rev
Log:
[clangd] Symbol index interfaces and an in-memory index implementation.

Summary:
o Index interfaces to support using different index sources (e.g. AST index, 
global index) for code completion, cross-reference finding etc. This patch 
focuses on code completion.

The following changes in the original patch has been split out.
o Implement an AST-based index.
o Add an option to replace sema code completion for qualified-id with 
index-based completion.
o Implement an initial naive code completion index which matches symbols that 
have the query string as substring.

Reviewers: malaperle, sammccall

Reviewed By: sammccall

Subscribers: hokein, klimek, malaperle, mgorny, ilya-biryukov, cfe-commits

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

Added:
clang-tools-extra/trunk/clangd/index/MemIndex.cpp
clang-tools-extra/trunk/clangd/index/MemIndex.h
clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp
Modified:
clang-tools-extra/trunk/clangd/CMakeLists.txt
clang-tools-extra/trunk/clangd/index/Index.h
clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt

Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CMakeLists.txt?rev=320688&r1=320687&r2=320688&view=diff
==
--- clang-tools-extra/trunk/clangd/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/CMakeLists.txt Thu Dec 14 03:25:49 2017
@@ -19,6 +19,7 @@ add_clang_library(clangDaemon
   Protocol.cpp
   ProtocolHandlers.cpp
   Trace.cpp
+  index/MemIndex.cpp
   index/Index.cpp
   index/SymbolCollector.cpp
 

Modified: clang-tools-extra/trunk/clangd/index/Index.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Index.h?rev=320688&r1=320687&r2=320688&view=diff
==
--- clang-tools-extra/trunk/clangd/index/Index.h (original)
+++ clang-tools-extra/trunk/clangd/index/Index.h Thu Dec 14 03:25:49 2017
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H
 
+#include "../Context.h"
 #include "clang/Index/IndexSymbol.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Hashing.h"
@@ -110,6 +111,34 @@ private:
   llvm::DenseMap Symbols;
 };
 
+struct FuzzyFindRequest {
+  /// \brief A query string for the fuzzy find. This is matched against 
symbols'
+  /// qualfified names.
+  std::string Query;
+  /// \brief The maxinum number of candidates to return.
+  size_t MaxCandidateCount = UINT_MAX;
+};
+
+/// \brief Interface for symbol indexes that can be used for searching or
+/// matching symbols among a set of symbols based on names or unique IDs.
+class SymbolIndex {
+public:
+  virtual ~SymbolIndex() = default;
+
+  /// \brief Matches symbols in the index fuzzily and applies \p Callback on
+  /// each matched symbol before returning.
+  ///
+  /// Returns true if the result list is complete, false if it was truncated 
due
+  /// to MaxCandidateCount
+  virtual bool
+  fuzzyFind(Context &Ctx, const FuzzyFindRequest &Req,
+std::function Callback) const = 0;
+
+  // FIXME: add interfaces for more index use cases:
+  //  - Symbol getSymbolInfo(SymbolID);
+  //  - getAllOccurrences(SymbolID);
+};
+
 } // namespace clangd
 } // namespace clang
 

Added: clang-tools-extra/trunk/clangd/index/MemIndex.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/MemIndex.cpp?rev=320688&view=auto
==
--- clang-tools-extra/trunk/clangd/index/MemIndex.cpp (added)
+++ clang-tools-extra/trunk/clangd/index/MemIndex.cpp Thu Dec 14 03:25:49 2017
@@ -0,0 +1,52 @@
+//===--- MemIndex.cpp - Dynamic in-memory symbol index. --*- 
C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---===//
+
+#include "MemIndex.h"
+
+namespace clang {
+namespace clangd {
+
+void MemIndex::build(std::shared_ptr> Syms) {
+  llvm::DenseMap TempIndex;
+  for (const Symbol *Sym : *Syms)
+TempIndex[Sym->ID] = Sym;
+
+  // Swap out the old symbols and index.
+  {
+std::lock_guard Lock(Mutex);
+Index = std::move(TempIndex);
+Symbols = std::move(Syms); // Relase old symbols.
+  }
+}
+
+bool MemIndex::fuzzyFind(Context & /*Ctx*/, const FuzzyFindRequest &Req,
+ std::function Callback) const {
+  std::string LoweredQuery = llvm::StringRef(Req.Query).lower();
+  unsigned Matched = 0;
+  {
+std::lock_guard Lock(Mutex);
+for (const auto Pair : Index) {

[PATCH] D40548: [clangd] Symbol index interfaces and an in-memory index implementation.

2017-12-14 Thread Eric Liu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rCTE320688: [clangd] Symbol index interfaces and an in-memory 
index implementation. (authored by ioeric, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D40548?vs=126919&id=126924#toc

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40548

Files:
  clangd/CMakeLists.txt
  clangd/index/Index.h
  clangd/index/MemIndex.cpp
  clangd/index/MemIndex.h
  unittests/clangd/CMakeLists.txt
  unittests/clangd/IndexTests.cpp

Index: clangd/CMakeLists.txt
===
--- clangd/CMakeLists.txt
+++ clangd/CMakeLists.txt
@@ -19,6 +19,7 @@
   Protocol.cpp
   ProtocolHandlers.cpp
   Trace.cpp
+  index/MemIndex.cpp
   index/Index.cpp
   index/SymbolCollector.cpp
 
Index: clangd/index/Index.h
===
--- clangd/index/Index.h
+++ clangd/index/Index.h
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H
 
+#include "../Context.h"
 #include "clang/Index/IndexSymbol.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Hashing.h"
@@ -110,6 +111,34 @@
   llvm::DenseMap Symbols;
 };
 
+struct FuzzyFindRequest {
+  /// \brief A query string for the fuzzy find. This is matched against symbols'
+  /// qualfified names.
+  std::string Query;
+  /// \brief The maxinum number of candidates to return.
+  size_t MaxCandidateCount = UINT_MAX;
+};
+
+/// \brief Interface for symbol indexes that can be used for searching or
+/// matching symbols among a set of symbols based on names or unique IDs.
+class SymbolIndex {
+public:
+  virtual ~SymbolIndex() = default;
+
+  /// \brief Matches symbols in the index fuzzily and applies \p Callback on
+  /// each matched symbol before returning.
+  ///
+  /// Returns true if the result list is complete, false if it was truncated due
+  /// to MaxCandidateCount
+  virtual bool
+  fuzzyFind(Context &Ctx, const FuzzyFindRequest &Req,
+std::function Callback) const = 0;
+
+  // FIXME: add interfaces for more index use cases:
+  //  - Symbol getSymbolInfo(SymbolID);
+  //  - getAllOccurrences(SymbolID);
+};
+
 } // namespace clangd
 } // namespace clang
 
Index: clangd/index/MemIndex.h
===
--- clangd/index/MemIndex.h
+++ clangd/index/MemIndex.h
@@ -0,0 +1,41 @@
+//===--- MemIndex.h - Dynamic in-memory symbol index. -- 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_TOOLS_EXTRA_CLANGD_INDEX_MEMINDEX_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_MEMINDEX_H
+
+#include "Index.h"
+#include 
+
+namespace clang {
+namespace clangd {
+
+/// \brief This implements an index for a (relatively small) set of symbols that
+/// can be easily managed in memory.
+class MemIndex : public SymbolIndex {
+public:
+  /// \brief (Re-)Build index for `Symbols`. All symbol pointers must remain
+  /// accessible as long as `Symbols` is kept alive.
+  void build(std::shared_ptr> Symbols);
+
+  bool fuzzyFind(Context &Ctx, const FuzzyFindRequest &Req,
+ std::function Callback) const override;
+
+private:
+  std::shared_ptr> Symbols;
+  // Index is a set of symbols that are deduplicated by symbol IDs.
+  // FIXME: build smarter index structure.
+  llvm::DenseMap Index;
+  mutable std::mutex Mutex;
+};
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_MEMINDEX_H
Index: clangd/index/MemIndex.cpp
===
--- clangd/index/MemIndex.cpp
+++ clangd/index/MemIndex.cpp
@@ -0,0 +1,52 @@
+//===--- MemIndex.cpp - Dynamic in-memory symbol index. --*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---===//
+
+#include "MemIndex.h"
+
+namespace clang {
+namespace clangd {
+
+void MemIndex::build(std::shared_ptr> Syms) {
+  llvm::DenseMap TempIndex;
+  for (const Symbol *Sym : *Syms)
+TempIndex[Sym->ID] = Sym;
+
+  // Swap out the old symbols and index.
+  {
+std::lock_guard Lock(Mutex);
+Index = std::move(TempIndex);
+Symbols = std::move(Syms); // Relase old symbols.
+  }
+}
+
+bool MemIndex::fuzzyFind(Context & /*Ctx*/, const FuzzyFindRequest &Req,
+ std::function Callback) const {
+  std::string LoweredQuery = llvm::StringRef(Req.Query).lower();
+  unsigned Matched = 0;
+  {
+std::lock_guard Lock(Mutex);
+for (c

[PATCH] D40731: Integrate CHash into CLang

2017-12-14 Thread Christian Dietrich via Phabricator via cfe-commits
stettberger updated this revision to Diff 126925.
stettberger added a comment.

@rtrieu: Fixed the checking of Decl::hasAttrs() before using Decl::attrs()


Repository:
  rC Clang

https://reviews.llvm.org/D40731

Files:
  include/clang/AST/AttrDataCollectors.td
  include/clang/AST/CHashVisitor.h
  include/clang/AST/CMakeLists.txt
  include/clang/AST/DataCollection.h
  include/clang/AST/DeclDataCollectors.td
  include/clang/AST/StmtDataCollectors.td
  include/clang/AST/TypeDataCollectors.td
  unittests/AST/CHashTest.cpp
  unittests/AST/CMakeLists.txt

Index: unittests/AST/CMakeLists.txt
===
--- unittests/AST/CMakeLists.txt
+++ unittests/AST/CMakeLists.txt
@@ -18,6 +18,7 @@
   PostOrderASTVisitor.cpp
   SourceLocationTest.cpp
   StmtPrinterTest.cpp
+  CHashTest.cpp
   )
 
 target_link_libraries(ASTTests
Index: unittests/AST/CHashTest.cpp
===
--- /dev/null
+++ unittests/AST/CHashTest.cpp
@@ -0,0 +1,91 @@
+//===- unittests/AST/DataCollectionTest.cpp ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// This file contains tests for the DataCollection module.
+//
+// They work by hashing the collected data of two nodes and asserting that the
+// hash values are equal iff the nodes are considered equal.
+//
+//===--===//
+
+#include "clang/AST/CHashVisitor.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+#include 
+
+using namespace clang;
+using namespace tooling;
+
+
+class CHashConsumer : public ASTConsumer {
+CompilerInstance &CI;
+llvm::MD5::MD5Result *ASTHash;
+
+public:
+
+CHashConsumer(CompilerInstance &CI, llvm::MD5::MD5Result *ASTHash)
+: CI(CI), ASTHash(ASTHash){}
+
+virtual void HandleTranslationUnit(clang::ASTContext &Context) override {
+TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
+
+// Traversing the translation unit decl via a RecursiveASTVisitor
+// will visit all nodes in the AST.
+CHashVisitor<> Visitor(Context);
+Visitor.TraverseDecl(TU);
+// Copy Away the resulting hash
+*ASTHash = *Visitor.getHash(TU);
+
+}
+
+~CHashConsumer() override {}
+};
+
+struct CHashAction : public ASTFrontendAction {
+llvm::MD5::MD5Result *Hash;
+
+CHashAction(llvm::MD5::MD5Result *Hash) : Hash(Hash) {}
+
+std::unique_ptr CreateASTConsumer(CompilerInstance &CI,
+   StringRef) override {
+return std::unique_ptr(new CHashConsumer(CI, Hash));
+}
+};
+
+static testing::AssertionResult
+isASTHashEqual(StringRef Code1, StringRef Code2) {
+llvm::MD5::MD5Result Hash1, Hash2;
+if (!runToolOnCode(new CHashAction(&Hash1), Code1)) {
+return testing::AssertionFailure()
+<< "Parsing error in (A)\"" << Code1.str() << "\"";
+}
+if (!runToolOnCode(new CHashAction(&Hash2), Code2)) {
+return testing::AssertionFailure()
+<< "Parsing error in (B) \"" << Code2.str() << "\"";
+}
+return testing::AssertionResult(Hash1 == Hash2);
+}
+
+TEST(CHashVisitor, TestRecordTypes) {
+ASSERT_TRUE(isASTHashEqual( // Unused struct
+ "struct foobar { int a0; char a1; unsigned long a2; };",
+ "struct foobar { int a0; char a1;};"
+ ));
+
+}
+
+TEST(CHashVisitor, TestSourceStructure) {
+ASSERT_FALSE(isASTHashEqual(
+ "void foo() { int c; if (0) { c = 1; } }",
+ "void foo() { int c; if (0) { } c = 1; }"));
+
+ASSERT_FALSE(isASTHashEqual(
+ "void f1() {} void f2() {   }",
+ "void f1() {} void f2() { f1(); }"));
+}
Index: include/clang/AST/TypeDataCollectors.td
===
--- include/clang/AST/TypeDataCollectors.td
+++ include/clang/AST/TypeDataCollectors.td
@@ -0,0 +1,78 @@
+//--- Types ---//
+
+class Type {
+  code Code = [{
+ addData(llvm::hash_value(S->getTypeClass()));
+  }];
+}
+
+class BuiltinType {
+   code Code = [{
+  addData(S->getKind());
+   }];
+}
+
+class ArrayType  {
+   code Code = [{
+  addData(S->getSizeModifier());
+  addData(S->getIndexTypeCVRQualifiers());
+   }];
+}
+
+class ConstantArrayType {
+   code Code = [{
+  addData(S->getSize().getZExtValue());
+   }];
+}
+
+class VectorType {
+   code Code = [{
+  addData(S->getNumElements());
+  addData(S->getVectorKind());
+   }];
+}
+
+class FunctionType {
+   code Code = [{
+  addData(S->getRe

[PATCH] D41178: [clangd] Construct SymbolSlab from YAML format.

2017-12-14 Thread Haojian Wu via Phabricator via cfe-commits
hokein updated this revision to Diff 126927.
hokein marked 2 inline comments as done.
hokein added a comment.

MappingTraits is not Symbol's friend.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41178

Files:
  clangd/CMakeLists.txt
  clangd/index/Index.cpp
  clangd/index/Index.h
  clangd/index/SymbolYAML.cpp
  clangd/index/SymbolYAML.h
  unittests/clangd/SymbolCollectorTests.cpp

Index: unittests/clangd/SymbolCollectorTests.cpp
===
--- unittests/clangd/SymbolCollectorTests.cpp
+++ unittests/clangd/SymbolCollectorTests.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include "index/SymbolCollector.h"
+#include "index/SymbolYAML.h"
 #include "clang/Index/IndexingAction.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
@@ -105,6 +106,49 @@
 QName("f1"), QName("f2")));
 }
 
+TEST_F(SymbolCollectorTest, YAMLConversions) {
+  const std::string YAML1 = R"(
+---
+ID: 057557CEBF6E6B2DD437FBF60CC58F352D1DF856
+QualifiedName:   'clang::Foo1'
+SymInfo:
+  Kind:Function
+  Lang:Cpp
+CanonicalDeclaration:
+  StartOffset: 0
+  EndOffset:   1
+  FilePath:/path/foo.h
+...
+)";
+  const std::string YAML2 = R"(
+---
+ID: 057557CEBF6E6B2DD437FBF60CC58F352D1DF858
+QualifiedName:   'clang::Foo2'
+SymInfo:
+  Kind:Function
+  Lang:Cpp
+CanonicalDeclaration:
+  StartOffset: 10
+  EndOffset:   12
+  FilePath:/path/foo.h
+...
+)";
+
+  auto Symbols1 = SymbolFromYAML(YAML1);
+  EXPECT_THAT(Symbols1,
+  UnorderedElementsAre(QName("clang::Foo1")));
+  auto Symbols2 = SymbolFromYAML(YAML2);
+  EXPECT_THAT(Symbols2,
+  UnorderedElementsAre(QName("clang::Foo2")));
+
+  std::string ConcatenatedYAML =
+  SymbolToYAML(Symbols1) + SymbolToYAML(Symbols2);
+  auto ConcatenatedSymbols = SymbolFromYAML(ConcatenatedYAML);
+  EXPECT_THAT(ConcatenatedSymbols,
+  UnorderedElementsAre(QName("clang::Foo1"),
+   QName("clang::Foo2")));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clangd/index/SymbolYAML.h
===
--- /dev/null
+++ clangd/index/SymbolYAML.h
@@ -0,0 +1,37 @@
+//===--- SymbolYAML.h *- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// SymbolYAML provides facilities to convert Symbol to YAML, and vice versa.
+// The YAML format of Symbol is designed for simplicity and experiment, but
+// isn't a suitable/efficient store.
+//
+// This is for **experimental** only. Don't use it in the production code.
+//
+//===-===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
+
+#include "Index.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace clangd {
+
+// Read symbols from a YAML-format string.
+SymbolSlab SymbolFromYAML(llvm::StringRef YAMLContent);
+
+// Convert symbols to a YAML-format string.
+// The YAML result is safe to concatenate if you have multiple symbol slabs.
+std::string SymbolToYAML(const SymbolSlab& Symbols);
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
Index: clangd/index/SymbolYAML.cpp
===
--- /dev/null
+++ clangd/index/SymbolYAML.cpp
@@ -0,0 +1,148 @@
+//===--- SymbolYAML.cpp --*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "SymbolYAML.h"
+
+#include "Index.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Errc.h"
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(clang::clangd::Symbol)
+
+namespace llvm {
+namespace yaml {
+
+using clang::clangd::Symbol;
+using clang::clangd::SymbolID;
+using clang::clangd::SymbolLocation;
+using clang::index::SymbolInfo;
+using clang::index::SymbolLanguage;
+using clang::index::SymbolKind;
+
+// Helper to (de)serialize the SymbolID. We serialize it as a hex string.
+struct NormalizedSymbolID {
+  NormalizedSymbolID(IO &) {}
+  NormalizedSymbolID(IO &, const SymbolID& ID) {
+llvm::raw_string_ostream OS(HexStr

[clang-tools-extra] r320694 - [clangd] Construct SymbolSlab from YAML format.

2017-12-14 Thread Haojian Wu via cfe-commits
Author: hokein
Date: Thu Dec 14 04:17:14 2017
New Revision: 320694

URL: http://llvm.org/viewvc/llvm-project?rev=320694&view=rev
Log:
[clangd] Construct SymbolSlab from YAML format.

Summary: This will be used together with D40548 for the global index source 
(experimental).

Reviewers: sammccall

Reviewed By: sammccall

Subscribers: klimek, mgorny, ilya-biryukov, cfe-commits, ioeric

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

Added:
clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp
clang-tools-extra/trunk/clangd/index/SymbolYAML.h
Modified:
clang-tools-extra/trunk/clangd/CMakeLists.txt
clang-tools-extra/trunk/clangd/index/Index.cpp
clang-tools-extra/trunk/clangd/index/Index.h
clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp

Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CMakeLists.txt?rev=320694&r1=320693&r2=320694&view=diff
==
--- clang-tools-extra/trunk/clangd/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/CMakeLists.txt Thu Dec 14 04:17:14 2017
@@ -22,6 +22,7 @@ add_clang_library(clangDaemon
   index/MemIndex.cpp
   index/Index.cpp
   index/SymbolCollector.cpp
+  index/SymbolYAML.cpp
 
   LINK_LIBS
   clangAST

Modified: clang-tools-extra/trunk/clangd/index/Index.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Index.cpp?rev=320694&r1=320693&r2=320694&view=diff
==
--- clang-tools-extra/trunk/clangd/index/Index.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/Index.cpp Thu Dec 14 04:17:14 2017
@@ -10,18 +10,24 @@
 #include "Index.h"
 
 #include "llvm/Support/SHA1.h"
+#include "llvm/ADT/StringExtras.h"
 
 namespace clang {
 namespace clangd {
 
-namespace {
-ArrayRef toArrayRef(StringRef S) {
-  return {reinterpret_cast(S.data()), S.size()};
+SymbolID::SymbolID(llvm::StringRef USR)
+: HashValue(llvm::SHA1::hash(arrayRefFromStringRef(USR))) {}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolID &ID) {
+  OS << toHex(llvm::toStringRef(ID.HashValue));
+  return OS;
 }
-} // namespace
 
-SymbolID::SymbolID(llvm::StringRef USR)
-: HashValue(llvm::SHA1::hash(toArrayRef(USR))) {}
+void operator>>(llvm::StringRef Str, SymbolID &ID) {
+  std::string HexString = fromHex(Str);
+  assert(HexString.size() == 20);
+  std::copy(HexString.begin(), HexString.end(), ID.HashValue.begin());
+}
 
 SymbolSlab::const_iterator SymbolSlab::begin() const { return Symbols.begin(); 
}
 

Modified: clang-tools-extra/trunk/clangd/index/Index.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Index.h?rev=320694&r1=320693&r2=320694&view=diff
==
--- clang-tools-extra/trunk/clangd/index/Index.h (original)
+++ clang-tools-extra/trunk/clangd/index/Index.h Thu Dec 14 04:17:14 2017
@@ -54,10 +54,22 @@ private:
   friend llvm::hash_code hash_value(const SymbolID &ID) {
 return hash_value(ArrayRef(ID.HashValue));
   }
+  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+   const SymbolID &ID);
+  friend void operator>>(llvm::StringRef Str, SymbolID &ID);
 
   std::array HashValue;
 };
 
+// Write SymbolID into the given stream. SymbolID is encoded as a 40-bytes
+// hex string.
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolID &ID);
+
+// Construct SymbolID from a hex string.
+// The HexStr is required to be a 40-bytes hex string, which is encoded from 
the
+// "<<" operator.
+void operator>>(llvm::StringRef HexStr, SymbolID &ID);
+
 // The class presents a C++ symbol, e.g. class, function.
 //
 // FIXME: instead of having own copy fields for each symbol, we can share

Added: clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp?rev=320694&view=auto
==
--- clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp (added)
+++ clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp Thu Dec 14 04:17:14 2017
@@ -0,0 +1,148 @@
+//===--- SymbolYAML.cpp --*- 
C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "SymbolYAML.h"
+
+#include "Index.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Errc.h"
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(clang::clangd::Symbol)
+
+namespace llvm {
+namespace ya

[PATCH] D41178: [clangd] Construct SymbolSlab from YAML format.

2017-12-14 Thread Haojian Wu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL320694: [clangd] Construct SymbolSlab from YAML format. 
(authored by hokein, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D41178?vs=126927&id=126929#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D41178

Files:
  clang-tools-extra/trunk/clangd/CMakeLists.txt
  clang-tools-extra/trunk/clangd/index/Index.cpp
  clang-tools-extra/trunk/clangd/index/Index.h
  clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp
  clang-tools-extra/trunk/clangd/index/SymbolYAML.h
  clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp

Index: clang-tools-extra/trunk/clangd/index/SymbolYAML.h
===
--- clang-tools-extra/trunk/clangd/index/SymbolYAML.h
+++ clang-tools-extra/trunk/clangd/index/SymbolYAML.h
@@ -0,0 +1,37 @@
+//===--- SymbolYAML.h *- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// SymbolYAML provides facilities to convert Symbol to YAML, and vice versa.
+// The YAML format of Symbol is designed for simplicity and experiment, but
+// isn't a suitable/efficient store.
+//
+// This is for **experimental** only. Don't use it in the production code.
+//
+//===-===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
+
+#include "Index.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace clangd {
+
+// Read symbols from a YAML-format string.
+SymbolSlab SymbolFromYAML(llvm::StringRef YAMLContent);
+
+// Convert symbols to a YAML-format string.
+// The YAML result is safe to concatenate if you have multiple symbol slabs.
+std::string SymbolToYAML(const SymbolSlab& Symbols);
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
Index: clang-tools-extra/trunk/clangd/index/Index.h
===
--- clang-tools-extra/trunk/clangd/index/Index.h
+++ clang-tools-extra/trunk/clangd/index/Index.h
@@ -54,10 +54,22 @@
   friend llvm::hash_code hash_value(const SymbolID &ID) {
 return hash_value(ArrayRef(ID.HashValue));
   }
+  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+   const SymbolID &ID);
+  friend void operator>>(llvm::StringRef Str, SymbolID &ID);
 
   std::array HashValue;
 };
 
+// Write SymbolID into the given stream. SymbolID is encoded as a 40-bytes
+// hex string.
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolID &ID);
+
+// Construct SymbolID from a hex string.
+// The HexStr is required to be a 40-bytes hex string, which is encoded from the
+// "<<" operator.
+void operator>>(llvm::StringRef HexStr, SymbolID &ID);
+
 // The class presents a C++ symbol, e.g. class, function.
 //
 // FIXME: instead of having own copy fields for each symbol, we can share
Index: clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp
===
--- clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp
+++ clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp
@@ -0,0 +1,148 @@
+//===--- SymbolYAML.cpp --*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "SymbolYAML.h"
+
+#include "Index.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Errc.h"
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(clang::clangd::Symbol)
+
+namespace llvm {
+namespace yaml {
+
+using clang::clangd::Symbol;
+using clang::clangd::SymbolID;
+using clang::clangd::SymbolLocation;
+using clang::index::SymbolInfo;
+using clang::index::SymbolLanguage;
+using clang::index::SymbolKind;
+
+// Helper to (de)serialize the SymbolID. We serialize it as a hex string.
+struct NormalizedSymbolID {
+  NormalizedSymbolID(IO &) {}
+  NormalizedSymbolID(IO &, const SymbolID& ID) {
+llvm::raw_string_ostream OS(HexString);
+OS << ID;
+  }
+
+  SymbolID denormalize(IO&) {
+SymbolID ID;
+HexString >> ID;
+return ID;
+  }
+
+  std::string HexString;
+};
+
+template <> struct MappingTraits {
+  static void mapping(IO &IO, SymbolLocation &Value) {
+IO.mapRequired("StartOffset", Value.StartOffset);
+IO.mapRequired("EndOffset", Value.EndOffset);

[clang-tools-extra] r320695 - [clangd] Fix a potential use-after-move bug.

2017-12-14 Thread Eric Liu via cfe-commits
Author: ioeric
Date: Thu Dec 14 04:31:04 2017
New Revision: 320695

URL: http://llvm.org/viewvc/llvm-project?rev=320695&view=rev
Log:
[clangd] Fix a potential use-after-move bug.

Modified:
clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp

Modified: clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp?rev=320695&r1=320694&r2=320695&view=diff
==
--- clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp Thu Dec 14 04:31:04 
2017
@@ -48,7 +48,8 @@ generateNumSymbols(int Begin, int End,
   for (const auto &Sym : Slab->Slab)
 Slab->Pointers.push_back(&Sym.second);
 
-  return {std::move(Slab), &Slab->Pointers};
+  auto *Pointers = &Slab->Pointers;
+  return {std::move(Slab), Pointers};
 }
 
 std::vector match(const SymbolIndex &I,


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


r320696 - [Frontend] Treat function with skipped body as definition

2017-12-14 Thread Ilya Biryukov via cfe-commits
Author: ibiryukov
Date: Thu Dec 14 05:00:33 2017
New Revision: 320696

URL: http://llvm.org/viewvc/llvm-project?rev=320696&view=rev
Log:
[Frontend] Treat function with skipped body as definition

Summary:
This fixes an invalid warning about missing definition of a function when
parsing with SkipFunctionBodies=true

Reviewers: bkramer, sepavloff

Reviewed By: sepavloff

Subscribers: klimek, cfe-commits

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

Added:
cfe/trunk/test/Index/skipped_function_bodies.cpp
Modified:
cfe/trunk/include/clang/AST/Decl.h

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=320696&r1=320695&r2=320696&view=diff
==
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Thu Dec 14 05:00:33 2017
@@ -1967,8 +1967,8 @@ public:
   /// This does not determine whether the function has been defined (e.g., in a
   /// previous definition); for that information, use isDefined.
   bool isThisDeclarationADefinition() const {
-return IsDeleted || IsDefaulted || Body || IsLateTemplateParsed ||
-  WillHaveBody || hasDefiningAttr();
+return IsDeleted || IsDefaulted || Body || HasSkippedBody ||
+   IsLateTemplateParsed || WillHaveBody || hasDefiningAttr();
   }
 
   /// doesThisDeclarationHaveABody - Returns whether this specific

Added: cfe/trunk/test/Index/skipped_function_bodies.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/skipped_function_bodies.cpp?rev=320696&view=auto
==
--- cfe/trunk/test/Index/skipped_function_bodies.cpp (added)
+++ cfe/trunk/test/Index/skipped_function_bodies.cpp Thu Dec 14 05:00:33 2017
@@ -0,0 +1,9 @@
+// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source 
all %s 2>&1 \
+// RUN: | FileCheck %s
+
+inline int with_body() { return 10; }
+inline int without_body();
+
+int x = with_body() + without_body();
+// CHECK: warning: inline function 'without_body' is not defined
+// CHECK-NOT: warning: inline function 'with_body' is not defined


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


[PATCH] D41189: [Frontend] Treat function with skipped body as definition

2017-12-14 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC320696: [Frontend] Treat function with skipped body as 
definition (authored by ibiryukov, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D41189?vs=126787&id=126932#toc

Repository:
  rC Clang

https://reviews.llvm.org/D41189

Files:
  include/clang/AST/Decl.h
  test/Index/skipped_function_bodies.cpp


Index: include/clang/AST/Decl.h
===
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -1967,8 +1967,8 @@
   /// This does not determine whether the function has been defined (e.g., in a
   /// previous definition); for that information, use isDefined.
   bool isThisDeclarationADefinition() const {
-return IsDeleted || IsDefaulted || Body || IsLateTemplateParsed ||
-  WillHaveBody || hasDefiningAttr();
+return IsDeleted || IsDefaulted || Body || HasSkippedBody ||
+   IsLateTemplateParsed || WillHaveBody || hasDefiningAttr();
   }
 
   /// doesThisDeclarationHaveABody - Returns whether this specific
Index: test/Index/skipped_function_bodies.cpp
===
--- test/Index/skipped_function_bodies.cpp
+++ test/Index/skipped_function_bodies.cpp
@@ -0,0 +1,9 @@
+// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source 
all %s 2>&1 \
+// RUN: | FileCheck %s
+
+inline int with_body() { return 10; }
+inline int without_body();
+
+int x = with_body() + without_body();
+// CHECK: warning: inline function 'without_body' is not defined
+// CHECK-NOT: warning: inline function 'with_body' is not defined


Index: include/clang/AST/Decl.h
===
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -1967,8 +1967,8 @@
   /// This does not determine whether the function has been defined (e.g., in a
   /// previous definition); for that information, use isDefined.
   bool isThisDeclarationADefinition() const {
-return IsDeleted || IsDefaulted || Body || IsLateTemplateParsed ||
-  WillHaveBody || hasDefiningAttr();
+return IsDeleted || IsDefaulted || Body || HasSkippedBody ||
+   IsLateTemplateParsed || WillHaveBody || hasDefiningAttr();
   }
 
   /// doesThisDeclarationHaveABody - Returns whether this specific
Index: test/Index/skipped_function_bodies.cpp
===
--- test/Index/skipped_function_bodies.cpp
+++ test/Index/skipped_function_bodies.cpp
@@ -0,0 +1,9 @@
+// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source all %s 2>&1 \
+// RUN: | FileCheck %s
+
+inline int with_body() { return 10; }
+inline int without_body();
+
+int x = with_body() + without_body();
+// CHECK: warning: inline function 'without_body' is not defined
+// CHECK-NOT: warning: inline function 'with_body' is not defined
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r320697 - Warn if we find a Unicode homoglyph for a symbol in an identifier.

2017-12-14 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Thu Dec 14 05:15:08 2017
New Revision: 320697

URL: http://llvm.org/viewvc/llvm-project?rev=320697&view=rev
Log:
Warn if we find a Unicode homoglyph for a symbol in an identifier.

Specifically, warn if:
 * we find a character that the language standard says we must treat as an
   identifier, and
 * that character is not reasonably an identifier character (it's a punctuation
   character or similar), and 
 * it renders identically to a valid non-identifier character in common
   fixed-width fonts.

Some tools "helpfully" substitute the surprising characters for the expected
characters, and replacing semicolons with Greek question marks is a common
"prank".

Modified:
cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
cfe/trunk/lib/Lex/Lexer.cpp
cfe/trunk/test/Lexer/unicode.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=320697&r1=320696&r2=320697&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Thu Dec 14 05:15:08 2017
@@ -119,6 +119,9 @@ def err_non_ascii : Error<
 def ext_unicode_whitespace : ExtWarn<
   "treating Unicode character as whitespace">,
   InGroup>;
+def warn_utf8_symbol_homoglyph : Warning<
+  "treating Unicode character  as identifier character rather than "
+  "as '%1' symbol">, InGroup>;
 
 def err_hex_escape_no_digits : Error<
   "\\%0 used with no following hex digits">;

Modified: cfe/trunk/lib/Lex/Lexer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=320697&r1=320696&r2=320697&view=diff
==
--- cfe/trunk/lib/Lex/Lexer.cpp (original)
+++ cfe/trunk/lib/Lex/Lexer.cpp Thu Dec 14 05:15:08 2017
@@ -37,6 +37,7 @@
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/NativeFormatting.h"
 #include "llvm/Support/UnicodeCharRanges.h"
 #include 
 #include 
@@ -1500,6 +1501,75 @@ static void maybeDiagnoseIDCharCompat(Di
   }
 }
 
+/// After encountering UTF-8 character C and interpreting it as an identifier
+/// character, check whether it's a homoglyph for a common non-identifier
+/// source character that is unlikely to be an intentional identifier
+/// character and warn if so.
+static void maybeDiagnoseUTF8Homoglyph(DiagnosticsEngine &Diags, uint32_t C,
+   CharSourceRange Range) {
+  // FIXME: Handle Unicode quotation marks (smart quotes, fullwidth quotes).
+  struct HomoglyphPair {
+uint32_t Character;
+char LooksLike;
+bool operator<(HomoglyphPair R) const { return Character < R.Character; }
+  };
+  static constexpr HomoglyphPair SortedHomoglyphs[] = {
+{U'\u01c3', '!'}, // LATIN LETTER RETROFLEX CLICK
+{U'\u037e', ';'}, // GREEK QUESTION MARK
+{U'\u2212', '-'}, // MINUS SIGN
+{U'\u2215', '/'}, // DIVISION SLASH
+{U'\u2216', '\\'}, // SET MINUS
+{U'\u2217', '*'}, // ASTERISK OPERATOR
+{U'\u2223', '|'}, // DIVIDES
+{U'\u2227', '^'}, // LOGICAL AND
+{U'\u2236', ':'}, // RATIO
+{U'\u223c', '~'}, // TILDE OPERATOR
+{U'\ua789', ':'}, // MODIFIER LETTER COLON
+{U'\uff01', '!'}, // FULLWIDTH EXCLAMATION MARK
+{U'\uff03', '#'}, // FULLWIDTH NUMBER SIGN
+{U'\uff04', '$'}, // FULLWIDTH DOLLAR SIGN
+{U'\uff05', '%'}, // FULLWIDTH PERCENT SIGN
+{U'\uff06', '&'}, // FULLWIDTH AMPERSAND
+{U'\uff08', '('}, // FULLWIDTH LEFT PARENTHESIS
+{U'\uff09', ')'}, // FULLWIDTH RIGHT PARENTHESIS
+{U'\uff0a', '*'}, // FULLWIDTH ASTERISK
+{U'\uff0b', '+'}, // FULLWIDTH ASTERISK
+{U'\uff0c', ','}, // FULLWIDTH COMMA
+{U'\uff0d', '-'}, // FULLWIDTH HYPHEN-MINUS
+{U'\uff0e', '.'}, // FULLWIDTH FULL STOP
+{U'\uff0f', '/'}, // FULLWIDTH SOLIDUS
+{U'\uff1a', ':'}, // FULLWIDTH COLON
+{U'\uff1b', ';'}, // FULLWIDTH SEMICOLON
+{U'\uff1c', '<'}, // FULLWIDTH LESS-THAN SIGN
+{U'\uff1d', '='}, // FULLWIDTH EQUALS SIGN
+{U'\uff1e', '>'}, // FULLWIDTH GREATER-THAN SIGN
+{U'\uff1f', '?'}, // FULLWIDTH QUESTION MARK
+{U'\uff20', '@'}, // FULLWIDTH COMMERCIAL AT
+{U'\uff3b', '['}, // FULLWIDTH LEFT SQUARE BRACKET
+{U'\uff3c', '\\'}, // FULLWIDTH REVERSE SOLIDUS
+{U'\uff3d', ']'}, // FULLWIDTH RIGHT SQUARE BRACKET
+{U'\uff3e', '^'}, // FULLWIDTH CIRCUMFLEX ACCENT
+{U'\uff5b', '{'}, // FULLWIDTH LEFT CURLY BRACKET
+{U'\uff5c', '|'}, // FULLWIDTH VERTICAL LINE
+{U'\uff5d', '}'}, // FULLWIDTH RIGHT CURLY BRACKET
+{U'\uff5e', '~'}, // FULLWIDTH TILDE
+{0, 0}
+  };
+  auto Homoglyph =
+  std::lower_bound(std::begin(SortedHomoglyphs),
+   std::end(SortedHomoglyphs) - 1, HomoglyphPair{C, '\0'});
+  if (Homoglyph->Charac

Re: r320697 - Warn if we find a Unicode homoglyph for a symbol in an identifier.

2017-12-14 Thread Aaron Ballman via cfe-commits
On Thu, Dec 14, 2017 at 8:15 AM, Richard Smith via cfe-commits
 wrote:
> Author: rsmith
> Date: Thu Dec 14 05:15:08 2017
> New Revision: 320697
>
> URL: http://llvm.org/viewvc/llvm-project?rev=320697&view=rev
> Log:
> Warn if we find a Unicode homoglyph for a symbol in an identifier.
>
> Specifically, warn if:
>  * we find a character that the language standard says we must treat as an
>identifier, and
>  * that character is not reasonably an identifier character (it's a 
> punctuation
>character or similar), and
>  * it renders identically to a valid non-identifier character in common
>fixed-width fonts.
>
> Some tools "helpfully" substitute the surprising characters for the expected
> characters, and replacing semicolons with Greek question marks is a common
> "prank".
>
> Modified:
> cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
> cfe/trunk/lib/Lex/Lexer.cpp
> cfe/trunk/test/Lexer/unicode.c
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=320697&r1=320696&r2=320697&view=diff
> ==
> --- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Thu Dec 14 05:15:08 
> 2017
> @@ -119,6 +119,9 @@ def err_non_ascii : Error<
>  def ext_unicode_whitespace : ExtWarn<
>"treating Unicode character as whitespace">,
>InGroup>;
> +def warn_utf8_symbol_homoglyph : Warning<
> +  "treating Unicode character  as identifier character rather than "
> +  "as '%1' symbol">, InGroup>;

Can this wording be tweaked slightly to "as an identifier character"
or does that cause too much of an "a/an" problem with "as %1 symbol"?

~Aaron

>
>  def err_hex_escape_no_digits : Error<
>"\\%0 used with no following hex digits">;
>
> Modified: cfe/trunk/lib/Lex/Lexer.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=320697&r1=320696&r2=320697&view=diff
> ==
> --- cfe/trunk/lib/Lex/Lexer.cpp (original)
> +++ cfe/trunk/lib/Lex/Lexer.cpp Thu Dec 14 05:15:08 2017
> @@ -37,6 +37,7 @@
>  #include "llvm/Support/ConvertUTF.h"
>  #include "llvm/Support/MathExtras.h"
>  #include "llvm/Support/MemoryBuffer.h"
> +#include "llvm/Support/NativeFormatting.h"
>  #include "llvm/Support/UnicodeCharRanges.h"
>  #include 
>  #include 
> @@ -1500,6 +1501,75 @@ static void maybeDiagnoseIDCharCompat(Di
>}
>  }
>
> +/// After encountering UTF-8 character C and interpreting it as an identifier
> +/// character, check whether it's a homoglyph for a common non-identifier
> +/// source character that is unlikely to be an intentional identifier
> +/// character and warn if so.
> +static void maybeDiagnoseUTF8Homoglyph(DiagnosticsEngine &Diags, uint32_t C,
> +   CharSourceRange Range) {
> +  // FIXME: Handle Unicode quotation marks (smart quotes, fullwidth quotes).
> +  struct HomoglyphPair {
> +uint32_t Character;
> +char LooksLike;
> +bool operator<(HomoglyphPair R) const { return Character < R.Character; }
> +  };
> +  static constexpr HomoglyphPair SortedHomoglyphs[] = {
> +{U'\u01c3', '!'}, // LATIN LETTER RETROFLEX CLICK
> +{U'\u037e', ';'}, // GREEK QUESTION MARK
> +{U'\u2212', '-'}, // MINUS SIGN
> +{U'\u2215', '/'}, // DIVISION SLASH
> +{U'\u2216', '\\'}, // SET MINUS
> +{U'\u2217', '*'}, // ASTERISK OPERATOR
> +{U'\u2223', '|'}, // DIVIDES
> +{U'\u2227', '^'}, // LOGICAL AND
> +{U'\u2236', ':'}, // RATIO
> +{U'\u223c', '~'}, // TILDE OPERATOR
> +{U'\ua789', ':'}, // MODIFIER LETTER COLON
> +{U'\uff01', '!'}, // FULLWIDTH EXCLAMATION MARK
> +{U'\uff03', '#'}, // FULLWIDTH NUMBER SIGN
> +{U'\uff04', '$'}, // FULLWIDTH DOLLAR SIGN
> +{U'\uff05', '%'}, // FULLWIDTH PERCENT SIGN
> +{U'\uff06', '&'}, // FULLWIDTH AMPERSAND
> +{U'\uff08', '('}, // FULLWIDTH LEFT PARENTHESIS
> +{U'\uff09', ')'}, // FULLWIDTH RIGHT PARENTHESIS
> +{U'\uff0a', '*'}, // FULLWIDTH ASTERISK
> +{U'\uff0b', '+'}, // FULLWIDTH ASTERISK
> +{U'\uff0c', ','}, // FULLWIDTH COMMA
> +{U'\uff0d', '-'}, // FULLWIDTH HYPHEN-MINUS
> +{U'\uff0e', '.'}, // FULLWIDTH FULL STOP
> +{U'\uff0f', '/'}, // FULLWIDTH SOLIDUS
> +{U'\uff1a', ':'}, // FULLWIDTH COLON
> +{U'\uff1b', ';'}, // FULLWIDTH SEMICOLON
> +{U'\uff1c', '<'}, // FULLWIDTH LESS-THAN SIGN
> +{U'\uff1d', '='}, // FULLWIDTH EQUALS SIGN
> +{U'\uff1e', '>'}, // FULLWIDTH GREATER-THAN SIGN
> +{U'\uff1f', '?'}, // FULLWIDTH QUESTION MARK
> +{U'\uff20', '@'}, // FULLWIDTH COMMERCIAL AT
> +{U'\uff3b', '['}, // FULLWIDTH LEFT SQUARE BRACKET
> +{U'\uff3c', '\\'}, // FULLWIDTH REVERSE SOLIDUS
> +{U'\uff3d', ']'}, // FULLWIDTH RIGHT SQUARE BRACKET
> +{U'\uff3e', '^'}, 

[PATCH] D41232: [clangd] Add a FileSymbols container that manages symbols from multiple files.

2017-12-14 Thread Eric Liu via Phabricator via cfe-commits
ioeric created this revision.
ioeric added a reviewer: sammccall.
Herald added subscribers: cfe-commits, ilya-biryukov, mgorny, klimek.

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41232

Files:
  clangd/CMakeLists.txt
  clangd/index/FileSymbols.cpp
  clangd/index/FileSymbols.h
  unittests/clangd/IndexTests.cpp

Index: unittests/clangd/IndexTests.cpp
===
--- unittests/clangd/IndexTests.cpp
+++ unittests/clangd/IndexTests.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 
+#include "index/FileSymbols.h"
 #include "index/Index.h"
 #include "index/MemIndex.h"
 #include "gmock/gmock.h"
@@ -31,6 +32,11 @@
   std::vector Pointers;
 };
 
+void addNumSymbolsToSlab(int Begin, int End, SymbolSlab *Slab) {
+  for (int i = Begin; i <= End; i++)
+Slab->insert(symbol(std::to_string(i)));
+}
+
 // Create a slab of symbols with IDs and names [Begin, End]. The life time of
 // the slab is managed by the returned shared pointer. If \p WeakSymbols is
 // provided, it will be pointed to the managed object in the returned shared
@@ -42,9 +48,7 @@
   if (WeakSymbols)
 *WeakSymbols = Slab;
 
-  for (int i = Begin; i <= End; i++)
-Slab->Slab.insert(symbol(std::to_string(i)));
-
+  addNumSymbolsToSlab(Begin, End, &Slab->Slab);
   for (const auto &Sym : Slab->Slab)
 Slab->Pointers.push_back(&Sym.second);
 
@@ -61,6 +65,13 @@
   return Matches;
 }
 
+std::vector getSymbolNames(const std::vector &Symbols) {
+  std::vector Names;
+  for (const Symbol *Sym : Symbols)
+Names.push_back(Sym->QualifiedName);
+  return Names;
+}
+
 TEST(MemIndexTest, MemIndexSymbolsRecycled) {
   MemIndex I;
   std::weak_ptr Symbols;
@@ -110,6 +121,53 @@
   EXPECT_EQ(Matches.size(), Req.MaxCandidateCount);
 }
 
+TEST(FileSymbolsTest, UpdateAndGet) {
+  FileSymbols FS;
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()), UnorderedElementsAre());
+
+  auto Slab = llvm::make_unique();
+  addNumSymbolsToSlab(1, 3, Slab.get());
+
+  FS.update("f1", std::move(Slab));
+
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()),
+  UnorderedElementsAre("1", "2", "3"));
+}
+
+TEST(FileSymbolsTest, Overlap) {
+  FileSymbols FS;
+
+  auto Slab = llvm::make_unique();
+  addNumSymbolsToSlab(1, 3, Slab.get());
+
+  FS.update("f1", std::move(Slab));
+
+  Slab = llvm::make_unique();
+  addNumSymbolsToSlab(3, 5, Slab.get());
+
+  FS.update("f2", std::move(Slab));
+
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()),
+  UnorderedElementsAre("1", "2", "3", "3", "4", "5"));
+}
+
+TEST(FileSymbolsTest, SnapshotAliveAfterRemove) {
+  FileSymbols FS;
+
+  auto Slab = llvm::make_unique();
+  addNumSymbolsToSlab(1, 3, Slab.get());
+
+  FS.update("f1", std::move(Slab));
+
+  auto Symbols = FS.allSymbols();
+  EXPECT_THAT(getSymbolNames(*Symbols), UnorderedElementsAre("1", "2", "3"));
+
+  FS.remove("f1");
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()), UnorderedElementsAre());
+
+  EXPECT_THAT(getSymbolNames(*Symbols), UnorderedElementsAre("1", "2", "3"));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clangd/index/FileSymbols.h
===
--- /dev/null
+++ clangd/index/FileSymbols.h
@@ -0,0 +1,55 @@
+//===--- FileSymbols.h - Symbols from files. -*- 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_TOOLS_EXTRA_CLANGD_INDEX_FILEINDEX_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILEINDEX_H
+
+#include "../Path.h"
+#include "Index.h"
+#include "llvm/ADT/StringMap.h"
+#include 
+
+namespace clang {
+namespace clangd {
+
+/// \brief A container of Symbols from several source files. It can be updated
+/// at source-file granularity, replacing all symbols from one file with a new
+/// set.
+///
+/// This implements a snapshot semantics for symbols in a file. Each update to a
+/// file will create a new snapshot for all symbols in the file. Snapshots are
+/// managed with shared pointers that are shared between this class and the
+/// users. For each file, this class only stores a pointer pointing to the
+/// newest snapshot, and an outdated snapshot is deleted by the last owner of
+/// the snapshot, either this class or the symbol index.
+///
+/// The snapshot semantics keeps critical sections minimal since we only need
+/// locking when we swap or obtain refereces to snapshots.
+class FileSymbols {
+public:
+  /// \brief Updates all symbols in a file.
+  void update(PathRef Path, std::unique_ptr Slab);
+
+  /// \brief Removes snapshots of \p Path.
+  void remove(PathRef Path);
+
+  // The shared_ptr keeps the symbols alive
+  std::shared_ptr> allSymbols();
+
+private:
+  m

[PATCH] D41102: Setup clang-doc frontend framework

2017-12-14 Thread Jonas Devlieghere via Phabricator via cfe-commits
JDevlieghere added inline comments.



Comment at: tools/clang-doc/ClangDoc.h:40
+
+  void ParseUnattachedComments();
+  bool ParseNewDecl(const NamedDecl *D);

I know it's confusing given the amount of existing code that uses 
UpperCamelCase for functions, but I think that (as this is new code) we'd want 
to stay close to the style guide and use lowerCamelCase where we can. 



Comment at: tools/clang-doc/ClangDocReporter.h:35
+
+struct StringPair {
+  std::string Key;

Do you still need this?



Comment at: tools/clang-doc/tool/ClangDocMain.cpp:43
+  doc::OutFormat EmitFormat;
+  EmitLLVM ? EmitFormat = clang::doc::OutFormat::LLVM
+   : EmitFormat = clang::doc::OutFormat::YAML;

I'm curious if there's a particular reason that you seems to prefer

```
EmitLLVM ? EmitFormat = clang::doc::OutFormat::LLVM
 : EmitFormat = clang::doc::OutFormat::YAML;
```

over

```
EmitFormat = EmitLLVM ? clang::doc::OutFormat::LLVM
  : clang::doc::OutFormat::YAML;
```


https://reviews.llvm.org/D41102



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


[PATCH] D41102: Setup clang-doc frontend framework

2017-12-14 Thread Jonas Devlieghere via Phabricator via cfe-commits
JDevlieghere added a comment.

I don't know what basis is used to differentiate between the two, but should 
this be part of clang tools or clang-tools-extra?


https://reviews.llvm.org/D41102



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


[PATCH] D41232: [clangd] Add a FileSymbols container that manages symbols from multiple files.

2017-12-14 Thread Sam McCall via Phabricator via cfe-commits
sammccall accepted this revision.
sammccall added inline comments.
This revision is now accepted and ready to land.



Comment at: clangd/index/FileSymbols.h:39
+
+  /// \brief Removes snapshots of \p Path.
+  void remove(PathRef Path);

Consider just accepting `update(Path, nullptr)` for this (or make callers pass 
an empty slab).
This can make callsites that might call one or the other conditionally, less 
awkward.



Comment at: unittests/clangd/IndexTests.cpp:124
 
+TEST(FileSymbolsTest, UpdateAndGet) {
+  FileSymbols FS;

Can you move these tests into a separate cpp file?
The code overlap is really minimal, and they test things from different headers.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41232



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


[PATCH] D35894: [clangd] Code hover for Clangd

2017-12-14 Thread Marc-Andre Laperle via Phabricator via cfe-commits
malaperle requested changes to this revision.
malaperle added a comment.
This revision now requires changes to proceed.
Herald added a subscriber: mgrang.

Needs to be rebased.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D35894



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


[PATCH] D41224: [ThreadSafetyAnalysis] Fix isCapabilityExpr

2017-12-14 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added a comment.

Hi.
I don't want to hijack the thread, but is PR32954 
 likely unrelated to this fix, and 
the problem (if it is a bug) is likely elsewhere?


Repository:
  rC Clang

https://reviews.llvm.org/D41224



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


[PATCH] D41232: [clangd] Add a FileSymbols container that manages symbols from multiple files.

2017-12-14 Thread Eric Liu via Phabricator via cfe-commits
ioeric updated this revision to Diff 126943.
ioeric marked 2 inline comments as done.
ioeric added a comment.

- Address review comments


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41232

Files:
  clangd/CMakeLists.txt
  clangd/index/FileSymbols.cpp
  clangd/index/FileSymbols.h
  unittests/clangd/CMakeLists.txt
  unittests/clangd/FileSymbolsTests.cpp

Index: unittests/clangd/FileSymbolsTests.cpp
===
--- /dev/null
+++ unittests/clangd/FileSymbolsTests.cpp
@@ -0,0 +1,91 @@
+//===-- FileSymbolsTests.cpp  -*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "index/FileSymbols.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using testing::UnorderedElementsAre;
+
+namespace clang {
+namespace clangd {
+
+namespace {
+
+Symbol symbol(llvm::StringRef ID) {
+  Symbol Sym;
+  Sym.ID = SymbolID(ID);
+  Sym.QualifiedName = ID;
+  return Sym;
+}
+
+void addNumSymbolsToSlab(int Begin, int End, SymbolSlab *Slab) {
+  for (int i = Begin; i <= End; i++)
+Slab->insert(symbol(std::to_string(i)));
+}
+
+std::vector
+getSymbolNames(const std::vector &Symbols) {
+  std::vector Names;
+  for (const Symbol *Sym : Symbols)
+Names.push_back(Sym->QualifiedName);
+  return Names;
+}
+
+TEST(FileSymbolsTest, UpdateAndGet) {
+  FileSymbols FS;
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()), UnorderedElementsAre());
+
+  auto Slab = llvm::make_unique();
+  addNumSymbolsToSlab(1, 3, Slab.get());
+
+  FS.update("f1", std::move(Slab));
+
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()),
+  UnorderedElementsAre("1", "2", "3"));
+}
+
+TEST(FileSymbolsTest, Overlap) {
+  FileSymbols FS;
+
+  auto Slab = llvm::make_unique();
+  addNumSymbolsToSlab(1, 3, Slab.get());
+
+  FS.update("f1", std::move(Slab));
+
+  Slab = llvm::make_unique();
+  addNumSymbolsToSlab(3, 5, Slab.get());
+
+  FS.update("f2", std::move(Slab));
+
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()),
+  UnorderedElementsAre("1", "2", "3", "3", "4", "5"));
+}
+
+TEST(FileSymbolsTest, SnapshotAliveAfterRemove) {
+  FileSymbols FS;
+
+  auto Slab = llvm::make_unique();
+  addNumSymbolsToSlab(1, 3, Slab.get());
+
+  FS.update("f1", std::move(Slab));
+
+  auto Symbols = FS.allSymbols();
+  EXPECT_THAT(getSymbolNames(*Symbols), UnorderedElementsAre("1", "2", "3"));
+
+  FS.update("f1", nullptr);
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()), UnorderedElementsAre());
+
+  EXPECT_THAT(getSymbolNames(*Symbols), UnorderedElementsAre("1", "2", "3"));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
+
Index: unittests/clangd/CMakeLists.txt
===
--- unittests/clangd/CMakeLists.txt
+++ unittests/clangd/CMakeLists.txt
@@ -12,6 +12,7 @@
   ClangdTests.cpp
   CodeCompleteTests.cpp
   ContextTests.cpp
+  FileSymbolsTests.cpp
   FuzzyMatchTests.cpp
   IndexTests.cpp
   JSONExprTests.cpp
Index: clangd/index/FileSymbols.h
===
--- /dev/null
+++ clangd/index/FileSymbols.h
@@ -0,0 +1,53 @@
+//===--- FileSymbols.h - Symbols from files. -*- 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_TOOLS_EXTRA_CLANGD_INDEX_FILEINDEX_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILEINDEX_H
+
+#include "../Path.h"
+#include "Index.h"
+#include "llvm/ADT/StringMap.h"
+#include 
+
+namespace clang {
+namespace clangd {
+
+/// \brief A container of Symbols from several source files. It can be updated
+/// at source-file granularity, replacing all symbols from one file with a new
+/// set.
+///
+/// This implements a snapshot semantics for symbols in a file. Each update to a
+/// file will create a new snapshot for all symbols in the file. Snapshots are
+/// managed with shared pointers that are shared between this class and the
+/// users. For each file, this class only stores a pointer pointing to the
+/// newest snapshot, and an outdated snapshot is deleted by the last owner of
+/// the snapshot, either this class or the symbol index.
+///
+/// The snapshot semantics keeps critical sections minimal since we only need
+/// locking when we swap or obtain refereces to snapshots.
+class FileSymbols {
+public:
+  /// \brief Updates all symbols in a file. If \p Slab is nullptr, symbols for
+  /// \p Path will be removed.
+  void update(PathRef Path, std::unique_ptr Slab);
+
+  // The shared_ptr keeps the symbols 

[PATCH] D40072: [libclang] Support querying whether a declaration is invalid

2017-12-14 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik added a comment.

Ping... "Please submit as I don't have the permissions."


https://reviews.llvm.org/D40072



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


[PATCH] D40561: [libclang] Fix cursors for functions with trailing return type

2017-12-14 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik added a comment.

Ping..."Please submit as I don't have the permissions for this."


https://reviews.llvm.org/D40561



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


[PATCH] D41232: [clangd] Add a FileSymbols container that manages symbols from multiple files.

2017-12-14 Thread Eric Liu via Phabricator via cfe-commits
ioeric updated this revision to Diff 126944.
ioeric added a comment.

- fix HEADER_GUARD


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41232

Files:
  clangd/CMakeLists.txt
  clangd/index/FileSymbols.cpp
  clangd/index/FileSymbols.h
  unittests/clangd/CMakeLists.txt
  unittests/clangd/FileSymbolsTests.cpp

Index: unittests/clangd/FileSymbolsTests.cpp
===
--- /dev/null
+++ unittests/clangd/FileSymbolsTests.cpp
@@ -0,0 +1,91 @@
+//===-- FileSymbolsTests.cpp  -*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "index/FileSymbols.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using testing::UnorderedElementsAre;
+
+namespace clang {
+namespace clangd {
+
+namespace {
+
+Symbol symbol(llvm::StringRef ID) {
+  Symbol Sym;
+  Sym.ID = SymbolID(ID);
+  Sym.QualifiedName = ID;
+  return Sym;
+}
+
+void addNumSymbolsToSlab(int Begin, int End, SymbolSlab *Slab) {
+  for (int i = Begin; i <= End; i++)
+Slab->insert(symbol(std::to_string(i)));
+}
+
+std::vector
+getSymbolNames(const std::vector &Symbols) {
+  std::vector Names;
+  for (const Symbol *Sym : Symbols)
+Names.push_back(Sym->QualifiedName);
+  return Names;
+}
+
+TEST(FileSymbolsTest, UpdateAndGet) {
+  FileSymbols FS;
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()), UnorderedElementsAre());
+
+  auto Slab = llvm::make_unique();
+  addNumSymbolsToSlab(1, 3, Slab.get());
+
+  FS.update("f1", std::move(Slab));
+
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()),
+  UnorderedElementsAre("1", "2", "3"));
+}
+
+TEST(FileSymbolsTest, Overlap) {
+  FileSymbols FS;
+
+  auto Slab = llvm::make_unique();
+  addNumSymbolsToSlab(1, 3, Slab.get());
+
+  FS.update("f1", std::move(Slab));
+
+  Slab = llvm::make_unique();
+  addNumSymbolsToSlab(3, 5, Slab.get());
+
+  FS.update("f2", std::move(Slab));
+
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()),
+  UnorderedElementsAre("1", "2", "3", "3", "4", "5"));
+}
+
+TEST(FileSymbolsTest, SnapshotAliveAfterRemove) {
+  FileSymbols FS;
+
+  auto Slab = llvm::make_unique();
+  addNumSymbolsToSlab(1, 3, Slab.get());
+
+  FS.update("f1", std::move(Slab));
+
+  auto Symbols = FS.allSymbols();
+  EXPECT_THAT(getSymbolNames(*Symbols), UnorderedElementsAre("1", "2", "3"));
+
+  FS.update("f1", nullptr);
+  EXPECT_THAT(getSymbolNames(*FS.allSymbols()), UnorderedElementsAre());
+
+  EXPECT_THAT(getSymbolNames(*Symbols), UnorderedElementsAre("1", "2", "3"));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
+
Index: unittests/clangd/CMakeLists.txt
===
--- unittests/clangd/CMakeLists.txt
+++ unittests/clangd/CMakeLists.txt
@@ -12,6 +12,7 @@
   ClangdTests.cpp
   CodeCompleteTests.cpp
   ContextTests.cpp
+  FileSymbolsTests.cpp
   FuzzyMatchTests.cpp
   IndexTests.cpp
   JSONExprTests.cpp
Index: clangd/index/FileSymbols.h
===
--- /dev/null
+++ clangd/index/FileSymbols.h
@@ -0,0 +1,53 @@
+//===--- FileSymbols.h - Symbols from files. -*- 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_TOOLS_EXTRA_CLANGD_INDEX_FILESYMBOLS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILESYMBOLS_H
+
+#include "../Path.h"
+#include "Index.h"
+#include "llvm/ADT/StringMap.h"
+#include 
+
+namespace clang {
+namespace clangd {
+
+/// \brief A container of Symbols from several source files. It can be updated
+/// at source-file granularity, replacing all symbols from one file with a new
+/// set.
+///
+/// This implements a snapshot semantics for symbols in a file. Each update to a
+/// file will create a new snapshot for all symbols in the file. Snapshots are
+/// managed with shared pointers that are shared between this class and the
+/// users. For each file, this class only stores a pointer pointing to the
+/// newest snapshot, and an outdated snapshot is deleted by the last owner of
+/// the snapshot, either this class or the symbol index.
+///
+/// The snapshot semantics keeps critical sections minimal since we only need
+/// locking when we swap or obtain refereces to snapshots.
+class FileSymbols {
+public:
+  /// \brief Updates all symbols in a file. If \p Slab is nullptr, symbols for
+  /// \p Path will be removed.
+  void update(PathRef Path, std::unique_ptr Slab);
+
+  // The shared_ptr keeps the symbols alive
+  std::shared_ptr> allSymbols();
+
+p

[PATCH] D41050: Fix over-release of return value of lambda implicitly converted to block/function pointer

2017-12-14 Thread Dan Zimmerman via Phabricator via cfe-commits
danzimm added a comment.

@dexonsmith Here are my results after passing those extra flags with `-O3` 
(/Users/danzimm/oss/build/bin/clang -cc1 -internal-isystem 
/Users/danzimm/oss/build/lib/clang/6.0.0/include -nostdsysteminc -triple 
x86_64-apple-macosx10.12.0 -emit-llvm -disable-llvm-passes -O3 -fblocks 
-fobjc-arc -fobjc-runtime-has-weak -std=c++11 -mllvm -debug-pass=Executions -o 
~/foo.ll 
/Users/danzimm/oss/llvm/tools/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm):

  Pass Arguments:  -tti
  Target Transform Information
FunctionPass Manager
  Pass Arguments:  -tti
  Target Transform Information
ModulePass Manager
  Print Module IR
  [2017-12-14 09:47:12.252472000] 0x7f87b90016f0   Executing Pass 'Print Module 
IR' on Module 
'/Users/danzimm/oss/llvm/tools/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm'...
  [2017-12-14 09:47:12.254702000] 0x7f87b90016f0Freeing Pass 'Print Module 
IR' on Module 
'/Users/danzimm/oss/llvm/tools/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm'...
  Pass Arguments:  -tti
  Target Transform Information
ModulePass Manager

and with `-O0` (/Users/danzimm/oss/build/bin/clang -cc1 -internal-isystem 
/Users/danzimm/oss/build/lib/clang/6.0.0/include -nostdsysteminc -triple 
x86_64-apple-macosx10.12.0 -emit-llvm -disable-llvm-passes -O0 -fblocks 
-fobjc-arc -fobjc-runtime-has-weak -std=c++11 -mllvm -debug-pass=Executions -o 
~/foo.ll 
/Users/danzimm/oss/llvm/tools/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm):

  Pass Arguments:  -tti
  Target Transform Information
FunctionPass Manager
  Pass Arguments:  -tti
  Target Transform Information
ModulePass Manager
  Print Module IR
  [2017-12-14 09:47:20.884147000] 0x7ff71ed097d0   Executing Pass 'Print Module 
IR' on Module 
'/Users/danzimm/oss/llvm/tools/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm'...
  [2017-12-14 09:47:20.886182000] 0x7ff71ed097d0Freeing Pass 'Print Module 
IR' on Module 
'/Users/danzimm/oss/llvm/tools/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm'...
  Pass Arguments:  -tti
  Target Transform Information
ModulePass Manager


Repository:
  rC Clang

https://reviews.llvm.org/D41050



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


[PATCH] D39903: [libclang] Allow pretty printing declarations

2017-12-14 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik added a comment.

Ping.


Repository:
  rC Clang

https://reviews.llvm.org/D39903



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


[PATCH] D40481: [libclang] Fix cursors for arguments of Subscript and Call operators

2017-12-14 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik added a comment.

Ping.


https://reviews.llvm.org/D40481



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


[clang-tools-extra] r320701 - [clangd] Add a FileSymbols container that manages symbols from multiple files.

2017-12-14 Thread Eric Liu via cfe-commits
Author: ioeric
Date: Thu Dec 14 06:50:58 2017
New Revision: 320701

URL: http://llvm.org/viewvc/llvm-project?rev=320701&view=rev
Log:
[clangd] Add a FileSymbols container that manages symbols from multiple files.

Reviewers: sammccall

Reviewed By: sammccall

Subscribers: klimek, mgorny, ilya-biryukov, cfe-commits

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

Added:
clang-tools-extra/trunk/clangd/index/FileSymbols.cpp
clang-tools-extra/trunk/clangd/index/FileSymbols.h
clang-tools-extra/trunk/unittests/clangd/FileSymbolsTests.cpp
Modified:
clang-tools-extra/trunk/clangd/CMakeLists.txt
clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt

Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CMakeLists.txt?rev=320701&r1=320700&r2=320701&view=diff
==
--- clang-tools-extra/trunk/clangd/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/CMakeLists.txt Thu Dec 14 06:50:58 2017
@@ -19,8 +19,9 @@ add_clang_library(clangDaemon
   Protocol.cpp
   ProtocolHandlers.cpp
   Trace.cpp
-  index/MemIndex.cpp
+  index/FileSymbols.cpp
   index/Index.cpp
+  index/MemIndex.cpp
   index/SymbolCollector.cpp
   index/SymbolYAML.cpp
 

Added: clang-tools-extra/trunk/clangd/index/FileSymbols.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/FileSymbols.cpp?rev=320701&view=auto
==
--- clang-tools-extra/trunk/clangd/index/FileSymbols.cpp (added)
+++ clang-tools-extra/trunk/clangd/index/FileSymbols.cpp Thu Dec 14 06:50:58 
2017
@@ -0,0 +1,48 @@
+//===--- FileSymbols.cpp - Symbols from files. --*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "FileSymbols.h"
+#include "clang/Index/IndexingAction.h"
+
+namespace clang {
+namespace clangd {
+
+void FileSymbols::update(PathRef Path, std::unique_ptr Slab) {
+  std::lock_guard Lock(Mutex);
+  if (!Slab)
+FileToSlabs.erase(Path);
+  else
+FileToSlabs[Path] = std::shared_ptr(Slab.release());
+}
+
+std::shared_ptr> FileSymbols::allSymbols() {
+  // The snapshot manages life time of symbol slabs and provides pointers of 
all
+  // symbols in all slabs.
+  struct Snapshot {
+std::vector Pointers;
+std::vector> KeepAlive;
+  };
+  auto Snap = std::make_shared();
+  {
+std::lock_guard Lock(Mutex);
+
+for (const auto &FileAndSlab : FileToSlabs) {
+  Snap->KeepAlive.push_back(FileAndSlab.second);
+  for (const auto &Iter : *FileAndSlab.second)
+Snap->Pointers.push_back(&Iter.second);
+}
+  }
+  auto *Pointers = &Snap->Pointers;
+  // Use aliasing constructor to keep the snapshot alive along with the
+  // pointers.
+  return {std::move(Snap), Pointers};
+}
+
+} // namespace clangd
+} // namespace clang

Added: clang-tools-extra/trunk/clangd/index/FileSymbols.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/FileSymbols.h?rev=320701&view=auto
==
--- clang-tools-extra/trunk/clangd/index/FileSymbols.h (added)
+++ clang-tools-extra/trunk/clangd/index/FileSymbols.h Thu Dec 14 06:50:58 2017
@@ -0,0 +1,53 @@
+//===--- FileSymbols.h - Symbols from files. -*- 
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_TOOLS_EXTRA_CLANGD_INDEX_FILESYMBOLS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILESYMBOLS_H
+
+#include "../Path.h"
+#include "Index.h"
+#include "llvm/ADT/StringMap.h"
+#include 
+
+namespace clang {
+namespace clangd {
+
+/// \brief A container of Symbols from several source files. It can be updated
+/// at source-file granularity, replacing all symbols from one file with a new
+/// set.
+///
+/// This implements a snapshot semantics for symbols in a file. Each update to 
a
+/// file will create a new snapshot for all symbols in the file. Snapshots are
+/// managed with shared pointers that are shared between this class and the
+/// users. For each file, this class only stores a pointer pointing to the
+/// newest snapshot, and an outdated snapshot is deleted by the last owner of
+/// the snapshot, either this class or the symbol index.
+///
+/// The snapshot semantics keeps critical sections minimal since we only need
+/// locking when we swap or obtain refereces to snapshots.
+class FileSymbols {
+public:
+  /// \brief Update

[PATCH] D41232: [clangd] Add a FileSymbols container that manages symbols from multiple files.

2017-12-14 Thread Eric Liu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL320701: [clangd] Add a FileSymbols container that manages 
symbols from multiple files. (authored by ioeric, committed by ).

Repository:
  rL LLVM

https://reviews.llvm.org/D41232

Files:
  clang-tools-extra/trunk/clangd/CMakeLists.txt
  clang-tools-extra/trunk/clangd/index/FileSymbols.cpp
  clang-tools-extra/trunk/clangd/index/FileSymbols.h
  clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt
  clang-tools-extra/trunk/unittests/clangd/FileSymbolsTests.cpp

Index: clang-tools-extra/trunk/clangd/CMakeLists.txt
===
--- clang-tools-extra/trunk/clangd/CMakeLists.txt
+++ clang-tools-extra/trunk/clangd/CMakeLists.txt
@@ -19,8 +19,9 @@
   Protocol.cpp
   ProtocolHandlers.cpp
   Trace.cpp
-  index/MemIndex.cpp
+  index/FileSymbols.cpp
   index/Index.cpp
+  index/MemIndex.cpp
   index/SymbolCollector.cpp
   index/SymbolYAML.cpp
 
Index: clang-tools-extra/trunk/clangd/index/FileSymbols.h
===
--- clang-tools-extra/trunk/clangd/index/FileSymbols.h
+++ clang-tools-extra/trunk/clangd/index/FileSymbols.h
@@ -0,0 +1,53 @@
+//===--- FileSymbols.h - Symbols from files. -*- 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_TOOLS_EXTRA_CLANGD_INDEX_FILESYMBOLS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILESYMBOLS_H
+
+#include "../Path.h"
+#include "Index.h"
+#include "llvm/ADT/StringMap.h"
+#include 
+
+namespace clang {
+namespace clangd {
+
+/// \brief A container of Symbols from several source files. It can be updated
+/// at source-file granularity, replacing all symbols from one file with a new
+/// set.
+///
+/// This implements a snapshot semantics for symbols in a file. Each update to a
+/// file will create a new snapshot for all symbols in the file. Snapshots are
+/// managed with shared pointers that are shared between this class and the
+/// users. For each file, this class only stores a pointer pointing to the
+/// newest snapshot, and an outdated snapshot is deleted by the last owner of
+/// the snapshot, either this class or the symbol index.
+///
+/// The snapshot semantics keeps critical sections minimal since we only need
+/// locking when we swap or obtain refereces to snapshots.
+class FileSymbols {
+public:
+  /// \brief Updates all symbols in a file. If \p Slab is nullptr, symbols for
+  /// \p Path will be removed.
+  void update(PathRef Path, std::unique_ptr Slab);
+
+  // The shared_ptr keeps the symbols alive
+  std::shared_ptr> allSymbols();
+
+private:
+  mutable std::mutex Mutex;
+
+  /// \brief Stores the latest snapshots for all active files.
+  llvm::StringMap> FileToSlabs;
+};
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILESYMBOLS_H
Index: clang-tools-extra/trunk/clangd/index/FileSymbols.cpp
===
--- clang-tools-extra/trunk/clangd/index/FileSymbols.cpp
+++ clang-tools-extra/trunk/clangd/index/FileSymbols.cpp
@@ -0,0 +1,48 @@
+//===--- FileSymbols.cpp - Symbols from files. --*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "FileSymbols.h"
+#include "clang/Index/IndexingAction.h"
+
+namespace clang {
+namespace clangd {
+
+void FileSymbols::update(PathRef Path, std::unique_ptr Slab) {
+  std::lock_guard Lock(Mutex);
+  if (!Slab)
+FileToSlabs.erase(Path);
+  else
+FileToSlabs[Path] = std::shared_ptr(Slab.release());
+}
+
+std::shared_ptr> FileSymbols::allSymbols() {
+  // The snapshot manages life time of symbol slabs and provides pointers of all
+  // symbols in all slabs.
+  struct Snapshot {
+std::vector Pointers;
+std::vector> KeepAlive;
+  };
+  auto Snap = std::make_shared();
+  {
+std::lock_guard Lock(Mutex);
+
+for (const auto &FileAndSlab : FileToSlabs) {
+  Snap->KeepAlive.push_back(FileAndSlab.second);
+  for (const auto &Iter : *FileAndSlab.second)
+Snap->Pointers.push_back(&Iter.second);
+}
+  }
+  auto *Pointers = &Snap->Pointers;
+  // Use aliasing constructor to keep the snapshot alive along with the
+  // pointers.
+  return {std::move(Snap), Pointers};
+}
+
+} // namespace clangd
+} // namespace clang
Index: clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt
===
--- clang-tools-extra/trunk/unittests/cla

r320702 - Renamed test file to use proper naming convention

2017-12-14 Thread Ilya Biryukov via cfe-commits
Author: ibiryukov
Date: Thu Dec 14 06:51:17 2017
New Revision: 320702

URL: http://llvm.org/viewvc/llvm-project?rev=320702&view=rev
Log:
Renamed test file to use proper naming convention

Also changed the order of CHECK statements.
CHEKC-NOT must come before CHECK in skipped-function-bodies.cpp

Added:
cfe/trunk/test/Index/skipped-function-bodies.cpp
  - copied, changed from r320697, 
cfe/trunk/test/Index/skipped_function_bodies.cpp
Removed:
cfe/trunk/test/Index/skipped_function_bodies.cpp

Copied: cfe/trunk/test/Index/skipped-function-bodies.cpp (from r320697, 
cfe/trunk/test/Index/skipped_function_bodies.cpp)
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/skipped-function-bodies.cpp?p2=cfe/trunk/test/Index/skipped-function-bodies.cpp&p1=cfe/trunk/test/Index/skipped_function_bodies.cpp&r1=320697&r2=320702&rev=320702&view=diff
==
--- cfe/trunk/test/Index/skipped_function_bodies.cpp (original)
+++ cfe/trunk/test/Index/skipped-function-bodies.cpp Thu Dec 14 06:51:17 2017
@@ -5,5 +5,5 @@ inline int with_body() { return 10; }
 inline int without_body();
 
 int x = with_body() + without_body();
-// CHECK: warning: inline function 'without_body' is not defined
 // CHECK-NOT: warning: inline function 'with_body' is not defined
+// CHECK: warning: inline function 'without_body' is not defined

Removed: cfe/trunk/test/Index/skipped_function_bodies.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/skipped_function_bodies.cpp?rev=320701&view=auto
==
--- cfe/trunk/test/Index/skipped_function_bodies.cpp (original)
+++ cfe/trunk/test/Index/skipped_function_bodies.cpp (removed)
@@ -1,9 +0,0 @@
-// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source 
all %s 2>&1 \
-// RUN: | FileCheck %s
-
-inline int with_body() { return 10; }
-inline int without_body();
-
-int x = with_body() + without_body();
-// CHECK: warning: inline function 'without_body' is not defined
-// CHECK-NOT: warning: inline function 'with_body' is not defined


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


[PATCH] D41237: [Frontend] Handle skipped bodies in template instantiations

2017-12-14 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov created this revision.
ilya-biryukov added reviewers: sepavloff, bkramer.

- Fixed an assert in Sema::InstantiateFunctionDefinition and added support for 
instantiating a function template with skipped body.
- Properly call setHasSkippedBody for FunctionTemplateDecl passed to 
Sema::ActOnSkippedFunctionBody.


Repository:
  rC Clang

https://reviews.llvm.org/D41237

Files:
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/Index/skipped-bodies-templates.cpp


Index: test/Index/skipped-bodies-templates.cpp
===
--- /dev/null
+++ test/Index/skipped-bodies-templates.cpp
@@ -0,0 +1,27 @@
+// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source 
all %s 2>&1 \
+// RUN: | FileCheck %s
+
+
+template 
+struct Foo {
+  inline int with_body() {
+return 100;
+  }
+
+  inline int without_body();
+};
+
+
+int bar = Foo().with_body() + Foo().without_body();
+// CHECK-NOT: warning: inline function 'Foo::with_body' is not defined
+// CHECK: warning: inline function 'Foo::without_body' is not defined
+
+template 
+inline int with_body() { return 10; }
+
+template 
+inline int without_body();
+
+int baz = with_body() + without_body();
+// CHECK-NOT: warning: inline function 'with_body' is not defined
+// CHECK: warning: inline function 'without_body' is not defined
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3855,7 +3855,8 @@
   }
 
   // Note, we should never try to instantiate a deleted function template.
-  assert((Pattern || PatternDecl->isDefaulted()) &&
+  assert((Pattern || PatternDecl->isDefaulted() ||
+  PatternDecl->hasSkippedBody()) &&
  "unexpected kind of function template definition");
 
   // C++1y [temp.explicit]p10:
@@ -3940,16 +3941,20 @@
   }
 }
 
-// Instantiate the function body.
-StmtResult Body = SubstStmt(Pattern, TemplateArgs);
+if (PatternDecl->hasSkippedBody()) {
+  ActOnSkippedFunctionBody(Function);
+} else {
+  // Instantiate the function body.
+  StmtResult Body = SubstStmt(Pattern, TemplateArgs);
 
-if (Body.isInvalid())
-  Function->setInvalidDecl();
+  if (Body.isInvalid())
+Function->setInvalidDecl();
 
-// FIXME: finishing the function body while in an expression evaluation
-// context seems wrong. Investigate more.
-ActOnFinishFunctionBody(Function, Body.get(),
-/*IsInstantiation=*/true);
+  // FIXME: finishing the function body while in an expression evaluation
+  // context seems wrong. Investigate more.
+  ActOnFinishFunctionBody(Function, Body.get(),
+  /*IsInstantiation=*/true);
+}
 
 PerformDependentDiagnostics(PatternDecl, TemplateArgs);
 
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -12181,7 +12181,7 @@
 }
 
 Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) {
-  if (FunctionDecl *FD = dyn_cast_or_null(Decl))
+  if (FunctionDecl *FD = Decl->getAsFunction())
 FD->setHasSkippedBody();
   else if (ObjCMethodDecl *MD = dyn_cast_or_null(Decl))
 MD->setHasSkippedBody();


Index: test/Index/skipped-bodies-templates.cpp
===
--- /dev/null
+++ test/Index/skipped-bodies-templates.cpp
@@ -0,0 +1,27 @@
+// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source all %s 2>&1 \
+// RUN: | FileCheck %s
+
+
+template 
+struct Foo {
+  inline int with_body() {
+return 100;
+  }
+
+  inline int without_body();
+};
+
+
+int bar = Foo().with_body() + Foo().without_body();
+// CHECK-NOT: warning: inline function 'Foo::with_body' is not defined
+// CHECK: warning: inline function 'Foo::without_body' is not defined
+
+template 
+inline int with_body() { return 10; }
+
+template 
+inline int without_body();
+
+int baz = with_body() + without_body();
+// CHECK-NOT: warning: inline function 'with_body' is not defined
+// CHECK: warning: inline function 'without_body' is not defined
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3855,7 +3855,8 @@
   }
 
   // Note, we should never try to instantiate a deleted function template.
-  assert((Pattern || PatternDecl->isDefaulted()) &&
+  assert((Pattern || PatternDecl->isDefaulted() ||
+  PatternDecl->hasSkippedBody()) &&
  "unexpected kind of function template definition");
 
   // C++1y [temp.explicit]p10:
@@ -3940,16 +3941,20 @@
   }
 }
 
-// Instantiate the function body.
-StmtResult Body = SubstStmt(Pattern, TemplateArgs);
+i

[PATCH] D40489: [clangd] Changed tracing interfaces

2017-12-14 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added inline comments.



Comment at: clangd/Trace.cpp:134
+  Callback = T->beginSpan(Ctx, Name);
+  if (!Callback)
+return;

sammccall wrote:
> I'm not sure this is useful. Tracers that aren't interested in args can't opt 
> out by providing a null callback, unless they also don't care about the end 
> time.
> This seems unlikely (a null tracer, I guess)
One use-case that came to mind is turning the tracing on or off on per-request 
basis


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40489



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


[PATCH] D41050: Fix over-release of return value of lambda implicitly converted to block/function pointer

2017-12-14 Thread Dan Zimmerman via Phabricator via cfe-commits
danzimm added a comment.

Also, I don't have commit access. Could someone else commit this for me?


Repository:
  rC Clang

https://reviews.llvm.org/D41050



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


[PATCH] D41005: Reuse preamble even if an unsaved file does not exist

2017-12-14 Thread Nikolai Kosjar via Phabricator via cfe-commits
nik added inline comments.



Comment at: include/clang/Frontend/ASTUnit.h:196
+  /// \brief Counter indicating how often the preamble was build in total.
+  unsigned PreambleCounter;
+

ilya-biryukov wrote:
> nik wrote:
> > Any better name for this one? Otherwise I would suggest renaming 
> > PreambleRebuildCounter to PreambleRebuildCountdownCounter to make them more 
> > distinct.
> +1, names PreambleRebuildCounter and PreambleCounter are too similar.
> 
OK, will address in the next patch set / diff.



Comment at: lib/Frontend/PrecompiledPreamble.cpp:461
 
 std::map::iterator Overridden =
 OverriddenFiles.find(Status.getUniqueID());

ilya-biryukov wrote:
> Will anything fail if we remove the map from `UniqueID` to hashes of 
> overriden files and the corresponding checks?
> 
> We should either document why having `UniqueID`-based checks is important or 
> remove the code doing those checks.
> Will anything fail if we remove the map from UniqueID to hashes of overriden 
> files and the corresponding checks?

Hmm, I would need to remove/replace it and run the tests.

I see these reasons for UniqueID:
* It's already there :)
* Normalization of file paths is not necessary.
* It potentially can deal with hard links, though I'm not sure whether this is 
real world use case at all.

> We should either document why having UniqueID-based checks is important or 
> remove the code doing those checks.

Agree.



Repository:
  rC Clang

https://reviews.llvm.org/D41005



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


[PATCH] D41217: [Concepts] Concept Specialization Expressions

2017-12-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 126950.
saar.raz added a comment.

- Fixed indentation problems


Repository:
  rC Clang

https://reviews.llvm.org/D41217

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

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -231,6 +231,7 @@
   case Stmt::TypeTraitExprClass:
   case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -5951,6 +5951,7 @@
   case Decl::PragmaComment:
   case Decl::PragmaDetectMismatch:
   case Decl::UsingPack:
+  case Decl::Concept:
 return C;
 
   // Declaration kinds that don't make any sense here, but are
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ test/Parser/cxx-concept-declaration.cpp
@@ -1,7 +1,38 @@
 
 // Support parsing of concepts
-// Disabled for now.
-// expected-no-diagnostics
 
-// RUN:  %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
-// template concept C1 = true;
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+template concept C1 = true;
+
+// TODO: Following line should fail.
+template concept C1 = true;
+
+template concept D1 = true; // expected-error {{expected template parameter}}
+
+struct S1 {
+  template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
+};
+
+template
+template
+concept C4 = true; // expected-error {{extraneous template parameter list in concept definition}}
+
+template concept C5 = true; // expected-note {{previous}} expected-note {{previous}}
+int C5; // expected-error {{redefinition}}
+struct C5 {}; // expected-error {{redefinition}}
+
+// TODO: Last of the following two lines should fail.
+struct C6 {};
+template concept C6 = true;
+
+// TODO: Add test to prevent explicit specialization, partial specialization
+// and explicit instantiation of concepts.
+
+template concept C7 = 2; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C8 = 2 && x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C9 = x || 2 || x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C10 = 8ull && x || x; // expected-error {{atomic constraint '8ULL' must be of type 'bool' (found 'unsigned long long')}}
+template concept C11 = sizeof(T); // expected-error {{atomic constraint 'sizeof(T)' must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+template concept C13 = (bool&&)true;
+template concept C14 = (const bool&)true;
Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -0,0 +1,52 @@
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+
+template concept C1 = true;
+static_assert(C1);
+
+template concept C2 = sizeof(T) == 4;
+static_assert(C2);
+static_assert(!C2);
+static_assert(C2);
+static_assert(!C2);
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);
+static_assert(!C3);
+
+struct A {
+static constexpr int add(int a, int b) {
+return a + b;
+}
+};
+struct B {
+static int add(int a, int b)

[PATCH] D40488: [clangd] Implemented tracing using Context

2017-12-14 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov updated this revision to Diff 126951.
ilya-biryukov added a comment.

- Renamed TracingSession to Session (it is always used qualified via 
trace::Session anyway)


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40488

Files:
  clangd/ClangdUnit.cpp
  clangd/JSONRPCDispatcher.cpp
  clangd/Trace.cpp
  clangd/Trace.h
  clangd/tool/ClangdMain.cpp
  unittests/clangd/TraceTests.cpp

Index: unittests/clangd/TraceTests.cpp
===
--- unittests/clangd/TraceTests.cpp
+++ unittests/clangd/TraceTests.cpp
@@ -7,6 +7,7 @@
 //
 //===--===//
 
+#include "Context.h"
 #include "Trace.h"
 
 #include "llvm/ADT/DenseMap.h"
@@ -74,10 +75,11 @@
   std::string JSON;
   {
 raw_string_ostream OS(JSON);
-auto Session = trace::Session::create(OS);
+auto JSONTracer = trace::createJSONTracer(OS);
+trace::Session Session(*JSONTracer);
 {
-  trace::Span S("A");
-  trace::log("B");
+  trace::Span S(Context::empty(), "A");
+  trace::log(Context::empty(), "B");
 }
   }
 
Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -115,19 +115,25 @@
<< EC.message();
 }
   }
+
+  // Setup tracing facilities.
   llvm::Optional TraceStream;
-  std::unique_ptr TraceSession;
+  std::unique_ptr Tracer;
   if (!TraceFile.empty()) {
 std::error_code EC;
 TraceStream.emplace(TraceFile, /*ref*/ EC, llvm::sys::fs::F_RW);
 if (EC) {
   TraceFile.reset();
   llvm::errs() << "Error while opening trace file: " << EC.message();
 } else {
-  TraceSession = trace::Session::create(*TraceStream, PrettyPrint);
+  Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
 }
   }
 
+  llvm::Optional TracingSession;
+  if (Tracer)
+TracingSession.emplace(*Tracer);
+
   llvm::raw_ostream &Outs = llvm::outs();
   llvm::raw_ostream &Logs = llvm::errs();
   JSONOutput Out(Outs, Logs,
Index: clangd/Trace.h
===
--- clangd/Trace.h
+++ clangd/Trace.h
@@ -8,60 +8,74 @@
 //===--===//
 //
 // Supports writing performance traces describing clangd's behavior.
-// Traces are written in the Trace Event format supported by chrome's trace
-// viewer (chrome://tracing).
+// Traces are consumed by implementations of the EventTracer interface.
 //
-// The format is documented here:
-// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
 //
 // All APIs are no-ops unless a Session is active (created by ClangdMain).
 //
 //===--===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
+#include "Context.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
 namespace trace {
 
-// A session directs the output of trace events. Only one Session can exist.
-// It should be created before clangd threads are spawned, and destroyed after
-// they exit.
-// TODO: we may want to add pluggable support for other tracing backends.
+/// A consumer of trace events. The events are produced by Spans and trace::log.
+class EventTracer {
+public:
+  virtual ~EventTracer() = default;
+  /// Consume a trace event.
+  virtual void event(const Context &Ctx, llvm::StringRef Phase,
+ json::obj &&Contents) = 0;
+};
+
+/// Sets up a global EventTracer that consumes events produced by Span and
+/// trace::log. Only one TracingSession can be active at a time and it should be
+/// set up before calling any clangd-specific functions.
 class Session {
 public:
-  // Starts a sessions capturing trace events and writing Trace Event JSON.
-  static std::unique_ptr create(llvm::raw_ostream &OS,
- bool Pretty = false);
+  Session(EventTracer &Tracer);
   ~Session();
-
-private:
-  Session() = default;
 };
 
-// Records a single instant event, associated with the current thread.
-void log(const llvm::Twine &Name);
+/// Create an instance of EventTracer that produces an output in the Trace Event
+/// format supported by Chrome's trace viewer (chrome://tracing).
+///
+/// The format is documented here:
+/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
+///
+/// The implementation supports concurrent calls and can be used as a global
+/// tracer (i.e., can be put into a global Context).
+std::unique_ptr createJSONTracer(llvm::raw_ostream &OS,
+  bool Pretty = false);
 
-// Records an event whose duration is the lifetime of the Span object.
-//
-// Arbitr

[clang-tools-extra] r320706 - [clangd] Implemented tracing using Context

2017-12-14 Thread Ilya Biryukov via cfe-commits
Author: ibiryukov
Date: Thu Dec 14 07:04:59 2017
New Revision: 320706

URL: http://llvm.org/viewvc/llvm-project?rev=320706&view=rev
Log:
[clangd] Implemented tracing using Context

Reviewers: sammccall, ioeric, hokein

Reviewed By: sammccall

Subscribers: klimek, luckygeck, cfe-commits

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

Modified:
clang-tools-extra/trunk/clangd/ClangdUnit.cpp
clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
clang-tools-extra/trunk/clangd/Trace.cpp
clang-tools-extra/trunk/clangd/Trace.h
clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
clang-tools-extra/trunk/unittests/clangd/TraceTests.cpp

Modified: clang-tools-extra/trunk/clangd/ClangdUnit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.cpp?rev=320706&r1=320705&r2=320706&view=diff
==
--- clang-tools-extra/trunk/clangd/ClangdUnit.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp Thu Dec 14 07:04:59 2017
@@ -770,7 +770,7 @@ CppFile::deferRebuild(StringRef NewConte
   // (if there are no other references to it).
   OldPreamble.reset();
 
-  trace::Span Tracer("Preamble");
+  trace::Span Tracer(Ctx, "Preamble");
   SPAN_ATTACH(Tracer, "File", That->FileName);
   std::vector PreambleDiags;
   StoreDiagsConsumer PreambleDiagnosticsConsumer(/*ref*/ PreambleDiags);
@@ -816,7 +816,7 @@ CppFile::deferRebuild(StringRef NewConte
 // Compute updated AST.
 llvm::Optional NewAST;
 {
-  trace::Span Tracer("Build");
+  trace::Span Tracer(Ctx, "Build");
   SPAN_ATTACH(Tracer, "File", That->FileName);
   NewAST = ParsedAST::Build(Ctx, std::move(CI), std::move(NewPreamble),
 std::move(ContentsBuffer), PCHs, VFS);

Modified: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp?rev=320706&r1=320705&r2=320706&view=diff
==
--- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp (original)
+++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp Thu Dec 14 07:04:59 
2017
@@ -45,7 +45,7 @@ void JSONOutput::writeMessage(const json
 }
 
 void JSONOutput::log(const Context &Ctx, const Twine &Message) {
-  trace::log(Message);
+  trace::log(Ctx, Message);
   std::lock_guard Guard(StreamMutex);
   Logs << Message << '\n';
   Logs.flush();
@@ -137,16 +137,19 @@ bool JSONRPCDispatcher::call(const json:
   auto I = Handlers.find(*Method);
   auto &Handler = I != Handlers.end() ? I->second : UnknownHandler;
 
-  auto Tracer = llvm::make_unique(*Method);
+  // Create a Context that contains request information.
+  auto Ctx = Context::empty().derive(RequestOut, &Out);
+  if (ID)
+Ctx = std::move(Ctx).derive(RequestID, *ID);
+
+  // Create a tracing Span covering the whole request lifetime.
+  auto Tracer = llvm::make_unique(Ctx, *Method);
   if (ID)
 SPAN_ATTACH(*Tracer, "ID", *ID);
   SPAN_ATTACH(*Tracer, "Params", Params);
 
-  auto Ctx = Context::empty()
- .derive(RequestOut, &Out)
- .derive(RequestSpan, std::move(Tracer));
-  if (ID)
-Ctx = std::move(Ctx).derive(RequestID, *ID);
+  // Update Ctx to include Tracer.
+  Ctx = std::move(Ctx).derive(RequestSpan, std::move(Tracer));
 
   Handler(std::move(Ctx), std::move(Params));
   return true;

Modified: clang-tools-extra/trunk/clangd/Trace.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Trace.cpp?rev=320706&r1=320705&r2=320706&view=diff
==
--- clang-tools-extra/trunk/clangd/Trace.cpp (original)
+++ clang-tools-extra/trunk/clangd/Trace.cpp Thu Dec 14 07:04:59 2017
@@ -24,9 +24,9 @@ using namespace llvm;
 namespace {
 // The current implementation is naive: each thread writes to Out guarded by 
Mu.
 // Perhaps we should replace this by something that disturbs performance less.
-class Tracer {
+class JSONTracer : public EventTracer {
 public:
-  Tracer(raw_ostream &Out, bool Pretty)
+  JSONTracer(raw_ostream &Out, bool Pretty)
   : Out(Out), Sep(""), Start(std::chrono::system_clock::now()),
 JSONFormat(Pretty ? "{0:2}" : "{0}") {
 // The displayTimeUnit must be ns to avoid low-precision overlap
@@ -39,14 +39,15 @@ public:
   });
   }
 
-  ~Tracer() {
+  ~JSONTracer() {
 Out << "\n]}";
 Out.flush();
   }
 
   // Record an event on the current thread. ph, pid, tid, ts are set.
   // Contents must be a list of the other JSON key/values.
-  void event(StringRef Phase, json::obj &&Contents) {
+  void event(const Context &Ctx, StringRef Phase,
+ json::obj &&Contents) override {
 uint64_t TID = get_threadid();
 std::lock_guard Lock(Mu);
 // If we haven't already, emit metadata describing th

[PATCH] D40488: [clangd] Implemented tracing using Context

2017-12-14 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL320706: [clangd] Implemented tracing using Context (authored 
by ibiryukov, committed by ).

Repository:
  rL LLVM

https://reviews.llvm.org/D40488

Files:
  clang-tools-extra/trunk/clangd/ClangdUnit.cpp
  clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
  clang-tools-extra/trunk/clangd/Trace.cpp
  clang-tools-extra/trunk/clangd/Trace.h
  clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
  clang-tools-extra/trunk/unittests/clangd/TraceTests.cpp

Index: clang-tools-extra/trunk/clangd/Trace.h
===
--- clang-tools-extra/trunk/clangd/Trace.h
+++ clang-tools-extra/trunk/clangd/Trace.h
@@ -8,60 +8,74 @@
 //===--===//
 //
 // Supports writing performance traces describing clangd's behavior.
-// Traces are written in the Trace Event format supported by chrome's trace
-// viewer (chrome://tracing).
+// Traces are consumed by implementations of the EventTracer interface.
 //
-// The format is documented here:
-// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
 //
 // All APIs are no-ops unless a Session is active (created by ClangdMain).
 //
 //===--===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
+#include "Context.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
 namespace trace {
 
-// A session directs the output of trace events. Only one Session can exist.
-// It should be created before clangd threads are spawned, and destroyed after
-// they exit.
-// TODO: we may want to add pluggable support for other tracing backends.
+/// A consumer of trace events. The events are produced by Spans and trace::log.
+class EventTracer {
+public:
+  virtual ~EventTracer() = default;
+  /// Consume a trace event.
+  virtual void event(const Context &Ctx, llvm::StringRef Phase,
+ json::obj &&Contents) = 0;
+};
+
+/// Sets up a global EventTracer that consumes events produced by Span and
+/// trace::log. Only one TracingSession can be active at a time and it should be
+/// set up before calling any clangd-specific functions.
 class Session {
 public:
-  // Starts a sessions capturing trace events and writing Trace Event JSON.
-  static std::unique_ptr create(llvm::raw_ostream &OS,
- bool Pretty = false);
+  Session(EventTracer &Tracer);
   ~Session();
-
-private:
-  Session() = default;
 };
 
-// Records a single instant event, associated with the current thread.
-void log(const llvm::Twine &Name);
-
-// Records an event whose duration is the lifetime of the Span object.
-//
-// Arbitrary JSON metadata can be attached while this span is active:
-//   SPAN_ATTACH(MySpan, "Payload", SomeJSONExpr);
-// SomeJSONExpr is evaluated and copied only if actually needed.
+/// Create an instance of EventTracer that produces an output in the Trace Event
+/// format supported by Chrome's trace viewer (chrome://tracing).
+///
+/// The format is documented here:
+/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
+///
+/// The implementation supports concurrent calls and can be used as a global
+/// tracer (i.e., can be put into a global Context).
+std::unique_ptr createJSONTracer(llvm::raw_ostream &OS,
+  bool Pretty = false);
+
+/// Records a single instant event, associated with the current thread.
+void log(const Context &Ctx, const llvm::Twine &Name);
+
+/// Records an event whose duration is the lifetime of the Span object.
+/// This is the main public interface for producing tracing events.
+///
+/// Arbitrary JSON metadata can be attached while this span is active:
+///   SPAN_ATTACH(MySpan, "Payload", SomeJSONExpr);
+/// SomeJSONExpr is evaluated and copied only if actually needed.
 class Span {
 public:
-  Span(std::string Name);
+  Span(const Context &Ctx, std::string Name);
   ~Span();
 
-  // Returns mutable span metadata if this span is interested.
-  // Prefer to use SPAN_ATTACH rather than accessing this directly.
+  /// Returns mutable span metadata if this span is interested.
+  /// Prefer to use SPAN_ATTACH rather than accessing this directly.
   json::obj *args() { return Args.get(); }
 
 private:
+  llvm::Optional Ctx;
   std::unique_ptr Args;
 };
 
Index: clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
===
--- clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
+++ clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
@@ -115,19 +115,25 @@
<< EC.message();
 }
   }
+
+  // Setup tracing facilities.
   llvm::Optional TraceSt

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2017-12-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 126953.
saar.raz added a comment.

Previous updated diff mistakenly included https://reviews.llvm.org/D40381, 
fixed that.


Repository:
  rC Clang

https://reviews.llvm.org/D41217

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

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -231,6 +231,7 @@
   case Stmt::TypeTraitExprClass:
   case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ test/Parser/cxx-concept-declaration.cpp
@@ -9,8 +9,6 @@
 
 template concept D1 = true; // expected-error {{expected template parameter}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be 'bool'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -29,3 +27,12 @@
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
+
+template concept C7 = 2; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C8 = 2 && x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C9 = x || 2 || x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C10 = 8ull && x || x; // expected-error {{atomic constraint '8ULL' must be of type 'bool' (found 'unsigned long long')}}
+template concept C11 = sizeof(T); // expected-error {{atomic constraint 'sizeof(T)' must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+template concept C13 = (bool&&)true;
+template concept C14 = (const bool&)true;
Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
===
--- test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
+++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -1,5 +1,52 @@
 // RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
-// expected-no-diagnostics
 
-template concept C = true;
-static_assert(C);
+template concept C1 = true;
+static_assert(C1);
+
+template concept C2 = sizeof(T) == 4;
+static_assert(C2);
+static_assert(!C2);
+static_assert(C2);
+static_assert(!C2);
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);
+static_assert(!C3);
+
+struct A {
+static constexpr int add(int a, int b) {
+return a + b;
+}
+};
+struct B {
+static int add(int a, int b) {
+return a + b;
+}
+};
+template
+concept C4 = U::add(1, 2) == 3;
+static_assert(C4);
+static_assert(!C4); // expected-error {{concept specialization 'C4' resulted in a non-constant expression 'B::add(1, 2) == 3'}}
+
+template
+constexpr bool is_same_v = false;
+
+template
+constexpr bool is_same_v = true;
+
+template
+concept Same = is_same_v;
+
+static_assert(Same);
+static_assert(Same);
+static_assert(!Same);
+static_assert(!Same);
+static_assert(Same);
+
+static_assert(Same)>);
+static_assert(Same)>);
+static_assert(Same)>);
+static_assert(Same)>);
+
+template concept C5 = T{}; // expected-error {{atomic constraint 'int{}' must be of type 'bool' (found 'int')}}
+constexpr bool x = C5; // expected-note {{in concept specialization 'C5'}}
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1018,6 +1018,7 @@
 case Stmt::CUDAKernelCallExprClass:
 case Stmt::OpaqueValueExprClass:
 case Stmt::AsTypeExprClass:
+case Stmt::ConceptSpecializationExprClass:
   // Fall through.
 
 // Cases we intentionally don't evaluate, since they don't need
Index: l

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2017-12-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz marked 2 inline comments as done.
saar.raz added a comment.

Fixed indentations.


Repository:
  rC Clang

https://reviews.llvm.org/D41217



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


[PATCH] D39375: [clang] Add PPCallbacks list to preprocessor when building a preacompiled preamble.

2017-12-14 Thread Marc-Andre Laperle via Phabricator via cfe-commits
malaperle requested changes to this revision.
malaperle added inline comments.
This revision now requires changes to proceed.



Comment at: include/clang/Frontend/PrecompiledPreamble.h:263
   const MacroDirective *MD);
+  /// Adds list of Preprocessor callbacks so we can also process information
+  /// about includes that are outside of a preamble i.e in the middle of a file

It doesn't add, it creates.It's also not a "list". Is it true that it will 
process includes outside the preamble? I would think building the preamble 
stopped at the end of the preamble.



Comment at: lib/Frontend/PrecompiledPreamble.cpp:354
 
+  if (Callbacks.createPPCallbacks())
+
Clang->getPreprocessor().addPPCallbacks(std::move(Callbacks.createPPCallbacks()));

extract this to a local variable


Repository:
  rC Clang

https://reviews.llvm.org/D39375



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


r320707 - [c++20] P0515R3: Parsing support and basic AST construction for operator <=>.

2017-12-14 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Thu Dec 14 07:16:18 2017
New Revision: 320707

URL: http://llvm.org/viewvc/llvm-project?rev=320707&view=rev
Log:
[c++20] P0515R3: Parsing support and basic AST construction for operator <=>.

Adding the new enumerator forced a bunch more changes into this patch than I
would have liked. The -Wtautological-compare warning was extended to properly
check the new comparison operator, clang-format needed updating because it uses
precedence levels as weights for determining where to break lines (and several
operators increased their precedence levels with this change), thread-safety
analysis needed changes to build its own IL properly for the new operator.

All "real" semantic checking for this operator has been deferred to a future
patch. For now, we use the relational comparison rules and arbitrarily give
the builtin form of the operator a return type of 'void'.

Added:
cfe/trunk/test/Parser/cxx2a-spaceship.cpp
cfe/trunk/test/SemaCXX/compare-cxx2a.cpp
cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/AST/OperationKinds.def
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/include/clang/AST/StmtVisitor.h
cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Basic/OperatorPrecedence.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp
cfe/trunk/lib/Analysis/ThreadSafetyTIL.cpp
cfe/trunk/lib/Basic/OperatorPrecedence.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
cfe/trunk/lib/Format/ContinuationIndenter.cpp
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/lib/Format/TokenAnnotator.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp
cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
cfe/trunk/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
cfe/trunk/test/SemaTemplate/cxx1z-fold-expressions.cpp
cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=320707&r1=320706&r2=320707&view=diff
==
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Dec 14 07:16:18 2017
@@ -3072,7 +3072,7 @@ public:
   static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; }
   bool isEqualityOp() const { return isEqualityOp(getOpcode()); }
 
-  static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; }
+  static bool isComparisonOp(Opcode Opc) { return Opc >= BO_Cmp && Opc<=BO_NE; 
}
   bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
 
   static Opcode negateComparisonOp(Opcode Opc) {

Modified: cfe/trunk/include/clang/AST/OperationKinds.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OperationKinds.def?rev=320707&r1=320706&r2=320707&view=diff
==
--- cfe/trunk/include/clang/AST/OperationKinds.def (original)
+++ cfe/trunk/include/clang/AST/OperationKinds.def Thu Dec 14 07:16:18 2017
@@ -332,7 +332,8 @@ CAST_OPERATION(IntToOCLSampler)
 
 //===- Binary Operations  
-===//
 // Operators listed in order of precedence.
-// Note that additions to this should also update the StmtVisitor class.
+// Note that additions to this should also update the StmtVisitor class and
+// BinaryOperator::getOverloadedOperator.
 
 // [C++ 5.5] Pointer-to-member operators.
 BINARY_OPERATION(PtrMemD, ".*")
@@ -347,6 +348,8 @@ BINARY_OPERATION(Sub, "-")
 // [C99 6.5.7] Bitwise shift operators.
 BINARY_OPERATION(Shl, "<<")
 BINARY_OPERATION(Shr, ">>")
+// C++20 [expr.spaceship] Three-way comparison operator.
+BINARY_OPERATION(Cmp, "<=>")
 // [C99 6.5.8] Relational operators.
 BINARY_OPERATION(LT, "<")
 BINARY_OPERATION(GT, ">")
@@ -382,7 +385,8 @@ BINARY_OPERATION(Comma, ",")
 
 
 //===- Unary Operations 
---===//
-// Note that additions to this should also update the StmtVisitor class.
+// Note that additions to this should also update the StmtVisitor class and
+// UnaryOperator::getOverloadedOperator.
 
 // [C99 6.5.2.4] Postfix increment and decrement
 UNARY_OPERATION(PostInc, "++")

Modified: cfe/trunk/include/clang/AST/RecursiveAS

[PATCH] D40548: [clangd] Symbol index interfaces and an in-memory index implementation.

2017-12-14 Thread Marc-Andre Laperle via Phabricator via cfe-commits
malaperle added a comment.

In https://reviews.llvm.org/D40548#947081, @ioeric wrote:

> Hi Marc, the patch is not ready for review yet. I am still cleaning up the 
> prototype and will let you know when it's ready for review.


I guess it was ready to review since it was submitted? ;)




Comment at: clangd/index/Index.h:134
+  virtual bool
+  fuzzyFind(Context &Ctx, const FuzzyFindRequest &Req,
+std::function Callback) const = 0;

I think a more generic std::function would be useful, similar to the 
indexstore's filter
```
bool searchSymbols(llvm::function_ref 
filter,
 llvm::function_ref receiver)
```


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40548



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


[PATCH] D40743: Make rehash(0) work with ubsan's unsigned-integer-overflow.

2017-12-14 Thread Marshall Clow via Phabricator via cfe-commits
mclow.lists accepted this revision.
mclow.lists added inline comments.
This revision is now accepted and ready to land.



Comment at: include/__hash_table:2141
 __n = 2;
 else if (__n & (__n - 1))
 __n = __next_prime(__n);

danalbert wrote:
> With `rehash(0)` this is `0 & (0 - 1)`, which triggers 
> unsigned-integer-overflow.
Grumble, grumble. That's not UB, that's just UBSan whining.
On the other hand, this doesn't appear to change any behavior, and shuts UBSan 
up.


Repository:
  rCXX libc++

https://reviews.llvm.org/D40743



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


[PATCH] D40489: [clangd] Changed tracing interfaces

2017-12-14 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov updated this revision to Diff 126957.
ilya-biryukov added a comment.

Merged with head


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40489

Files:
  clangd/Trace.cpp
  clangd/Trace.h

Index: clangd/Trace.h
===
--- clangd/Trace.h
+++ clangd/Trace.h
@@ -19,6 +19,7 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
 #include "Context.h"
+#include "Function.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
@@ -28,12 +29,24 @@
 namespace trace {
 
 /// A consumer of trace events. The events are produced by Spans and trace::log.
+/// Implmentations of this interface must be thread-safe.
 class EventTracer {
 public:
+  /// A callback executed when an event with duration ends. Args represent data
+  /// that was attached to the event via SPAN_ATTACH.
+  using EndEventCallback = UniqueFunction;
+
   virtual ~EventTracer() = default;
-  /// Consume a trace event.
-  virtual void event(const Context &Ctx, llvm::StringRef Phase,
- json::obj &&Contents) = 0;
+
+  /// Called when event that has a duration starts. The returned callback will
+  /// be executed when the event ends. \p Name is a descriptive name
+  /// of the event that was passed to Span constructor.
+  virtual EndEventCallback beginSpan(const Context &Ctx,
+ llvm::StringRef Name) = 0;
+
+  /// Called for instant events.
+  virtual void instant(const Context &Ctx, llvm::StringRef Name,
+   json::obj &&Args) = 0;
 };
 
 /// Sets up a global EventTracer that consumes events produced by Span and
@@ -50,9 +63,6 @@
 ///
 /// The format is documented here:
 /// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
-///
-/// The implementation supports concurrent calls and can be used as a global
-/// tracer (i.e., can be put into a global Context).
 std::unique_ptr createJSONTracer(llvm::raw_ostream &OS,
   bool Pretty = false);
 
@@ -67,16 +77,16 @@
 /// SomeJSONExpr is evaluated and copied only if actually needed.
 class Span {
 public:
-  Span(const Context &Ctx, std::string Name);
+  Span(const Context &Ctx, llvm::StringRef Name);
   ~Span();
 
   /// Returns mutable span metadata if this span is interested.
   /// Prefer to use SPAN_ATTACH rather than accessing this directly.
   json::obj *args() { return Args.get(); }
 
 private:
-  llvm::Optional Ctx;
   std::unique_ptr Args;
+  EventTracer::EndEventCallback Callback;
 };
 
 #define SPAN_ATTACH(S, Name, Expr) \
Index: clangd/Trace.cpp
===
--- clangd/Trace.cpp
+++ clangd/Trace.cpp
@@ -44,10 +44,24 @@
 Out.flush();
   }
 
+  EndEventCallback beginSpan(const Context &Ctx,
+ llvm::StringRef Name) override {
+jsonEvent("B", json::obj{{"name", Name}});
+
+// The callback that will run when event ends.
+return [this](json::Expr &&Args) {
+  jsonEvent("E", json::obj{{"args", std::move(Args)}});
+};
+  }
+
+  void instant(const Context &Ctx, llvm::StringRef Name,
+   json::obj &&Args) override {
+jsonEvent("i", json::obj{{"name", Name}, {"args", std::move(Args)}});
+  }
+
   // Record an event on the current thread. ph, pid, tid, ts are set.
   // Contents must be a list of the other JSON key/values.
-  void event(const Context &Ctx, StringRef Phase,
- json::obj &&Contents) override {
+  void jsonEvent(StringRef Phase, json::obj &&Contents) {
 uint64_t TID = get_threadid();
 std::lock_guard Lock(Mu);
 // If we haven't already, emit metadata describing this thread.
@@ -109,30 +123,26 @@
 void log(const Context &Ctx, const Twine &Message) {
   if (!T)
 return;
-  T->event(Ctx, "i",
-   json::obj{
-   {"name", "Log"},
-   {"args", json::obj{{"Message", Message.str()}}},
-   });
+  T->instant(Ctx, "Log", json::obj{{"Message", Message.str()}});
 }
 
-Span::Span(const Context &Ctx, std::string Name) {
+Span::Span(const Context &Ctx, llvm::StringRef Name) {
   if (!T)
 return;
-  // Clone the context, so that the original Context can be moved.
-  this->Ctx.emplace(Ctx.clone());
 
-  T->event(*this->Ctx, "B", json::obj{{"name", std::move(Name)}});
+  Callback = T->beginSpan(Ctx, Name);
+  if (!Callback)
+return;
+
   Args = llvm::make_unique();
 }
 
 Span::~Span() {
-  if (!T)
+  if (!Callback)
 return;
-  if (!Args)
-Args = llvm::make_unique();
-  T->event(*Ctx, "E",
-   Args ? json::obj{{"args", std::move(*Args)}} : json::obj{});
+
+  assert(Args && "Args must be non-null if Callback is defined");
+  Callback(std::move(*Args));
 }
 
 } // namespace trace
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://list

[PATCH] D41239: Turn a config macro (_LIBCPP_HAS_NO_INLINE_VARIABLES) into an attribute macro (_LIBCPP_INLINE_VAR)

2017-12-14 Thread Marshall Clow via Phabricator via cfe-commits
mclow.lists created this revision.
mclow.lists added a reviewer: EricWF.

We're going to be defining a lot of inline variables going forward, and the 
current way of doing it is ... long-winded.
Add an attribute macro which we can put everywhere we need, and handles the 
conditional.

Instead of writing

  #ifndef _LIBCPP_HAS_NO_INLINE_VARIABLES
  inline
  #endif
  constexpr in_place_t in_place{};

we can now write:

  _LIBCPP_INLINE_VAR constexpr in_place_t in_place{};

(and it gets rid of a FIXME!)


https://reviews.llvm.org/D41239

Files:
  include/__config
  include/utility


Index: include/utility
===
--- include/utility
+++ include/utility
@@ -904,10 +904,7 @@
 struct _LIBCPP_TYPE_VIS in_place_t {
 explicit in_place_t() = default;
 };
-#ifndef _LIBCPP_HAS_NO_INLINE_VARIABLES
-inline
-#endif
-constexpr in_place_t in_place{};
+_LIBCPP_INLINE_VAR constexpr in_place_t in_place{};
 
 template 
 struct _LIBCPP_TEMPLATE_VIS in_place_type_t {
@@ -914,10 +911,7 @@
 explicit in_place_type_t() = default;
 };
 template 
-#ifndef _LIBCPP_HAS_NO_INLINE_VARIABLES
-inline
-#endif
-constexpr in_place_type_t<_Tp> in_place_type{};
+_LIBCPP_INLINE_VAR constexpr in_place_type_t<_Tp> in_place_type{};
 
 template 
 struct _LIBCPP_TYPE_VIS in_place_index_t {
@@ -924,10 +918,7 @@
 explicit in_place_index_t() = default;
 };
 template 
-#ifndef _LIBCPP_HAS_NO_INLINE_VARIABLES
-inline
-#endif
-constexpr in_place_index_t<_Idx> in_place_index{};
+_LIBCPP_INLINE_VAR constexpr in_place_index_t<_Idx> in_place_index{};
 
 template  struct __is_inplace_type_imp : false_type {};
 template  struct __is_inplace_type_imp> : 
true_type {};
Index: include/__config
===
--- include/__config
+++ include/__config
@@ -978,9 +978,10 @@
 #define _LIBCPP_NODISCARD_AFTER_CXX17
 #endif
 
-// FIXME: Remove all usages of this macro once compilers catch up.
-#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606L)
-# define _LIBCPP_HAS_NO_INLINE_VARIABLES
+#if _LIBCPP_STD_VER > 14 && defined(__cpp_inline_variables) && 
(__cpp_inline_variables >= 201606L)
+# define _LIBCPP_INLINE_VAR  inline
+#else
+# define _LIBCPP_INLINE_VAR  
 #endif
 
 #ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES


Index: include/utility
===
--- include/utility
+++ include/utility
@@ -904,10 +904,7 @@
 struct _LIBCPP_TYPE_VIS in_place_t {
 explicit in_place_t() = default;
 };
-#ifndef _LIBCPP_HAS_NO_INLINE_VARIABLES
-inline
-#endif
-constexpr in_place_t in_place{};
+_LIBCPP_INLINE_VAR constexpr in_place_t in_place{};
 
 template 
 struct _LIBCPP_TEMPLATE_VIS in_place_type_t {
@@ -914,10 +911,7 @@
 explicit in_place_type_t() = default;
 };
 template 
-#ifndef _LIBCPP_HAS_NO_INLINE_VARIABLES
-inline
-#endif
-constexpr in_place_type_t<_Tp> in_place_type{};
+_LIBCPP_INLINE_VAR constexpr in_place_type_t<_Tp> in_place_type{};
 
 template 
 struct _LIBCPP_TYPE_VIS in_place_index_t {
@@ -924,10 +918,7 @@
 explicit in_place_index_t() = default;
 };
 template 
-#ifndef _LIBCPP_HAS_NO_INLINE_VARIABLES
-inline
-#endif
-constexpr in_place_index_t<_Idx> in_place_index{};
+_LIBCPP_INLINE_VAR constexpr in_place_index_t<_Idx> in_place_index{};
 
 template  struct __is_inplace_type_imp : false_type {};
 template  struct __is_inplace_type_imp> : true_type {};
Index: include/__config
===
--- include/__config
+++ include/__config
@@ -978,9 +978,10 @@
 #define _LIBCPP_NODISCARD_AFTER_CXX17
 #endif
 
-// FIXME: Remove all usages of this macro once compilers catch up.
-#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606L)
-# define _LIBCPP_HAS_NO_INLINE_VARIABLES
+#if _LIBCPP_STD_VER > 14 && defined(__cpp_inline_variables) && (__cpp_inline_variables >= 201606L)
+# define _LIBCPP_INLINE_VAR  inline
+#else
+# define _LIBCPP_INLINE_VAR  
 #endif
 
 #ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r320708 - [clangd] Changed tracing interfaces

2017-12-14 Thread Ilya Biryukov via cfe-commits
Author: ibiryukov
Date: Thu Dec 14 07:33:38 2017
New Revision: 320708

URL: http://llvm.org/viewvc/llvm-project?rev=320708&view=rev
Log:
[clangd] Changed tracing interfaces

Summary:
EventTracer interface now contains two methods:
- spanEvent for events that have duration,
- instant for events that are instant.

Reviewers: sammccall

Reviewed By: sammccall

Subscribers: klimek, luckygeck, cfe-commits

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

Modified:
clang-tools-extra/trunk/clangd/Trace.cpp
clang-tools-extra/trunk/clangd/Trace.h

Modified: clang-tools-extra/trunk/clangd/Trace.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Trace.cpp?rev=320708&r1=320707&r2=320708&view=diff
==
--- clang-tools-extra/trunk/clangd/Trace.cpp (original)
+++ clang-tools-extra/trunk/clangd/Trace.cpp Thu Dec 14 07:33:38 2017
@@ -44,10 +44,24 @@ public:
 Out.flush();
   }
 
+  EndEventCallback beginSpan(const Context &Ctx,
+ llvm::StringRef Name) override {
+jsonEvent("B", json::obj{{"name", Name}});
+
+// The callback that will run when event ends.
+return [this](json::Expr &&Args) {
+  jsonEvent("E", json::obj{{"args", std::move(Args)}});
+};
+  }
+
+  void instant(const Context &Ctx, llvm::StringRef Name,
+   json::obj &&Args) override {
+jsonEvent("i", json::obj{{"name", Name}, {"args", std::move(Args)}});
+  }
+
   // Record an event on the current thread. ph, pid, tid, ts are set.
   // Contents must be a list of the other JSON key/values.
-  void event(const Context &Ctx, StringRef Phase,
- json::obj &&Contents) override {
+  void jsonEvent(StringRef Phase, json::obj &&Contents) {
 uint64_t TID = get_threadid();
 std::lock_guard Lock(Mu);
 // If we haven't already, emit metadata describing this thread.
@@ -109,30 +123,26 @@ std::unique_ptr createJSONT
 void log(const Context &Ctx, const Twine &Message) {
   if (!T)
 return;
-  T->event(Ctx, "i",
-   json::obj{
-   {"name", "Log"},
-   {"args", json::obj{{"Message", Message.str()}}},
-   });
+  T->instant(Ctx, "Log", json::obj{{"Message", Message.str()}});
 }
 
-Span::Span(const Context &Ctx, std::string Name) {
+Span::Span(const Context &Ctx, llvm::StringRef Name) {
   if (!T)
 return;
-  // Clone the context, so that the original Context can be moved.
-  this->Ctx.emplace(Ctx.clone());
 
-  T->event(*this->Ctx, "B", json::obj{{"name", std::move(Name)}});
+  Callback = T->beginSpan(Ctx, Name);
+  if (!Callback)
+return;
+
   Args = llvm::make_unique();
 }
 
 Span::~Span() {
-  if (!T)
+  if (!Callback)
 return;
-  if (!Args)
-Args = llvm::make_unique();
-  T->event(*Ctx, "E",
-   Args ? json::obj{{"args", std::move(*Args)}} : json::obj{});
+
+  assert(Args && "Args must be non-null if Callback is defined");
+  Callback(std::move(*Args));
 }
 
 } // namespace trace

Modified: clang-tools-extra/trunk/clangd/Trace.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Trace.h?rev=320708&r1=320707&r2=320708&view=diff
==
--- clang-tools-extra/trunk/clangd/Trace.h (original)
+++ clang-tools-extra/trunk/clangd/Trace.h Thu Dec 14 07:33:38 2017
@@ -19,6 +19,7 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
 #include "Context.h"
+#include "Function.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
@@ -28,12 +29,24 @@ namespace clangd {
 namespace trace {
 
 /// A consumer of trace events. The events are produced by Spans and 
trace::log.
+/// Implmentations of this interface must be thread-safe.
 class EventTracer {
 public:
+  /// A callback executed when an event with duration ends. Args represent data
+  /// that was attached to the event via SPAN_ATTACH.
+  using EndEventCallback = UniqueFunction;
+
   virtual ~EventTracer() = default;
-  /// Consume a trace event.
-  virtual void event(const Context &Ctx, llvm::StringRef Phase,
- json::obj &&Contents) = 0;
+
+  /// Called when event that has a duration starts. The returned callback will
+  /// be executed when the event ends. \p Name is a descriptive name
+  /// of the event that was passed to Span constructor.
+  virtual EndEventCallback beginSpan(const Context &Ctx,
+ llvm::StringRef Name) = 0;
+
+  /// Called for instant events.
+  virtual void instant(const Context &Ctx, llvm::StringRef Name,
+   json::obj &&Args) = 0;
 };
 
 /// Sets up a global EventTracer that consumes events produced by Span and
@@ -50,9 +63,6 @@ public:
 ///
 /// The format is documented here:
 /// 
https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
-///
-/// The implementation supports concurrent calls and can be used

[PATCH] D41239: Turn a config macro (_LIBCPP_HAS_NO_INLINE_VARIABLES) into an attribute macro (_LIBCPP_INLINE_VAR)

2017-12-14 Thread Marshall Clow via Phabricator via cfe-commits
mclow.lists added a comment.

There are no tests because this should not change any functionality.


https://reviews.llvm.org/D41239



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


[PATCH] D40489: [clangd] Changed tracing interfaces

2017-12-14 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rCTE320708: [clangd] Changed tracing interfaces (authored by 
ibiryukov, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D40489?vs=126957&id=126959#toc

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40489

Files:
  clangd/Trace.cpp
  clangd/Trace.h

Index: clangd/Trace.cpp
===
--- clangd/Trace.cpp
+++ clangd/Trace.cpp
@@ -44,10 +44,24 @@
 Out.flush();
   }
 
+  EndEventCallback beginSpan(const Context &Ctx,
+ llvm::StringRef Name) override {
+jsonEvent("B", json::obj{{"name", Name}});
+
+// The callback that will run when event ends.
+return [this](json::Expr &&Args) {
+  jsonEvent("E", json::obj{{"args", std::move(Args)}});
+};
+  }
+
+  void instant(const Context &Ctx, llvm::StringRef Name,
+   json::obj &&Args) override {
+jsonEvent("i", json::obj{{"name", Name}, {"args", std::move(Args)}});
+  }
+
   // Record an event on the current thread. ph, pid, tid, ts are set.
   // Contents must be a list of the other JSON key/values.
-  void event(const Context &Ctx, StringRef Phase,
- json::obj &&Contents) override {
+  void jsonEvent(StringRef Phase, json::obj &&Contents) {
 uint64_t TID = get_threadid();
 std::lock_guard Lock(Mu);
 // If we haven't already, emit metadata describing this thread.
@@ -109,30 +123,26 @@
 void log(const Context &Ctx, const Twine &Message) {
   if (!T)
 return;
-  T->event(Ctx, "i",
-   json::obj{
-   {"name", "Log"},
-   {"args", json::obj{{"Message", Message.str()}}},
-   });
+  T->instant(Ctx, "Log", json::obj{{"Message", Message.str()}});
 }
 
-Span::Span(const Context &Ctx, std::string Name) {
+Span::Span(const Context &Ctx, llvm::StringRef Name) {
   if (!T)
 return;
-  // Clone the context, so that the original Context can be moved.
-  this->Ctx.emplace(Ctx.clone());
 
-  T->event(*this->Ctx, "B", json::obj{{"name", std::move(Name)}});
+  Callback = T->beginSpan(Ctx, Name);
+  if (!Callback)
+return;
+
   Args = llvm::make_unique();
 }
 
 Span::~Span() {
-  if (!T)
+  if (!Callback)
 return;
-  if (!Args)
-Args = llvm::make_unique();
-  T->event(*Ctx, "E",
-   Args ? json::obj{{"args", std::move(*Args)}} : json::obj{});
+
+  assert(Args && "Args must be non-null if Callback is defined");
+  Callback(std::move(*Args));
 }
 
 } // namespace trace
Index: clangd/Trace.h
===
--- clangd/Trace.h
+++ clangd/Trace.h
@@ -19,6 +19,7 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
 
 #include "Context.h"
+#include "Function.h"
 #include "JSONExpr.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
@@ -28,12 +29,24 @@
 namespace trace {
 
 /// A consumer of trace events. The events are produced by Spans and trace::log.
+/// Implmentations of this interface must be thread-safe.
 class EventTracer {
 public:
+  /// A callback executed when an event with duration ends. Args represent data
+  /// that was attached to the event via SPAN_ATTACH.
+  using EndEventCallback = UniqueFunction;
+
   virtual ~EventTracer() = default;
-  /// Consume a trace event.
-  virtual void event(const Context &Ctx, llvm::StringRef Phase,
- json::obj &&Contents) = 0;
+
+  /// Called when event that has a duration starts. The returned callback will
+  /// be executed when the event ends. \p Name is a descriptive name
+  /// of the event that was passed to Span constructor.
+  virtual EndEventCallback beginSpan(const Context &Ctx,
+ llvm::StringRef Name) = 0;
+
+  /// Called for instant events.
+  virtual void instant(const Context &Ctx, llvm::StringRef Name,
+   json::obj &&Args) = 0;
 };
 
 /// Sets up a global EventTracer that consumes events produced by Span and
@@ -50,9 +63,6 @@
 ///
 /// The format is documented here:
 /// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
-///
-/// The implementation supports concurrent calls and can be used as a global
-/// tracer (i.e., can be put into a global Context).
 std::unique_ptr createJSONTracer(llvm::raw_ostream &OS,
   bool Pretty = false);
 
@@ -67,16 +77,16 @@
 /// SomeJSONExpr is evaluated and copied only if actually needed.
 class Span {
 public:
-  Span(const Context &Ctx, std::string Name);
+  Span(const Context &Ctx, llvm::StringRef Name);
   ~Span();
 
   /// Returns mutable span metadata if this span is interested.
   /// Prefer to use SPAN_ATTACH rather than accessing this directly.
   json::obj *args() { return Args.get(); }
 
 private:
-  llvm::Optional Ctx;
   std::unique_ptr Args;
+  EventTracer::EndEventCallback Callback;
 };
 
 #define SPAN_ATTACH(S, Name, E

r320709 - When attempting to complete an incomplete array bound type in an expression,

2017-12-14 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Thu Dec 14 07:40:16 2017
New Revision: 320709

URL: http://llvm.org/viewvc/llvm-project?rev=320709&view=rev
Log:
When attempting to complete an incomplete array bound type in an expression,
update the type from the definition even if we didn't instantiate a definition.

We may have instantiated the definition in an earlier stage of semantic
analysis, after creating the DeclRefExpr but before we reach a point where a
complete expression type is required.

Modified:
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/SemaTemplate/cxx17-inline-variables.cpp

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=320709&r1=320708&r2=320709&view=diff
==
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Dec 14 07:40:16 2017
@@ -7268,27 +7268,29 @@ static void processTypeAttrs(TypeProcess
 void Sema::completeExprArrayBound(Expr *E) {
   if (DeclRefExpr *DRE = dyn_cast(E->IgnoreParens())) {
 if (VarDecl *Var = dyn_cast(DRE->getDecl())) {
-  if (isTemplateInstantiation(Var->getTemplateSpecializationKind()) &&
-  !Var->getDefinition()) {
-SourceLocation PointOfInstantiation = E->getExprLoc();
-InstantiateVariableDefinition(PointOfInstantiation, Var);
+  if (isTemplateInstantiation(Var->getTemplateSpecializationKind())) {
 auto *Def = Var->getDefinition();
+if (!Def) {
+  SourceLocation PointOfInstantiation = E->getExprLoc();
+  InstantiateVariableDefinition(PointOfInstantiation, Var);
+  Def = Var->getDefinition();
 
-// If we don't already have a point of instantiation, and we managed to
-// instantiate a definition, this is the point of instantiation.
-// Otherwise, we don't request an end-of-TU instantiation, so this is
-// not a point of instantiation.
-// FIXME: Is this really the right behavior?
-if (Var->getPointOfInstantiation().isInvalid() && Def) {
-  assert(Var->getTemplateSpecializationKind() ==
- TSK_ImplicitInstantiation &&
- "explicit instantiation with no point of instantiation");
-  Var->setTemplateSpecializationKind(
-  Var->getTemplateSpecializationKind(), PointOfInstantiation);
+  // If we don't already have a point of instantiation, and we managed
+  // to instantiate a definition, this is the point of instantiation.
+  // Otherwise, we don't request an end-of-TU instantiation, so this is
+  // not a point of instantiation.
+  // FIXME: Is this really the right behavior?
+  if (Var->getPointOfInstantiation().isInvalid() && Def) {
+assert(Var->getTemplateSpecializationKind() ==
+   TSK_ImplicitInstantiation &&
+   "explicit instantiation with no point of instantiation");
+Var->setTemplateSpecializationKind(
+Var->getTemplateSpecializationKind(), PointOfInstantiation);
+  }
 }
 
-// Update the type to the newly instantiated definition's type both
-// here and within the expression.
+// Update the type to the definition's type both here and within the
+// expression.
 if (Def) {
   DRE->setDecl(Def);
   QualType T = Def->getType();

Modified: cfe/trunk/test/SemaTemplate/cxx17-inline-variables.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/cxx17-inline-variables.cpp?rev=320709&r1=320708&r2=320709&view=diff
==
--- cfe/trunk/test/SemaTemplate/cxx17-inline-variables.cpp (original)
+++ cfe/trunk/test/SemaTemplate/cxx17-inline-variables.cpp Thu Dec 14 07:40:16 
2017
@@ -5,3 +5,14 @@ template struct DominatorTreeBase
 };
 extern template class DominatorTreeBase;
 constexpr bool k = DominatorTreeBase::IsPostDominator;
+
+namespace CompleteType {
+  template constexpr int f(const bool (&)[N]) { return 0; }
+
+  template struct X {
+static constexpr bool arr[] = {V...};
+static constexpr int value = f(arr);
+  };
+
+  constexpr int n = X::value;
+}


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


[PATCH] D41240: [Solaris] __float128 is supported on Solaris/x86

2017-12-14 Thread Rainer Orth via Phabricator via cfe-commits
ro created this revision.
ro added a reviewer: rsmith.
Herald added a subscriber: fedor.sergeev.

When rebasing https://reviews.llvm.org/D40898 with GCC 5.4 on Solaris 11.4, I 
ran
into a few instances of

In file included from 
/vol/llvm/src/compiler-rt/local/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc:19:
In file included from 
/usr/gcc/5/lib/gcc/x86_64-pc-solaris2.11/5.4.0/../../../../include/c++/5.4.0/string:40:
In file included from 
/usr/gcc/5/lib/gcc/x86_64-pc-solaris2.11/5.4.0/../../../../include/c++/5.4.0/bits/char_traits.h:39:
In file included from 
/usr/gcc/5/lib/gcc/x86_64-pc-solaris2.11/5.4.0/../../../../include/c++/5.4.0/bits/stl_algobase.h:64:
In file included from 
/usr/gcc/5/lib/gcc/x86_64-pc-solaris2.11/5.4.0/../../../../include/c++/5.4.0/bits/stl_pair.h:59:
In file included from 
/usr/gcc/5/lib/gcc/x86_64-pc-solaris2.11/5.4.0/../../../../include/c++/5.4.0/bits/move.h:57:
/usr/gcc/5/lib/gcc/x86_64-pc-solaris2.11/5.4.0/../../../../include/c++/5.4.0/type_traits:311:39:
 error: __float128 is not supported on this target

  struct __is_floating_point_helper<__float128>
^

during make check-all.  The line above is inside

#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)

  template<>
struct __is_floating_point_helper<__float128>
: public true_type { };

#endif

While the libstdc++ header indicates support for __float128, clang does not, but
should.  The following patch implements this and fixed those errors.


Repository:
  rC Clang

https://reviews.llvm.org/D41240

Files:
  lib/Basic/Targets/OSTargets.h


Index: lib/Basic/Targets/OSTargets.h
===
--- lib/Basic/Targets/OSTargets.h
+++ lib/Basic/Targets/OSTargets.h
@@ -545,12 +545,22 @@
 Builder.defineMacro("_LARGEFILE64_SOURCE");
 Builder.defineMacro("__EXTENSIONS__");
 Builder.defineMacro("_REENTRANT");
+if (this->HasFloat128)
+  Builder.defineMacro("__FLOAT128__");
   }
 
 public:
   SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
   : OSTargetInfo(Triple, Opts) {
 // FIXME: WIntType should be SignedLong
+switch (Triple.getArch()) {
+default:
+  break;
+case llvm::Triple::x86:
+case llvm::Triple::x86_64:
+  this->HasFloat128 = true;
+  break;
+}
   }
 };
 


Index: lib/Basic/Targets/OSTargets.h
===
--- lib/Basic/Targets/OSTargets.h
+++ lib/Basic/Targets/OSTargets.h
@@ -545,12 +545,22 @@
 Builder.defineMacro("_LARGEFILE64_SOURCE");
 Builder.defineMacro("__EXTENSIONS__");
 Builder.defineMacro("_REENTRANT");
+if (this->HasFloat128)
+  Builder.defineMacro("__FLOAT128__");
   }
 
 public:
   SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
   : OSTargetInfo(Triple, Opts) {
 // FIXME: WIntType should be SignedLong
+switch (Triple.getArch()) {
+default:
+  break;
+case llvm::Triple::x86:
+case llvm::Triple::x86_64:
+  this->HasFloat128 = true;
+  break;
+}
   }
 };
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41240: [Solaris] __float128 is supported on Solaris/x86

2017-12-14 Thread Rainer Orth via Phabricator via cfe-commits
ro added a comment.

I forgot: this patch is on top of https://reviews.llvm.org/D35755.


Repository:
  rC Clang

https://reviews.llvm.org/D41240



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


[PATCH] D40548: [clangd] Symbol index interfaces and an in-memory index implementation.

2017-12-14 Thread Eric Liu via Phabricator via cfe-commits
ioeric added a comment.

In https://reviews.llvm.org/D40548#955289, @malaperle wrote:

> In https://reviews.llvm.org/D40548#947081, @ioeric wrote:
>
> > Hi Marc, the patch is not ready for review yet. I am still cleaning up the 
> > prototype and will let you know when it's ready for review.
>
>
> I guess it was ready to review since it was submitted? ;)


Sorry! I should've pinged you before landing this. My apologies! I am happy to 
address any comment you have.




Comment at: clangd/index/Index.h:134
+  virtual bool
+  fuzzyFind(Context &Ctx, const FuzzyFindRequest &Req,
+std::function Callback) const = 0;

malaperle wrote:
> I think a more generic std::function would be useful, similar to the 
> indexstore's filter
> ```
> bool searchSymbols(llvm::function_ref 
> filter,
>  llvm::function_ref receiver)
> ```
Do you have an use case in mind which requires different filtering? This could 
probably be a separate interface. 

I think the behavior of fuzzy finding is well-defined, and how filtering is 
done is an implementation detail. User-specified filter might make 
implementation less flexible, especially for large indexes that are not managed 
in memory. 


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40548



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


[PATCH] D41241: [Solaris] Only define _REENTRANT if -pthread

2017-12-14 Thread Rainer Orth via Phabricator via cfe-commits
ro created this revision.
ro added a reviewer: rsmith.
Herald added a subscriber: fedor.sergeev.

When looking at lib/Basic/Targets/OSTargets.h, I noticed that _REENTRANT is 
defined
unconditionally on Solaris, unlike all other targets and what either Studio cc 
(only define
it with -mt) or gcc (only define it with -pthread) do.

This patch (on top of https://reviews.llvm.org/D41240) follows that lead.


Repository:
  rC Clang

https://reviews.llvm.org/D41241

Files:
  lib/Basic/Targets/OSTargets.h


Index: lib/Basic/Targets/OSTargets.h
===
--- lib/Basic/Targets/OSTargets.h
+++ lib/Basic/Targets/OSTargets.h
@@ -544,7 +544,8 @@
 Builder.defineMacro("_LARGEFILE_SOURCE");
 Builder.defineMacro("_LARGEFILE64_SOURCE");
 Builder.defineMacro("__EXTENSIONS__");
-Builder.defineMacro("_REENTRANT");
+if (Opts.POSIXThreads)
+  Builder.defineMacro("_REENTRANT");
 if (this->HasFloat128)
   Builder.defineMacro("__FLOAT128__");
   }


Index: lib/Basic/Targets/OSTargets.h
===
--- lib/Basic/Targets/OSTargets.h
+++ lib/Basic/Targets/OSTargets.h
@@ -544,7 +544,8 @@
 Builder.defineMacro("_LARGEFILE_SOURCE");
 Builder.defineMacro("_LARGEFILE64_SOURCE");
 Builder.defineMacro("__EXTENSIONS__");
-Builder.defineMacro("_REENTRANT");
+if (Opts.POSIXThreads)
+  Builder.defineMacro("_REENTRANT");
 if (this->HasFloat128)
   Builder.defineMacro("__FLOAT128__");
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41242: [Solaris] Silence -pthread warning on Solaris

2017-12-14 Thread Rainer Orth via Phabricator via cfe-commits
ro created this revision.
ro added a reviewer: rsmith.
Herald added a subscriber: fedor.sergeev.

During make check-all on Solaris, I see several instances of this warning:

clang-6.0: warning: argument unused during compilation: '-pthread' 
[-Wunused-command-line-argument]

Since Solaris 10, libpthread has been folded into libc, so there's nothing to 
do.  gcc
just ignores -pthread here.  Darwin claims the option to silence the warning, 
and
this patch follows that lead.


Repository:
  rC Clang

https://reviews.llvm.org/D41242

Files:
  lib/Driver/ToolChains/Solaris.cpp


Index: lib/Driver/ToolChains/Solaris.cpp
===
--- lib/Driver/ToolChains/Solaris.cpp
+++ lib/Driver/ToolChains/Solaris.cpp
@@ -71,6 +71,11 @@
   CmdArgs.push_back(
   Args.MakeArgString(getToolChain().GetFilePath("ld.so.1")));
 }
+
+// libpthread has been folded into libc since Solaris 10, no need to do
+// anything for pthreads. Claim argument to avoid warning.
+Args.ClaimAllArgs(options::OPT_pthread);
+Args.ClaimAllArgs(options::OPT_pthreads);
   }
 
   if (Output.isFilename()) {


Index: lib/Driver/ToolChains/Solaris.cpp
===
--- lib/Driver/ToolChains/Solaris.cpp
+++ lib/Driver/ToolChains/Solaris.cpp
@@ -71,6 +71,11 @@
   CmdArgs.push_back(
   Args.MakeArgString(getToolChain().GetFilePath("ld.so.1")));
 }
+
+// libpthread has been folded into libc since Solaris 10, no need to do
+// anything for pthreads. Claim argument to avoid warning.
+Args.ClaimAllArgs(options::OPT_pthread);
+Args.ClaimAllArgs(options::OPT_pthreads);
   }
 
   if (Output.isFilename()) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40671: [clang-tidy] Support specific checks for NOLINT directive

2017-12-14 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In https://reviews.llvm.org/D40671#954906, @xgsa wrote:

> In https://reviews.llvm.org/D40671#954661, @alexfh wrote:
>
> > In https://reviews.llvm.org/D40671#953888, @aaron.ballman wrote:
> >
> > > FWIW, I think we should do something about unknown check names in NOLINT 
> > > comments, but that can be done as a follow-up patch. If we're ignoring 
> > > the comment, we might want to diagnose that fact so users have an idea 
> > > what's going on.
> >
> >
> > IIUC, cpplint can output a diagnostic about unknown categories inside 
> > NOLINT and about NOLINT directives that happen on lines where no warning is 
> > emitted. Both would be useful in clang-tidy, IMO.
>
>
> I agree with your statements and I think there should be the following 
> diagnostics about NOLINT usage:
>
> - as you described, using of NOLINT with unknown check names;
> - using of NOLINT for the line, on which there is no diagnostics (at all with 
> NOLINT and for the swpecified diagnostics); this should help to detect 
> dangling NOLINT comments, that have no meaning anymore.
>
>   Moreover, there should be a way to turn on/off these diagnostics, so 
> possibily they should be a separate checks. What do you think? Is there a way 
> for a check to collect the emitted diagnostics?


I think this is desirable functionality and can be done in follow-up patches. 
NOLINT of unknown check names should be pretty easy, but detecting NOLINT 
comments on lines that do not trigger the specified diagnostic may be a bit 
more tricky.


https://reviews.llvm.org/D40671



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


[PATCH] D41240: [Solaris] __float128 is supported on Solaris/x86

2017-12-14 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

Mechanically, the code change looks fine, but I can't comment on whether this 
is a correct change for Solaris, or whether the type provided by `__float128` 
would use the right floating-point representation. You will also need to 
provide a test for this change.


Repository:
  rC Clang

https://reviews.llvm.org/D41240



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


[clang-tools-extra] r320713 - Add support for NOLINT and NOLINTNEXTLINE comments mentioning specific check names.

2017-12-14 Thread Aaron Ballman via cfe-commits
Author: aaronballman
Date: Thu Dec 14 08:13:57 2017
New Revision: 320713

URL: http://llvm.org/viewvc/llvm-project?rev=320713&view=rev
Log:
Add support for NOLINT and NOLINTNEXTLINE comments mentioning specific check 
names.

Supports a comma-separated list of check names to be disabled on the given 
line. Also supports * as a wildcard to disable all lint diagnostic messages on 
that line.

Patch by Anton (xgsa).

Modified:
clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
clang-tools-extra/trunk/docs/ReleaseNotes.rst
clang-tools-extra/trunk/docs/clang-tidy/index.rst
clang-tools-extra/trunk/test/clang-tidy/nolint.cpp
clang-tools-extra/trunk/test/clang-tidy/nolintnextline.cpp

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp?rev=320713&r1=320712&r2=320713&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Thu Dec 
14 08:13:57 2017
@@ -21,6 +21,7 @@
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include 
 #include 
@@ -290,7 +291,38 @@ void ClangTidyDiagnosticConsumer::finali
   LastErrorPassesLineFilter = false;
 }
 
-static bool LineIsMarkedWithNOLINT(SourceManager &SM, SourceLocation Loc) {
+static bool IsNOLINTFound(StringRef NolintDirectiveText, StringRef Line,
+  unsigned DiagID, const ClangTidyContext &Context) {
+  const size_t NolintIndex = Line.find(NolintDirectiveText);
+  if (NolintIndex == StringRef::npos)
+return false;
+
+  size_t BracketIndex = NolintIndex + NolintDirectiveText.size();
+  // Check if the specific checks are specified in brackets.
+  if (BracketIndex < Line.size() && Line[BracketIndex] == '(') {
+++BracketIndex;
+const size_t BracketEndIndex = Line.find(')', BracketIndex);
+if (BracketEndIndex != StringRef::npos) {
+  StringRef ChecksStr =
+  Line.substr(BracketIndex, BracketEndIndex - BracketIndex);
+  // Allow disabling all the checks with "*".
+  if (ChecksStr != "*") {
+StringRef CheckName = Context.getCheckName(DiagID);
+// Allow specifying a few check names, delimited with comma.
+SmallVector Checks;
+ChecksStr.split(Checks, ',', -1, false);
+llvm::transform(Checks, Checks.begin(),
+[](StringRef S) { return S.trim(); });
+return llvm::find(Checks, CheckName) != Checks.end();
+  }
+}
+  }
+  return true;
+}
+
+static bool LineIsMarkedWithNOLINT(SourceManager &SM, SourceLocation Loc,
+   unsigned DiagID,
+   const ClangTidyContext &Context) {
   bool Invalid;
   const char *CharacterData = SM.getCharacterData(Loc, &Invalid);
   if (Invalid)
@@ -301,8 +333,7 @@ static bool LineIsMarkedWithNOLINT(Sourc
   while (*P != '\0' && *P != '\r' && *P != '\n')
 ++P;
   StringRef RestOfLine(CharacterData, P - CharacterData + 1);
-  // FIXME: Handle /\bNOLINT\b(\([^)]*\))?/ as cpplint.py does.
-  if (RestOfLine.find("NOLINT") != StringRef::npos)
+  if (IsNOLINTFound("NOLINT", RestOfLine, DiagID, Context))
 return true;
 
   // Check if there's a NOLINTNEXTLINE on the previous line.
@@ -329,16 +360,17 @@ static bool LineIsMarkedWithNOLINT(Sourc
 --P;
 
   RestOfLine = StringRef(P, LineEnd - P + 1);
-  if (RestOfLine.find("NOLINTNEXTLINE") != StringRef::npos)
+  if (IsNOLINTFound("NOLINTNEXTLINE", RestOfLine, DiagID, Context))
 return true;
 
   return false;
 }
 
-static bool LineIsMarkedWithNOLINTinMacro(SourceManager &SM,
-  SourceLocation Loc) {
+static bool LineIsMarkedWithNOLINTinMacro(SourceManager &SM, SourceLocation 
Loc,
+  unsigned DiagID,
+  const ClangTidyContext &Context) {
   while (true) {
-if (LineIsMarkedWithNOLINT(SM, Loc))
+if (LineIsMarkedWithNOLINT(SM, Loc, DiagID, Context))
   return true;
 if (!Loc.isMacroID())
   return false;
@@ -355,7 +387,8 @@ void ClangTidyDiagnosticConsumer::Handle
   if (Info.getLocation().isValid() && DiagLevel != DiagnosticsEngine::Error &&
   DiagLevel != DiagnosticsEngine::Fatal &&
   LineIsMarkedWithNOLINTinMacro(Diags->getSourceManager(),
-Info.getLocation())) {
+Info.getLocation(), Info.getID(),
+Context)) {
 ++Context.Stats.ErrorsIgnoredNOLINT;
 // Ignored a warning, should ignore related notes as well
 LastErrorWasIgnored = true;

Modified: cla

[PATCH] D20124: [PCH] Serialize skipped preprocessor ranges

2017-12-14 Thread Cameron via Phabricator via cfe-commits
cameron314 added a comment.

Ping?
The patch is ready to go, just needs a final approval...


https://reviews.llvm.org/D20124



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


[PATCH] D41195: [ClangFormat] IndentWrappedFunctionNames should be true in the google ObjC style

2017-12-14 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton updated this revision to Diff 126969.
benhamilton marked an inline comment as done.
benhamilton added a comment.

- Use 40 column limit for test.


Repository:
  rC Clang

https://reviews.llvm.org/D41195

Files:
  lib/Format/Format.cpp
  unittests/Format/FormatTestObjC.cpp


Index: unittests/Format/FormatTestObjC.cpp
===
--- unittests/Format/FormatTestObjC.cpp
+++ unittests/Format/FormatTestObjC.cpp
@@ -382,9 +382,9 @@
"ofSize:(size_t)height\n"
"  :(size_t)width;");
 
+  Style = getGoogleStyle(FormatStyle::LK_ObjC);
   // Continuation indent width should win over aligning colons if the function
   // name is long.
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
   Style.ColumnLimit = 40;
   Style.IndentWrappedFunctionNames = true;
   verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
@@ -395,7 +395,10 @@
   verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
"   aShortf:(NSRect)theRect {\n"
"}");
-
+  // Wrapped method parameters should be indented.
+  verifyFormat("- (LongReturnTypeName)\n"
+   "longParam:(ParamName)longParamName\n"
+   "param:(paramName)paramName;");
   // Format pairs correctly.
   Style.ColumnLimit = 80;
   verifyFormat("- (void)drawRectOn:(id)surface\n"
Index: lib/Format/Format.cpp
===
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -732,6 +732,7 @@
 GoogleStyle.SpacesInContainerLiterals = false;
   } else if (Language == FormatStyle::LK_ObjC) {
 GoogleStyle.ColumnLimit = 100;
+GoogleStyle.IndentWrappedFunctionNames = true;
   }
 
   return GoogleStyle;


Index: unittests/Format/FormatTestObjC.cpp
===
--- unittests/Format/FormatTestObjC.cpp
+++ unittests/Format/FormatTestObjC.cpp
@@ -382,9 +382,9 @@
"ofSize:(size_t)height\n"
"  :(size_t)width;");
 
+  Style = getGoogleStyle(FormatStyle::LK_ObjC);
   // Continuation indent width should win over aligning colons if the function
   // name is long.
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
   Style.ColumnLimit = 40;
   Style.IndentWrappedFunctionNames = true;
   verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
@@ -395,7 +395,10 @@
   verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
"   aShortf:(NSRect)theRect {\n"
"}");
-
+  // Wrapped method parameters should be indented.
+  verifyFormat("- (LongReturnTypeName)\n"
+   "longParam:(ParamName)longParamName\n"
+   "param:(paramName)paramName;");
   // Format pairs correctly.
   Style.ColumnLimit = 80;
   verifyFormat("- (void)drawRectOn:(id)surface\n"
Index: lib/Format/Format.cpp
===
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -732,6 +732,7 @@
 GoogleStyle.SpacesInContainerLiterals = false;
   } else if (Language == FormatStyle::LK_ObjC) {
 GoogleStyle.ColumnLimit = 100;
+GoogleStyle.IndentWrappedFunctionNames = true;
   }
 
   return GoogleStyle;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41195: [ClangFormat] IndentWrappedFunctionNames should be true in the google ObjC style

2017-12-14 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton added inline comments.



Comment at: unittests/Format/FormatTestObjC.cpp:388
+  // Wrapped method parameters should be indented.
+  verifyFormat("- (VeryLongReturnTypeName)\n"
+   "veryLongMethodParameter:(VeryLongParameterName)"

djasper wrote:
> Set Style.ColumnLimit to something lower so that you don't have to wrap 
> single lines (for better test readability).
Good call, done. I was wondering why tests were doing that, should have 
realized.


Repository:
  rC Clang

https://reviews.llvm.org/D41195



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


r320714 - [ClangFormat] IndentWrappedFunctionNames should be true in the google ObjC style

2017-12-14 Thread Ben Hamilton via cfe-commits
Author: benhamilton
Date: Thu Dec 14 08:17:38 2017
New Revision: 320714

URL: http://llvm.org/viewvc/llvm-project?rev=320714&view=rev
Log:
[ClangFormat] IndentWrappedFunctionNames should be true in the google ObjC style

Summary:
If we write the following code, it goes over 100 columns, so we need to wrap it:

```
- 
(VeryLongReturnTypeName)veryLongMethodParameter:(VeryLongParameterName)thisIsAVeryLongParameterName
  
longMethodParameter:(LongParameterName)thisIsAlsoAnotherLongParameterName;
```

Currently, clang-format with the google style aligns the method parameter names 
on the first column:

```
- (VeryLongReturnTypeName)
veryLongMethodParameter:(VeryLongParameterName)thisIsAVeryLongParameterName
longMethodParameter:(LongParameterName)thisIsAlsoAnotherLongParameterName;
```

We'd like clang-format in the google style to align these to column 4 for 
Objective-C:

```
- (VeryLongReturnTypeName)
veryLongMethodParameter:(VeryLongParameterName)thisIsAVeryLongParameterName

longMethodParameter:(LongParameterName)thisIsAlsoAnotherLongParameterName;
```

Test Plan: make -j12 FormatTests && ./tools/clang/unittests/Format/FormatTests

Reviewers: krasimir, djasper, klimek

Reviewed By: djasper

Subscribers: cfe-commits, thakis

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

Modified:
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/unittests/Format/FormatTestObjC.cpp

Modified: cfe/trunk/lib/Format/Format.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=320714&r1=320713&r2=320714&view=diff
==
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Thu Dec 14 08:17:38 2017
@@ -732,6 +732,7 @@ FormatStyle getGoogleStyle(FormatStyle::
 GoogleStyle.SpacesInContainerLiterals = false;
   } else if (Language == FormatStyle::LK_ObjC) {
 GoogleStyle.ColumnLimit = 100;
+GoogleStyle.IndentWrappedFunctionNames = true;
   }
 
   return GoogleStyle;

Modified: cfe/trunk/unittests/Format/FormatTestObjC.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestObjC.cpp?rev=320714&r1=320713&r2=320714&view=diff
==
--- cfe/trunk/unittests/Format/FormatTestObjC.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestObjC.cpp Thu Dec 14 08:17:38 2017
@@ -382,9 +382,9 @@ TEST_F(FormatTestObjC, FormatObjCMethodD
"ofSize:(size_t)height\n"
"  :(size_t)width;");
 
+  Style = getGoogleStyle(FormatStyle::LK_ObjC);
   // Continuation indent width should win over aligning colons if the function
   // name is long.
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
   Style.ColumnLimit = 40;
   Style.IndentWrappedFunctionNames = true;
   verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
@@ -395,7 +395,10 @@ TEST_F(FormatTestObjC, FormatObjCMethodD
   verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
"   aShortf:(NSRect)theRect {\n"
"}");
-
+  // Wrapped method parameters should be indented.
+  verifyFormat("- (LongReturnTypeName)\n"
+   "longParam:(ParamName)longParamName\n"
+   "param:(paramName)paramName;");
   // Format pairs correctly.
   Style.ColumnLimit = 80;
   verifyFormat("- (void)drawRectOn:(id)surface\n"


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


[PATCH] D41195: [ClangFormat] IndentWrappedFunctionNames should be true in the google ObjC style

2017-12-14 Thread Ben Hamilton via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC320714: [ClangFormat] IndentWrappedFunctionNames should be 
true in the google ObjC style (authored by benhamilton, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D41195?vs=126969&id=126970#toc

Repository:
  rC Clang

https://reviews.llvm.org/D41195

Files:
  lib/Format/Format.cpp
  unittests/Format/FormatTestObjC.cpp


Index: lib/Format/Format.cpp
===
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -732,6 +732,7 @@
 GoogleStyle.SpacesInContainerLiterals = false;
   } else if (Language == FormatStyle::LK_ObjC) {
 GoogleStyle.ColumnLimit = 100;
+GoogleStyle.IndentWrappedFunctionNames = true;
   }
 
   return GoogleStyle;
Index: unittests/Format/FormatTestObjC.cpp
===
--- unittests/Format/FormatTestObjC.cpp
+++ unittests/Format/FormatTestObjC.cpp
@@ -382,9 +382,9 @@
"ofSize:(size_t)height\n"
"  :(size_t)width;");
 
+  Style = getGoogleStyle(FormatStyle::LK_ObjC);
   // Continuation indent width should win over aligning colons if the function
   // name is long.
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
   Style.ColumnLimit = 40;
   Style.IndentWrappedFunctionNames = true;
   verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
@@ -395,7 +395,10 @@
   verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
"   aShortf:(NSRect)theRect {\n"
"}");
-
+  // Wrapped method parameters should be indented.
+  verifyFormat("- (LongReturnTypeName)\n"
+   "longParam:(ParamName)longParamName\n"
+   "param:(paramName)paramName;");
   // Format pairs correctly.
   Style.ColumnLimit = 80;
   verifyFormat("- (void)drawRectOn:(id)surface\n"


Index: lib/Format/Format.cpp
===
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -732,6 +732,7 @@
 GoogleStyle.SpacesInContainerLiterals = false;
   } else if (Language == FormatStyle::LK_ObjC) {
 GoogleStyle.ColumnLimit = 100;
+GoogleStyle.IndentWrappedFunctionNames = true;
   }
 
   return GoogleStyle;
Index: unittests/Format/FormatTestObjC.cpp
===
--- unittests/Format/FormatTestObjC.cpp
+++ unittests/Format/FormatTestObjC.cpp
@@ -382,9 +382,9 @@
"ofSize:(size_t)height\n"
"  :(size_t)width;");
 
+  Style = getGoogleStyle(FormatStyle::LK_ObjC);
   // Continuation indent width should win over aligning colons if the function
   // name is long.
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
   Style.ColumnLimit = 40;
   Style.IndentWrappedFunctionNames = true;
   verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
@@ -395,7 +395,10 @@
   verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
"   aShortf:(NSRect)theRect {\n"
"}");
-
+  // Wrapped method parameters should be indented.
+  verifyFormat("- (LongReturnTypeName)\n"
+   "longParam:(ParamName)longParamName\n"
+   "param:(paramName)paramName;");
   // Format pairs correctly.
   Style.ColumnLimit = 80;
   verifyFormat("- (void)drawRectOn:(id)surface\n"
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40671: [clang-tidy] Support specific checks for NOLINT directive

2017-12-14 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman closed this revision.
aaron.ballman added a comment.

Committed in r320713.


https://reviews.llvm.org/D40671



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


[PATCH] D40813: [clang-tidy] Adding Fuchsia checker for virtual inheritance

2017-12-14 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: test/clang-tidy/fuchsia-virtual-inheritance.cpp:34-36
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: constructing a class that 
inherits a virtual base class is disallowed [fuchsia-virtual-inheritance]
+  // CHECK-NEXT:  D(int value) : A(value), B(), C() {}
+  // CHECK-MESSAGES: [[@LINE-3]]:33: warning: constructing a class that 
inherits a virtual base class is disallowed [fuchsia-virtual-inheritance]

juliehockett wrote:
> aaron.ballman wrote:
> > I'm also not certain this should be diagnosed either. It's technically 
> > correct because it's calling the base class constructors here, but at the 
> > same time, it seems very low-value and likely to cause the user to do 
> > something really bad, like silence the warning by not calling the base 
> > class constructors.
> I see what you mean, but where then would you draw the line between warning 
> and not? We could warn for construction everywhere except in initialization 
> lists, but that seems like it might open the door to trivially get around the 
> check in ways that should be disallowed.
Would it be sufficient to only flag at the point of inheritance, or do you have 
existing header files with class declarations using virtual inheritance and are 
worried about consumers inheriting from those?

e.g., flag declarations but not construction.


https://reviews.llvm.org/D40813



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


r320717 - [OPENMP] Add codegen for target data constructs with `nowait` clause.

2017-12-14 Thread Alexey Bataev via cfe-commits
Author: abataev
Date: Thu Dec 14 09:00:17 2017
New Revision: 320717

URL: http://llvm.org/viewvc/llvm-project?rev=320717&view=rev
Log:
[OPENMP] Add codegen for target data constructs with `nowait` clause.

Added codegen for the `nowait` clause in target data constructs.

Modified:
cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
cfe/trunk/test/OpenMP/target_enter_data_codegen.cpp
cfe/trunk/test/OpenMP/target_exit_data_codegen.cpp
cfe/trunk/test/OpenMP/target_update_codegen.cpp

Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=320717&r1=320716&r2=320717&view=diff
==
--- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Thu Dec 14 09:00:17 2017
@@ -691,12 +691,24 @@ enum OpenMPRTLFunction {
   // Call to void __tgt_target_data_begin(int64_t device_id, int32_t arg_num,
   // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
   OMPRTL__tgt_target_data_begin,
+  // Call to void __tgt_target_data_begin_nowait(int64_t device_id, int32_t
+  // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
+  // *arg_types);
+  OMPRTL__tgt_target_data_begin_nowait,
   // Call to void __tgt_target_data_end(int64_t device_id, int32_t arg_num,
   // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
   OMPRTL__tgt_target_data_end,
+  // Call to void __tgt_target_data_end_nowait(int64_t device_id, int32_t
+  // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
+  // *arg_types);
+  OMPRTL__tgt_target_data_end_nowait,
   // Call to void __tgt_target_data_update(int64_t device_id, int32_t arg_num,
   // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
   OMPRTL__tgt_target_data_update,
+  // Call to void __tgt_target_data_update_nowait(int64_t device_id, int32_t
+  // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
+  // *arg_types);
+  OMPRTL__tgt_target_data_update_nowait,
 };
 
 /// A basic class for pre|post-action for advanced codegen sequence for OpenMP
@@ -2136,6 +2148,21 @@ CGOpenMPRuntime::createRuntimeFunction(u
 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_begin");
 break;
   }
+  case OMPRTL__tgt_target_data_begin_nowait: {
+// Build void __tgt_target_data_begin_nowait(int64_t device_id, int32_t
+// arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
+// *arg_types);
+llvm::Type *TypeParams[] = {CGM.Int64Ty,
+CGM.Int32Ty,
+CGM.VoidPtrPtrTy,
+CGM.VoidPtrPtrTy,
+CGM.SizeTy->getPointerTo(),
+CGM.Int64Ty->getPointerTo()};
+auto *FnTy =
+llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
+RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_begin_nowait");
+break;
+  }
   case OMPRTL__tgt_target_data_end: {
 // Build void __tgt_target_data_end(int64_t device_id, int32_t arg_num,
 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
@@ -2150,6 +2177,21 @@ CGOpenMPRuntime::createRuntimeFunction(u
 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_end");
 break;
   }
+  case OMPRTL__tgt_target_data_end_nowait: {
+// Build void __tgt_target_data_end_nowait(int64_t device_id, int32_t
+// arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
+// *arg_types);
+llvm::Type *TypeParams[] = {CGM.Int64Ty,
+CGM.Int32Ty,
+CGM.VoidPtrPtrTy,
+CGM.VoidPtrPtrTy,
+CGM.SizeTy->getPointerTo(),
+CGM.Int64Ty->getPointerTo()};
+auto *FnTy =
+llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
+RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_end_nowait");
+break;
+  }
   case OMPRTL__tgt_target_data_update: {
 // Build void __tgt_target_data_update(int64_t device_id, int32_t arg_num,
 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
@@ -2164,6 +2206,21 @@ CGOpenMPRuntime::createRuntimeFunction(u
 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_update");
 break;
   }
+  case OMPRTL__tgt_target_data_update_nowait: {
+// Build void __tgt_target_data_update_nowait(int64_t device_id, int32_t
+// arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
+// *arg_types);
+llvm::Type *TypeParams[] = {CGM.Int64Ty,
+CGM.Int32Ty,
+CGM.VoidPtrPtrTy,
+CGM.VoidPtrPtrTy,
+CGM.SizeTy->getPointerTo(),
+

[PATCH] D39571: [clangd] DidChangeConfiguration Notification

2017-12-14 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 126980.
Nebiroth marked 5 inline comments as done.
Nebiroth added a comment.

Removed test file
Added mutex lock when changing CDB
Minor code cleanup


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D39571

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/DraftStore.cpp
  clangd/DraftStore.h
  clangd/GlobalCompilationDatabase.cpp
  clangd/GlobalCompilationDatabase.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/ProtocolHandlers.h
  test/clangd/initialize-params-invalid.test
  test/clangd/initialize-params.test

Index: test/clangd/initialize-params.test
===
--- test/clangd/initialize-params.test
+++ test/clangd/initialize-params.test
@@ -18,9 +18,10 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
-# CHECK-NEXT:  "documentHighlightProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
@@ -49,4 +50,4 @@
 # CHECK-NEXT:  "result": null
 Content-Length: 33
 
-{"jsonrpc":"2.0":"method":"exit"}
+{"jsonrpc":"2.0":"method":"exit"}
\ No newline at end of file
Index: test/clangd/initialize-params-invalid.test
===
--- test/clangd/initialize-params-invalid.test
+++ test/clangd/initialize-params-invalid.test
@@ -18,9 +18,10 @@
 # CHECK-NEXT:  ":"
 # CHECK-NEXT:]
 # CHECK-NEXT:  },
+# CHECK-NEXT:  "configurationChangeProvider": true,
 # CHECK-NEXT:  "definitionProvider": true,
 # CHECK-NEXT:  "documentFormattingProvider": true,
-# CHECK-NEXT:  "documentHighlightProvider": true,
+# CHECK-NEXT:	   "documentHighlightProvider": true,
 # CHECK-NEXT:  "documentOnTypeFormattingProvider": {
 # CHECK-NEXT:"firstTriggerCharacter": "}",
 # CHECK-NEXT:"moreTriggerCharacter": []
Index: clangd/ProtocolHandlers.h
===
--- clangd/ProtocolHandlers.h
+++ clangd/ProtocolHandlers.h
@@ -57,6 +57,8 @@
   virtual void onRename(Ctx C, RenameParams &Parames) = 0;
   virtual void onDocumentHighlight(Ctx C,
TextDocumentPositionParams &Params) = 0;
+  virtual void onChangeConfiguration(Ctx C,
+ DidChangeConfigurationParams &Params) = 0;
 };
 
 void registerCallbackHandlers(JSONRPCDispatcher &Dispatcher, JSONOutput &Out,
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -73,4 +73,6 @@
   Register("workspace/executeCommand", &ProtocolCallbacks::onCommand);
   Register("textDocument/documentHighlight",
&ProtocolCallbacks::onDocumentHighlight);
+  Register("workspace/didChangeConfiguration",
+   &ProtocolCallbacks::onChangeConfiguration);
 }
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -257,6 +257,24 @@
 };
 bool fromJSON(const json::Expr &, DidChangeWatchedFilesParams &);
 
+/// Clangd extension to manage a workspace/didChangeConfiguration notification
+/// since the data received is described as 'any' type in LSP.
+struct ClangdConfigurationParamsChange {
+  llvm::Optional compilationDatabasePath;
+};
+bool fromJSON(const json::Expr &, ClangdConfigurationParamsChange &);
+
+struct DidChangeConfigurationParams {
+  DidChangeConfigurationParams() = default;
+  DidChangeConfigurationParams(ClangdConfigurationParamsChange settings): settings(settings) {}
+
+  // We use this predefined struct because it is easier to use
+  // than the protocol specified type of 'any'.
+  ClangdConfigurationParamsChange settings;
+};
+bool fromJSON(const json::Expr &, DidChangeConfigurationParams &);
+json::Expr toJSON(const DidChangeConfigurationParams &);
+
 struct FormattingOptions {
   /// Size of a tab in spaces.
   int tabSize;
Index: clangd/Protocol.cpp
===
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -366,5 +366,21 @@
   };
 }
 
+bool fromJSON(const json::Expr &Params, DidChangeConfigurationParams &CCP) {
+  json::ObjectMapper O(Params);
+  return O && O.map("settings", CCP.settings);
+}
+
+json::Expr toJSON(const DidChangeConfigurationParams &CCP) {
+  return json::obj{
+{"settings", CCP.settings},
+  };
+}
+
+bool fromJSON(const json::Expr &Params, ClangdConfigurationParamsChange &CCPC) {
+  json::ObjectMapper O(Params);
+  re

[PATCH] D39375: [clang] Add PPCallbacks list to preprocessor when building a preacompiled preamble.

2017-12-14 Thread William Enright via Phabricator via cfe-commits
Nebiroth updated this revision to Diff 126984.
Nebiroth marked an inline comment as done.
Nebiroth added a comment.

Minor code cleanup


Repository:
  rC Clang

https://reviews.llvm.org/D39375

Files:
  include/clang/Frontend/PrecompiledPreamble.h
  lib/Frontend/PrecompiledPreamble.cpp


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -351,6 +351,10 @@
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
+  std::unique_ptr DelegatedPPCallbacks = 
Callbacks.createPPCallbacks();
+
+  if (DelegatedPPCallbacks)
+Clang->getPreprocessor().addPPCallbacks(std::move(DelegatedPPCallbacks));
   Act->Execute();
 
   // Run the callbacks.
@@ -709,6 +713,7 @@
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
 void PreambleCallbacks::HandleMacroDefined(const Token &MacroNameTok,
const MacroDirective *MD) {}
+std::unique_ptr PreambleCallbacks::createPPCallbacks() {return 
nullptr;}
 
 std::error_code clang::make_error_code(BuildPreambleError Error) {
   return std::error_code(static_cast(Error), 
BuildPreambleErrorCategory());
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -260,6 +260,9 @@
   /// used instead, but having only this method allows a simpler API.
   virtual void HandleMacroDefined(const Token &MacroNameTok,
   const MacroDirective *MD);
+  /// Creates wrapper class for PPCallbacks so we can also process information
+  /// about includes that are inside of a preamble
+  virtual std::unique_ptr createPPCallbacks();
 };
 
 enum class BuildPreambleError {


Index: lib/Frontend/PrecompiledPreamble.cpp
===
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -351,6 +351,10 @@
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
 return BuildPreambleError::BeginSourceFileFailed;
 
+  std::unique_ptr DelegatedPPCallbacks = Callbacks.createPPCallbacks();
+
+  if (DelegatedPPCallbacks)
+Clang->getPreprocessor().addPPCallbacks(std::move(DelegatedPPCallbacks));
   Act->Execute();
 
   // Run the callbacks.
@@ -709,6 +713,7 @@
 void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
 void PreambleCallbacks::HandleMacroDefined(const Token &MacroNameTok,
const MacroDirective *MD) {}
+std::unique_ptr PreambleCallbacks::createPPCallbacks() {return nullptr;}
 
 std::error_code clang::make_error_code(BuildPreambleError Error) {
   return std::error_code(static_cast(Error), BuildPreambleErrorCategory());
Index: include/clang/Frontend/PrecompiledPreamble.h
===
--- include/clang/Frontend/PrecompiledPreamble.h
+++ include/clang/Frontend/PrecompiledPreamble.h
@@ -260,6 +260,9 @@
   /// used instead, but having only this method allows a simpler API.
   virtual void HandleMacroDefined(const Token &MacroNameTok,
   const MacroDirective *MD);
+  /// Creates wrapper class for PPCallbacks so we can also process information
+  /// about includes that are inside of a preamble
+  virtual std::unique_ptr createPPCallbacks();
 };
 
 enum class BuildPreambleError {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40651: Implement most of P0451 - Constexpr for std::complex

2017-12-14 Thread Marshall Clow via Phabricator via cfe-commits
mclow.lists updated this revision to Diff 126986.
mclow.lists added a comment.

More context in the diff, and removed some tabs.
Also commented out the constexpr tests for divide, since they fail at the 
moment.


https://reviews.llvm.org/D40651

Files:
  include/complex
  test/std/numerics/complex.number/complex.member.ops/assignment_scalar.pass.cpp
  
test/std/numerics/complex.number/complex.member.ops/divide_equal_scalar.pass.cpp
  
test/std/numerics/complex.number/complex.member.ops/minus_equal_scalar.pass.cpp
  test/std/numerics/complex.number/complex.member.ops/plus_equal_scalar.pass.cpp
  
test/std/numerics/complex.number/complex.member.ops/times_equal_scalar.pass.cpp
  test/std/numerics/complex.number/complex.members/real_imag.pass.cpp
  test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp
  test/std/numerics/complex.number/complex.ops/complex_divide_scalar.pass.cpp
  test/std/numerics/complex.number/complex.ops/complex_minus_complex.pass.cpp
  test/std/numerics/complex.number/complex.ops/complex_plus_complex.pass.cpp
  test/std/numerics/complex.number/complex.ops/complex_plus_scalar.pass.cpp
  test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp
  test/std/numerics/complex.number/complex.ops/complex_times_scalar.pass.cpp
  test/std/numerics/complex.number/complex.ops/scalar_divide_complex.pass.cpp
  test/std/numerics/complex.number/complex.ops/scalar_minus_complex.pass.cpp
  test/std/numerics/complex.number/complex.ops/scalar_plus_complex.pass.cpp
  test/std/numerics/complex.number/complex.ops/scalar_times_complex.pass.cpp
  test/std/numerics/complex.number/complex.ops/unary_minus.pass.cpp
  test/std/numerics/complex.number/complex.ops/unary_plus.pass.cpp
  test/std/numerics/complex.number/complex.value.ops/conj.pass.cpp
  test/std/numerics/complex.number/complex.value.ops/imag.pass.cpp
  test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp
  test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp
  test/std/numerics/complex.number/complex.value.ops/real.pass.cpp

Index: test/std/numerics/complex.number/complex.value.ops/real.pass.cpp
===
--- test/std/numerics/complex.number/complex.value.ops/real.pass.cpp
+++ test/std/numerics/complex.number/complex.value.ops/real.pass.cpp
@@ -12,16 +12,30 @@
 // template
 //   T
 //   real(const complex& x);
+//   constexpr in C++20
 
 #include 
 #include 
 
+#include "test_macros.h"
+
+template 
+TEST_CONSTEXPR bool
+constexpr_test()
+{
+std::complex z(1.5, 2.5);
+return real(z) == 1.5;
+}
+
 template 
 void
 test()
 {
 std::complex z(1.5, 2.5);
 assert(real(z) == 1.5);
+#if TEST_STD_VER > 17
+static_assert(constexpr_test(), "");
+#endif
 }
 
 int main()
Index: test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp
===
--- test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp
+++ test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp
@@ -12,13 +12,24 @@
 // template
 //   complex
 //   proj(const complex& x);
+//   constexpr in C++20
 
 #include 
 #include 
 
+#include "test_macros.h"
+
 #include "../cases.h"
 
 template 
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex &z, std::complex x)
+{
+return proj(z) == x;
+}
+
+
+template 
 void
 test(const std::complex& z, std::complex x)
 {
@@ -29,10 +40,24 @@
 void
 test()
 {
-test(std::complex(1, 2), std::complex(1, 2));
-test(std::complex(-1, 2), std::complex(-1, 2));
-test(std::complex(1, -2), std::complex(1, -2));
-test(std::complex(-1, -2), std::complex(-1, -2));
+typedef std::complex C;
+
+TEST_CONSTEXPR C v12  ( 1,  2);
+TEST_CONSTEXPR C v1_2 ( 1, -2);
+TEST_CONSTEXPR C v_12 (-1,  2);
+TEST_CONSTEXPR C v_1_2(-1, -2);
+
+test(v12,   v12);
+test(v_12,  v_12);
+test(v1_2,  v1_2);
+test(v_1_2, v_1_2);
+
+#if TEST_STD_VER > 17
+static_assert(constexpr_test(v12,   v12), "");
+static_assert(constexpr_test(v_12,  v_12), "");
+static_assert(constexpr_test(v1_2,  v1_2), "");
+static_assert(constexpr_test(v_1_2, v_1_2), "");
+#endif
 }
 
 void test_edges()
Index: test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp
===
--- test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp
+++ test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp
@@ -12,18 +12,31 @@
 // template
 //   T
 //   norm(const complex& x);
+//   constexpr in C++20
 
 #include 
 #include 
 
+#include "test_macros.h"
+
 #include "../cases.h"
 
 template 
+TEST_CONSTEXPR bool
+constexpr_test(const std::complex &z, T expected)
+{
+return norm(z) == expected;
+}
+
+template 
 void
 test()
 {
-std::complex z(3, 4);
+TEST_CONSTEXPR std::complex z(3, 4);
 assert(norm(z) == 25);
+#if TEST_STD_VER > 17
+static_assert(conste

[PATCH] D41103: [CMake] Allow passing extra CMake arguments to custom libc++

2017-12-14 Thread Vitaly Buka via Phabricator via cfe-commits
vitalybuka added a comment.

Can you please add some details about why someone wants to customize LIBXX here?
Or even better attach a patch which uses this.


Repository:
  rCRT Compiler Runtime

https://reviews.llvm.org/D41103



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


[PATCH] D41248: [libcxx] Suppress unused warning on apple.

2017-12-14 Thread Don Hinton via Phabricator via cfe-commits
hintonda created this revision.
hintonda added a reviewer: EricWF.

This warning is already suppressed on non-apple platforms, so
this change just suppresses it on apple as well.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41248

Files:
  src/experimental/filesystem/operations.cpp


Index: src/experimental/filesystem/operations.cpp
===
--- src/experimental/filesystem/operations.cpp
+++ src/experimental/filesystem/operations.cpp
@@ -512,6 +512,7 @@
 
 #if defined(__APPLE__)
 TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
+__attribute__((unused)) // Suppress warning
 TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
 #else
 TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }


Index: src/experimental/filesystem/operations.cpp
===
--- src/experimental/filesystem/operations.cpp
+++ src/experimental/filesystem/operations.cpp
@@ -512,6 +512,7 @@
 
 #if defined(__APPLE__)
 TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
+__attribute__((unused)) // Suppress warning
 TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
 #else
 TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41050: Fix over-release of return value of lambda implicitly converted to block/function pointer

2017-12-14 Thread John McCall via Phabricator via cfe-commits
rjmccall closed this revision.
rjmccall added a comment.

Sure, r320721.


Repository:
  rC Clang

https://reviews.llvm.org/D41050



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


r320721 - In an ARC lambda-to-block conversion thunk, reclaim the return value of

2017-12-14 Thread John McCall via cfe-commits
Author: rjmccall
Date: Thu Dec 14 10:21:14 2017
New Revision: 320721

URL: http://llvm.org/viewvc/llvm-project?rev=320721&view=rev
Log:
In an ARC lambda-to-block conversion thunk, reclaim the return value of
the lambda so that we don't over-release it.

Patch by Dan Zimmerman!

Added:
cfe/trunk/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm
Modified:
cfe/trunk/lib/CodeGen/CGClass.cpp

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=320721&r1=320720&r2=320721&view=diff
==
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Thu Dec 14 10:21:14 2017
@@ -2777,9 +2777,12 @@ void CodeGenFunction::EmitForwardingCall
   RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs);
 
   // If necessary, copy the returned value into the slot.
-  if (!resultType->isVoidType() && returnSlot.isNull())
+  if (!resultType->isVoidType() && returnSlot.isNull()) {
+if (getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) {
+  RV = 
RValue::get(EmitARCRetainAutoreleasedReturnValue(RV.getScalarVal()));
+}
 EmitReturnOfRValue(RV, resultType);
-  else
+  } else
 EmitBranchThroughCleanup(ReturnBlock);
 }
 

Added: cfe/trunk/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm?rev=320721&view=auto
==
--- cfe/trunk/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm (added)
+++ cfe/trunk/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm Thu Dec 14 
10:21:14 2017
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -emit-llvm 
-disable-llvm-passes -O3 -fblocks -fobjc-arc -fobjc-runtime-has-weak -std=c++11 
-o - %s | FileCheck %s
+
+void test0(id x) {
+  extern void test0_helper(id (^)(void));
+  test0_helper([=]() { return x; });
+  // CHECK-LABEL: define internal i8* @___Z5test0P11objc_object_block_invoke
+  // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test0P11objc_objectENK3$_0clEv"
+  // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* 
[[T0]])
+  // CHECK-NEXT: [[T2:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* 
[[T1]])
+  // CHECK-NEXT: ret i8* [[T2]]
+}
+
+id test1_rv;
+
+void test1() {
+  extern void test1_helper(id (*)(void));
+  test1_helper([](){ return test1_rv; });
+  // CHECK-LABEL: define internal i8* @"_ZZ5test1vEN3$_18__invokeEv"
+  // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test1vENK3$_1clEv"
+  // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* 
[[T0]])
+  // CHECK-NEXT: [[T2:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* 
[[T1]])
+  // CHECK-NEXT: ret i8* [[T2]]
+}


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


r320730 - [CodeGen][X86] Implement _InterlockedCompareExchange128 intrinsic

2017-12-14 Thread Reid Kleckner via cfe-commits
Author: rnk
Date: Thu Dec 14 11:00:21 2017
New Revision: 320730

URL: http://llvm.org/viewvc/llvm-project?rev=320730&view=rev
Log:
[CodeGen][X86] Implement _InterlockedCompareExchange128 intrinsic

Summary:
InterlockedCompareExchange128 is a bit more complicated than the other
InterlockedCompareExchange functions, so it requires a bit more work. It
doesn't directly refer to 128bit ints, instead it takes pointers to
64bit ints for Destination and ComparandResult, and exchange is taken as
two 64bit ints (high & low). The previous value is written to
ComparandResult, and success is returned. This implementation does the
following in order to produce a cmpxchg instruction:

  1. Cast everything to 128bit ints or int pointers, and glues together
 the Exchange values
  2. Reads from CompareandResult to get the comparand
  3. Calls cmpxchg volatile (on X86 this will produce a lock cmpxchg16b
 instruction)
1. Result 0 (previous value) is written back to ComparandResult
2. Result 1 (success bool) is zext'ed to a uchar and returned

Resolves bug https://llvm.org/PR35251

Patch by Colden Cullen!

Reviewers: rnk, agutowski

Reviewed By: rnk

Subscribers: majnemer, cfe-commits

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

Modified:
cfe/trunk/include/clang/Basic/BuiltinsX86_64.def
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/test/CodeGen/ms-intrinsics.c

Modified: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86_64.def?rev=320730&r1=320729&r2=320730&view=diff
==
--- cfe/trunk/include/clang/Basic/BuiltinsX86_64.def (original)
+++ cfe/trunk/include/clang/Basic/BuiltinsX86_64.def Thu Dec 14 11:00:21 2017
@@ -40,6 +40,7 @@ TARGET_HEADER_BUILTIN(_InterlockedExchan
 TARGET_HEADER_BUILTIN(_InterlockedIncrement64,   "LLiLLiD*","nh", 
"intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(_InterlockedOr64,  "LLiLLiD*LLi", "nh", 
"intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", 
"intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", 
"nh", "intrin.h", ALL_MS_LANGUAGES, "cx16")
 
 TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "")
 TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "")

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=320730&r1=320729&r2=320730&view=diff
==
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Thu Dec 14 11:00:21 2017
@@ -8432,6 +8432,45 @@ Value *CodeGenFunction::EmitX86BuiltinEx
 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E);
   case X86::BI_InterlockedIncrement64:
 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E);
+  case X86::BI_InterlockedCompareExchange128: {
+// InterlockedCompareExchange128 doesn't directly refer to 128bit ints,
+// instead it takes pointers to 64bit ints for Destination and
+// ComparandResult, and exchange is taken as two 64bit ints (high & low).
+// The previous value is written to ComparandResult, and success is
+// returned.
+
+llvm::Type *Int128Ty = Builder.getInt128Ty();
+llvm::Type *Int128PtrTy = Int128Ty->getPointerTo();
+
+Value *Destination =
+Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PtrTy);
+Value *ExchangeHigh128 =
+Builder.CreateZExt(EmitScalarExpr(E->getArg(1)), Int128Ty);
+Value *ExchangeLow128 =
+Builder.CreateZExt(EmitScalarExpr(E->getArg(2)), Int128Ty);
+Address ComparandResult(
+Builder.CreateBitCast(EmitScalarExpr(E->getArg(3)), Int128PtrTy),
+getContext().toCharUnitsFromBits(128));
+
+Value *Exchange = Builder.CreateOr(
+Builder.CreateShl(ExchangeHigh128, 64, "", false, false),
+ExchangeLow128);
+
+Value *Comparand = Builder.CreateLoad(ComparandResult);
+
+AtomicCmpXchgInst *CXI =
+Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange,
+AtomicOrdering::SequentiallyConsistent,
+AtomicOrdering::SequentiallyConsistent);
+CXI->setVolatile(true);
+
+// Write the result back to the inout pointer.
+Builder.CreateStore(Builder.CreateExtractValue(CXI, 0), ComparandResult);
+
+// Get the success boolean and zero extend it to i8.
+Value *Success = Builder.CreateExtractValue(CXI, 1);
+return Builder.CreateZExt(Success, ConvertType(E->getType()));
+  }
 
   case X86::BI_AddressOfReturnAddress: {
 Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress);

Modified: cfe/trunk/test/CodeGen/ms-intrinsics.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/

[PATCH] D41032: [CodeGen][X86] Implement _InterlockedCompareExchange128 intrinsic

2017-12-14 Thread Reid Kleckner via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC320730: [CodeGen][X86] Implement 
_InterlockedCompareExchange128 intrinsic (authored by rnk, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D41032?vs=126641&id=126997#toc

Repository:
  rC Clang

https://reviews.llvm.org/D41032

Files:
  include/clang/Basic/BuiltinsX86_64.def
  lib/CodeGen/CGBuiltin.cpp
  test/CodeGen/ms-intrinsics.c

Index: include/clang/Basic/BuiltinsX86_64.def
===
--- include/clang/Basic/BuiltinsX86_64.def
+++ include/clang/Basic/BuiltinsX86_64.def
@@ -40,6 +40,7 @@
 TARGET_HEADER_BUILTIN(_InterlockedIncrement64,   "LLiLLiD*","nh", "intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(_InterlockedOr64,  "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "cx16")
 
 TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "")
 TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "")
Index: test/CodeGen/ms-intrinsics.c
===
--- test/CodeGen/ms-intrinsics.c
+++ test/CodeGen/ms-intrinsics.c
@@ -5,7 +5,7 @@
 // RUN: -triple thumbv7--windows -Oz -emit-llvm %s -o - \
 // RUN: | FileCheck %s --check-prefixes CHECK,CHECK-ARM,CHECK-ARM-X64
 // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
-// RUN: -triple x86_64--windows -Oz -emit-llvm %s -o - \
+// RUN: -triple x86_64--windows -Oz -emit-llvm -target-feature +cx16 %s -o - \
 // RUN: | FileCheck %s --check-prefixes CHECK,CHECK-X64,CHECK-ARM-X64,CHECK-INTEL
 
 // intrin.h needs size_t, but -ffreestanding prevents us from getting it from
@@ -329,6 +329,27 @@
 // CHECK: ret i64 [[RESULT]]
 // CHECK: }
 
+#if defined(__x86_64__)
+unsigned char test_InterlockedCompareExchange128(__int64 volatile *Destination, __int64 ExchangeHigh, __int64 ExchangeLow, __int64* ComparandResult) {
+  return _InterlockedCompareExchange128(Destination, ExchangeHigh, ExchangeLow, ComparandResult);
+}
+// CHECK-X64: define{{.*}}i8 @test_InterlockedCompareExchange128(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%ExchangeHigh, i64{{[a-z_ ]*}}%ExchangeLow, i64*{{[a-z_ ]*}}%ComparandResult){{.*}}{
+// CHECK-X64: [[DST:%[0-9]+]] = bitcast i64* %Destination to i128*
+// CHECK-X64: [[EH:%[0-9]+]] = zext i64 %ExchangeHigh to i128
+// CHECK-X64: [[EL:%[0-9]+]] = zext i64 %ExchangeLow to i128
+// CHECK-X64: [[CNR:%[0-9]+]] = bitcast i64* %ComparandResult to i128*
+// CHECK-X64: [[EHS:%[0-9]+]] = shl nuw i128 [[EH]], 64
+// CHECK-X64: [[EXP:%[0-9]+]] = or i128 [[EHS]], [[EL]]
+// CHECK-X64: [[ORG:%[0-9]+]] = load i128, i128* [[CNR]], align 16
+// CHECK-X64: [[RES:%[0-9]+]] = cmpxchg volatile i128* [[DST]], i128 [[ORG]], i128 [[EXP]] seq_cst seq_cst
+// CHECK-X64: [[OLD:%[0-9]+]] = extractvalue { i128, i1 } [[RES]], 0
+// CHECK-X64: store i128 [[OLD]], i128* [[CNR]], align 16
+// CHECK-X64: [[SUC1:%[0-9]+]] = extractvalue { i128, i1 } [[RES]], 1
+// CHECK-X64: [[SUC8:%[0-9]+]] = zext i1 [[SUC1]] to i8
+// CHECK-X64: ret i8 [[SUC8]]
+// CHECK-X64: }
+#endif
+
 short test_InterlockedIncrement16(short volatile *Addend) {
   return _InterlockedIncrement16(Addend);
 }
Index: lib/CodeGen/CGBuiltin.cpp
===
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -8432,6 +8432,45 @@
 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E);
   case X86::BI_InterlockedIncrement64:
 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E);
+  case X86::BI_InterlockedCompareExchange128: {
+// InterlockedCompareExchange128 doesn't directly refer to 128bit ints,
+// instead it takes pointers to 64bit ints for Destination and
+// ComparandResult, and exchange is taken as two 64bit ints (high & low).
+// The previous value is written to ComparandResult, and success is
+// returned.
+
+llvm::Type *Int128Ty = Builder.getInt128Ty();
+llvm::Type *Int128PtrTy = Int128Ty->getPointerTo();
+
+Value *Destination =
+Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PtrTy);
+Value *ExchangeHigh128 =
+Builder.CreateZExt(EmitScalarExpr(E->getArg(1)), Int128Ty);
+Value *ExchangeLow128 =
+Builder.CreateZExt(EmitScalarExpr(E->getArg(2)), Int128Ty);
+Address ComparandResult(
+Builder.CreateBitCast(EmitScalarExpr(E->getArg(3)), Int128PtrTy),
+getContext().toCharUnitsFromBits(128));
+
+Value *Exchange = Builder.CreateOr(
+Builder.CreateShl(ExchangeHigh128, 64, "", false, false),
+ExchangeLow128);
+
+Value *Comparand = Builder.CreateLoad(Compar

[PATCH] D41250: [analyzer] Model implied cast around operator new().

2017-12-14 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet.
Herald added subscribers: cfe-commits, rnkovacs, eraman.

C++ overridable `operator new()` has the following prototype:

  void *operator new(size_t size, user-defined arguments...);

The return value is `void *`. However, before passing it to constructor, we 
need to make a cast to the respective object pointer type. Hence an implicit 
cast is present here, which is not represented in the current AST or CFG. 
Modeling this cast is straightforward though. This is the change i mentioned in 
https://reviews.llvm.org/D40939.

I also noticed that `evalCast` from `void *` to `T *` is uncomfortable to use 
because sometimes it transforms `&SymRegion{$x}` into `&element{T, 0S32b, 
SymRegion{$x}}` even when `$x` is already of type `T *`. The form 
`&SymRegion{$x}` seems to be the canonical form of this symbolic pointer value 
in the rest of the analyzer, so i decided to change `evalCast` to preserve it.

The problem of how to represent memregion value casts better still stands - it 
wouldn't add much to the analyzer's quality, but we just keep running into it 
over and over again.


Repository:
  rC Clang

https://reviews.llvm.org/D41250

Files:
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  lib/StaticAnalyzer/Core/Store.cpp
  test/Analysis/new-ctor-conservative.cpp
  test/Analysis/new-ctor-inlined.cpp


Index: test/Analysis/new-ctor-inlined.cpp
===
--- test/Analysis/new-ctor-inlined.cpp
+++ test/Analysis/new-ctor-inlined.cpp
@@ -27,3 +27,12 @@
   // Check that bindings are correct (and also not dying).
   clang_analyzer_eval(s->x == 1); // expected-warning{{TRUE}}
 }
+
+void checkNewPOD() {
+  int *i = new int;
+  clang_analyzer_eval(*i == 0); // expected-warning{{UNKNOWN}}
+  int *j = new int();
+  clang_analyzer_eval(*j == 0); // expected-warning{{TRUE}}
+  int *k = new int(5);
+  clang_analyzer_eval(*k == 5); // expected-warning{{TRUE}}
+}
Index: test/Analysis/new-ctor-conservative.cpp
===
--- test/Analysis/new-ctor-conservative.cpp
+++ test/Analysis/new-ctor-conservative.cpp
@@ -12,3 +12,12 @@
   S *s = new S;
   clang_analyzer_eval(s->x == 1); // expected-warning{{TRUE}}
 }
+
+void checkNewPOD() {
+  int *i = new int;
+  clang_analyzer_eval(*i == 0); // expected-warning{{UNKNOWN}}
+  int *j = new int();
+  clang_analyzer_eval(*j == 0); // expected-warning{{TRUE}}
+  int *k = new int(5);
+  clang_analyzer_eval(*k == 5); // expected-warning{{TRUE}}
+}
Index: lib/StaticAnalyzer/Core/Store.cpp
===
--- lib/StaticAnalyzer/Core/Store.cpp
+++ lib/StaticAnalyzer/Core/Store.cpp
@@ -91,13 +91,21 @@
 return R;
 
   // Handle casts from compatible types.
-  if (R->isBoundable())
+  if (R->isBoundable()) {
 if (const TypedValueRegion *TR = dyn_cast(R)) {
   QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());
   if (CanonPointeeTy == ObjTy)
 return R;
 }
 
+if (const SymbolicRegion *SR = dyn_cast(R)) {
+  QualType SymTy =
+  Ctx.getCanonicalType(SR->getSymbol()->getType()->getPointeeType());
+  if (CanonPointeeTy == SymTy)
+return R;
+}
+  }
+
   // Process region cast according to the kind of the region being cast.
   switch (R->getKind()) {
 case MemRegion::CXXThisRegionKind:
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -571,6 +571,10 @@
 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),
   CNE->getPlacementArg(0)->getType());
+  } else {
+Result =
+svalBuilder.evalCast(Result, CNE->getType(),
+ getContext().getPointerType(getContext().VoidTy));
   }
 
   // Bind the address of the object, then check to see if we cached out.


Index: test/Analysis/new-ctor-inlined.cpp
===
--- test/Analysis/new-ctor-inlined.cpp
+++ test/Analysis/new-ctor-inlined.cpp
@@ -27,3 +27,12 @@
   // Check that bindings are correct (and also not dying).
   clang_analyzer_eval(s->x == 1); // expected-warning{{TRUE}}
 }
+
+void checkNewPOD() {
+  int *i = new int;
+  clang_analyzer_eval(*i == 0); // expected-warning{{UNKNOWN}}
+  int *j = new int();
+  clang_analyzer_eval(*j == 0); // expected-warning{{TRUE}}
+  int *k = new int(5);
+  clang_analyzer_eval(*k == 5); // expected-warning{{TRUE}}
+}
Index: test/Analysis/new-ctor-conservative.cpp
===
--- test/Analysis/new-ctor-conservative.cpp
+++ test/Analysis/new-ctor-conservative.cpp
@@ -12,3 +12

Re: Status of CET support? (Re: [PATCH] D40224:...)

2017-12-14 Thread Kostya Serebryany via cfe-commits
On Thu, Dec 14, 2017 at 2:39 AM, Pavel Chupin 
wrote:

> Hi Kostya,
> Long time no see. :)
>

Yey!! Thanks for the update!

--kcc


> I would estimate that everything (glibc, kernel, loader, simulator)
> should be available approx. February 2018 as soon as implementation
> finished and tested on our side.
> CET is enabled already in GCC, glibc branch with CET is available
> (https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/
> heads/hjl/cet/master)
> and will be upstreamed as soon as kernel upstream progress made.
>
> On Wed, Nov 29, 2017 at 8:41 AM, Ben Simhon, Oren
>  wrote:
> > Hi Kostya,
> >
> >
> >
> > Sorry for the detailed response.
> >
> > I forwarded your questions to GCC team who are also adding CET support
> for
> > Glibc / Linux Kernel / Loader.
> >
> >
> >
> > I also talked to the simulations team to understand their timeline.
> >
> > They will contact this mailing list with detailed answers.
> >
> >
> >
> > There are few more patches to complete LLVM Compiler support.
> >
> > I will appreciate your help in reviewing some of them:
> >
> > https://reviews.llvm.org/D40482
> >
> > https://reviews.llvm.org/D40478
> >
> >
> >
> > Thanks,
> >
> > Oren
> >
> >
> >
> > From: Kostya Serebryany [mailto:k...@google.com]
> > Sent: Tuesday, November 28, 2017 01:46
> > Cc: Ben Simhon, Oren ;
> pavel.v.chu...@gmail.com;
> > Keane, Erich ; Justin Bogner <
> m...@justinbogner.com>;
> > ablik...@gmail.com; Reid Kleckner ; Craig Topper
> > ; cfe-commits ;
> Evgeniy
> > Stepanov ; Peter Collingbourne ;
> Sahita,
> > Ravi ; Zuckerman, Michael
> > 
> > Subject: Status of CET support? (Re: [PATCH] D40224:...)
> >
> >
> >
> > Hi,
> >
> >
> >
> > I see these patches for the CET support in LLVM -- great!
> >
> > Could you please also tell us
> >
> >   * what's the status of the Linux Kernel and Glibc support for CET?
> >
> >   * how we can start evaluating the hardware feature (simulators, etc)?
> >
> >
> >
> > Thanks!
> >
> >
> >
> > --kcc
> >
> >
> >
> >
> >
> > On Sun, Nov 26, 2017 at 4:35 AM, Phabricator via Phabricator via
> cfe-commits
> >  wrote:
> >
> > This revision was automatically updated to reflect the committed changes.
> > Closed by commit rL318995: Control-Flow Enforcement Technology - Shadow
> > Stack and Indirect Branch Tracking… (authored by orenb).
> >
> > Changed prior to commit:
> >   https://reviews.llvm.org/D40224?vs=123937&id=124287#toc
> >
> > Repository:
> >   rL LLVM
> >
> > https://reviews.llvm.org/D40224
> >
> > Files:
> >   cfe/trunk/include/clang/Basic/BuiltinsX86.def
> >   cfe/trunk/include/clang/Basic/BuiltinsX86_64.def
> >   cfe/trunk/include/clang/Driver/Options.td
> >   cfe/trunk/lib/Basic/Targets/X86.cpp
> >   cfe/trunk/lib/Basic/Targets/X86.h
> >   cfe/trunk/lib/Headers/CMakeLists.txt
> >   cfe/trunk/lib/Headers/cetintrin.h
> >   cfe/trunk/lib/Headers/immintrin.h
> >   cfe/trunk/test/CodeGen/builtins-x86.c
> >   cfe/trunk/test/CodeGen/cetintrin.c
> >   cfe/trunk/test/Driver/x86-target-features.c
> >   cfe/trunk/test/Preprocessor/x86_target_features.c
> >
> >
> > ___
> > cfe-commits mailing list
> > cfe-commits@lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
> >
> >
> >
> > -
> > Intel Israel (74) Limited
> >
> > This e-mail and any attachments may contain confidential material for
> > the sole use of the intended recipient(s). Any review or distribution
> > by others is strictly prohibited. If you are not the intended
> > recipient, please contact the sender and delete all copies.
>
>
>
> --
> Pavel Chupin
> Intel Corporation
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41087: [Preprocessor] Implement __is_target_{arch|vendor|os|environment} function-like builtin macros

2017-12-14 Thread Alex Lorenz via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC320734: [Preprocessor] Implement 
__is_target_{arch|vendor|os|environment} function-like (authored by arphaman, 
committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D41087?vs=126856&id=127000#toc

Repository:
  rC Clang

https://reviews.llvm.org/D41087

Files:
  docs/ReleaseNotes.rst
  include/clang/Lex/Preprocessor.h
  lib/Lex/PPMacroExpansion.cpp

Index: include/clang/Lex/Preprocessor.h
===
--- include/clang/Lex/Preprocessor.h
+++ include/clang/Lex/Preprocessor.h
@@ -175,6 +175,10 @@
   IdentifierInfo *Ident__has_cpp_attribute;// __has_cpp_attribute
   IdentifierInfo *Ident__has_c_attribute;  // __has_c_attribute
   IdentifierInfo *Ident__has_declspec; // __has_declspec_attribute
+  IdentifierInfo *Ident__is_target_arch;   // __is_target_arch
+  IdentifierInfo *Ident__is_target_vendor; // __is_target_vendor
+  IdentifierInfo *Ident__is_target_os; // __is_target_os
+  IdentifierInfo *Ident__is_target_environment;// __is_target_environment
 
   SourceLocation DATELoc, TIMELoc;
 
Index: lib/Lex/PPMacroExpansion.cpp
===
--- lib/Lex/PPMacroExpansion.cpp
+++ lib/Lex/PPMacroExpansion.cpp
@@ -375,6 +375,11 @@
   Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next");
   Ident__has_warning  = RegisterBuiltinMacro(*this, "__has_warning");
   Ident__is_identifier= RegisterBuiltinMacro(*this, "__is_identifier");
+  Ident__is_target_arch   = RegisterBuiltinMacro(*this, "__is_target_arch");
+  Ident__is_target_vendor = RegisterBuiltinMacro(*this, "__is_target_vendor");
+  Ident__is_target_os = RegisterBuiltinMacro(*this, "__is_target_os");
+  Ident__is_target_environment =
+  RegisterBuiltinMacro(*this, "__is_target_environment");
 
   // Modules.
   Ident__building_module  = RegisterBuiltinMacro(*this, "__building_module");
@@ -1593,6 +1598,57 @@
   return nullptr;
 }
 
+/// Implements the __is_target_arch builtin macro.
+static bool isTargetArch(const TargetInfo &TI, const IdentifierInfo *II) {
+  std::string ArchName = II->getName().lower() + "--";
+  llvm::Triple Arch(ArchName);
+  const llvm::Triple &TT = TI.getTriple();
+  if (TT.isThumb()) {
+// arm matches thumb or thumbv7. armv7 matches thumbv7.
+if ((Arch.getSubArch() == llvm::Triple::NoSubArch ||
+ Arch.getSubArch() == TT.getSubArch()) &&
+((TT.getArch() == llvm::Triple::thumb &&
+  Arch.getArch() == llvm::Triple::arm) ||
+ (TT.getArch() == llvm::Triple::thumbeb &&
+  Arch.getArch() == llvm::Triple::armeb)))
+  return true;
+  }
+  // Check the parsed arch when it has no sub arch to allow Clang to
+  // match thumb to thumbv7 but to prohibit matching thumbv6 to thumbv7.
+  return (Arch.getSubArch() == llvm::Triple::NoSubArch &&
+  Arch.getArch() == TT.getArch()) ||
+ Arch.getArchName() == TT.getArchName();
+}
+
+/// Implements the __is_target_vendor builtin macro.
+static bool isTargetVendor(const TargetInfo &TI, const IdentifierInfo *II) {
+  StringRef VendorName = TI.getTriple().getVendorName();
+  if (VendorName.empty())
+VendorName = "unknown";
+  return VendorName.equals_lower(II->getName());
+}
+
+/// Implements the __is_target_os builtin macro.
+static bool isTargetOS(const TargetInfo &TI, const IdentifierInfo *II) {
+  std::string OSName =
+  (llvm::Twine("unknown-unknown-") + II->getName().lower()).str();
+  llvm::Triple OS(OSName);
+  if (OS.getOS() == llvm::Triple::Darwin) {
+// Darwin matches macos, ios, etc.
+return TI.getTriple().isOSDarwin();
+  }
+  return TI.getTriple().getOS() == OS.getOS();
+}
+
+/// Implements the __is_target_environment builtin macro.
+static bool isTargetEnvironment(const TargetInfo &TI,
+const IdentifierInfo *II) {
+  StringRef EnvName = TI.getTriple().getEnvironmentName();
+  if (EnvName.empty())
+EnvName = "unknown";
+  return EnvName.equals_lower(II->getName());
+}
+
 /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
 /// as a builtin macro, handle it and return the next token as 'Tok'.
 void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
@@ -1755,6 +1811,10 @@
   .Case("__make_integer_seq", LangOpts.CPlusPlus)
   .Case("__type_pack_element", LangOpts.CPlusPlus)
   .Case("__builtin_available", true)
+  .Case("__is_target_arch", true)
+  .Case("__is_target_vendor", true)
+  .Case("__is_target_os", true)
+  .Case("__is_target_environment", true)
   .Default(false);
 }
   });
@@ -1906,6 +1966,34 @@
   Diag(LParenLoc, diag::note_matching) << tok::l_paren;
 }
 retu

r320734 - [Preprocessor] Implement __is_target_{arch|vendor|os|environment} function-like

2017-12-14 Thread Alex Lorenz via cfe-commits
Author: arphaman
Date: Thu Dec 14 11:22:02 2017
New Revision: 320734

URL: http://llvm.org/viewvc/llvm-project?rev=320734&view=rev
Log:
[Preprocessor] Implement __is_target_{arch|vendor|os|environment} function-like
builtin macros

This patch implements the __is_target_arch, __is_target_vendor, __is_target_os,
and __is_target_environment Clang preprocessor extensions that were proposed by
@compnerd in Bob's cfe-dev post:
http://lists.llvm.org/pipermail/cfe-dev/2017-November/056166.html.

These macros can be used to examine the components of the target triple at
compile time. A has_builtin(is_target_???) preprocessor check can be used to
check for their availability.

__is_target_arch allows you to check if an arch is specified without worring
about a specific subarch, e.g.

__is_target_arch(arm) returns 1 for the target arch "armv7"
__is_target_arch(armv7) returns 1 for the target arch "armv7"
__is_target_arch(armv6) returns 0 for the target arch "armv7"

__is_target_vendor and __is_target_environment match the specific vendor
or environment. __is_target_os matches the specific OS, but
__is_target_os(darwin) will match any Darwin-based OS. "Unknown" can be used
to test if the triple's component is specified.

rdar://35753116

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

Modified:
cfe/trunk/docs/ReleaseNotes.rst
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/Lex/PPMacroExpansion.cpp

Modified: cfe/trunk/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=320734&r1=320733&r2=320734&view=diff
==
--- cfe/trunk/docs/ReleaseNotes.rst (original)
+++ cfe/trunk/docs/ReleaseNotes.rst Thu Dec 14 11:22:02 2017
@@ -110,6 +110,10 @@ Non-comprehensive list of changes in thi
   If a gcc installation is found, it still prefers ``.ctors`` if the found
   gcc is older than 4.7.0.
 
+- The new builtin preprocessor macros ``__is_target_arch``,
+  ``__is_target_vendor``, ``__is_target_os``, and ``__is_target_environment``
+  can be used to to examine the individual components of the target triple.
+
 New Compiler Flags
 --
 

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=320734&r1=320733&r2=320734&view=diff
==
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Thu Dec 14 11:22:02 2017
@@ -175,6 +175,10 @@ class Preprocessor {
   IdentifierInfo *Ident__has_cpp_attribute;// __has_cpp_attribute
   IdentifierInfo *Ident__has_c_attribute;  // __has_c_attribute
   IdentifierInfo *Ident__has_declspec; // __has_declspec_attribute
+  IdentifierInfo *Ident__is_target_arch;   // __is_target_arch
+  IdentifierInfo *Ident__is_target_vendor; // __is_target_vendor
+  IdentifierInfo *Ident__is_target_os; // __is_target_os
+  IdentifierInfo *Ident__is_target_environment;// __is_target_environment
 
   SourceLocation DATELoc, TIMELoc;
 

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=320734&r1=320733&r2=320734&view=diff
==
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Thu Dec 14 11:22:02 2017
@@ -375,6 +375,11 @@ void Preprocessor::RegisterBuiltinMacros
   Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next");
   Ident__has_warning  = RegisterBuiltinMacro(*this, "__has_warning");
   Ident__is_identifier= RegisterBuiltinMacro(*this, "__is_identifier");
+  Ident__is_target_arch   = RegisterBuiltinMacro(*this, "__is_target_arch");
+  Ident__is_target_vendor = RegisterBuiltinMacro(*this, "__is_target_vendor");
+  Ident__is_target_os = RegisterBuiltinMacro(*this, "__is_target_os");
+  Ident__is_target_environment =
+  RegisterBuiltinMacro(*this, "__is_target_environment");
 
   // Modules.
   Ident__building_module  = RegisterBuiltinMacro(*this, "__building_module");
@@ -1593,6 +1598,57 @@ static IdentifierInfo *ExpectFeatureIden
   return nullptr;
 }
 
+/// Implements the __is_target_arch builtin macro.
+static bool isTargetArch(const TargetInfo &TI, const IdentifierInfo *II) {
+  std::string ArchName = II->getName().lower() + "--";
+  llvm::Triple Arch(ArchName);
+  const llvm::Triple &TT = TI.getTriple();
+  if (TT.isThumb()) {
+// arm matches thumb or thumbv7. armv7 matches thumbv7.
+if ((Arch.getSubArch() == llvm::Triple::NoSubArch ||
+ Arch.getSubArch() == TT.getSubArch()) &&
+((TT.getArch() == llvm::Triple::thumb &&
+  Arch.getArch() == llvm::Triple::arm) ||
+ (TT.getArch() == llvm::Triple::thumbeb &&
+

r320735 - Commit missing tests for r320734

2017-12-14 Thread Alex Lorenz via cfe-commits
Author: arphaman
Date: Thu Dec 14 11:22:41 2017
New Revision: 320735

URL: http://llvm.org/viewvc/llvm-project?rev=320735&view=rev
Log:
Commit missing tests for r320734

Added:
cfe/trunk/test/Preprocessor/is_target.c
cfe/trunk/test/Preprocessor/is_target_arm.c
cfe/trunk/test/Preprocessor/is_target_os_darwin.c
cfe/trunk/test/Preprocessor/is_target_unknown.c

Added: cfe/trunk/test/Preprocessor/is_target.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/is_target.c?rev=320735&view=auto
==
--- cfe/trunk/test/Preprocessor/is_target.c (added)
+++ cfe/trunk/test/Preprocessor/is_target.c Thu Dec 14 11:22:41 2017
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin-simulator -verify 
%s
+
+#if !__is_target_arch(x86_64) || !__is_target_arch(X86_64)
+  #error "mismatching arch"
+#endif
+
+#if __is_target_arch(arm64)
+  #error "mismatching arch"
+#endif
+
+// Silently ignore invalid archs. This will ensure that older compilers will
+// accept headers that support new arches/vendors/os variants.
+#if __is_target_arch(foo)
+  #error "invalid arch"
+#endif
+
+#if !__is_target_vendor(apple) || !__is_target_vendor(APPLE)
+  #error "mismatching vendor"
+#endif
+
+#if __is_target_vendor(unknown)
+  #error "mismatching vendor"
+#endif
+
+#if __is_target_vendor(foo)
+  #error "invalid vendor"
+#endif
+
+#if !__is_target_os(darwin) || !__is_target_os(DARWIN)
+  #error "mismatching os"
+#endif
+
+#if __is_target_os(ios)
+  #error "mismatching os"
+#endif
+
+#if __is_target_os(foo)
+  #error "invalid os"
+#endif
+
+#if !__is_target_environment(simulator) || !__is_target_environment(SIMULATOR)
+  #error "mismatching environment"
+#endif
+
+#if __is_target_environment(unknown)
+  #error "mismatching environment"
+#endif
+
+#if __is_target_environment(foo)
+  #error "invalid environment"
+#endif
+
+#if !__has_builtin(__is_target_arch) || !__has_builtin(__is_target_os) || 
!__has_builtin(__is_target_vendor) || !__has_builtin(__is_target_environment)
+  #error "has builtin doesn't work"
+#endif
+
+#if __is_target_arch(11) // expected-error {{builtin feature check macro 
requires a parenthesized identifier}}
+  #error "invalid arch"
+#endif
+
+#if __is_target_arch x86 // expected-error{{missing '(' after 
'__is_target_arch'}}
+  #error "invalid arch"
+#endif
+
+#if __is_target_arch ( x86  // expected-error {{unterminated function-like 
macro invocation}}
+  #error "invalid arch"
+#endif // expected-error@-2 {{expected value in expression}}

Added: cfe/trunk/test/Preprocessor/is_target_arm.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/is_target_arm.c?rev=320735&view=auto
==
--- cfe/trunk/test/Preprocessor/is_target_arm.c (added)
+++ cfe/trunk/test/Preprocessor/is_target_arm.c Thu Dec 14 11:22:41 2017
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -triple thumbv7--windows-msvc19.11.0 -verify 
%s
+// RUN: %clang_cc1 -fsyntax-only -triple armv7--windows-msvc19.11.0 -DARM 
-verify %s
+// expected-no-diagnostics
+
+// ARM does match arm and thumb.
+#if !__is_target_arch(arm)
+  #error "mismatching arch"
+#endif
+
+#if __is_target_arch(armeb) || __is_target_arch(armebv7) || 
__is_target_arch(thumbeb) || __is_target_arch(thumbebv7)
+  #error "mismatching arch"
+#endif
+
+// ARMV7 does match armv7 and thumbv7.
+#if !__is_target_arch(armv7)
+  #error "mismatching arch"
+#endif
+
+// ARMV6 does not match armv7 or thumbv7.
+#if __is_target_arch(armv6)
+  #error "mismatching arch"
+#endif
+
+#if __is_target_arch(arm64)
+  #error "mismatching arch"
+#endif
+
+#ifndef ARM
+
+// Allow checking for precise arch + subarch.
+#if !__is_target_arch(thumbv7)
+  #error "mismatching arch"
+#endif
+
+// But also allow checking for the arch without subarch.
+#if !__is_target_arch(thumb)
+  #error "mismatching arch"
+#endif
+
+// Same arch with a different subarch doesn't match.
+#if __is_target_arch(thumbv6)
+  #error "mismatching arch"
+#endif
+
+#else
+
+#if __is_target_arch(thumbv7) || __is_target_arch(thumb)
+  #error "mismatching arch"
+#endif
+
+#endif

Added: cfe/trunk/test/Preprocessor/is_target_os_darwin.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/is_target_os_darwin.c?rev=320735&view=auto
==
--- cfe/trunk/test/Preprocessor/is_target_os_darwin.c (added)
+++ cfe/trunk/test/Preprocessor/is_target_os_darwin.c Thu Dec 14 11:22:41 2017
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-macos -DMAC -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-ios -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-tvos -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-watchos -verify %s
+// expected-no-diagnostics
+
+#if !__is_target_os(darwin)
+  #error "misma

Re: r320734 - [Preprocessor] Implement __is_target_{arch|vendor|os|environment} function-like

2017-12-14 Thread Alex L via cfe-commits
Sorry, I forgot to add the tests in SVN. I committed them in 320735

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

> Author: arphaman
> Date: Thu Dec 14 11:22:02 2017
> New Revision: 320734
>
> URL: http://llvm.org/viewvc/llvm-project?rev=320734&view=rev
> Log:
> [Preprocessor] Implement __is_target_{arch|vendor|os|environment}
> function-like
> builtin macros
>
> This patch implements the __is_target_arch, __is_target_vendor,
> __is_target_os,
> and __is_target_environment Clang preprocessor extensions that were
> proposed by
> @compnerd in Bob's cfe-dev post:
> http://lists.llvm.org/pipermail/cfe-dev/2017-November/056166.html.
>
> These macros can be used to examine the components of the target triple at
> compile time. A has_builtin(is_target_???) preprocessor check can be used
> to
> check for their availability.
>
> __is_target_arch allows you to check if an arch is specified without
> worring
> about a specific subarch, e.g.
>
> __is_target_arch(arm) returns 1 for the target arch "armv7"
> __is_target_arch(armv7) returns 1 for the target arch "armv7"
> __is_target_arch(armv6) returns 0 for the target arch "armv7"
>
> __is_target_vendor and __is_target_environment match the specific vendor
> or environment. __is_target_os matches the specific OS, but
> __is_target_os(darwin) will match any Darwin-based OS. "Unknown" can be
> used
> to test if the triple's component is specified.
>
> rdar://35753116
>
> Differential Revision: https://reviews.llvm.org/D41087
>
> Modified:
> cfe/trunk/docs/ReleaseNotes.rst
> cfe/trunk/include/clang/Lex/Preprocessor.h
> cfe/trunk/lib/Lex/PPMacroExpansion.cpp
>
> Modified: cfe/trunk/docs/ReleaseNotes.rst
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/
> ReleaseNotes.rst?rev=320734&r1=320733&r2=320734&view=diff
> 
> ==
> --- cfe/trunk/docs/ReleaseNotes.rst (original)
> +++ cfe/trunk/docs/ReleaseNotes.rst Thu Dec 14 11:22:02 2017
> @@ -110,6 +110,10 @@ Non-comprehensive list of changes in thi
>If a gcc installation is found, it still prefers ``.ctors`` if the found
>gcc is older than 4.7.0.
>
> +- The new builtin preprocessor macros ``__is_target_arch``,
> +  ``__is_target_vendor``, ``__is_target_os``, and
> ``__is_target_environment``
> +  can be used to to examine the individual components of the target
> triple.
> +
>  New Compiler Flags
>  --
>
>
> Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Lex/Preprocessor.h?rev=320734&r1=320733&r2=320734&view=diff
> 
> ==
> --- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
> +++ cfe/trunk/include/clang/Lex/Preprocessor.h Thu Dec 14 11:22:02 2017
> @@ -175,6 +175,10 @@ class Preprocessor {
>IdentifierInfo *Ident__has_cpp_attribute;// __has_cpp_attribute
>IdentifierInfo *Ident__has_c_attribute;  // __has_c_attribute
>IdentifierInfo *Ident__has_declspec; //
> __has_declspec_attribute
> +  IdentifierInfo *Ident__is_target_arch;   // __is_target_arch
> +  IdentifierInfo *Ident__is_target_vendor; // __is_target_vendor
> +  IdentifierInfo *Ident__is_target_os; // __is_target_os
> +  IdentifierInfo *Ident__is_target_environment;//
> __is_target_environment
>
>SourceLocation DATELoc, TIMELoc;
>
>
> Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/
> PPMacroExpansion.cpp?rev=320734&r1=320733&r2=320734&view=diff
> 
> ==
> --- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
> +++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Thu Dec 14 11:22:02 2017
> @@ -375,6 +375,11 @@ void Preprocessor::RegisterBuiltinMacros
>Ident__has_include_next = RegisterBuiltinMacro(*this,
> "__has_include_next");
>Ident__has_warning  = RegisterBuiltinMacro(*this, "__has_warning");
>Ident__is_identifier= RegisterBuiltinMacro(*this,
> "__is_identifier");
> +  Ident__is_target_arch   = RegisterBuiltinMacro(*this,
> "__is_target_arch");
> +  Ident__is_target_vendor = RegisterBuiltinMacro(*this,
> "__is_target_vendor");
> +  Ident__is_target_os = RegisterBuiltinMacro(*this, "__is_target_os");
> +  Ident__is_target_environment =
> +  RegisterBuiltinMacro(*this, "__is_target_environment");
>
>// Modules.
>Ident__building_module  = RegisterBuiltinMacro(*this,
> "__building_module");
> @@ -1593,6 +1598,57 @@ static IdentifierInfo *ExpectFeatureIden
>return nullptr;
>  }
>
> +/// Implements the __is_target_arch builtin macro.
> +static bool isTargetArch(const TargetInfo &TI, const IdentifierInfo *II) {
> +  std::string ArchName = II->getName().lower() + "--";
> +  llvm::Triple Arch(ArchName);
> +  const ll

[PATCH] D40819: Implement Attribute Target MultiVersioning (Improved edition!)

2017-12-14 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:9333-9335
+  "multiversion function would have identical mangling to a previous "
+  "definition.  Duplicate declarations must have identical target attribute "
+  "values">;

erichkeane wrote:
> aaron.ballman wrote:
> > Diagnostics are not complete sentences, so this should be reworded to be 
> > even less grammatically correct. ;-)
> I tried again, hopefully this one is better? :)  Let me know if my grammar is 
> still too good...
You've achieved sufficiently incorrect grammar. ;-)



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:9333
+def err_multiversion_duplicate : Error<
+  "multiversion function duplicate declarations require identical target "
+  "attributes">;

instead of duplicate, do you mean redeclarations? Or do you mean overloaded 
declarations? Both?


https://reviews.llvm.org/D40819



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


[PATCH] D40548: [clangd] Symbol index interfaces and an in-memory index implementation.

2017-12-14 Thread Marc-Andre Laperle via Phabricator via cfe-commits
malaperle added inline comments.



Comment at: clangd/index/Index.h:134
+  virtual bool
+  fuzzyFind(Context &Ctx, const FuzzyFindRequest &Req,
+std::function Callback) const = 0;

ioeric wrote:
> malaperle wrote:
> > I think a more generic std::function would be useful, similar to the 
> > indexstore's filter
> > ```
> > bool searchSymbols(llvm::function_ref 
> > filter,
> >  llvm::function_ref receiver)
> > ```
> Do you have an use case in mind which requires different filtering? This 
> could probably be a separate interface. 
> 
> I think the behavior of fuzzy finding is well-defined, and how filtering is 
> done is an implementation detail. User-specified filter might make 
> implementation less flexible, especially for large indexes that are not 
> managed in memory. 
For example
- Searching by USR
- By non-qualified name (useful also for Open Workspace Symbol)
- Most likely other filters, hmm, by Symbol kind, language?
- No filter, i.e. retrieve *all* symbols. Useful mainly for development and to 
get index statistics

There could also be a boolean in the callback return value (or the filter 
callback) to limit the number of returned values.
I haven't tried locally but it looks like it would be pretty doable to change 
the FuzzyFindRequest into a std::function.
A big disadvantage of having just one method though is that is would be 
difficult for an implementation to optimize for a specific type of query. For 
example, if you search by non-qualified name, an implementation could use a 
mapping of non-qualified-name-to-USR but it would be difficult to know what to 
do given only the std::function/filter passed by argument.
In that sense, perhaps it is better to have multiple methods for each use 
cases. Or perhaps some enum for each kind of query. What do you think?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D40548



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


[PATCH] D40819: Implement Attribute Target MultiVersioning (Improved edition!)

2017-12-14 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:9333
+def err_multiversion_duplicate : Error<
+  "multiversion function duplicate declarations require identical target "
+  "attributes">;

aaron.ballman wrote:
> instead of duplicate, do you mean redeclarations? Or do you mean overloaded 
> declarations? Both?
I do mean redeclarations, thanks!  Change incoming.  


https://reviews.llvm.org/D40819



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


[PATCH] D41224: [ThreadSafetyAnalysis] Fix isCapabilityExpr

2017-12-14 Thread Yi Kong via Phabricator via cfe-commits
kongyi added a comment.

In https://reviews.llvm.org/D41224#955213, @lebedev.ri wrote:

> Hi.
>  I don't want to hijack the thread, but is PR32954 
>  likely unrelated to this fix, 
> and the problem (if it is a bug) is likely elsewhere?


Should be unrelated.


Repository:
  rC Clang

https://reviews.llvm.org/D41224



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


Re: [PATCH] D39622: Fix type name generation in DWARF for template instantiations with enum types and template specializations

2017-12-14 Thread David Blaikie via cfe-commits
On Thu, Dec 14, 2017 at 2:21 AM Anton via Phabricator <
revi...@reviews.llvm.org> wrote:

> xgsa added a comment.
>
> In https://reviews.llvm.org/D39622#954585, @probinson wrote:
>
> > Philosophically, mangled names and DWARF information serve different
> purposes, and I don't think you will find one true solution where both of
> them can yield the same name that everyone will be happy with.  Mangled
> names exist to provide unique and reproducible identifiers for the "same"
> entity across compilation units.  They are carefully specified (for
> example) to allow a linker to associate a reference in one object file to a
> definition in a different object file, and be guaranteed that the
> association is correct.  A demangled name is a necessarily context-free
> translation of the mangled name into something that has a closer
> relationship to how a human would think of or write the name of the thing,
> but isn't necessarily the only way to write the name of the thing.
> >
> > DWARF names are (deliberately not carefully specified) strings that
> ought to bear some relationship to how source code would name the thing,
> but you probably don't want to attach semantic significance to those
> names.  This is rather emphatically true for names containing template
> parameters.  Typedefs (and their recent offspring, 'using' aliases) are
> your sworn enemy here.  Enums, as you have found, are also a problem.
> >
> > Basically, the type of an entity does not have a unique name, and trying
> to coerce different representations of the type into having the same unique
> name is a losing battle.
>

I'm actually going back and forth on this ^. It seems to me, regardless of
mangled names, etc, it'd be good if LLVM used the same name for a type in
DWARF across different translation units. And, to a large extent, we do
(the case of typedefs in template parameters doesn't seem to present a
problem for the current implementation - the underlying type is used),
enums being one place where we don't - and we don't actually make it that
much closer to the source/based on what the user wrote.

Even if the user had: "enum X { Y = 0, Z = 0; } ... template struct
foo; ... foo" LLVM still describes that type as "foo". Also if you
have "enum X: int; ... foo<(X)0>" you get "foo<0>" whereas in another
translation unit with a definition of X you'd get "foo".

So for consistency there, I kind of think maybe a change like this isn't
bad.

But of course the specific way a template name is written may easily still
vary between compilers, so relying on it being exactly the same might not
be a great idea anyway...


> Thank you for clarification, Paul! Nevertheless, I suppose, showing actual
> type of a dynamic variable is very important for the projects, where RTTI
> is used. Moreover, it works properly in gcc+gdb pair, so I am extremely
> interested in fixing it in clang+lldb.
>
> I understand that the suggested solution possibly does not cover all the
> cases, but it improves the situation and actually covers all the cases
> found by me (I have just rechecked -- typedefs/usings seems to work fine
> when displaying the real type of variable). If more cases are found in
> future, they could be fixed similarly too. Moreover, the debuggers already
> rely on the fact that the type name looks the same in RTTI and DWARF, and I
> suppose they have no choice, because there is no other source of
> information for them (or am I missing something?).


I think they would have a choice, actually - let's walk through it...

It sounds like you're thinking of two other possibilities:

1) "I suppose, we cannot extend RTTI with the debug type name (is it
correct?)" - yeah, that's probably correct, extending the RTTI format
probably isn't desirable and we'd still need a singular/canonical DWARF
name which we don't seem to have (& the RTTI might go in another object
file that may not have debug info, or debug info generated by a different
compiler with a different type printing format, etc... )

2) Extending DWARF to include the mangled name
Sort of possible, DW_AT_linkage_name on a DW_AT_class could be used for
this just fine - no DWARF extension required.

But an alternative would be to have debuggers use a more semantically aware
matching here. The debugger does have enough information in the DWARF to
semantically match "foo<(X)0>" with "foo". enum X is in the DWARF,
and the enumerator Y is present with its value 0.

Another case of Clang's DWARF type printing differing from a common
demangling, is an unsigned parameter. template foo; foo<0> -
common demangling for this is "foo<0u>" but Clang will happily render the
type as "foo<0>" - this one seems less easy to justify changing than the
enum case (the enum case, given the declared-but-not-defined enum example,
seems more compelling to try to have clang give a consistent name to the
type (which, while not complete (differing compilers could still use
different printings), seems somewhat desirable)) because i

[PATCH] D41253: [analyzer] WIP: trackNullOrUndefValue: track last store to symbolic pointers.

2017-12-14 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet.
Herald added subscribers: cfe-commits, rnkovacs, eraman.

`bugreporter::trackNullOrUndefValue()` checker API function extends a bug 
report with a recursive family of bug report visitors (`ReturnVisitor`, 
`FindLastStoreBRVisitor`, etc.) that collectively try to figure out where the 
given value came from. In particular, a null or undefined value, which is 
useful for null dereferences, uninitialized value checks, or divisions by zero. 
This not only improves the bug report with additional helpful diagnostic 
pieces, but also helps us suppress bugs that come from inlined defensive checks 
(the more solid potential solution for at least some of these false positives 
would be to introduce a state merge at call exit, but state merge is a new 
operation over the program states, so it would require checker side support, 
which is heavy).

In this patch i attempt to add more logic into the tracking, namely to be able 
to track a value stored in an arbitrary memory region `R` back to the 
expression that caused this value to be stored there. Previously it only worked 
when `R` is coming from a `ExplodedGraph::isInterestingLValueExpression()` (the 
exact meaning of which is "the respective node would not be reclaimed during 
garbage collection" (!), of course it would indeed be a shame if the node we're 
looking for disappears). This leaves with plain variables, member variables, 
and ObjC instance variables.

`FindLastStoreBRVisitor` is already capable of doing this in the general case 
of an arbitrary memory region - not only it finds the node where `getSVal(R)` 
changed, but also it finds `PostStore` nodes to this region even if the newly 
written value is same as old value.

Note that visitors are deduplicated, so we're not afraid of adding too many 
identical visitors.

TODO: For now i just stuffed the visitor in there, and it seems to work. But 
i'd like to see how much the existing code for variables can (or even must) be 
reused before committing, hence WIP.


Repository:
  rC Clang

https://reviews.llvm.org/D41253

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
@@ -142,8 +142,9 @@
   // expected-note@-1{{Passing null pointer value via 1st 
parameter 'x'}}
   if (getSymbol()) {  // expected-note  {{Assuming the condition is true}}
   // expected-note@-1{{Taking true branch}}
-X *x = Type().x; // expected-note{{'x' initialized to a null pointer 
value}}
-x->f(); // expected-warning{{Called C++ object pointer is null}}
+X *xx = Type().x; // expected-note   {{Null pointer value stored to field 
'x'}}
+  // expected-note@-1{{'xx' initialized to a null pointer 
value}}
+xx->f(); // expected-warning{{Called C++ object pointer is null}}
 // expected-note@-1{{Called C++ object pointer is null}}
   }
 }
Index: test/Analysis/inlining/inline-defensive-checks.c
===
--- test/Analysis/inlining/inline-defensive-checks.c
+++ test/Analysis/inlining/inline-defensive-checks.c
@@ -190,3 +190,21 @@
   idc(s);
   *(&(s->a[0])) = 7; // no-warning
 }
+
+void idcTrackConstraintThroughSymbolicRegion(int **x) {
+  idc(*x);
+  // FIXME: Should not warn.
+  **x = 7; // expected-warning{{Dereference of null pointer}}
+}
+
+int *idcPlainNull(int coin) {
+  if (coin)
+return 0;
+  static int X;
+  return &X;
+}
+
+void idcTrackZeroValueThroughSymbolicRegion(int coin, int **x) {
+  *x = idcPlainNull(coin);
+  **x = 7; // no-warning
+}
Index: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
===
--- lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -1142,9 +1142,12 @@
 else
   RVal = state->getSVal(L->getRegion());
 
-const MemRegion *RegionRVal = RVal.getAsRegion();
 
report.addVisitor(llvm::make_unique(L->getRegion()));
+if (Optional KV = RVal.getAs())
+  report.addVisitor(llvm::make_unique(
+  *KV, L->getRegion(), EnableNullFPSuppression));
 
+const MemRegion *RegionRVal = RVal.getAsRegion();
 if (RegionRVal && isa(RegionRVal)) {
   report.markInteresting(RegionRVal);
   report.addVisitor(llvm::make_unique(


Index: test/Analysis/nullptr.cpp
===
--- test/Analysis/nullptr.cpp
+++ test/Analysis/nullptr.cpp
@@ -142,8 +142,9 @@
   // expected-note@-1{{Passing null pointer value via 1st parameter 'x'}}
   if (getSymbol()) {  // expected-note  {{Assuming the condition is true}}

  1   2   >