[PATCH] D41716: clang-tidy: add IgnoreMacros option to readability-inconsistent-declaration-parameter-name

2018-01-04 Thread Miklos Vajna via Phabricator via cfe-commits
vmiklos added a comment.

In https://reviews.llvm.org/D41716#967237, @lebedev.ri wrote:

> That changes the defaults though. I thought clang-tidy *tried* to produce the 
> same results
>  on different clang-tidy versions with the same `.clang-tidy` config? Or is 
> there no such guarantees?


Hmm, I see this as a trade-off between backwards compatibility and consistency. 
Here I went for consistency, so that all of 
readability-inconsistent-declaration-parameter-name, 
modernize-use-default-member-init and modernize-use-using default to 
IgnoreMacros=1. But I don't have a too strong opinion on that, can change the 
default to 0 if really wanted,


https://reviews.llvm.org/D41716



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


[PATCH] D40478: Added control flow architecture protection Flag

2018-01-04 Thread Oren Ben Simhon via Phabricator via cfe-commits
oren_ben_simhon updated this revision to Diff 128601.
oren_ben_simhon added a comment.

Implemented comments posted until 01/04 (Thanks Craig)


Repository:
  rL LLVM

https://reviews.llvm.org/D40478

Files:
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/TargetInfo.h
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.def
  lib/Basic/Targets/X86.cpp
  lib/Basic/Targets/X86.h
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/x86-cf-protection.c
  test/Driver/clang_f_opts.c

Index: test/Driver/clang_f_opts.c
===
--- test/Driver/clang_f_opts.c
+++ test/Driver/clang_f_opts.c
@@ -503,3 +503,17 @@
 // CHECK-WINDOWS-ISO10646: "-fwchar-type=int"
 // CHECK-WINDOWS-ISO10646: "-fsigned-wchar"
 
+// RUN: %clang -### -S -fcf-protection %s 2>&1 | FileCheck -check-prefix=CHECK-CF-PROTECTION-FULL %s
+// RUN: %clang -### -S %s 2>&1 | FileCheck -check-prefix=CHECK-NO-CF-PROTECTION-FULL %s
+// RUN: %clang -### -S -fcf-protection=full %s 2>&1 | FileCheck -check-prefix=CHECK-CF-PROTECTION-FULL %s
+// RUN: %clang -### -S %s 2>&1 | FileCheck -check-prefix=CHECK-NO-CF-PROTECTION-FULL %s
+// CHECK-CF-PROTECTION-FULL: -fcf-protection=full
+// CHECK-NO-CF-PROTECTION-FULL-NOT: -fcf-protection=full
+// RUN: %clang -### -S -fcf-protection=return %s 2>&1 | FileCheck -check-prefix=CHECK-CF-PROTECTION-RETURN %s
+// RUN: %clang -### -S %s 2>&1 | FileCheck -check-prefix=CHECK-NO-CF-PROTECTION-RETURN %s
+// CHECK-CF-PROTECTION-RETURN: -fcf-protection=return
+// CHECK-NO-CF-PROTECTION-RETURN-NOT: -fcf-protection=return
+// RUN: %clang -### -S -fcf-protection=branch %s 2>&1 | FileCheck -check-prefix=CHECK-CF-PROTECTION-BRANCH %s
+// RUN: %clang -### -S %s 2>&1 | FileCheck -check-prefix=CHECK-NO-CF-PROTECTION-BRANCH %s
+// CHECK-CF-PROTECTION-BRANCH: -fcf-protection=branch
+// CHECK-NO-CF-PROTECTION-BRANCH-NOT: -fcf-protection=branch
Index: test/CodeGen/x86-cf-protection.c
===
--- /dev/null
+++ test/CodeGen/x86-cf-protection.c
@@ -0,0 +1,6 @@
+// RUN: not %clang_cc1 -fsyntax-only -S -emit-llvm -triple i386-unknown-unknown -fcf-protection=return %s 2>&1 | FileCheck %s --check-prefix=RETURN
+// RUN: not %clang_cc1 -fsyntax-only -S -emit-llvm -triple i386-unknown-unknown -fcf-protection=branch %s 2>&1 | FileCheck %s --check-prefix=BRANCH
+
+// RETURN: error: option 'cf-protection=return' cannot be specified without '-mshstk'
+// BRANCH: error: option 'cf-protection=branch' cannot be specified without '-mibt'
+void foo() {}
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -791,6 +791,21 @@
   Opts.CallFEntry = Args.hasArg(OPT_mfentry);
   Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info);
 
+  if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
+StringRef Name = A->getValue();
+if (Name == "full") {
+  Opts.CFProtectionReturn = 1;
+  Opts.CFProtectionBranch = 1;
+} else if (Name == "return")
+  Opts.CFProtectionReturn = 1;
+else if (Name == "branch")
+  Opts.CFProtectionBranch = 1;
+else if (Name != "none") {
+  Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
+  Success = false;
+}
+  }
+
   if (const Arg *A = Args.getLastArg(OPT_compress_debug_sections,
  OPT_compress_debug_sections_EQ)) {
 if (A->getOption().getID() == OPT_compress_debug_sections) {
Index: lib/Driver/ToolChains/Clang.cpp
===
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -3977,6 +3977,11 @@
   // Forward -cl options to -cc1
   RenderOpenCLOptions(Args, CmdArgs);
 
+  if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
+CmdArgs.push_back(
+Args.MakeArgString(Twine("-fcf-protection=") + A->getValue()));
+  }
+
   // Forward -f options with positive and negative forms; we translate
   // these by hand.
   if (Arg *A = getLastProfileSampleUseArg(Args)) {
Index: lib/CodeGen/CodeGenModule.cpp
===
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -497,6 +497,20 @@
 getModule().addModuleFlag(llvm::Module::Override, "Cross-DSO CFI", 1);
   }
 
+  if (CodeGenOpts.CFProtectionReturn &&
+  Target.checkCFProtectionReturnSupported(getDiags())) {
+// Indicate that we want to instrument return control flow protection.
+getModule().addModuleFlag(llvm::Module::Override, "cf-protection-return",
+  1);
+  }
+
+  if (CodeGenOpts.CFProtectionBranch &&
+  Target.checkCFProtectionBranchSupported(getDiags())) {

[PATCH] D41668: [clangd] Add static index for the global code completion.

2018-01-04 Thread Haojian Wu via Phabricator via cfe-commits
hokein updated this revision to Diff 128603.
hokein marked an inline comment as done.
hokein added a comment.

Add index source information to the completion item.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41668

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/CodeComplete.cpp
  clangd/CodeComplete.h
  clangd/index/MemIndex.cpp
  clangd/index/MemIndex.h
  clangd/tool/ClangdMain.cpp
  unittests/clangd/CodeCompleteTests.cpp

Index: unittests/clangd/CodeCompleteTests.cpp
===
--- unittests/clangd/CodeCompleteTests.cpp
+++ unittests/clangd/CodeCompleteTests.cpp
@@ -68,6 +68,7 @@
 MATCHER_P(Labeled, Label, "") { return arg.label == Label; }
 MATCHER_P(Kind, K, "") { return arg.kind == K; }
 MATCHER_P(Filter, F, "") { return arg.filterText == F; }
+MATCHER_P(Detail, Text, "") { return arg.detail == Text; }
 MATCHER_P(PlainText, Text, "") {
   return arg.insertTextFormat == clangd::InsertTextFormat::PlainText &&
  arg.insertText == Text;
@@ -453,12 +454,6 @@
 
 std::unique_ptr simpleIndexFromSymbols(
 std::vector> Symbols) {
-  auto I = llvm::make_unique();
-  struct Snapshot {
-SymbolSlab Slab;
-std::vector Pointers;
-  };
-  auto Snap = std::make_shared();
   SymbolSlab::Builder Slab;
   for (const auto &Pair : Symbols) {
 Symbol Sym;
@@ -475,13 +470,7 @@
 Sym.SymInfo.Kind = Pair.second;
 Slab.insert(Sym);
   }
-  Snap->Slab = std::move(Slab).build();
-  for (auto &Iter : Snap->Slab)
-Snap->Pointers.push_back(&Iter);
-  auto S = std::shared_ptr>(std::move(Snap),
-&Snap->Pointers);
-  I->build(std::move(S));
-  return std::move(I);
+  return MemIndex::build(std::move(Slab).build());
 }
 
 TEST(CompletionTest, NoIndex) {
@@ -496,6 +485,38 @@
   EXPECT_THAT(Results.items, Has("No"));
 }
 
+TEST(CompletionTest, StaticIndex) {
+  clangd::CodeCompleteOptions Opts;
+  auto I = simpleIndexFromSymbols({{"ns::XYZ", index::SymbolKind::Class}});
+  Opts.StaticIndex = I.get();
+
+  auto Results = completions(R"cpp(
+  void f() { ::ns::^ }
+  )cpp",
+ Opts);
+  EXPECT_THAT(Results.items,
+  Contains(AllOf(Named("XYZ"), Detail("[StaticIndex]";
+}
+
+TEST(CompletionTest, StaticAndDynamicIndex) {
+  clangd::CodeCompleteOptions Opts;
+  auto StaticIdx =
+  simpleIndexFromSymbols({{"ns::XYZ", index::SymbolKind::Class}});
+  Opts.StaticIndex = StaticIdx.get();
+  auto DynamicIdx =
+  simpleIndexFromSymbols({{"ns::foo", index::SymbolKind::Function}});
+  Opts.Index = DynamicIdx.get();
+
+  auto Results = completions(R"cpp(
+  void f() { ::ns::^ }
+  )cpp",
+ Opts);
+  EXPECT_THAT(Results.items,
+  Contains(AllOf(Named("XYZ"), Detail("[StaticIndex]";
+  EXPECT_THAT(Results.items,
+  Contains(AllOf(Named("foo"), Detail("[DynamicIndex]";
+}
+
 TEST(CompletionTest, SimpleIndexBased) {
   clangd::CodeCompleteOptions Opts;
   auto I = simpleIndexFromSymbols({{"ns::XYZ", index::SymbolKind::Class},
Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,6 +11,7 @@
 #include "JSONRPCDispatcher.h"
 #include "Path.h"
 #include "Trace.h"
+#include "index/SymbolYAML.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -26,7 +27,24 @@
 
 namespace {
 enum class PCHStorageFlag { Disk, Memory };
+
+// Build an in-memory static index for global symbols from a YAML-format file.
+// The size of global symbols should be relatively small, so that all symbols
+// can be managed in memory.
+std::unique_ptr BuildStaticIndex(llvm::StringRef YamlSymbolFile) {
+  auto Buffer = llvm::MemoryBuffer::getFile(YamlSymbolFile);
+  if (!Buffer) {
+llvm::errs() << "Can't open " << YamlSymbolFile << "\n";
+return nullptr;
+  }
+  auto Slab = SymbolFromYAML(Buffer.get()->getBuffer());
+  SymbolSlab::Builder SymsBuilder;
+  for (auto Sym : Slab)
+SymsBuilder.insert(Sym);
+
+  return MemIndex::build(std::move(SymsBuilder).build());
 }
+} // namespace
 
 static llvm::cl::opt CompileCommandsDir(
 "compile-commands-dir",
@@ -97,6 +115,15 @@
 "use index built from symbols in opened files"),
 llvm::cl::init(false), llvm::cl::Hidden);
 
+static llvm::cl::opt YamlSymbolFile(
+"yaml-symbol-file",
+llvm::cl::desc(
+"YAML-format global symbol file to build the static index. It is only "
+"available when 'enable-index-based-completion' is enabled.\n"
+"WARNING: This option is experimental only, and will be removed "
+"eventually. Don't rely on it."),
+llvm::cl::init(""), llvm::cl::Hidden);
+
 int main(int argc, char *argv[]) {
   llvm::cl::ParseCommandLineOptions(argc, ar

[PATCH] D41668: [clangd] Add static index for the global code completion.

2018-01-04 Thread Haojian Wu via Phabricator via cfe-commits
hokein updated this revision to Diff 128604.
hokein added a comment.

Update


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41668

Files:
  clangd/ClangdLSPServer.cpp
  clangd/ClangdLSPServer.h
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/CodeComplete.cpp
  clangd/CodeComplete.h
  clangd/index/MemIndex.cpp
  clangd/index/MemIndex.h
  clangd/tool/ClangdMain.cpp
  unittests/clangd/CodeCompleteTests.cpp

Index: unittests/clangd/CodeCompleteTests.cpp
===
--- unittests/clangd/CodeCompleteTests.cpp
+++ unittests/clangd/CodeCompleteTests.cpp
@@ -68,6 +68,7 @@
 MATCHER_P(Labeled, Label, "") { return arg.label == Label; }
 MATCHER_P(Kind, K, "") { return arg.kind == K; }
 MATCHER_P(Filter, F, "") { return arg.filterText == F; }
+MATCHER_P(Detail, Text, "") { return arg.detail == Text; }
 MATCHER_P(PlainText, Text, "") {
   return arg.insertTextFormat == clangd::InsertTextFormat::PlainText &&
  arg.insertText == Text;
@@ -453,12 +454,6 @@
 
 std::unique_ptr simpleIndexFromSymbols(
 std::vector> Symbols) {
-  auto I = llvm::make_unique();
-  struct Snapshot {
-SymbolSlab Slab;
-std::vector Pointers;
-  };
-  auto Snap = std::make_shared();
   SymbolSlab::Builder Slab;
   for (const auto &Pair : Symbols) {
 Symbol Sym;
@@ -475,13 +470,7 @@
 Sym.SymInfo.Kind = Pair.second;
 Slab.insert(Sym);
   }
-  Snap->Slab = std::move(Slab).build();
-  for (auto &Iter : Snap->Slab)
-Snap->Pointers.push_back(&Iter);
-  auto S = std::shared_ptr>(std::move(Snap),
-&Snap->Pointers);
-  I->build(std::move(S));
-  return std::move(I);
+  return MemIndex::build(std::move(Slab).build());
 }
 
 TEST(CompletionTest, NoIndex) {
@@ -496,6 +485,38 @@
   EXPECT_THAT(Results.items, Has("No"));
 }
 
+TEST(CompletionTest, StaticIndex) {
+  clangd::CodeCompleteOptions Opts;
+  auto I = simpleIndexFromSymbols({{"ns::XYZ", index::SymbolKind::Class}});
+  Opts.StaticIndex = I.get();
+
+  auto Results = completions(R"cpp(
+  void f() { ::ns::^ }
+  )cpp",
+ Opts);
+  EXPECT_THAT(Results.items,
+  Contains(AllOf(Named("XYZ"), Detail("[StaticIndex]";
+}
+
+TEST(CompletionTest, StaticAndDynamicIndex) {
+  clangd::CodeCompleteOptions Opts;
+  auto StaticIdx =
+  simpleIndexFromSymbols({{"ns::XYZ", index::SymbolKind::Class}});
+  Opts.StaticIndex = StaticIdx.get();
+  auto DynamicIdx =
+  simpleIndexFromSymbols({{"ns::foo", index::SymbolKind::Function}});
+  Opts.Index = DynamicIdx.get();
+
+  auto Results = completions(R"cpp(
+  void f() { ::ns::^ }
+  )cpp",
+ Opts);
+  EXPECT_THAT(Results.items,
+  Contains(AllOf(Named("XYZ"), Detail("[StaticIndex]";
+  EXPECT_THAT(Results.items,
+  Contains(AllOf(Named("foo"), Detail("[DynamicIndex]";
+}
+
 TEST(CompletionTest, SimpleIndexBased) {
   clangd::CodeCompleteOptions Opts;
   auto I = simpleIndexFromSymbols({{"ns::XYZ", index::SymbolKind::Class},
Index: clangd/tool/ClangdMain.cpp
===
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,6 +11,7 @@
 #include "JSONRPCDispatcher.h"
 #include "Path.h"
 #include "Trace.h"
+#include "index/SymbolYAML.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -26,7 +27,24 @@
 
 namespace {
 enum class PCHStorageFlag { Disk, Memory };
+
+// Build an in-memory static index for global symbols from a YAML-format file.
+// The size of global symbols should be relatively small, so that all symbols
+// can be managed in memory.
+std::unique_ptr BuildStaticIndex(llvm::StringRef YamlSymbolFile) {
+  auto Buffer = llvm::MemoryBuffer::getFile(YamlSymbolFile);
+  if (!Buffer) {
+llvm::errs() << "Can't open " << YamlSymbolFile << "\n";
+return nullptr;
+  }
+  auto Slab = SymbolFromYAML(Buffer.get()->getBuffer());
+  SymbolSlab::Builder SymsBuilder;
+  for (auto Sym : Slab)
+SymsBuilder.insert(Sym);
+
+  return MemIndex::build(std::move(SymsBuilder).build());
 }
+} // namespace
 
 static llvm::cl::opt CompileCommandsDir(
 "compile-commands-dir",
@@ -97,6 +115,15 @@
 "use index built from symbols in opened files"),
 llvm::cl::init(false), llvm::cl::Hidden);
 
+static llvm::cl::opt YamlSymbolFile(
+"yaml-symbol-file",
+llvm::cl::desc(
+"YAML-format global symbol file to build the static index. It is only "
+"available when 'enable-index-based-completion' is enabled.\n"
+"WARNING: This option is experimental only, and will be removed "
+"eventually. Don't rely on it."),
+llvm::cl::init(""), llvm::cl::Hidden);
+
 int main(int argc, char *argv[]) {
   llvm::cl::ParseCommandLineOptions(argc, argv, "clangd");
 
@@ -182,13 +209,16 @@
   // Change stdin to binary to not lose \r\n on

Re: [clang-tools-extra] r321762 - [clang-tidy] Update fuchsia-overloaded-operator to check for valid loc

2018-01-04 Thread Alexander Kornienko via cfe-commits
Yes, would be nice to include this into 6.0.

On Wed, Jan 3, 2018 at 11:16 PM, Aaron Ballman 
wrote:

> Hans, I'd like to nominate this patch for the 6.0 branch. It fixes a
> failing assertion with new functionality; without this fix, anyone
> enabling this check and including a STL header that transitively
> includes  (which is most of them) will hit the assertion.
>
> Thanks!
>
> ~Aaron
>
> On Wed, Jan 3, 2018 at 5:10 PM, Julie Hockett via cfe-commits
>  wrote:
> > Author: juliehockett
> > Date: Wed Jan  3 14:10:11 2018
> > New Revision: 321762
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=321762&view=rev
> > Log:
> > [clang-tidy] Update fuchsia-overloaded-operator to check for valid loc
> >
> > Updating fuchsia-overloaded-operator check to not issue warnings for
> > invalid locations.
> >
> > Fixes PR35803.
> >
> > Differential Revision: https://reviews.llvm.org/D41708
> >
> > Modified:
> > clang-tools-extra/trunk/clang-tidy/fuchsia/
> OverloadedOperatorCheck.cpp
> > clang-tools-extra/trunk/test/clang-tidy/fuchsia-overloaded-
> operator.cpp
> >
> > Modified: clang-tools-extra/trunk/clang-tidy/fuchsia/
> OverloadedOperatorCheck.cpp
> > URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
> trunk/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp?
> rev=321762&r1=321761&r2=321762&view=diff
> > 
> ==
> > --- clang-tools-extra/trunk/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
> (original)
> > +++ clang-tools-extra/trunk/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
> Wed Jan  3 14:10:11 2018
> > @@ -30,8 +30,12 @@ void OverloadedOperatorCheck::registerMa
> >  }
> >
> >  void OverloadedOperatorCheck::check(const MatchFinder::MatchResult
> &Result) {
> > -  if (const auto *D = Result.Nodes.getNodeAs("decl"))
> > -diag(D->getLocStart(), "cannot overload %0") << D;
> > +  const auto *D = Result.Nodes.getNodeAs("decl");
> > +  assert(D && "No FunctionDecl captured!");
> > +
> > +  SourceLocation Loc = D->getLocStart();
> > +  if (Loc.isValid())
> > +diag(Loc, "cannot overload %0") << D;
> >  }
> >
> >  } // namespace fuchsia
> >
> > Modified: clang-tools-extra/trunk/test/clang-tidy/fuchsia-overloaded-
> operator.cpp
> > URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/
> trunk/test/clang-tidy/fuchsia-overloaded-operator.cpp?rev=
> 321762&r1=321761&r2=321762&view=diff
> > 
> ==
> > --- clang-tools-extra/trunk/test/clang-tidy/fuchsia-overloaded-operator.cpp
> (original)
> > +++ clang-tools-extra/trunk/test/clang-tidy/fuchsia-overloaded-operator.cpp
> Wed Jan  3 14:10:11 2018
> > @@ -16,3 +16,6 @@ public:
> >
> >  A operator-(const A &A1, const A &A2);
> >  // CHECK-MESSAGES: [[@LINE-1]]:1: warning: cannot overload 'operator-'
> [fuchsia-overloaded-operator]
> > +
> > +void operator delete(void*, void*) throw();
> > +// CHECK-MESSAGES: [[@LINE-1]]:1: warning: cannot overload 'operator
> delete' [fuchsia-overloaded-operator]
> >
> >
> > ___
> > cfe-commits mailing list
> > cfe-commits@lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r321794 - [libclang] Support querying whether a declaration is invalid

2018-01-04 Thread Ivan Donchevskii via cfe-commits
Author: yvvan
Date: Thu Jan  4 02:59:50 2018
New Revision: 321794

URL: http://llvm.org/viewvc/llvm-project?rev=321794&view=rev
Log:
[libclang] Support querying whether a declaration is invalid

This is useful for e.g. highlighting purposes in an IDE.

Note: First version of this patch was reverted due to failing tests in
opencl-types.cl with -target ppc64le-unknown-linux. These tests are
adapted now.

Patch by Nikolai Kosjar.

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

Modified:
cfe/trunk/include/clang-c/Index.h
cfe/trunk/test/Index/opencl-types.cl
cfe/trunk/test/Index/print-type-size.cpp
cfe/trunk/tools/c-index-test/c-index-test.c
cfe/trunk/tools/libclang/CIndex.cpp
cfe/trunk/tools/libclang/libclang.exports

Modified: cfe/trunk/include/clang-c/Index.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=321794&r1=321793&r2=321794&view=diff
==
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Thu Jan  4 02:59:50 2018
@@ -32,7 +32,7 @@
  * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
  */
 #define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 45
+#define CINDEX_VERSION_MINOR 46
 
 #define CINDEX_VERSION_ENCODE(major, minor) ( \
   ((major) * 1)   \
@@ -2642,6 +2642,16 @@ CINDEX_LINKAGE enum CXCursorKind clang_g
 CINDEX_LINKAGE unsigned clang_isDeclaration(enum CXCursorKind);
 
 /**
+ * \brief Determine whether the given declaration is invalid.
+ *
+ * A declaration is invalid if it could not be parsed successfully.
+ *
+ * \returns non-zero if the cursor represents a declaration and it is
+ * invalid, otherwise NULL.
+ */
+CINDEX_LINKAGE unsigned clang_isInvalidDeclaration(CXCursor);
+
+/**
  * \brief Determine whether the given cursor kind represents a simple
  * reference.
  *

Modified: cfe/trunk/test/Index/opencl-types.cl
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/opencl-types.cl?rev=321794&r1=321793&r2=321794&view=diff
==
--- cfe/trunk/test/Index/opencl-types.cl (original)
+++ cfe/trunk/test/Index/opencl-types.cl Thu Jan  4 02:59:50 2018
@@ -16,11 +16,11 @@ void kernel testFloatTypes() {
   double4 vectorDouble;
 }
 
-// CHECK: VarDecl=scalarHalf:11:8 (Definition) [type=half] [typekind=Half] 
[isPOD=1]
+// CHECK: VarDecl=scalarHalf:11:8 (Definition){{( \(invalid\))?}} [type=half] 
[typekind=Half] [isPOD=1]
 // CHECK: VarDecl=vectorHalf:12:9 (Definition) [type=half4] [typekind=Typedef] 
[canonicaltype=half __attribute__((ext_vector_type(4)))] 
[canonicaltypekind=Unexposed] [isPOD=1]
 // CHECK: VarDecl=scalarFloat:13:9 (Definition) [type=float] [typekind=Float] 
[isPOD=1]
 // CHECK: VarDecl=vectorFloat:14:10 (Definition) [type=float4] 
[typekind=Typedef] [canonicaltype=float __attribute__((ext_vector_type(4)))] 
[canonicaltypekind=Unexposed] [isPOD=1]
-// CHECK: VarDecl=scalarDouble:15:10 (Definition) [type=double] 
[typekind=Double] [isPOD=1]
+// CHECK: VarDecl=scalarDouble:15:10 (Definition){{( \(invalid\))?}} 
[type=double] [typekind=Double] [isPOD=1]
 // CHECK: VarDecl=vectorDouble:16:11 (Definition) [type=double4] 
[typekind=Typedef] [canonicaltype=double __attribute__((ext_vector_type(4)))] 
[canonicaltypekind=Unexposed] [isPOD=1]
 
 #pragma OPENCL EXTENSION cl_khr_gl_msaa_sharing : enable
@@ -45,10 +45,10 @@ void kernel OCLImage3dROTest(read_only i
 // CHECK: ParmDecl=scalarOCLImage2dArrayRO:32:61 (Definition) 
[type=__read_only image2d_array_t] [typekind=OCLImage2dArrayRO] [isPOD=1]
 // CHECK: ParmDecl=scalarOCLImage2dDepthRO:33:61 (Definition) 
[type=__read_only image2d_depth_t] [typekind=OCLImage2dDepthRO] [isPOD=1]
 // CHECK: ParmDecl=scalarOCLImage2dArrayDepthRO:34:72 (Definition) 
[type=__read_only image2d_array_depth_t] [typekind=OCLImage2dArrayDepthRO] 
[isPOD=1]
-// CHECK: ParmDecl=scalarOCLImage2dMSAARO:35:59 (Definition) [type=__read_only 
image2d_msaa_t] [typekind=OCLImage2dMSAARO] [isPOD=1]
-// CHECK: ParmDecl=scalarOCLImage2dArrayMSAARO:36:70 (Definition) 
[type=__read_only image2d_array_msaa_t] [typekind=OCLImage2dArrayMSAARO] 
[isPOD=1]
-// CHECK: ParmDecl=scalarOCLImage2dMSAADepthRO:37:70 (Definition) 
[type=__read_only image2d_msaa_depth_t] [typekind=OCLImage2dMSAADepthRO] 
[isPOD=1]
-// CHECK: ParmDecl=scalarOCLImage2dArrayMSAADepthRO:38:81 (Definition) 
[type=__read_only image2d_array_msaa_depth_t] 
[typekind=OCLImage2dArrayMSAADepthRO] [isPOD=1]
+// CHECK: ParmDecl=scalarOCLImage2dMSAARO:35:59 (Definition){{( 
\(invalid\))?}} [type=__read_only image2d_msaa_t] [typekind=OCLImage2dMSAARO] 
[isPOD=1]
+// CHECK: ParmDecl=scalarOCLImage2dArrayMSAARO:36:70 (Definition){{( 
\(invalid\))?}} [type=__read_only image2d_array_msaa_t] 
[typekind=OCLImage2dArrayMSAARO] [isPOD=1]
+// CHECK: ParmDecl=scalarOCLImage2dMSAADepthRO:37:70 (Definition){{( 
\(invalid\))?}} 

[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2018-01-04 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

friendly ping

any further input, or should I consider this good enough to go in now?


https://reviews.llvm.org/D40720



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


Re: [clang-tools-extra] r321762 - [clang-tidy] Update fuchsia-overloaded-operator to check for valid loc

2018-01-04 Thread Hans Wennborg via cfe-commits
Merged in r321800.

Thanks,
Hans

On Thu, Jan 4, 2018 at 11:20 AM, Alexander Kornienko via cfe-commits
 wrote:
> Yes, would be nice to include this into 6.0.
>
> On Wed, Jan 3, 2018 at 11:16 PM, Aaron Ballman 
> wrote:
>>
>> Hans, I'd like to nominate this patch for the 6.0 branch. It fixes a
>> failing assertion with new functionality; without this fix, anyone
>> enabling this check and including a STL header that transitively
>> includes  (which is most of them) will hit the assertion.
>>
>> Thanks!
>>
>> ~Aaron
>>
>> On Wed, Jan 3, 2018 at 5:10 PM, Julie Hockett via cfe-commits
>>  wrote:
>> > Author: juliehockett
>> > Date: Wed Jan  3 14:10:11 2018
>> > New Revision: 321762
>> >
>> > URL: http://llvm.org/viewvc/llvm-project?rev=321762&view=rev
>> > Log:
>> > [clang-tidy] Update fuchsia-overloaded-operator to check for valid loc
>> >
>> > Updating fuchsia-overloaded-operator check to not issue warnings for
>> > invalid locations.
>> >
>> > Fixes PR35803.
>> >
>> > Differential Revision: https://reviews.llvm.org/D41708
>> >
>> > Modified:
>> >
>> > clang-tools-extra/trunk/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
>> >
>> > clang-tools-extra/trunk/test/clang-tidy/fuchsia-overloaded-operator.cpp
>> >
>> > Modified:
>> > clang-tools-extra/trunk/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
>> > URL:
>> > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp?rev=321762&r1=321761&r2=321762&view=diff
>> >
>> > ==
>> > ---
>> > clang-tools-extra/trunk/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
>> > (original)
>> > +++
>> > clang-tools-extra/trunk/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp Wed
>> > Jan  3 14:10:11 2018
>> > @@ -30,8 +30,12 @@ void OverloadedOperatorCheck::registerMa
>> >  }
>> >
>> >  void OverloadedOperatorCheck::check(const MatchFinder::MatchResult
>> > &Result) {
>> > -  if (const auto *D = Result.Nodes.getNodeAs("decl"))
>> > -diag(D->getLocStart(), "cannot overload %0") << D;
>> > +  const auto *D = Result.Nodes.getNodeAs("decl");
>> > +  assert(D && "No FunctionDecl captured!");
>> > +
>> > +  SourceLocation Loc = D->getLocStart();
>> > +  if (Loc.isValid())
>> > +diag(Loc, "cannot overload %0") << D;
>> >  }
>> >
>> >  } // namespace fuchsia
>> >
>> > Modified:
>> > clang-tools-extra/trunk/test/clang-tidy/fuchsia-overloaded-operator.cpp
>> > URL:
>> > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/fuchsia-overloaded-operator.cpp?rev=321762&r1=321761&r2=321762&view=diff
>> >
>> > ==
>> > ---
>> > clang-tools-extra/trunk/test/clang-tidy/fuchsia-overloaded-operator.cpp
>> > (original)
>> > +++
>> > clang-tools-extra/trunk/test/clang-tidy/fuchsia-overloaded-operator.cpp Wed
>> > Jan  3 14:10:11 2018
>> > @@ -16,3 +16,6 @@ public:
>> >
>> >  A operator-(const A &A1, const A &A2);
>> >  // CHECK-MESSAGES: [[@LINE-1]]:1: warning: cannot overload 'operator-'
>> > [fuchsia-overloaded-operator]
>> > +
>> > +void operator delete(void*, void*) throw();
>> > +// CHECK-MESSAGES: [[@LINE-1]]:1: warning: cannot overload 'operator
>> > delete' [fuchsia-overloaded-operator]
>> >
>> >
>> > ___
>> > cfe-commits mailing list
>> > cfe-commits@lists.llvm.org
>> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
>
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41729: Add a tool executor that runs actions on all TUs in the compilation database.

2018-01-04 Thread Eric Liu via Phabricator via cfe-commits
ioeric created this revision.
ioeric added a reviewer: hokein.
Herald added subscribers: cfe-commits, mgorny, klimek.

Tool results are deduplicated by the result key.


Repository:
  rC Clang

https://reviews.llvm.org/D41729

Files:
  include/clang/Tooling/AllTUsExecution.h
  lib/Tooling/AllTUsExecution.cpp
  lib/Tooling/CMakeLists.txt
  lib/Tooling/Execution.cpp
  unittests/Tooling/ExecutionTest.cpp

Index: unittests/Tooling/ExecutionTest.cpp
===
--- unittests/Tooling/ExecutionTest.cpp
+++ unittests/Tooling/ExecutionTest.cpp
@@ -7,17 +7,19 @@
 //
 //===--===//
 
+#include "clang/Tooling/Execution.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/FrontendActions.h"
+#include "clang/Tooling/AllTUsExecution.h"
 #include "clang/Tooling/CompilationDatabase.h"
-#include "clang/Tooling/Execution.h"
 #include "clang/Tooling/StandaloneExecution.h"
 #include "clang/Tooling/ToolExecutorPluginRegistry.h"
 #include "clang/Tooling/Tooling.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include 
 #include 
@@ -217,5 +219,70 @@
   [](StringRef, StringRef Value) { EXPECT_EQ("1", Value); });
 }
 
+class FixedCompilationDatabaseWithFiles : public CompilationDatabase {
+public:
+  FixedCompilationDatabaseWithFiles(Twine Directory,
+ArrayRef Files,
+ArrayRef CommandLine)
+  : FixedCompilations(Directory, CommandLine), Files(Files) {}
+
+  std::vector
+  getCompileCommands(StringRef FilePath) const override {
+return FixedCompilations.getCompileCommands(FilePath);
+  }
+
+  std::vector getAllFiles() const override { return Files; }
+
+private:
+  FixedCompilationDatabase FixedCompilations;
+  std::vector Files;
+};
+
+MATCHER_P(Named, Name, "") { return arg.first == Name; }
+
+TEST(AllTUsToolTest, AFewFiles) {
+  FixedCompilationDatabaseWithFiles Compilations(".", {"a.cc", "b.cc", "c.cc"},
+ std::vector());
+  AllTUsToolExecutor Executor(Compilations, /*ThreadCount=*/0);
+  Executor.mapVirtualFile("a.cc", "void x() {}");
+  Executor.mapVirtualFile("b.cc", "void y() {}");
+  Executor.mapVirtualFile("c.cc", "void z() {}");
+
+  auto Err = Executor.execute(std::unique_ptr(
+  new ReportResultActionFactory(Executor.getExecutionContext(;
+  ASSERT_TRUE(!Err);
+  EXPECT_THAT(
+  Executor.getToolResults()->AllKVResults(),
+  ::testing::UnorderedElementsAre(Named("x"), Named("y"), Named("z")));
+}
+
+TEST(AllTUsToolTest, ManyFiles) {
+  unsigned NumFiles = 100;
+  std::vector Files;
+  std::map FileToContent;
+  std::vector ExpectedSymbols;
+  for (unsigned i = 1; i <= NumFiles; i++) {
+std::string File = "f" + std::to_string(i) + ".cc";
+std::string Symbol = "looong_function_name_" + std::to_string(i);
+Files.push_back(File);
+FileToContent[File] = "void " + Symbol + "() {}";
+ExpectedSymbols.push_back(Symbol);
+  }
+  FixedCompilationDatabaseWithFiles Compilations(".", Files,
+ std::vector());
+  AllTUsToolExecutor Executor(Compilations, /*ThreadCount=*/0);
+  for (const auto &FileAndContent : FileToContent) {
+Executor.mapVirtualFile(FileAndContent.first, FileAndContent.second);
+  }
+
+  auto Err = Executor.execute(std::unique_ptr(
+  new ReportResultActionFactory(Executor.getExecutionContext(;
+  ASSERT_TRUE(!Err);
+  std::vector Results;
+  Executor.getToolResults()->forEachResult(
+  [&](StringRef Name, StringRef) { Results.push_back(Name); });
+  EXPECT_THAT(ExpectedSymbols, ::testing::UnorderedElementsAreArray(Results));
+}
+
 } // end namespace tooling
 } // end namespace clang
Index: lib/Tooling/Execution.cpp
===
--- lib/Tooling/Execution.cpp
+++ lib/Tooling/Execution.cpp
@@ -96,10 +96,13 @@
 }
 
 // This anchor is used to force the linker to link in the generated object file
-// and thus register the StandaloneToolExecutorPlugin.
+// and thus register the StandaloneToolExecutorPlugin etc.
 extern volatile int StandaloneToolExecutorAnchorSource;
+extern volatile int AllTUsToolExecutorAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest =
 StandaloneToolExecutorAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED AllTUsToolExecutorAnchorDest =
+AllTUsToolExecutorAnchorSource;
 
 } // end namespace tooling
 } // end namespace clang
Index: lib/Tooling/CMakeLists.txt
===
--- lib/Tooling/CMakeLists.txt
+++ lib/Tooling/CMakeLists.txt
@@ -8,6 +8,7 @@
 add_subdirectory(ASTDiff)
 
 add_clang_library(clangTooling
+  AllTUsExecution.cpp
   Arg

[PATCH] D41730: [clangd] Use ToolExecutor to write the global-symbol-builder tool.

2018-01-04 Thread Eric Liu via Phabricator via cfe-commits
ioeric created this revision.
ioeric added reviewers: hokein, sammccall.
Herald added subscribers: cfe-commits, ilya-biryukov, klimek.

This enables more execution modes like standalone and Mapreduce-style execution.

See also https://reviews.llvm.org/D41729


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41730

Files:
  clangd/global-symbol-builder/GlobalSymbolBuilderMain.cpp
  clangd/index/SymbolCollector.cpp
  clangd/index/SymbolCollector.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
@@ -147,7 +147,7 @@
   UnorderedElementsAre(QName("clang::Foo2")));
 
   std::string ConcatenatedYAML =
-  SymbolToYAML(Symbols1) + SymbolToYAML(Symbols2);
+  SymbolsToYAML(Symbols1) + SymbolsToYAML(Symbols2);
   auto ConcatenatedSymbols = SymbolFromYAML(ConcatenatedYAML);
   EXPECT_THAT(ConcatenatedSymbols,
   UnorderedElementsAre(QName("clang::Foo1"),
Index: clangd/index/SymbolYAML.h
===
--- clangd/index/SymbolYAML.h
+++ clangd/index/SymbolYAML.h
@@ -27,9 +27,12 @@
 // Read symbols from a YAML-format string.
 SymbolSlab SymbolFromYAML(llvm::StringRef YAMLContent);
 
+// Convert a single symbol to YAML-format string.
+std::string SymbolToYAML(const Symbol &Sym);
+
 // 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);
+std::string SymbolsToYAML(const SymbolSlab& Symbols);
 
 } // namespace clangd
 } // namespace clang
Index: clangd/index/SymbolYAML.cpp
===
--- clangd/index/SymbolYAML.cpp
+++ clangd/index/SymbolYAML.cpp
@@ -133,14 +133,23 @@
   return std::move(Syms).build();
 }
 
-std::string SymbolToYAML(const SymbolSlab& Symbols) {
+std::string SymbolsToYAML(const SymbolSlab& Symbols) {
   std::string Str;
   llvm::raw_string_ostream OS(Str);
   llvm::yaml::Output Yout(OS);
   for (Symbol S : Symbols) // copy: Yout<< requires mutability.
 Yout<< S;
   return OS.str();
 }
 
+std::string SymbolToYAML(const Symbol& Sym) {
+  std::string Str;
+  llvm::raw_string_ostream OS(Str);
+  llvm::yaml::Output Yout(OS);
+  auto S = Sym; // copy: Yout<< requires mutability.
+  Yout << S;
+  return OS.str();
+}
+
 } // namespace clangd
 } // namespace clang
Index: clangd/index/SymbolCollector.h
===
--- clangd/index/SymbolCollector.h
+++ clangd/index/SymbolCollector.h
@@ -10,18 +10,23 @@
 #include "Index.h"
 #include "clang/Index/IndexDataConsumer.h"
 #include "clang/Index/IndexSymbol.h"
+#include "clang/Tooling/Execution.h"
 
 namespace clang {
 namespace clangd {
 
-// Collect all symbols from an AST.
-//
-// Clients (e.g. clangd) can use SymbolCollector together with
-// index::indexTopLevelDecls to retrieve all symbols when the source file is
-// changed.
+/// \brief Collect all symbols from an AST.
+///
+/// Clients (e.g. clangd) can use SymbolCollector together with
+/// index::indexTopLevelDecls to retrieve all symbols when the source file is
+/// changed.
 class SymbolCollector : public index::IndexDataConsumer {
 public:
-  SymbolCollector() = default;
+  /// \brief If Context is provided, collected symbols will also be reported via
+  /// the execution context with symbol IDs as keys and yamlized symbols as
+  /// values.
+  SymbolCollector(tooling::ExecutionContext *Context = nullptr)
+  : ExecutionCtx(Context) {}
 
   bool
   handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles,
@@ -34,6 +39,7 @@
 private:
   // All Symbols collected from the AST.
   SymbolSlab::Builder Symbols;
+  tooling::ExecutionContext *ExecutionCtx;
 };
 
 } // namespace clangd
Index: clangd/index/SymbolCollector.cpp
===
--- clangd/index/SymbolCollector.cpp
+++ clangd/index/SymbolCollector.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include "SymbolCollector.h"
+#include "index/SymbolYAML.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
@@ -106,6 +107,12 @@
 S.Name = ScopeAndName.second;
 S.SymInfo = index::getSymbolInfo(D);
 S.CanonicalDeclaration = Location;
+if (ExecutionCtx) {
+  std::string IDStr;
+  llvm::raw_string_ostream OS(IDStr);
+  OS << S.ID;
+  ExecutionCtx->reportResult(OS.str(), SymbolToYAML(S));
+}
 Symbols.insert(S);
   }
 
Index: clangd/global-symbol-builder/GlobalSymbolBuilderMain.cpp
===
--- clangd/global-symbol-builder/Gl

[PATCH] D41733: [Driver] Suggest correctly spelled driver options

2018-01-04 Thread Brian Gesiak via Phabricator via cfe-commits
modocache created this revision.
modocache added reviewers: yamaguchi, v.g.vassilev, teemperor, ruiu.

Depends on https://reviews.llvm.org/D41732.

Utilities such as `opt`, when invoked with arguments that are very
nearly spelled correctly, suggest the correctly spelled options:

  bin/opt -hel
  opt: Unknown command line argument '-hel'.  Try: 'bin/opt -help'
  opt: Did you mean '-help'?

Clang, on the other hand, prior to this commit, does not:

  bin/clang -hel
  clang-6.0: error: unknown argument: '-hel'

This commit makes use of the new libLLVMOption API from
https://reviews.llvm.org/D41732 in order to provide correct suggestions:

  bin/clang -hel
  clang-6.0: error: unknown argument: '-hel', did you mean '-help'?

Test Plan: `check-clang`


Repository:
  rC Clang

https://reviews.llvm.org/D41733

Files:
  include/clang/Basic/DiagnosticDriverKinds.td
  lib/Driver/Driver.cpp
  test/Driver/unknown-arg.c
  test/Driver/unsupported-option.c

Index: test/Driver/unsupported-option.c
===
--- /dev/null
+++ test/Driver/unsupported-option.c
@@ -0,0 +1,7 @@
+// RUN: not %clang %s --hedonism -### 2>&1 | \
+// RUN: FileCheck %s
+// RUN: not %clang %s --hell -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=DID-YOU-MEAN
+
+// CHECK: error: unsupported option '--hedonism'
+// DID-YOU-MEAN: error: unsupported option '--hell', did you mean '--help'?
Index: test/Driver/unknown-arg.c
===
--- test/Driver/unknown-arg.c
+++ test/Driver/unknown-arg.c
@@ -1,9 +1,15 @@
 // RUN: not %clang %s -cake-is-lie -%0 -%d - -munknown-to-clang-option -print-stats -funknown-to-clang-option -### 2>&1 | \
 // RUN: FileCheck %s
+// RUN: not %clang %s -stdlibs=foo -hell -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=DID-YOU-MEAN
 // RUN: %clang_cl -cake-is-lie -%0 -%d - -munknown-to-clang-option -print-stats -funknown-to-clang-option -### -c -- %s 2>&1 | \
 // RUN: FileCheck %s --check-prefix=CL
+// RUN: %clang_cl -Brepo -### -- %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CL-DID-YOU-MEAN
 // RUN: not %clang_cl -cake-is-lie -%0 -%d - -munknown-to-clang-option -print-stats -funknown-to-clang-option -c -Werror=unknown-argument -### -- %s 2>&1 | \
 // RUN: FileCheck %s --check-prefix=CL-ERROR
+// RUN: not %clang_cl -helo -Werror=unknown-argument -### -- %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CL-ERROR-DID-YOU-MEAN
 // RUN: %clang_cl -cake-is-lie -%0 -%d - -munknown-to-clang-option -print-stats -funknown-to-clang-option -c -Wno-unknown-argument -### -- %s 2>&1 | \
 // RUN: FileCheck %s --check-prefix=SILENT
 
@@ -14,20 +20,24 @@
 // CHECK: error: unknown argument: '-munknown-to-clang-option'
 // CHECK: error: unknown argument: '-print-stats'
 // CHECK: error: unknown argument: '-funknown-to-clang-option'
+// DID-YOU-MEAN: error: unknown argument '-stdlibs=foo', did you mean '-stdlib=foo'?
+// DID-YOU-MEAN: error: unknown argument '-hell', did you mean '-help'?
 // CL: warning: unknown argument ignored in clang-cl: '-cake-is-lie'
 // CL: warning: unknown argument ignored in clang-cl: '-%0'
 // CL: warning: unknown argument ignored in clang-cl: '-%d'
 // CL: warning: unknown argument ignored in clang-cl: '-'
 // CL: warning: unknown argument ignored in clang-cl: '-munknown-to-clang-option'
 // CL: warning: unknown argument ignored in clang-cl: '-print-stats'
 // CL: warning: unknown argument ignored in clang-cl: '-funknown-to-clang-option'
+// CL-DID-YOU-MEAN: warning: unknown argument ignored in clang-cl '-Brepo' (did you mean '-Brepro'?)
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-cake-is-lie'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-%0'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-%d'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-munknown-to-clang-option'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-print-stats'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-funknown-to-clang-option'
+// CL-ERROR-DID-YOU-MEAN: error: unknown argument ignored in clang-cl '-helo' (did you mean '-help'?)
 // SILENT-NOT: error:
 // SILENT-NOT: warning:
 
Index: lib/Driver/Driver.cpp
===
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -188,9 +188,19 @@
   // Check for unsupported options.
   for (const Arg *A : Args) {
 if (A->getOption().hasFlag(options::Unsupported)) {
-  Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
-  ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
-SourceLocation()) >
+  unsigned DiagID;
+  auto ArgString = A->getAsString(Args);
+  std::string Nearest;
+  if (getOpts().findNearest(
+ArgString, Nearest, IncludedFlagsBitmask,

[PATCH] D40712: [Driver] Add flag enabling the function stack size section that was added in r319430

2018-01-04 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno added inline comments.



Comment at: lib/Driver/ToolChains/Clang.cpp:3783
+CmdArgs.push_back("-fno-stack-size-section");
+
   CmdArgs.push_back("-ferror-limit");

What happens when you invoke cc1 directly for ps4 and don't specify any of the 
two options? Is it going to default to not using stack size section? It also 
seems that all non ps4 targets will get -fno-stack-size-section flag by default 
in cc1, is it really needed?


https://reviews.llvm.org/D40712



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


[PATCH] D41544: Use backslash escape, replacing xargs -0 in test macro-multiline.c

2018-01-04 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno accepted this revision.
bruno added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rC Clang

https://reviews.llvm.org/D41544



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


[PATCH] D41538: [analyzer] Fix some checker's output plist not containing the checker name #2

2018-01-04 Thread Gábor Horváth via Phabricator via cfe-commits
xazax.hun updated this revision to Diff 128630.
xazax.hun marked an inline comment as done.
xazax.hun added a comment.

- Address some review comments.


https://reviews.llvm.org/D41538

Files:
  include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
  lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  lib/StaticAnalyzer/Checkers/ValistChecker.cpp
  test/Analysis/malloc.c

Index: test/Analysis/malloc.c
===
--- test/Analysis/malloc.c
+++ test/Analysis/malloc.c
@@ -1720,13 +1720,6 @@
   }
 }
 
-char *dupstrWarn(const char *s) {
-  const int len = strlen(s);
-  char *p = (char*) smallocWarn(len + 1);
-  strcpy(p, s); // expected-warning{{String copy function overflows destination buffer}}
-  return p;
-}
-
 int *radar15580979() {
   int *data = (int *)malloc(32);
   int *p = data ?: (int*)malloc(32); // no warning
Index: lib/StaticAnalyzer/Checkers/ValistChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/ValistChecker.cpp
+++ lib/StaticAnalyzer/Checkers/ValistChecker.cpp
@@ -64,7 +64,7 @@
  CheckerContext &C) const;
   void reportLeakedVALists(const RegionVector &LeakedVALists, StringRef Msg1,
StringRef Msg2, CheckerContext &C, ExplodedNode *N,
-   bool ForceReport = false) const;
+   bool ReportUninit = false) const;
 
   void checkVAListStartCall(const CallEvent &Call, CheckerContext &C,
 bool IsCopy) const;
@@ -267,15 +267,17 @@
 void ValistChecker::reportLeakedVALists(const RegionVector &LeakedVALists,
 StringRef Msg1, StringRef Msg2,
 CheckerContext &C, ExplodedNode *N,
-bool ForceReport) const {
+bool ReportUninit) const {
   if (!(ChecksEnabled[CK_Unterminated] ||
-(ChecksEnabled[CK_Uninitialized] && ForceReport)))
+(ChecksEnabled[CK_Uninitialized] && ReportUninit)))
 return;
   for (auto Reg : LeakedVALists) {
 if (!BT_leakedvalist) {
-  BT_leakedvalist.reset(new BugType(CheckNames[CK_Unterminated],
-"Leaked va_list",
-categories::MemoryError));
+  BT_leakedvalist.reset(
+  new BugType(CheckNames[CK_Unterminated].getName().empty()
+  ? CheckNames[CK_Uninitialized]
+  : CheckNames[CK_Unterminated],
+  "Leaked va_list", categories::MemoryError));
   BT_leakedvalist->setSuppressOnSink(true);
 }
 
@@ -375,7 +377,7 @@
 
 std::shared_ptr ValistChecker::ValistBugVisitor::VisitNode(
 const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
-BugReport &BR) {
+BugReport &) {
   ProgramStateRef State = N->getState();
   ProgramStateRef StatePrev = PrevN->getState();
 
Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -2900,8 +2900,13 @@
   mgr.getCurrentCheckName();
   // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete
   // checker.
-  if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker])
+  if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker]) {
 checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true;
+// FIXME: This does not set the correct name, but without this workaround
+//no name will be set at all.
+checker->CheckNames[MallocChecker::CK_NewDeleteChecker] =
+mgr.getCurrentCheckName();
+  }
 }
 
 #define REGISTER_CHECKER(name) \
Index: include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
===
--- include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -32,27 +32,39 @@
   const CheckName Check;
   const std::string Name;
   const std::string Category;
-  bool SuppressonSink;
+  const CheckerBase *Checker;
+  bool SuppressOnSink;
 
   virtual void anchor();
+
 public:
-  BugType(class CheckName check, StringRef name, StringRef cat)
-  : Check(check), Name(name), Category(cat), SuppressonSink(false) {}
-  BugType(const CheckerBase *checker, StringRef name, StringRef cat)
-  : Check(checker->getCheckName()), Name(name), Category(cat),
-SuppressonSink(false) {}
-  virtual ~BugType() {}
-
-  // FIXME: Should these be made strings as well?
+  BugType(CheckName Check, StringRef Name, StringRef Cat)
+  : Check(Check), Name(Name), Category(Cat), Checker(nullptr),
+SuppressOnSink(false) {}
+  BugType(const CheckerBase *Ch

[PATCH] D41538: [analyzer] Fix some checker's output plist not containing the checker name #2

2018-01-04 Thread Gábor Horváth via Phabricator via cfe-commits
xazax.hun added inline comments.



Comment at: include/clang/StaticAnalyzer/Core/BugReporter/BugType.h:51
   StringRef getCategory() const { return Category; }
-  StringRef getCheckName() const { return Check.getName(); }
+  StringRef getCheckName() const {
+// FIXME: This is a workaround to ensure that Check is initialized 

NoQ wrote:
> I suggest:
> 
> ```
> if (Checker)
>   return Checker->getCheckname().getName();
> return Check.getName();
> ```
> 
> Like, what's the point of storing the StringRef if we can retrieve it any 
> time anyway?
> 
> I guess `Checker` does live long enough?
I slightly modified your snippet to preserve the assertion that can be useful 
to not to reintroduce this bug in the future.



Comment at: lib/StaticAnalyzer/Checkers/ValistChecker.cpp:277
+  BT_leakedvalist.reset(new BugType(
+  CheckNames[ReportUninit ? CK_Uninitialized : CK_Unterminated],
+  "Leaked va_list", categories::MemoryError));

NoQ wrote:
> a.sidorin wrote:
> > xazax.hun wrote:
> > > a.sidorin wrote:
> > > > If I understand correctly, if we report uninitialized and then 
> > > > unterminated, the second report will have wrong CheckName because it is 
> > > > never reset.
> > > That is right. Unfortunately, If unterminated check is not turned on but 
> > > uninitialized is, we can end up with empty check names. I replaced this 
> > > workaround with a slightly more robust one.
> > Maybe we should use different BugTypes for Uninitialized and Unterminated?
> Yep, this rings my bells too. We shouldn't race on how do we initialize a 
> `BugType` depending on what bug is encountered first in the translation unit.
Maybe I am missing something but right now there is no race on how we 
initialize the `BugType`. The result of the initialization can depend on, 
however, the set of checks that are registered. I agree that this is 
unfortunate but introducing a new `BugType` does not solve this problem or at 
least it is not apparent for me how would it solve this. One option would be to 
simply not report these issues unless the corresponding check is registered. 
The other option would be to make this depend on a new check name that needs to 
be enabled.


https://reviews.llvm.org/D41538



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


[PATCH] D41655: [clang-tidy] New check bugprone-unused-return-value

2018-01-04 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang-tidy/bugprone/UnusedReturnValueCheck.cpp:68
+diag(Matched->getLocStart(),
+ "the value returned by %0 should normally be used")
+<< dyn_cast_or_null(Matched->getCalleeDecl())

"Normally" is probably a bad term to use here. How about "the value returned by 
%0 is usually not intended to be discarded"?



Comment at: clang-tidy/bugprone/UnusedReturnValueCheck.cpp:69
+ "the value returned by %0 should normally be used")
+<< dyn_cast_or_null(Matched->getCalleeDecl())
+<< Matched->getSourceRange();

In the event this returns null, the diagnostic is going to look rather odd. 
Because the value of the call expression is unused, this will most often 
trigger in a context where the method call can be inferred (especially because 
you're now highlighting the source range). It might make sense to simply 
replace the %0 with "this call expression" or somesuch in the diagnostic.


https://reviews.llvm.org/D41655



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


[PATCH] D41720: [clang-tidy] Add a -show-color flag.

2018-01-04 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

This patch is missing test coverage.




Comment at: clang-tidy/ClangTidy.cpp:99-103
+if (Context.getOptions().ShowColor.hasValue()) {
+  DiagOpts->ShowColors = Context.getOptions().ShowColor.getValue();
+} else {
+  DiagOpts->ShowColors = llvm::sys::Process::StandardOutHasColors();
+}

I think this can be simplified to:
```
DiagOpts->ShowColors = 
Context.getOptions().ShowColor.getValueOr(llvm::sys::Process::StandardOutHasColors());
```



Comment at: clang-tidy/tool/ClangTidyMain.cpp:150-152
+Show color diagnostics. If not specified,
+defaults to on when a color-capable terminal
+is detected.)"),

I think this raw string can be reflowed a bit?

Instead of "defaults to on", how about "Defaults to true when a color-capable 
terminal is detected."?


Repository:
  rL LLVM

https://reviews.llvm.org/D41720



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


[PATCH] D41736: make attribute instantiation instantiate all attributes

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith created this revision.
rsmith added reviewers: aaron.ballman, erichkeane.
rsmith added a project: clang.
Herald added a subscriber: sanjoy.

Attribute instantiation would previously default to instantiating each kind of 
attribute only once. This was overridden by a flag whose intended purpose was 
to permit attributes from a prior declaration to be inherited onto a new 
declaration even if that new declaration had its own copy of the attribute. 
This appears to be the wrong behavior: when instantiating attributes from a 
template, we should always instantiate all the attributes that were written on 
that template.

This patch renames the flag in the Attr class (and TableGen sources) to more 
clearly identify what it's actually for, and removes the usage of the flag from 
template instantiation. I also removed the flag from AlignedAttr, which was 
only added to work around the seemingly-incorrect suppression of duplicate 
attribute instantiation.


Repository:
  rC Clang

https://reviews.llvm.org/D41736

Files:
  include/clang/AST/Attr.h
  include/clang/Basic/Attr.td
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  utils/TableGen/ClangAttrEmitter.cpp

Index: utils/TableGen/ClangAttrEmitter.cpp
===
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -2065,10 +2065,13 @@
 ArrayRef> Supers = R.getSuperClasses();
 assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
 std::string SuperName;
+bool Inheritable = false;
 for (const auto &Super : llvm::reverse(Supers)) {
   const Record *R = Super.first;
   if (R->getName() != "TargetSpecificAttr" && SuperName.empty())
 SuperName = R->getName();
+  if (R->getName() == "InheritableAttr")
+Inheritable = true;
 }
 
 OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
@@ -2162,8 +2165,13 @@
 
   OS << " )\n";
   OS << ": " << SuperName << "(attr::" << R.getName() << ", R, SI, "
- << ( R.getValueAsBit("LateParsed") ? "true" : "false" ) << ", "
- << ( R.getValueAsBit("DuplicatesAllowedWhileMerging") ? "true" : "false" ) << ")\n";
+ << ( R.getValueAsBit("LateParsed") ? "true" : "false" );
+  if (Inheritable) {
+OS << ", "
+   << (R.getValueAsBit("InheritEvenIfAlreadyPresent") ? "true"
+  : "false");
+  }
+  OS << ")\n";
 
   for (auto const &ai : Args) {
 OS << "  , ";
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -343,14 +343,6 @@
   Attr.getRange());
 }
 
-static bool DeclContainsAttr(const Decl *D, const Attr *NewAttr) {
-  if (!D->hasAttrs() || NewAttr->duplicatesAllowed())
-return false;
-  return llvm::find_if(D->getAttrs(), [NewAttr](const Attr *Attr) {
-   return Attr->getKind() == NewAttr->getKind();
- }) != D->getAttrs().end();
-}
-
 void Sema::InstantiateAttrsForDecl(
 const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl,
 Decl *New, LateInstantiatedAttrVec *LateAttrs,
@@ -365,7 +357,7 @@
 
   Attr *NewAttr = sema::instantiateTemplateAttributeForDecl(
   TmplAttr, Context, *this, TemplateArgs);
-  if (NewAttr && !DeclContainsAttr(New, NewAttr))
+  if (NewAttr)
 New->addAttr(NewAttr);
 }
   }
@@ -470,8 +462,7 @@
 
   Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
  *this, TemplateArgs);
-
-  if (NewAttr && !DeclContainsAttr(New, NewAttr))
+  if (NewAttr)
 New->addAttr(NewAttr);
 }
   }
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -2495,7 +2495,7 @@
   else if (const auto *UA = dyn_cast(Attr))
 NewAttr = S.mergeUuidAttr(D, UA->getRange(), AttrSpellingListIndex,
   UA->getGuid());
-  else if (Attr->duplicatesAllowed() || !DeclHasAttr(D, Attr))
+  else if (Attr->isInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
 NewAttr = cast(Attr->clone(S.Context));
 
   if (NewAttr) {
Index: include/clang/Basic/Attr.td
===
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -441,9 +441,6 @@
   // Set to true if all of the attribute's arguments should be parsed in an
   // unevaluated context.
   bit ParseArgumentsAsUnevaluated = 0;
-  // Set to true if this attribute can be duplicated on a subject when merging
-  // attributes. By default, attributes are not merged.
-  bit DuplicatesAllowedWhileMerging = 0;
   // Set to true if this attribu

[PATCH] D41736: make attribute instantiation instantiate all attributes

2018-01-04 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

Presumably this didn't break any tests, so I'm Ok with it.  The initial patch 
was to make sure that template specializations could clear certain attributes, 
so I think this properly gets that done.  The below test was apparently missed 
in the initial patch (and was the reason for the revert/restore), so perhaps 
this is something that could be validated still works as well.  See comments 
here: https://reviews.llvm.org/rL298410

class Mutex {
public:

  void Lock() __attribute__((exclusive_lock_function()));
  void Unlock() __attribute__((unlock_function()));

};

class A {
public:

  Mutex mu1, mu2;
  
  void foo() __attribute__((exclusive_locks_required(mu1))) 
__attribute__((exclusive_locks_required(mu2))) {}
  
  template  void bar() __attribute__((exclusive_locks_required(mu1))) 
__attribute__((exclusive_locks_required(mu2))) {
foo();
  }

};

void f() {

  A a;
  a.mu1.Lock();
  a.mu2.Lock();
  a.bar();
  a.mu2.Unlock();
  a.mu1.Unlock();

}


Repository:
  rC Clang

https://reviews.llvm.org/D41736



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


[PATCH] D41736: make attribute instantiation instantiate all attributes

2018-01-04 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

I don't suppose there is a chance at test coverage for this change?




Comment at: include/clang/AST/Attr.h:142
+  /// explicitly provided in the current declaration?
+  bool isInheritEvenIfAlreadyPresent() const {
+return InheritEvenIfAlreadyPresent;

I'm not too keen on the name -- perhaps `isInheritedEvenIfAlreadyPresent()`?


Repository:
  rC Clang

https://reviews.llvm.org/D41736



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


r321816 - [OPENMP] Add debug info for generated functions.

2018-01-04 Thread Alexey Bataev via cfe-commits
Author: abataev
Date: Thu Jan  4 11:45:16 2018
New Revision: 321816

URL: http://llvm.org/viewvc/llvm-project?rev=321816&view=rev
Log:
[OPENMP] Add debug info for generated functions.

Most of the generated functions for the OpenMP were generated with
disabled debug info. Patch fixes this for better user experience.

Modified:
cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h
cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
cfe/trunk/test/OpenMP/target_parallel_debug_codegen.cpp

Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=321816&r1=321815&r2=321816&view=diff
==
--- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Thu Jan  4 11:45:16 2018
@@ -1216,7 +1216,8 @@ emitCombinerOrInitializer(CodeGenModule
   CodeGenFunction CGF(CGM);
   // Map "T omp_in;" variable to "*omp_in_parm" value in all expressions.
   // Map "T omp_out;" variable to "*omp_out_parm" value in all expressions.
-  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args);
+  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, 
In->getLocation(),
+Out->getLocation());
   CodeGenFunction::OMPPrivateScope Scope(CGF);
   Address AddrIn = CGF.GetAddrOfLocalVar(&OmpInParm);
   Scope.addPrivate(In, [&CGF, AddrIn, PtrTy]() -> Address {
@@ -2383,7 +2384,8 @@ llvm::Function *CGOpenMPRuntime::emitThr
   // threadprivate copy of the variable VD
   CodeGenFunction CtorCGF(CGM);
   FunctionArgList Args;
-  ImplicitParamDecl Dst(CGM.getContext(), CGM.getContext().VoidPtrTy,
+  ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
+/*Id=*/nullptr, CGM.getContext().VoidPtrTy,
 ImplicitParamDecl::Other);
   Args.push_back(&Dst);
 
@@ -2393,13 +2395,13 @@ llvm::Function *CGOpenMPRuntime::emitThr
   auto Fn = CGM.CreateGlobalInitOrDestructFunction(
   FTy, ".__kmpc_global_ctor_.", FI, Loc);
   CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidPtrTy, Fn, FI,
-Args, SourceLocation());
+Args, Loc, Loc);
   auto ArgVal = CtorCGF.EmitLoadOfScalar(
   CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
   CGM.getContext().VoidPtrTy, Dst.getLocation());
   Address Arg = Address(ArgVal, VDAddr.getAlignment());
-  Arg = CtorCGF.Builder.CreateElementBitCast(Arg,
- CtorCGF.ConvertTypeForMem(ASTTy));
+  Arg = CtorCGF.Builder.CreateElementBitCast(
+  Arg, CtorCGF.ConvertTypeForMem(ASTTy));
   CtorCGF.EmitAnyExprToMem(Init, Arg, Init->getType().getQualifiers(),
/*IsInitializer=*/true);
   ArgVal = CtorCGF.EmitLoadOfScalar(
@@ -2414,7 +2416,8 @@ llvm::Function *CGOpenMPRuntime::emitThr
   // of the variable VD
   CodeGenFunction DtorCGF(CGM);
   FunctionArgList Args;
-  ImplicitParamDecl Dst(CGM.getContext(), CGM.getContext().VoidPtrTy,
+  ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
+/*Id=*/nullptr, CGM.getContext().VoidPtrTy,
 ImplicitParamDecl::Other);
   Args.push_back(&Dst);
 
@@ -2425,7 +2428,7 @@ llvm::Function *CGOpenMPRuntime::emitThr
   FTy, ".__kmpc_global_dtor_.", FI, Loc);
   auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
   DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI, 
Args,
-SourceLocation());
+Loc, Loc);
   // Create a scope with an artificial location for the body of this 
function.
   auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
   auto ArgVal = DtorCGF.EmitLoadOfScalar(
@@ -2469,7 +2472,7 @@ llvm::Function *CGOpenMPRuntime::emitThr
   FunctionArgList ArgList;
   InitCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, 
InitFunction,
 CGM.getTypes().arrangeNullaryFunction(), ArgList,
-Loc);
+Loc, Loc);
   emitThreadPrivateVarInit(InitCGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
   InitCGF.FinishFunction();
   return InitFunction;
@@ -2783,12 +2786,15 @@ static Address emitAddrOfVarFromArray(Co
 static llvm::Value *emitCopyprivateCopyFunction(
 CodeGenModule &CGM, llvm::Type *ArgsType,
 ArrayRef CopyprivateVars, ArrayRef DestExprs,
-ArrayRef SrcExprs, ArrayRef AssignmentOps) {
+ArrayRef SrcExprs, ArrayRef AssignmentOps,
+SourceLocation Loc) {
   auto &C = CGM.getContext();
   // void copy_func(void *LHSArg, void *RHSArg);
   FunctionArgList Args;
-  ImplicitParamDecl LHSArg(C, C.VoidPtrTy, Impl

[PATCH] D41517: mmintrin.h documentation fixes and updates

2018-01-04 Thread Craig Topper via Phabricator via cfe-commits
craig.topper added inline comments.



Comment at: lib/Headers/mmintrin.h:1292
 ///
-/// This intrinsic corresponds to the  VXORPS / XORPS  instruction.
+/// This intrinsic corresponds to the  XOR  instruction.
 ///

kromanova wrote:
> craig.topper wrote:
> > PXOR?
> For which platform/compiler? 
>  
> I checked, for x86_64 Linux XORPS(no avx)/VXORPS (with -mavx) is generated.
> For PS4 we generate XORL.
> 
> I guess, we need to write something more generic, implying that an 
> appropriate platform-specific XOR instruction is generated. 
Ideally to interoperate with other mmx intrinsics it should have been a PXOR 
into an mmx register. But apparently our mmx support is so limited that we 
aren't capable of that and instead create it in another domain and move it over.

I guess just indicate it as a utility function with no specific instruction.



Comment at: lib/Headers/mmintrin.h:1384
 ///
-/// This intrinsic corresponds to the  VPSHUFD / PSHUFD  instruction.
+/// This intrinsic corresponds to the  PSHUFD  instruction.
 ///

kromanova wrote:
> craig.topper wrote:
> > This is overly specific there is no guarantee we'd use those instructions. 
> > If it was a constant we'd probably just use a load.
> That's right. I think we should use the following wording to match other 
> _mm_set* intrinsics documentation in this file.
> 
> /// This intrinsic is a utility function and does not correspond to a specific
> ///instruction.
> 
Agreed.


https://reviews.llvm.org/D41517



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


r321818 - [OPENMP] Fix casting in NVPTX support library.

2018-01-04 Thread Alexey Bataev via cfe-commits
Author: abataev
Date: Thu Jan  4 12:18:55 2018
New Revision: 321818

URL: http://llvm.org/viewvc/llvm-project?rev=321818&view=rev
Log:
[OPENMP] Fix casting in NVPTX support library.

If the reduction required shuffle in the NVPTX codegen, we may need to
cast the reduced value to the integer type. This casting was implemented
incorrectly and may cause compiler crash. Patch fixes this problem.

Modified:
cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
cfe/trunk/test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp
cfe/trunk/test/OpenMP/nvptx_teams_reduction_codegen.cpp

Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp?rev=321818&r1=321817&r2=321818&view=diff
==
--- cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp Thu Jan  4 12:18:55 2018
@@ -1059,19 +1059,41 @@ void CGOpenMPRuntimeNVPTX::emitSpmdParal
   emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs);
 }
 
+/// Cast value to the specified type.
+static llvm::Value *
+castValueToType(CodeGenFunction &CGF, llvm::Value *Val, llvm::Type *CastTy,
+llvm::Optional IsSigned = llvm::None) {
+  if (Val->getType() == CastTy)
+return Val;
+  if (Val->getType()->getPrimitiveSizeInBits() > 0 &&
+  CastTy->getPrimitiveSizeInBits() > 0 &&
+  Val->getType()->getPrimitiveSizeInBits() ==
+  CastTy->getPrimitiveSizeInBits())
+return CGF.Builder.CreateBitCast(Val, CastTy);
+  if (IsSigned.hasValue() && CastTy->isIntegerTy() &&
+  Val->getType()->isIntegerTy())
+return CGF.Builder.CreateIntCast(Val, CastTy, *IsSigned);
+  Address CastItem = CGF.CreateTempAlloca(
+  CastTy,
+  CharUnits::fromQuantity(
+  CGF.CGM.getDataLayout().getPrefTypeAlignment(Val->getType(;
+  Address ValCastItem = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+  CastItem, Val->getType()->getPointerTo(CastItem.getAddressSpace()));
+  CGF.Builder.CreateStore(Val, ValCastItem);
+  return CGF.Builder.CreateLoad(CastItem);
+}
+
 /// This function creates calls to one of two shuffle functions to copy
 /// variables between lanes in a warp.
 static llvm::Value *createRuntimeShuffleFunction(CodeGenFunction &CGF,
- QualType ElemTy,
  llvm::Value *Elem,
  llvm::Value *Offset) {
   auto &CGM = CGF.CGM;
-  auto &C = CGM.getContext();
   auto &Bld = CGF.Builder;
   CGOpenMPRuntimeNVPTX &RT =
   *(static_cast(&CGM.getOpenMPRuntime()));
 
-  unsigned Size = CGM.getContext().getTypeSizeInChars(ElemTy).getQuantity();
+  unsigned Size = CGM.getDataLayout().getTypeStoreSize(Elem->getType());
   assert(Size <= 8 && "Unsupported bitwidth in shuffle instruction.");
 
   OpenMPRTLFunctionNVPTX ShuffleFn = Size <= 4
@@ -1079,17 +1101,16 @@ static llvm::Value *createRuntimeShuffle
  : OMPRTL_NVPTX__kmpc_shuffle_int64;
 
   // Cast all types to 32- or 64-bit values before calling shuffle routines.
-  auto CastTy = Size <= 4 ? CGM.Int32Ty : CGM.Int64Ty;
-  auto *ElemCast = Bld.CreateSExtOrBitCast(Elem, CastTy);
-  auto *WarpSize = CGF.EmitScalarConversion(
-  getNVPTXWarpSize(CGF), C.getIntTypeForBitwidth(32, /* Signed */ true),
-  C.getIntTypeForBitwidth(16, /* Signed */ true), SourceLocation());
+  llvm::Type *CastTy = Size <= 4 ? CGM.Int32Ty : CGM.Int64Ty;
+  llvm::Value *ElemCast = castValueToType(CGF, Elem, CastTy, 
/*isSigned=*/true);
+  auto *WarpSize =
+  Bld.CreateIntCast(getNVPTXWarpSize(CGF), CGM.Int16Ty, /*isSigned=*/true);
 
   auto *ShuffledVal =
   CGF.EmitRuntimeCall(RT.createNVPTXRuntimeFunction(ShuffleFn),
   {ElemCast, Offset, WarpSize});
 
-  return Bld.CreateTruncOrBitCast(ShuffledVal, CGF.ConvertTypeForMem(ElemTy));
+  return castValueToType(CGF, ShuffledVal, Elem->getType(), /*isSigned=*/true);
 }
 
 namespace {
@@ -1151,10 +1172,9 @@ static void emitReductionListCopy(
   // Step 1.1: Get the address for the src element in the Reduce list.
   Address SrcElementPtrAddr =
   Bld.CreateConstArrayGEP(SrcBase, Idx, CGF.getPointerSize());
-  llvm::Value *SrcElementPtrPtr = CGF.EmitLoadOfScalar(
-  SrcElementPtrAddr, /*Volatile=*/false, C.VoidPtrTy, 
SourceLocation());
-  SrcElementAddr =
-  Address(SrcElementPtrPtr, C.getTypeAlignInChars(Private->getType()));
+  SrcElementAddr = CGF.EmitLoadOfPointer(
+  SrcElementPtrAddr,
+  C.getPointerType(Private->getType())->castAs());
 
   // Step 1.2: Create a temporary to store the element in the destination
   // Reduce list.
@@ -1170,32 +1190,26 @@ static void emitReductionListCopy(
   // Step 1.1: Get the address for the src element in the Reduce l

[PATCH] D40478: Added control flow architecture protection Flag

2018-01-04 Thread Craig Topper via Phabricator via cfe-commits
craig.topper accepted this revision.
craig.topper added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rL LLVM

https://reviews.llvm.org/D40478



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


[PATCH] D41733: [Driver] Suggest correctly spelled driver options

2018-01-04 Thread Jonathan Roelofs via Phabricator via cfe-commits
jroelofs added inline comments.



Comment at: lib/Driver/Driver.cpp:191
 if (A->getOption().hasFlag(options::Unsupported)) {
-  Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
-  ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
-SourceLocation()) >
+  unsigned DiagID;
+  auto ArgString = A->getAsString(Args);

No need for this variable.



Comment at: lib/Driver/Driver.cpp:218
   for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) {
-auto ID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl
- : diag::err_drv_unknown_argument;
-
-Diags.Report(ID) << A->getAsString(Args);
-ContainsError |= Diags.getDiagnosticLevel(ID, SourceLocation()) >
+unsigned DiagID;
+auto ArgString = A->getAsString(Args);

Likewise.


Repository:
  rC Clang

https://reviews.llvm.org/D41733



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


[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.

2018-01-04 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb added a comment.

ping @sdardis, @compnerd


https://reviews.llvm.org/D39074



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


r321820 - [OPENMP] Fix capturing of expressions in clauses.

2018-01-04 Thread Alexey Bataev via cfe-commits
Author: abataev
Date: Thu Jan  4 12:50:08 2018
New Revision: 321820

URL: http://llvm.org/viewvc/llvm-project?rev=321820&view=rev
Log:
[OPENMP] Fix capturing of expressions in clauses.

Patch fixes incorrect capturing of the expressions in clauses with
expressions that must be captured for the combined constructs. Incorrect
capturing may lead to compiler crash during codegen phase.

Modified:
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/test/OpenMP/target_teams_distribute_codegen.cpp

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=321820&r1=321819&r2=321820&view=diff
==
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Jan  4 12:50:08 2018
@@ -7732,12 +7732,12 @@ static OpenMPDirectiveKind getOpenMPCapt
 case OMPD_target_parallel:
 case OMPD_target_parallel_for:
 case OMPD_target_parallel_for_simd:
-case OMPD_target_teams_distribute_parallel_for:
-case OMPD_target_teams_distribute_parallel_for_simd:
   CaptureRegion = OMPD_target;
   break;
 case OMPD_teams_distribute_parallel_for:
 case OMPD_teams_distribute_parallel_for_simd:
+case OMPD_target_teams_distribute_parallel_for:
+case OMPD_target_teams_distribute_parallel_for_simd:
   CaptureRegion = OMPD_teams;
   break;
 case OMPD_parallel:
@@ -7920,20 +7920,16 @@ static OpenMPDirectiveKind getOpenMPCapt
 break;
   case OMPC_schedule:
 switch (DKind) {
-case OMPD_target_parallel_for:
-case OMPD_target_parallel_for_simd:
-case OMPD_target_teams_distribute_parallel_for:
-case OMPD_target_teams_distribute_parallel_for_simd:
-  CaptureRegion = OMPD_target;
-  break;
-case OMPD_teams_distribute_parallel_for:
-case OMPD_teams_distribute_parallel_for_simd:
-  CaptureRegion = OMPD_teams;
-  break;
 case OMPD_parallel_for:
 case OMPD_parallel_for_simd:
 case OMPD_distribute_parallel_for:
 case OMPD_distribute_parallel_for_simd:
+case OMPD_teams_distribute_parallel_for:
+case OMPD_teams_distribute_parallel_for_simd:
+case OMPD_target_parallel_for:
+case OMPD_target_parallel_for_simd:
+case OMPD_target_teams_distribute_parallel_for:
+case OMPD_target_teams_distribute_parallel_for_simd:
   CaptureRegion = OMPD_parallel;
   break;
 case OMPD_for:
@@ -7991,18 +7987,14 @@ static OpenMPDirectiveKind getOpenMPCapt
 case OMPD_teams_distribute_parallel_for_simd:
 case OMPD_teams_distribute:
 case OMPD_teams_distribute_simd:
-  CaptureRegion = OMPD_teams;
-  break;
 case OMPD_target_teams_distribute_parallel_for:
 case OMPD_target_teams_distribute_parallel_for_simd:
 case OMPD_target_teams_distribute:
 case OMPD_target_teams_distribute_simd:
-  CaptureRegion = OMPD_target;
+  CaptureRegion = OMPD_teams;
   break;
 case OMPD_distribute_parallel_for:
 case OMPD_distribute_parallel_for_simd:
-  CaptureRegion = OMPD_parallel;
-  break;
 case OMPD_distribute:
 case OMPD_distribute_simd:
   // Do not capture thread_limit-clause expressions.

Modified: cfe/trunk/test/OpenMP/target_teams_distribute_codegen.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_teams_distribute_codegen.cpp?rev=321820&r1=321819&r2=321820&view=diff
==
--- cfe/trunk/test/OpenMP/target_teams_distribute_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/target_teams_distribute_codegen.cpp Thu Jan  4 
12:50:08 2018
@@ -62,7 +62,7 @@
 // CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i64] [i64 288]
 // CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] 
[i[[SZ]] 4, i[[SZ]] 2]
 // CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i64] [i64 
288, i64 288]
-// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i64] [i64 
288, i64 547, i64 288, i64 547, i64 547, i64 288, i64 288, i64 547, i64 547]
+// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [10 x i64] [i64 
288, i64 547, i64 288, i64 547, i64 547, i64 288, i64 288, i64 547, i64 547, 
i64 288]
 // CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [5 x i64] [i64 
547, i64 288, i64 288, i64 288, i64 547]
 // CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [5 x i[[SZ]]] 
[i[[SZ]] 4, i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
 // CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [5 x i64] [i64 
288, i64 288, i64 288, i64 288, i64 547]
@@ -211,6 +211,7 @@ int foo(int n) {
   }
 
   // We capture 3 VLA sizes in this target region
+  // CHECK:  load i32, i32* %
   // CHECK-64:   [[A_VAL:%.+]] = load i32, i32* %{{.+}},
   // CHECK-64:   [[A_ADDR:%.+]] = bitcast i[[SZ]]* [[A_CADDR:%.+]] to i32*
   // CHECK-64:   store i32 [[A_VAL]], i32

Re: r321816 - [OPENMP] Add debug info for generated functions.

2018-01-04 Thread Jonas Hahnfeld via cfe-commits

Hi Alexey,

should this change be backported to 6.0?

Regards,
Jonas

Am 2018-01-04 20:45, schrieb Alexey Bataev via cfe-commits:

Author: abataev
Date: Thu Jan  4 11:45:16 2018
New Revision: 321816

URL: http://llvm.org/viewvc/llvm-project?rev=321816&view=rev
Log:
[OPENMP] Add debug info for generated functions.

Most of the generated functions for the OpenMP were generated with
disabled debug info. Patch fixes this for better user experience.

Modified:
cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h
cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
cfe/trunk/test/OpenMP/target_parallel_debug_codegen.cpp

Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=321816&r1=321815&r2=321816&view=diff
==
--- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Thu Jan  4 11:45:16 2018
@@ -1216,7 +1216,8 @@ emitCombinerOrInitializer(CodeGenModule
   CodeGenFunction CGF(CGM);
   // Map "T omp_in;" variable to "*omp_in_parm" value in all 
expressions.
   // Map "T omp_out;" variable to "*omp_out_parm" value in all 
expressions.

-  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args);
+  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args,
In->getLocation(),
+Out->getLocation());
   CodeGenFunction::OMPPrivateScope Scope(CGF);
   Address AddrIn = CGF.GetAddrOfLocalVar(&OmpInParm);
   Scope.addPrivate(In, [&CGF, AddrIn, PtrTy]() -> Address {
@@ -2383,7 +2384,8 @@ llvm::Function *CGOpenMPRuntime::emitThr
   // threadprivate copy of the variable VD
   CodeGenFunction CtorCGF(CGM);
   FunctionArgList Args;
-  ImplicitParamDecl Dst(CGM.getContext(), 
CGM.getContext().VoidPtrTy,

+  ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
+/*Id=*/nullptr, 
CGM.getContext().VoidPtrTy,

 ImplicitParamDecl::Other);
   Args.push_back(&Dst);

@@ -2393,13 +2395,13 @@ llvm::Function *CGOpenMPRuntime::emitThr
   auto Fn = CGM.CreateGlobalInitOrDestructFunction(
   FTy, ".__kmpc_global_ctor_.", FI, Loc);
   CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidPtrTy, 
Fn, FI,

-Args, SourceLocation());
+Args, Loc, Loc);
   auto ArgVal = CtorCGF.EmitLoadOfScalar(
   CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
   CGM.getContext().VoidPtrTy, Dst.getLocation());
   Address Arg = Address(ArgVal, VDAddr.getAlignment());
-  Arg = CtorCGF.Builder.CreateElementBitCast(Arg,
- 
CtorCGF.ConvertTypeForMem(ASTTy));

+  Arg = CtorCGF.Builder.CreateElementBitCast(
+  Arg, CtorCGF.ConvertTypeForMem(ASTTy));
   CtorCGF.EmitAnyExprToMem(Init, Arg, 
Init->getType().getQualifiers(),

/*IsInitializer=*/true);
   ArgVal = CtorCGF.EmitLoadOfScalar(
@@ -2414,7 +2416,8 @@ llvm::Function *CGOpenMPRuntime::emitThr
   // of the variable VD
   CodeGenFunction DtorCGF(CGM);
   FunctionArgList Args;
-  ImplicitParamDecl Dst(CGM.getContext(), 
CGM.getContext().VoidPtrTy,

+  ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
+/*Id=*/nullptr, 
CGM.getContext().VoidPtrTy,

 ImplicitParamDecl::Other);
   Args.push_back(&Dst);

@@ -2425,7 +2428,7 @@ llvm::Function *CGOpenMPRuntime::emitThr
   FTy, ".__kmpc_global_dtor_.", FI, Loc);
   auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
   DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy,
Fn, FI, Args,
-SourceLocation());
+Loc, Loc);
   // Create a scope with an artificial location for the body of
this function.
   auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
   auto ArgVal = DtorCGF.EmitLoadOfScalar(
@@ -2469,7 +2472,7 @@ llvm::Function *CGOpenMPRuntime::emitThr
   FunctionArgList ArgList;
   InitCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy,
InitFunction,
 CGM.getTypes().arrangeNullaryFunction(), 
ArgList,

-Loc);
+Loc, Loc);
   emitThreadPrivateVarInit(InitCGF, VDAddr, Ctor, CopyCtor, Dtor, 
Loc);

   InitCGF.FinishFunction();
   return InitFunction;
@@ -2783,12 +2786,15 @@ static Address emitAddrOfVarFromArray(Co
 static llvm::Value *emitCopyprivateCopyFunction(
 CodeGenModule &CGM, llvm::Type *ArgsType,
 ArrayRef CopyprivateVars, ArrayRef 
DestExprs,
-ArrayRef SrcExprs, ArrayRef 
AssignmentOps) {
+ArrayRef SrcExprs, ArrayRef 
AssignmentOps,

+SourceLocation Loc) {
   a

[PATCH] D41102: Setup clang-doc frontend framework

2018-01-04 Thread Julie Hockett via Phabricator via cfe-commits
juliehockett updated this revision to Diff 128641.
juliehockett added a comment.

1. Adding in a basic test setup for the framework
2. Pulling the YAML specs out into their own file
3. Expanding the representation to consider different types of declarations 
(namespace, tag, and function) and store the appropriate information for output.


https://reviews.llvm.org/D41102

Files:
  test/CMakeLists.txt
  test/Tooling/clang-doc-basic.cpp
  test/lit.cfg.py
  tools/CMakeLists.txt
  tools/clang-doc/CMakeLists.txt
  tools/clang-doc/ClangDoc.cpp
  tools/clang-doc/ClangDoc.h
  tools/clang-doc/ClangDocReporter.cpp
  tools/clang-doc/ClangDocReporter.h
  tools/clang-doc/ClangDocYAML.h
  tools/clang-doc/tool/CMakeLists.txt
  tools/clang-doc/tool/ClangDocMain.cpp

Index: tools/clang-doc/tool/ClangDocMain.cpp
===
--- /dev/null
+++ tools/clang-doc/tool/ClangDocMain.cpp
@@ -0,0 +1,68 @@
+//===-- ClangDocMain.cpp - Clangdoc -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangDoc.h"
+#include "clang/Driver/Options.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
+#include 
+
+using namespace clang;
+using namespace llvm;
+
+namespace {
+
+cl::OptionCategory ClangDocCategory("clang-doc options");
+
+cl::opt
+EmitLLVM("emit-llvm",
+ cl::desc("Output in LLVM bitstream format (default is YAML)."),
+ cl::init(false), cl::cat(ClangDocCategory));
+
+cl::opt
+DoxygenOnly("doxygen",
+cl::desc("Use only doxygen-style comments to generate docs."),
+cl::init(false), cl::cat(ClangDocCategory));
+
+} // namespace
+
+int main(int argc, const char **argv) {
+  sys::PrintStackTraceOnErrorSignal(argv[0]);
+  tooling::CommonOptionsParser OptionsParser(argc, argv, ClangDocCategory);
+
+  clang::doc::OutFormat EmitFormat =
+  EmitLLVM ? doc::OutFormat::LLVM : doc::OutFormat::YAML;
+
+  // TODO: Update the source path list to only consider changed files for
+  // incremental doc updates.
+  doc::ClangDocReporter Reporter(OptionsParser.getSourcePathList());
+  doc::ClangDocContext Context{EmitFormat};
+
+  tooling::ClangTool Tool(OptionsParser.getCompilations(),
+  OptionsParser.getSourcePathList());
+
+  if (!DoxygenOnly)
+Tool.appendArgumentsAdjuster(tooling::getInsertArgumentAdjuster(
+"-fparse-all-comments", tooling::ArgumentInsertPosition::BEGIN));
+
+  doc::ClangDocActionFactory Factory(Context, Reporter);
+
+  outs() << "Parsing codebase...\n";
+  int Status = Tool.run(&Factory);
+  if (Status)
+return Status;
+
+  outs() << "Writing docs...\n";
+  Reporter.serialize(EmitFormat, outs());
+
+  return 0;
+}
Index: tools/clang-doc/tool/CMakeLists.txt
===
--- /dev/null
+++ tools/clang-doc/tool/CMakeLists.txt
@@ -0,0 +1,18 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
+
+add_clang_executable(clang-doc
+  ClangDocMain.cpp
+  )
+
+target_link_libraries(clang-doc
+  PRIVATE
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangFormat
+  clangFrontend
+  clangDoc
+  clangRewrite
+  clangTooling
+  clangToolingCore
+  )
Index: tools/clang-doc/ClangDocYAML.h
===
--- /dev/null
+++ tools/clang-doc/ClangDocYAML.h
@@ -0,0 +1,193 @@
+//===--  ClangDocYAML.h - ClangDoc YAML -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "llvm/Support/YAMLTraits.h"
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::doc::CommentInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::doc::Link)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::doc::NamedType)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::doc::Pair)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::doc::Pair)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::doc::Pair)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::doc::Pair)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::doc::Pair)
+
+namespace llvm {
+namespace yaml {
+
+template  struct NormalizedMap {
+  NormalizedMap(IO &) {}
+  NormalizedMap(IO &, const StringMap &Map) {
+for (const auto &Entry : Map) {
+  clang::doc::Pair Pair{Entry.getKeyData(), Entry.getValue()};
+  VectorMap.push_back(Pair);
+}
+  }
+
+  StringMap denormalize(IO &) {
+StringMap Map;
+for (const auto &Pair : VectorMap)
+  Map[Pair.Key] = Pair.Value;
+

[PATCH] D41733: [Driver] Suggest correctly spelled driver options

2018-01-04 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno added a comment.

This is great!

I assume it also works for cc1 invocations, right? Can you also add a test for 
%clang_cc1?


Repository:
  rC Clang

https://reviews.llvm.org/D41733



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


Re: r321816 - [OPENMP] Add debug info for generated functions.

2018-01-04 Thread Jonas Hahnfeld via cfe-commits
You mean r321818 and r321820? I skipped them because they are for NVPTX 
and target directives which aren't fully functional in 6.0 anyway, 
right?

Or patches in the future?

Am 2018-01-04 21:58, schrieb Alexey Bataev:

Hi Jonas, I don't think it is necessary. It is better to backport my 2
next patches with bug fixes.

Best regards,
Alexey

04.01.2018 15:54, Jonas Hahnfeld пишет:


Hi Alexey,

should this change be backported to 6.0?

Regards,
Jonas

Am 2018-01-04 20:45, schrieb Alexey Bataev via cfe-commits:


Author: abataev
Date: Thu Jan  4 11:45:16 2018
New Revision: 321816

URL:




https://eur02.safelinks.protection.outlook.com/?url=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%3Frev%3D321816%26view%3Drev&data=02%7C01%7C%7Ceb0f898e6fe040bc1a4208d553b566ae%7C84df9e7fe9f640afb435%7C1%7C0%7C636506960925164662&sdata=g3DdxRoQ%2B8RbIORsLLfEJAAP4Zn2Orsshr6PwIthnQw%3D&reserved=0

Log:
[OPENMP] Add debug info for generated functions.

Most of the generated functions for the OpenMP were generated with

disabled debug info. Patch fixes this for better user experience.

Modified:
cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h
cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
cfe/trunk/test/OpenMP/target_parallel_debug_codegen.cpp

Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
URL:




https://eur02.safelinks.protection.outlook.com/?url=http%3A%2F%2Fllvm.org%2Fviewvc%2Fllvm-project%2Fcfe%2Ftrunk%2Flib%2FCodeGen%2FCGOpenMPRuntime.cpp%3Frev%3D321816%26r1%3D321815%26r2%3D321816%26view%3Ddiff&data=02%7C01%7C%7Ceb0f898e6fe040bc1a4208d553b566ae%7C84df9e7fe9f640afb435%7C1%7C0%7C636506960925164662&sdata=2ppjOPjnpev4zlt1Fh6ByuYdotTiSr0Z1WyvBa8WWHo%3D&reserved=0






==


--- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Thu Jan  4 11:45:16
2018
@@ -1216,7 +1216,8 @@ emitCombinerOrInitializer(CodeGenModule
CodeGenFunction CGF(CGM);
// Map "T omp_in;" variable to "*omp_in_parm" value in all
expressions.
// Map "T omp_out;" variable to "*omp_out_parm" value in all
expressions.
-  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args);
+  CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args,
In->getLocation(),
+Out->getLocation());
CodeGenFunction::OMPPrivateScope Scope(CGF);
Address AddrIn = CGF.GetAddrOfLocalVar(&OmpInParm);
Scope.addPrivate(In, [&CGF, AddrIn, PtrTy]() -> Address {
@@ -2383,7 +2384,8 @@ llvm::Function *CGOpenMPRuntime::emitThr
// threadprivate copy of the variable VD
CodeGenFunction CtorCGF(CGM);
FunctionArgList Args;
-  ImplicitParamDecl Dst(CGM.getContext(),
CGM.getContext().VoidPtrTy,
+  ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr,
Loc,
+/*Id=*/nullptr,
CGM.getContext().VoidPtrTy,
ImplicitParamDecl::Other);
Args.push_back(&Dst);

@@ -2393,13 +2395,13 @@ llvm::Function *CGOpenMPRuntime::emitThr
auto Fn = CGM.CreateGlobalInitOrDestructFunction(
FTy, ".__kmpc_global_ctor_.", FI, Loc);
CtorCGF.StartFunction(GlobalDecl(),
CGM.getContext().VoidPtrTy, Fn, FI,
-Args, SourceLocation());
+Args, Loc, Loc);
auto ArgVal = CtorCGF.EmitLoadOfScalar(
CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
CGM.getContext().VoidPtrTy, Dst.getLocation());
Address Arg = Address(ArgVal, VDAddr.getAlignment());
-  Arg = CtorCGF.Builder.CreateElementBitCast(Arg,
-
CtorCGF.ConvertTypeForMem(ASTTy));
+  Arg = CtorCGF.Builder.CreateElementBitCast(
+  Arg, CtorCGF.ConvertTypeForMem(ASTTy));
CtorCGF.EmitAnyExprToMem(Init, Arg,
Init->getType().getQualifiers(),
/*IsInitializer=*/true);
ArgVal = CtorCGF.EmitLoadOfScalar(
@@ -2414,7 +2416,8 @@ llvm::Function *CGOpenMPRuntime::emitThr
// of the variable VD
CodeGenFunction DtorCGF(CGM);
FunctionArgList Args;
-  ImplicitParamDecl Dst(CGM.getContext(),
CGM.getContext().VoidPtrTy,
+  ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr,
Loc,
+/*Id=*/nullptr,
CGM.getContext().VoidPtrTy,
ImplicitParamDecl::Other);
Args.push_back(&Dst);

@@ -2425,7 +2428,7 @@ llvm::Function *CGOpenMPRuntime::emitThr
FTy, ".__kmpc_global_dtor_.", FI, Loc);
auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
DtorCGF.StartFunction(GlobalDecl(),
CGM.getContext().VoidTy,
Fn, FI, Args,
-SourceLocation());
+Loc, Loc);
// Create a scope with an artificial location for the body
of
this function.
auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
auto ArgVal = DtorCGF.EmitLoadOfScalar(
@@ -2469,7 +2472,7 @@ llvm::Function *CGOpenMPRuntime::emitThr
FunctionArgList ArgList;
InitCGF.StartFunction(GlobalDecl(),
CGM.getContext().VoidTy,
InitFunction,

CGM.getTypes().arrangeNullaryFunction(), ArgList,
-Loc);
+ 

[PATCH] D41311: [CodeGen] Fix crash when a function taking transparent union is redeclared.

2018-01-04 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai reopened this revision.
vsapsai added a comment.
This revision is now accepted and ready to land.

The fix wasn't entirely correct and was reverted in r321306 as it caused test 
failures

FAIL: imp.execution_time
FAIL: 2007-01-04-KNR-Args.execution_time
FAIL: sse_expandfft.execution_time
FAIL: sse_stepfft.execution_time

in LLVM test suite. Will push new revision with better fix shortly.


Repository:
  rC Clang

https://reviews.llvm.org/D41311



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


[PATCH] D41039: Add support for attribute "trivial_abi"

2018-01-04 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak updated this revision to Diff 128642.
ahatanak added a comment.

I've only fixed the places where the bits to track the triviality of special 
functions are set or reset, so this is still a WIP. I'll update the patch again 
later today, but let me know if anyone has any feedback in the meantime.

A couple of comments and questions about this patch:

- CXXRecordDecl and FunctionDecl still have the flags that keep track of the 
triviality of special functions for calls. I don't think we can avoid using 
them even under the new simpler rules? I also had to add 
"DeclaredNonTrivialSpecialMembersForCall" since 
ItaniumCXXABI::passClassIndirect needs to know whether a struct has a 
non-trivial destructor or copy constructor (I plan to make changes to  
passClassIndirect later so that hasNonTrivial*ForCalls methods are called 
there).

- If a struct annotated with "trivial_abi" turns out to be ill-formed (because 
it has virtual bases, virtual functions, or __weak pointers), the attribute is 
dropped after all the members explicitly declared in the struct are seen. The 
triviality bits for user-provided special functions are set or reset only after 
we know whether "trivial_abi" has to be dropped or not. Currently, a diagnostic 
is printed if the struct becomes ill-formed because of the attribute, but it is 
possible to make changes to suppress them or make them more user-friendly.


https://reviews.llvm.org/D41039

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclCXX.h
  include/clang/AST/Type.h
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/DeclCXX.cpp
  lib/AST/Type.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaType.cpp
  test/CodeGenCXX/trivial_abi.cpp
  test/Misc/pragma-attribute-supported-attributes-list.test
  test/SemaObjCXX/attr-trivial-abi.mm

Index: test/SemaObjCXX/attr-trivial-abi.mm
===
--- /dev/null
+++ test/SemaObjCXX/attr-trivial-abi.mm
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -std=c++11 -fobjc-runtime-has-weak -fobjc-weak -fobjc-arc -fsyntax-only -verify %s
+
+void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}}
+
+struct [[clang::trivial_abi]] S0 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S1 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S2 { // expected-warning {{'trivial_abi' cannot be applied to 'S2'}}
+  __weak id a;
+};
+
+struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}}
+  virtual void m();
+};
+
+struct S4 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}}
+};
+
+struct __attribute__((trivial_abi)) S9 : public S4 {
+};
+
+struct S6 {
+  __weak id a;
+};
+
+struct __attribute__((trivial_abi)) S7 { // expected-warning {{'trivial_abi' cannot be applied to 'S7'}}
+  S6 a;
+};
+
+struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}}
+  int a;
+};
+
+template
+struct __attribute__((trivial_abi)) S10 {
+  T p;
+};
+
+S10 p1;
+
+// Do not warn when 'trivial_abi' is used to annotate a template class.
+S10<__weak id> p2;
Index: test/Misc/pragma-attribute-supported-attributes-list.test
===
--- test/Misc/pragma-attribute-supported-attributes-list.test
+++ test/Misc/pragma-attribute-supported-attributes-list.test
@@ -2,7 +2,7 @@
 
 // The number of supported attributes should never go down!
 
-// CHECK: #pragma clang attribute supports 66 attributes:
+// CHECK: #pragma clang attribute supports 67 attributes:
 // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function)
 // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function)
 // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function)
@@ -66,6 +66,7 @@
 // CHECK-NEXT: TLSModel (SubjectMatchRule_variable_is_thread_local)
 // CHECK-NEXT: Target (SubjectMatchRule_function)
 // CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member)
+// CHECK-NEXT: TrivialABI (SubjectMatchRule_record)
 // CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType)
 // CHECK-NEXT: XRayInstrument (SubjectMatchRule_function, SubjectMatchRule_objc_method)
 // CHECK-NEXT: XRayLogArgs (SubjectMatchRule_function, SubjectMatchRule_objc_method)
Index: test/CodeGenCXX/trivial_abi.cpp
===
--- /dev/null
+++ test/CodeGenCXX/trivial_abi.cpp
@@ -0,0 +1,196 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: %[[STRUCT_SMALL:.*]] = type { i

[PATCH] D41311: [CodeGen] Fix crash when a function taking transparent union is redeclared.

2018-01-04 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai updated this revision to Diff 128643.
vsapsai added a comment.

- Fix using CreateCoercedStore for promoted float parameters.

For promoted parameters double -> float conversion should use fptrunc, not
casting through memory preserving bits. Tried to change CreateCoercedStore to
do CreateFPCast but it caused CodeGen/arm-fp16-arguments.c to fail as it
expects __fp16 values to be passed in the least-significant 16 bits.


https://reviews.llvm.org/D41311

Files:
  clang/lib/CodeGen/CGCall.cpp
  clang/test/CodeGen/kr-func-promote.c
  clang/test/CodeGen/transparent-union-redecl.c
  clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
  clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
  clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
  clang/test/Sema/transparent-union.c

Index: clang/test/Sema/transparent-union.c
===
--- clang/test/Sema/transparent-union.c
+++ clang/test/Sema/transparent-union.c
@@ -43,6 +43,35 @@
 void fvpp(TU); // expected-note{{previous declaration is here}}
 void fvpp(void **v) {} // expected-error{{conflicting types}}
 
+/* Test redeclaring a function taking a transparent_union arg more than twice.
+   Merging different declarations depends on their order, vary order too. */
+
+void f_triple0(TU tu) {}
+void f_triple0(int *); // expected-note{{previous declaration is here}}
+void f_triple0(float *f); // expected-error{{conflicting types}}
+
+void f_triple1(int *);
+void f_triple1(TU tu) {} // expected-note{{previous definition is here}}
+void f_triple1(float *f); // expected-error{{conflicting types}}
+
+void f_triple2(int *); // expected-note{{previous declaration is here}}
+void f_triple2(float *f); // expected-error{{conflicting types}}
+void f_triple2(TU tu) {}
+
+/* Test calling redeclared function taking a transparent_union arg. */
+
+void f_callee(TU);
+void f_callee(int *i) {} // expected-note{{passing argument to parameter 'i' here}}
+
+void caller(void) {
+  TU tu;
+  f_callee(tu); // expected-error{{passing 'TU' to parameter of incompatible type 'int *'}}
+
+  int *i;
+  f_callee(i);
+}
+
+
 /* FIXME: we'd like to just use an "int" here and align it differently
from the normal "int", but if we do so we lose the alignment
information from the typedef within the compiler. */
Index: clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
===
--- clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -115,9 +115,15 @@
 // B::foo gets 'this' cast to VBase* in ECX (i.e. this+8) so we
 // need to adjust 'this' before use.
 //
-// Store initial this:
+// Coerce this to correct type:
+// CHECK:   %[[THIS_STORE:.*]] = alloca %struct.B*
 // CHECK:   %[[THIS_ADDR:.*]] = alloca %struct.B*
-// CHECK:   store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR]], align 4
+// CHECK:   %[[COERCE_VAL:.*]] = bitcast i8* %{{.*}} to %struct.B*
+// CHECK:   store %struct.B* %[[COERCE_VAL]], %struct.B** %[[THIS_STORE]], align 4
+//
+// Store initial this:
+// CHECK:   %[[THIS_INIT:.*]] = load %struct.B*, %struct.B** %[[THIS_STORE]]
+// CHECK:   store %struct.B* %[[THIS_INIT]], %struct.B** %[[THIS_ADDR]], align 4
 //
 // Reload and adjust the this parameter:
 // CHECK:   %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
Index: clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
===
--- clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
+++ clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
@@ -25,6 +25,7 @@
 
 // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPM@A@AEXXZ"
 // Note that the vtordisp is applied before really adjusting to D*.
+// CHECK: %[[COERCE_LOAD:.*]] = load %struct.D*, %struct.D** %{{.*}}
 // CHECK: %[[ECX:.*]] = load %struct.D*, %struct.D** %{{.*}}
 // CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
 // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX_i8]], i32 -4
@@ -36,6 +37,7 @@
 // CHECK: ret void
 
 // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPI@3AEXXZ"
+// CHECK: %[[COERCE_LOAD:.*]] = load %struct.D*, %struct.D** %{{.*}}
 // CHECK: %[[ECX:.*]] = load %struct.D*, %struct.D** %{{.*}}
 // CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
 // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX_i8]], i32 -8
@@ -64,7 +66,8 @@
 
 G::G() {}  // Forces vftable emission.
 
-// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@E@@$R4BA@M@PPPM@7AEXXZ"(i8*)
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@E@@$R4BA@M@PPPM@7AEXXZ"(i8*
+// CHECK: %[[COERCE_LOAD:.*]] = load %struct.E*, %struct.E** %{{.*}}
 // CHECK: %[[ECX:.*]] = load %struct.E*, %str

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

2018-01-04 Thread Vassil Vassilev via Phabricator via cfe-commits
v.g.vassilev updated this revision to Diff 128645.
v.g.vassilev added a comment.

Loading of lazy partial template specializations should not trigger loading of 
full template specializations.

Often during selection process we need to load all partial template 
specializations. It is very rare to do so for full template specialization.


https://reviews.llvm.org/D41416

Files:
  include/clang/AST/DeclTemplate.h
  lib/AST/DeclTemplate.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -162,22 +162,61 @@
   Record.AddSourceLocation(typeParams->getRAngleLoc());
 }
 
-/// Add to the record the first declaration from each module file that
-/// provides a declaration of D. The intent is to provide a sufficient
-/// set such that reloading this set will load all current redeclarations.
-void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
-  llvm::MapVector Firsts;
+/// Collect the first declaration from each module file that provides a
+/// declaration of D.
+void CollectFirstDeclFromEachModule(const Decl *D, bool IncludeLocal,
+llvm::MapVector &Firsts) {
+
   // FIXME: We can skip entries that we know are implied by others.
   for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) {
 if (R->isFromASTFile())
   Firsts[Writer.Chain->getOwningModuleFile(R)] = R;
 else if (IncludeLocal)
   Firsts[nullptr] = R;
   }
+}
+
+/// Add to the record the first declaration from each module file that
+/// provides a declaration of D. The intent is to provide a sufficient
+/// set such that reloading this set will load all current redeclarations.
+void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
+  llvm::MapVector Firsts;
+  CollectFirstDeclFromEachModule(D, IncludeLocal, Firsts);
+
   for (const auto &F : Firsts)
 Record.AddDeclRef(F.second);
 }
 
+/// Add to the record the first template specialization from each module
+/// file that provides a declaration of D. We store the DeclId and an
+/// ODRHash of the template arguments of D which should provide enough
+/// information to load D only if the template instantiator needs it.
+void AddFirstSpecializationDeclFromEachModule(const Decl *D,
+  bool IncludeLocal) {
+  assert(isa(D) ||
+ isa(D) || isa(D) &&
+ "Must not be called with other decls");
+  llvm::MapVector Firsts;
+  CollectFirstDeclFromEachModule(D, IncludeLocal, Firsts);
+
+  for (const auto &F : Firsts) {
+Record.AddDeclRef(F.second);
+ArrayRef Args;
+if (auto *CTSD = dyn_cast(D))
+  Args = CTSD->getTemplateArgs().asArray();
+else if (auto *VTSD = dyn_cast(D))
+  Args = VTSD->getTemplateArgs().asArray();
+else if (auto *FD = dyn_cast(D))
+  Args = FD->getTemplateSpecializationArgs()->asArray();
+assert(Args.size());
+Record.push_back(TemplateArgumentList::ComputeODRHash(Args));
+bool IsPartialSpecialization
+  = isa(D) ||
+  isa(D);
+Record.push_back(IsPartialSpecialization);
+  }
+}
+
 /// Get the specialization decl from an entry in the specialization list.
 template 
 typename RedeclarableTemplateDecl::SpecEntryTraits::DeclType *
@@ -190,7 +229,8 @@
 decltype(T::PartialSpecializations) &getPartialSpecializations(T *Common) {
   return Common->PartialSpecializations;
 }
-ArrayRef getPartialSpecializations(FunctionTemplateDecl::Common *) {
+MutableArrayRef
+getPartialSpecializations(FunctionTemplateDecl::Common *) {
   return None;
 }
 
@@ -207,9 +247,11 @@
 assert(!Common->LazySpecializations);
   }
 
-  ArrayRef LazySpecializations;
+  using LazySpecializationInfo
+= RedeclarableTemplateDecl::LazySpecializationInfo;
+  ArrayRef LazySpecializations;
   if (auto *LS = Common->LazySpecializations)
-LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0]);
+LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0].DeclID);
 
   // Add a slot to the record for the number of specializations.
   unsigned I = Record.size();
@@ -225,12 +267,19 @@
 
   for (auto *D : Specs) {
 assert(D->isCanonicalDecl() && "non-canonical decl in set");
-AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
+AddFirstSpecializationDeclFromEachModule(D, /*IncludeLocal*/true);
+  }
+  for (auto &SpecInfo : LazySpecializations) {
+Record.push_back(SpecInfo.DeclID);
+Record.pus

[PATCH] D41357: WIP: Fix Diagnostic layering, moving diagnostics out of Basic

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

Yes, I think this is the right general direction -- in general, moving towards 
making clang's diagnostic infrastructure a reusable component that isn't tied 
to a particular diagnostics table, and in particular moving the knowledge of 
the complete set of diagnostics and diagnostic groups out of the diagnostics 
infrastructure and into the frontend tool.




Comment at: tools/driver/cc1_main.cpp:171-261
+static const DiagnosticIDs::DiagInfoRec StaticDiagInfo[] = {
+#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, 
\
+ SHOWINSYSHEADER, CATEGORY)
\
+  {diag::ENUM, 
\
+   DEFAULT_SEVERITY,   
\
+   DiagnosticIDs::CLASS,   
\
+   DiagnosticIDs::SFINAE,  
\

The best home for this is probably the `FrontendTool` library.


Repository:
  rC Clang

https://reviews.llvm.org/D41357



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


[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

LGTM, thank you!


https://reviews.llvm.org/D40720



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


[PATCH] D41720: [clang-tidy] Add a -show-color flag.

2018-01-04 Thread Ian Tessier via Phabricator via cfe-commits
itessier updated this revision to Diff 128652.

https://reviews.llvm.org/D41720

Files:
  clang-tidy/ClangTidy.cpp
  clang-tidy/ClangTidyOptions.cpp
  clang-tidy/ClangTidyOptions.h
  clang-tidy/tool/ClangTidyMain.cpp
  test/clang-tidy/show-color.cpp


Index: test/clang-tidy/show-color.cpp
===
--- /dev/null
+++ test/clang-tidy/show-color.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-tidy -checks='-*,clang-analyzer-core.NullDereference' 
-show-color %s -- | FileCheck --check-prefix=CHECK-COLOR %s
+// RUN: clang-tidy -checks='-*,clang-analyzer-core.NullDereference' 
-show-color=0 %s -- | FileCheck --check-prefix=CHECK-NO-COLOR %s
+// REQUIRES: ansi-escape-sequences
+
+void test() {
+  int *value = 0;
+  // CHECK-COLOR: [[BOLD:.\[1m]]{{.*}}[[@LINE+2]]:10: 
[[RESET:.\[0m]][[MAGENTA:.\[0;1;35m]]warning: [[RESET]][[BOLD]]Dereference of 
null pointer (loaded from variable 'value') 
[clang-analyzer-core.NullDereference][[RESET]]
+  // CHECK-NO-COLOR: [[@LINE+1]]:10: warning: Dereference of null pointer 
(loaded from variable 'value') [clang-analyzer-core.NullDereference]
+  *value = 1;
+}
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -146,6 +146,12 @@
cl::init("none"),
cl::cat(ClangTidyCategory));
 
+static cl::opt ShowColor("show-color", cl::desc(R"(
+Show color diagnostics. If not specified,
+defaults to on when a color-capable terminal
+is detected.)"),
+   cl::ValueOptional, cl::cat(ClangTidyCategory));
+
 static cl::opt ListChecks("list-checks", cl::desc(R"(
 List all enabled checks and exit. Use with
 -checks=* to list all available checks.
@@ -304,6 +310,7 @@
   DefaultOptions.SystemHeaders = SystemHeaders;
   DefaultOptions.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors;
   DefaultOptions.FormatStyle = FormatStyle;
+  DefaultOptions.ShowColor = ShowColor;
   DefaultOptions.User = llvm::sys::Process::GetEnv("USER");
   // USERNAME is used on Windows.
   if (!DefaultOptions.User)
@@ -322,6 +329,8 @@
 OverrideOptions.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors;
   if (FormatStyle.getNumOccurrences() > 0)
 OverrideOptions.FormatStyle = FormatStyle;
+  if (ShowColor.getNumOccurrences() > 0)
+OverrideOptions.ShowColor = ShowColor;
 
   if (!Config.empty()) {
 if (llvm::ErrorOr ParsedConfig =
Index: clang-tidy/ClangTidyOptions.h
===
--- clang-tidy/ClangTidyOptions.h
+++ clang-tidy/ClangTidyOptions.h
@@ -89,6 +89,9 @@
   /// See clang-format documentation for more about configuring format style.
   llvm::Optional FormatStyle;
 
+  /// \brief Show color diagnostics.
+  llvm::Optional ShowColor;
+
   /// \brief Specifies the name or e-mail of the user running clang-tidy.
   ///
   /// This option is used, for example, to place the correct user name in 
TODO()
Index: clang-tidy/ClangTidyOptions.cpp
===
--- clang-tidy/ClangTidyOptions.cpp
+++ clang-tidy/ClangTidyOptions.cpp
@@ -88,6 +88,7 @@
 IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex);
 IO.mapOptional("AnalyzeTemporaryDtors", Options.AnalyzeTemporaryDtors);
 IO.mapOptional("FormatStyle", Options.FormatStyle);
+IO.mapOptional("ShowColor", Options.ShowColor);
 IO.mapOptional("User", Options.User);
 IO.mapOptional("CheckOptions", NOpts->Options);
 IO.mapOptional("ExtraArgs", Options.ExtraArgs);
@@ -149,6 +150,7 @@
   overrideValue(Result.SystemHeaders, Other.SystemHeaders);
   overrideValue(Result.AnalyzeTemporaryDtors, Other.AnalyzeTemporaryDtors);
   overrideValue(Result.FormatStyle, Other.FormatStyle);
+  overrideValue(Result.ShowColor, Other.ShowColor);
   overrideValue(Result.User, Other.User);
   mergeVectors(Result.ExtraArgs, Other.ExtraArgs);
   mergeVectors(Result.ExtraArgsBefore, Other.ExtraArgsBefore);
Index: clang-tidy/ClangTidy.cpp
===
--- clang-tidy/ClangTidy.cpp
+++ clang-tidy/ClangTidy.cpp
@@ -96,7 +96,8 @@
   DiagPrinter),
 SourceMgr(Diags, Files), Context(Context), ApplyFixes(ApplyFixes),
 TotalFixes(0), AppliedFixes(0), WarningsAsErrors(0) {
-DiagOpts->ShowColors = llvm::sys::Process::StandardOutHasColors();
+DiagOpts->ShowColors = Context.getOptions().ShowColor.getValueOr(
+llvm::sys::Process::StandardOutHasColors());
 DiagPrinter->BeginSourceFile(LangOpts);
   }
 


Index: test/clang-tidy/show-color.cpp
===
--- /dev/null
+++ test/clang-tidy/show-color.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-tidy -checks='-*,clang-analyzer-core.NullDereference' -show-color %s -- | FileCheck --check-prefix=CHECK-COLOR %s

[PATCH] D41720: [clang-tidy] Add a -show-color flag.

2018-01-04 Thread Ian Tessier via Phabricator via cfe-commits
itessier marked an inline comment as done.
itessier added a comment.

> This patch is missing test coverage.

Done.




Comment at: clang-tidy/tool/ClangTidyMain.cpp:150-152
+Show color diagnostics. If not specified,
+defaults to on when a color-capable terminal
+is detected.)"),

aaron.ballman wrote:
> I think this raw string can be reflowed a bit?
> 
> Instead of "defaults to on", how about "Defaults to true when a color-capable 
> terminal is detected."?
I copied that part from the -fcolor-diagnostics flag to be consistent. I don't 
changing "on" to "true" if you prefer that instead.


https://reviews.llvm.org/D41720



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


[PATCH] D41736: make attribute instantiation instantiate all attributes

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith updated this revision to Diff 128654.
Herald added a subscriber: javed.absar.

Repository:
  rC Clang

https://reviews.llvm.org/D41736

Files:
  include/clang/AST/Attr.h
  include/clang/Basic/Attr.td
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/SemaTemplate/attributes.cpp
  test/SemaTemplate/warn-thread-safety-analysis.cpp
  utils/TableGen/ClangAttrEmitter.cpp

Index: utils/TableGen/ClangAttrEmitter.cpp
===
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -2065,10 +2065,13 @@
 ArrayRef> Supers = R.getSuperClasses();
 assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
 std::string SuperName;
+bool Inheritable = false;
 for (const auto &Super : llvm::reverse(Supers)) {
   const Record *R = Super.first;
   if (R->getName() != "TargetSpecificAttr" && SuperName.empty())
 SuperName = R->getName();
+  if (R->getName() == "InheritableAttr")
+Inheritable = true;
 }
 
 OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
@@ -2162,8 +2165,13 @@
 
   OS << " )\n";
   OS << ": " << SuperName << "(attr::" << R.getName() << ", R, SI, "
- << ( R.getValueAsBit("LateParsed") ? "true" : "false" ) << ", "
- << ( R.getValueAsBit("DuplicatesAllowedWhileMerging") ? "true" : "false" ) << ")\n";
+ << ( R.getValueAsBit("LateParsed") ? "true" : "false" );
+  if (Inheritable) {
+OS << ", "
+   << (R.getValueAsBit("InheritEvenIfAlreadyPresent") ? "true"
+  : "false");
+  }
+  OS << ")\n";
 
   for (auto const &ai : Args) {
 OS << "  , ";
Index: test/SemaTemplate/warn-thread-safety-analysis.cpp
===
--- test/SemaTemplate/warn-thread-safety-analysis.cpp
+++ test/SemaTemplate/warn-thread-safety-analysis.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=c++11 %s -verify -Wthread-safety-analysis
+
+class Mutex {
+public:
+  void Lock() __attribute__((exclusive_lock_function()));
+  void Unlock() __attribute__((unlock_function()));
+};
+
+class A {
+public:
+  Mutex mu1, mu2;
+
+  void foo() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) {}
+
+  template  void bar() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) {
+foo();
+  }
+};
+
+void f() {
+  A a;
+  a.mu1.Lock();
+  a.mu2.Lock();
+  a.bar();
+  a.mu2.Unlock();
+  a.bar(); // expected-warning {{calling function 'bar' requires holding mutex 'a.mu2' exclusively}}
+  a.mu1.Unlock();
+  a.bar(); // expected-warning {{calling function 'bar' requires holding mutex 'a.mu1' exclusively}} \
+   expected-warning {{calling function 'bar' requires holding mutex 'a.mu2' exclusively}}
+}
Index: test/SemaTemplate/attributes.cpp
===
--- test/SemaTemplate/attributes.cpp
+++ test/SemaTemplate/attributes.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -verify %s
+// RUN: not %clang_cc1 -std=gnu++11 -ast-dump %s | FileCheck %s
 
 namespace attribute_aligned {
   template
@@ -52,3 +53,13 @@
   template
   inline void WBCFRelease(__attribute__((cf_consumed)) T aValue) { if(aValue) CFRelease(aValue); }
 }
+
+// CHECK: FunctionTemplateDecl {{.*}} HasAnnotations
+// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_BAR"
+// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_FOO"
+// CHECK: FunctionDecl {{.*}} HasAnnotations
+// CHECK:   TemplateArgument type 'int'
+// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_BAR"
+// CHECK:   AnnotateAttr {{.*}} "ANNOTATE_FOO"
+template [[clang::annotate("ANNOTATE_FOO"), clang::annotate("ANNOTATE_BAR")]] void HasAnnotations();
+void UseAnnotations() { HasAnnotations(); }
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -343,14 +343,6 @@
   Attr.getRange());
 }
 
-static bool DeclContainsAttr(const Decl *D, const Attr *NewAttr) {
-  if (!D->hasAttrs() || NewAttr->duplicatesAllowed())
-return false;
-  return llvm::find_if(D->getAttrs(), [NewAttr](const Attr *Attr) {
-   return Attr->getKind() == NewAttr->getKind();
- }) != D->getAttrs().end();
-}
-
 void Sema::InstantiateAttrsForDecl(
 const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl,
 Decl *New, LateInstantiatedAttrVec *LateAttrs,
@@ -365,7 +357,7 @@
 
   Attr *NewAttr = sema::instantiateTemplateAttributeForDecl(
   TmplAttr, Context, *this, TemplateArgs);
-  if (NewAttr && !DeclContainsAttr(New, NewAttr))
+  if (NewAttr)
 New->addAttr(NewAttr);
 }
   }
@@ -470,8 +462,7 @@
 

[PATCH] D41736: make attribute instantiation instantiate all attributes

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

In https://reviews.llvm.org/D41736#967552, @aaron.ballman wrote:

> I don't suppose there is a chance at test coverage for this change?


Added Erich's test, plus a test that all instances of another attribute 
(`annotate`) get instantiated (the latter test failed prior to this change).




Comment at: include/clang/AST/Attr.h:142
+  /// explicitly provided in the current declaration?
+  bool isInheritEvenIfAlreadyPresent() const {
+return InheritEvenIfAlreadyPresent;

aaron.ballman wrote:
> I'm not too keen on the name -- perhaps `isInheritedEvenIfAlreadyPresent()`?
I started with that, but then changed to this abomination because 
`isInherited[...]` suggests it's telling you whether this attribute was 
inherited (like `isInherited()` does), which is not what it's for.

How about `shouldInheritEvenIfAlreadyPresent`?


Repository:
  rC Clang

https://reviews.llvm.org/D41736



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


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

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

I have created a simple (-ish) benchmark targeted to stress test modules with a 
good number of template specializations. I use the mp11 
 library from boost. I am building two 
modules which contain around 1K specializations (mostly full specializations). 
The example can be found here . I use a 
small fraction of them. This patch deserializes (only) 1117 specializations for 
around 0.2 seconds whereas without it clang deserializes 1905 specializations 
for 0.4 s.

This I believe can be further improved and I am investigating but that should 
not be a blocker for this patch.


https://reviews.llvm.org/D41416



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


[PATCH] D41736: make attribute instantiation instantiate all attributes

2018-01-04 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

LGTM, I like the shouldInheritEvenIfAlreadyPresent name better than 
isInherited... FWIW.  I'll let @aaron.ballman make the final call though.


Repository:
  rC Clang

https://reviews.llvm.org/D41736



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


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

2018-01-04 Thread Vassil Vassilev via Phabricator via cfe-commits
v.g.vassilev updated this revision to Diff 128655.
v.g.vassilev added a comment.

Zero `IsPartial` and improve comments in assert and free text.


https://reviews.llvm.org/D41416

Files:
  include/clang/AST/DeclTemplate.h
  lib/AST/DeclTemplate.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -162,22 +162,61 @@
   Record.AddSourceLocation(typeParams->getRAngleLoc());
 }
 
-/// Add to the record the first declaration from each module file that
-/// provides a declaration of D. The intent is to provide a sufficient
-/// set such that reloading this set will load all current redeclarations.
-void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
-  llvm::MapVector Firsts;
+/// Collect the first declaration from each module file that provides a
+/// declaration of D.
+void CollectFirstDeclFromEachModule(const Decl *D, bool IncludeLocal,
+llvm::MapVector &Firsts) {
+
   // FIXME: We can skip entries that we know are implied by others.
   for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) {
 if (R->isFromASTFile())
   Firsts[Writer.Chain->getOwningModuleFile(R)] = R;
 else if (IncludeLocal)
   Firsts[nullptr] = R;
   }
+}
+
+/// Add to the record the first declaration from each module file that
+/// provides a declaration of D. The intent is to provide a sufficient
+/// set such that reloading this set will load all current redeclarations.
+void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
+  llvm::MapVector Firsts;
+  CollectFirstDeclFromEachModule(D, IncludeLocal, Firsts);
+
   for (const auto &F : Firsts)
 Record.AddDeclRef(F.second);
 }
 
+/// Add to the record the first template specialization from each module
+/// file that provides a declaration of D. We store the DeclId and an
+/// ODRHash of the template arguments of D which should provide enough
+/// information to load D only if the template instantiator needs it.
+void AddFirstSpecializationDeclFromEachModule(const Decl *D,
+  bool IncludeLocal) {
+  assert(isa(D) ||
+ isa(D) || isa(D) &&
+ "Must not be called with other decls");
+  llvm::MapVector Firsts;
+  CollectFirstDeclFromEachModule(D, IncludeLocal, Firsts);
+
+  for (const auto &F : Firsts) {
+Record.AddDeclRef(F.second);
+ArrayRef Args;
+if (auto *CTSD = dyn_cast(D))
+  Args = CTSD->getTemplateArgs().asArray();
+else if (auto *VTSD = dyn_cast(D))
+  Args = VTSD->getTemplateArgs().asArray();
+else if (auto *FD = dyn_cast(D))
+  Args = FD->getTemplateSpecializationArgs()->asArray();
+assert(Args.size());
+Record.push_back(TemplateArgumentList::ComputeODRHash(Args));
+bool IsPartialSpecialization
+  = isa(D) ||
+  isa(D);
+Record.push_back(IsPartialSpecialization);
+  }
+}
+
 /// Get the specialization decl from an entry in the specialization list.
 template 
 typename RedeclarableTemplateDecl::SpecEntryTraits::DeclType *
@@ -190,7 +229,8 @@
 decltype(T::PartialSpecializations) &getPartialSpecializations(T *Common) {
   return Common->PartialSpecializations;
 }
-ArrayRef getPartialSpecializations(FunctionTemplateDecl::Common *) {
+MutableArrayRef
+getPartialSpecializations(FunctionTemplateDecl::Common *) {
   return None;
 }
 
@@ -207,9 +247,11 @@
 assert(!Common->LazySpecializations);
   }
 
-  ArrayRef LazySpecializations;
+  using LazySpecializationInfo
+= RedeclarableTemplateDecl::LazySpecializationInfo;
+  ArrayRef LazySpecializations;
   if (auto *LS = Common->LazySpecializations)
-LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0]);
+LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0].DeclID);
 
   // Add a slot to the record for the number of specializations.
   unsigned I = Record.size();
@@ -225,12 +267,20 @@
 
   for (auto *D : Specs) {
 assert(D->isCanonicalDecl() && "non-canonical decl in set");
-AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
+AddFirstSpecializationDeclFromEachModule(D, /*IncludeLocal*/true);
+  }
+  for (auto &SpecInfo : LazySpecializations) {
+Record.push_back(SpecInfo.DeclID);
+Record.push_back(SpecInfo.ODRHash);
+Record.push_back(SpecInfo.IsPartial);
   }
-  Record.append(LazySpecializations.begin(), LazySpecializations.end());
 
-  // Update the size entry 

[PATCH] D41740: [clang-tidy] Adding a new bugprone check for streaming objects of type int8_t or uint8_t

2018-01-04 Thread Barry Revzin via Phabricator via cfe-commits
BRevzin added a comment.

So admittedly, I don't have any experience in clang-tidy. This check is 
intended to catch what is to us a really annoying source of error (and I'm 
probably not the only one?). I suspect there are far better ways of writing 
this check than the one that I pretty much guess-and-checked my way into.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41740



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


[PATCH] D41740: [clang-tidy] Adding a new bugprone check for streaming objects of type int8_t or uint8_t

2018-01-04 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone added inline comments.



Comment at: clang-tidy/bugprone/StreamInt8Check.cpp:44
+} else if (Name == "int8_t") {
+diag(Offender->getLocStart(), "streaming int8_t");
+break;

I don't know clang-tidy style either, but might it be more appropriate to say 
something like "value of type int8_t will be printed as character, not number"? 
I had to go all the way down to the test cases in this patch before it occurred 
to me what the actual problem being diagnosed here was.

And speaking of "printed": do you care about streaming *in* values of these 
types with ">>"?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41740



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


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

2018-01-04 Thread Vassil Vassilev via Phabricator via cfe-commits
v.g.vassilev updated this revision to Diff 128657.
v.g.vassilev added a comment.

Reverse template specialization order.


https://reviews.llvm.org/D41416

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

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

r321828 - Use backslash escape, replacing xargs -0 in test macro-multiline.c

2018-01-04 Thread Hubert Tong via cfe-commits
Author: hubert.reinterpretcast
Date: Thu Jan  4 14:58:30 2018
New Revision: 321828

URL: http://llvm.org/viewvc/llvm-project?rev=321828&view=rev
Log:
Use backslash escape, replacing xargs -0 in test macro-multiline.c

Summary:
xargs supports escaping of newline characters with backslash.
xargs -0 is neither part of POSIX nor the LSB.

This patch removes the -0 option and adjusts the input to xargs
accordingly; that is, the input is a text file not ending in an
incomplete line, and the newline of interest is preceded by a backslash.

Note: The treatment of escaped newline characters is not as clearly
specified by POSIX as for escaped blank characters; however, the same
can be said for escaped backslashes. It is slightly more clear for the
case where the -I option is used; however, -I is also of limited
portability.

Reviewers: bruno

Reviewed By: bruno

Subscribers: bruno, rcraik, cfe-commits

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

Modified:
cfe/trunk/test/Preprocessor/macro-multiline.c

Modified: cfe/trunk/test/Preprocessor/macro-multiline.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/macro-multiline.c?rev=321828&r1=321827&r2=321828&view=diff
==
--- cfe/trunk/test/Preprocessor/macro-multiline.c (original)
+++ cfe/trunk/test/Preprocessor/macro-multiline.c Thu Jan  4 14:58:30 2018
@@ -1,4 +1,4 @@
-// RUN: printf -- "-DX=A\nTHIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT" | xargs -0 
%clang -E %s | FileCheck -strict-whitespace %s
+// RUN: printf -- "-DX=A\nTHIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT\n" | xargs 
%clang -E %s | FileCheck -strict-whitespace %s
 
 // Per GCC -D semantics, \n and anything that follows is ignored.
 


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


[PATCH] D41544: Use backslash escape, replacing xargs -0 in test macro-multiline.c

2018-01-04 Thread Hubert Tong via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC321828: Use backslash escape, replacing xargs -0 in test 
macro-multiline.c (authored by hubert.reinterpretcast, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D41544?vs=128034&id=128658#toc

Repository:
  rC Clang

https://reviews.llvm.org/D41544

Files:
  test/Preprocessor/macro-multiline.c


Index: test/Preprocessor/macro-multiline.c
===
--- test/Preprocessor/macro-multiline.c
+++ test/Preprocessor/macro-multiline.c
@@ -1,4 +1,4 @@
-// RUN: printf -- "-DX=A\nTHIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT" | xargs -0 
%clang -E %s | FileCheck -strict-whitespace %s
+// RUN: printf -- "-DX=A\nTHIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT\n" | xargs 
%clang -E %s | FileCheck -strict-whitespace %s
 
 // Per GCC -D semantics, \n and anything that follows is ignored.
 


Index: test/Preprocessor/macro-multiline.c
===
--- test/Preprocessor/macro-multiline.c
+++ test/Preprocessor/macro-multiline.c
@@ -1,4 +1,4 @@
-// RUN: printf -- "-DX=A\nTHIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT" | xargs -0 %clang -E %s | FileCheck -strict-whitespace %s
+// RUN: printf -- "-DX=A\nTHIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT\n" | xargs %clang -E %s | FileCheck -strict-whitespace %s
 
 // Per GCC -D semantics, \n and anything that follows is ignored.
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2018-01-04 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno added a comment.
Herald added a subscriber: mgrang.

The change seems good to me in general. I wonder if this will hit any broken 
assumption in the code. Did you run other tests beside unittests?


https://reviews.llvm.org/D34030



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


r321830 - Use POSIX argument syntax in test rewrite-includes-messages.c

2018-01-04 Thread Hubert Tong via cfe-commits
Author: hubert.reinterpretcast
Date: Thu Jan  4 15:03:48 2018
New Revision: 321830

URL: http://llvm.org/viewvc/llvm-project?rev=321830&view=rev
Log:
Use POSIX argument syntax in test rewrite-includes-messages.c

Invoke diff such that options precede operands. Not doing so leads to
unspecified behaviour under the LSB.

Modified:
cfe/trunk/test/Frontend/rewrite-includes-messages.c

Modified: cfe/trunk/test/Frontend/rewrite-includes-messages.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/rewrite-includes-messages.c?rev=321830&r1=321829&r2=321830&view=diff
==
--- cfe/trunk/test/Frontend/rewrite-includes-messages.c (original)
+++ cfe/trunk/test/Frontend/rewrite-includes-messages.c Thu Jan  4 15:03:48 2018
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -E -frewrite-includes %s -I%S/Inputs/ | %clang_cc1 -Wall 
-fsyntax-only -Wunused-macros -x c - 2>&1 > %t.1
 // RUN: %clang_cc1 -I%S/Inputs/ -Wall -Wunused-macros -fsyntax-only %s 2>&1 > 
%t.2
-// RUN: diff %t.1 %t.2 -u
+// RUN: diff -u %t.1 %t.2
 // expected-no-diagnostics
 
 #include "rewrite-includes-messages.h"


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


[PATCH] D40445: [C++17] Allow an empty expression in an if init statement

2018-01-04 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 128659.
Rakete added a comment.

Rebased + friendly 2018 ping :)


https://reviews.llvm.org/D40445

Files:
  lib/Parse/ParseExprCXX.cpp
  test/CXX/stmt.stmt/stmt.select/p3.cpp

Index: test/CXX/stmt.stmt/stmt.select/p3.cpp
===
--- test/CXX/stmt.stmt/stmt.select/p3.cpp
+++ test/CXX/stmt.stmt/stmt.select/p3.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++14-compat -verify %s -DCPP17
 
 int f();
 
@@ -10,10 +11,67 @@
   }
 }
 
-
 void h() {
   if (int x = f()) // expected-note 2{{previous definition}}
 int x; // expected-error{{redefinition of 'x'}}
   else
 int x; // expected-error{{redefinition of 'x'}}
 }
+
+void ifInitStatement() {
+  int Var = 0;
+
+  if (int I = 0; true) {}
+  if (Var + Var; true) {}
+  if (; true) {}
+#ifdef CPP17
+  // expected-warning@-4 {{if initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{if initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{if initialization statements are incompatible with C++ standards before C++17}}
+#else
+  // expected-warning@-8 {{'if' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'if' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'if' initialization statements are a C++17 extension}}
+#endif
+}
+
+void switchInitStatement() {
+  int Var = 0;
+
+  switch (int I = 0; Var) {}
+  switch (Var + Var; Var) {}
+  switch (; Var) {}
+#ifdef CPP17
+  // expected-warning@-4 {{switch initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{switch initialization statements are incompatible with C++ standards before C++17}}
+  // expected-warning@-4 {{switch initialization statements are incompatible with C++ standards before C++17}}
+#else
+  // expected-warning@-8 {{'switch' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'switch' initialization statements are a C++17 extension}}
+  // expected-warning@-8 {{'switch' initialization statements are a C++17 extension}}
+#endif
+}
+
+// TODO: Better diagnostics for while init statements.
+void whileInitStatement() {
+  while (int I = 10; I--); // expected-error {{expected ')'}}
+  // expected-note@-1 {{to match this '('}}
+  // expected-error@-2 {{use of undeclared identifier 'I'}}
+
+  int Var = 10;
+  while (Var + Var; Var--) {} // expected-error {{expected ')'}}
+  // expected-note@-1 {{to match this '('}}
+  // expected-error@-2 {{expected ';' after expression}}
+  // expected-error@-3 {{expected expression}}
+  // expected-warning@-4 {{while loop has empty body}}
+  // expected-note@-5 {{put the semicolon on a separate line to silence this warning}}
+}
+
+// TODO: This is needed because clang can't seem to diagnose invalid syntax after the
+// last loop above. It would be nice to remove this.
+void whileInitStatement2() {
+  while (; false) {} // expected-error {{expected expression}}
+  // expected-warning@-1 {{expression result unused}}
+  // expected-error@-2 {{expected ';' after expression}}
+  // expected-error@-3 {{expected expression}}
+}
Index: lib/Parse/ParseExprCXX.cpp
===
--- lib/Parse/ParseExprCXX.cpp
+++ lib/Parse/ParseExprCXX.cpp
@@ -1742,17 +1742,32 @@
   ParsedAttributesWithRange attrs(AttrFactory);
   MaybeParseCXX11Attributes(attrs);
 
+  const auto WarnOnInit = [this, &CK] {
+Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
+? diag::warn_cxx14_compat_init_statement
+: diag::ext_init_statement)
+<< (CK == Sema::ConditionKind::Switch);
+  };
+
   // Determine what kind of thing we have.
   switch (isCXXConditionDeclarationOrInitStatement(InitStmt)) {
   case ConditionOrInitStatement::Expression: {
 ProhibitAttributes(attrs);
 
+// We can have an empty expression here.
+//   if (; true);
+if (InitStmt && TryConsumeToken(tok::semi)) {
+  WarnOnInit();
+  return ParseCXXCondition(nullptr, Loc, CK);
+}
+
 // Parse the expression.
 ExprResult Expr = ParseExpression(); // expression
 if (Expr.isInvalid())
   return Sema::ConditionError();
 
 if (InitStmt && Tok.is(tok::semi)) {
+  WarnOnInit();
   *InitStmt = Actions.ActOnExprStmt(Expr.get());
   ConsumeToken();
   return ParseCXXCondition(nullptr, Loc, CK);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

Generally this looks good.

Is there some way we can prevent this bug from recurring by construction (eg, 
by making a `return` ill-formed, or making it "just work")? Wrapping the code 
block in the `DEF_TRAVERSE_*` invocation in a lambda would help, but would 
probably significantly increase the compile-time (and possibly code size) cost 
of `RecursiveASTVisitor`, so I'd prefer a different solution if possible. We 
could move the post-code-block actions into the destructor of an RAII object, 
but then we can't suppress running them when the code block returns false. 
Ideas welcome.




Comment at: include/clang/AST/RecursiveASTVisitor.h:1587
   TRY_TO(TraverseType(D->getType()));
   return true;
 })

Same problem here?



Comment at: include/clang/AST/RecursiveASTVisitor.h:2430
   TRY_TO(TraverseDecl(S->getBlockDecl()));
   return true; // no child statements to loop through.
 })

Likewise.


https://reviews.llvm.org/D34030



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


[PATCH] D41736: make attribute instantiation instantiate all attributes

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

LGTM, thank you!




Comment at: include/clang/AST/Attr.h:142
+  /// explicitly provided in the current declaration?
+  bool isInheritEvenIfAlreadyPresent() const {
+return InheritEvenIfAlreadyPresent;

rsmith wrote:
> aaron.ballman wrote:
> > I'm not too keen on the name -- perhaps `isInheritedEvenIfAlreadyPresent()`?
> I started with that, but then changed to this abomination because 
> `isInherited[...]` suggests it's telling you whether this attribute was 
> inherited (like `isInherited()` does), which is not what it's for.
> 
> How about `shouldInheritEvenIfAlreadyPresent`?
Sold!


Repository:
  rC Clang

https://reviews.llvm.org/D41736



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


[PATCH] D39679: [C++11] Fix warning when dropping cv-qualifiers when assigning to a reference with a braced initializer list

2018-01-04 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 128661.
Rakete added a comment.

Rebased + friendly 2018 ping :)


https://reviews.llvm.org/D39679

Files:
  lib/Sema/SemaInit.cpp
  test/SemaCXX/references.cpp


Index: test/SemaCXX/references.cpp
===
--- test/SemaCXX/references.cpp
+++ test/SemaCXX/references.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 
 int g(int);
 
 void f() {
@@ -55,6 +56,13 @@
   //  const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
   const volatile int cvi = 1;
   const int& r = cvi; // expected-error{{binding value of type 'const volatile 
int' to reference to type 'const int' drops 'volatile' qualifier}}
+
+#if __cplusplus >= 201103L
+  const int& r2{cvi}; // expected-error{{binding value of type 'const volatile 
int' to reference to type 'const int' drops 'volatile' qualifier}}
+
+  const int a = 2;
+  int& r3{a}; // expected-error{{binding value of type 'const int' to 
reference to type 'int' drops 'const'}}
+#endif
 }
 
 // C++ [dcl.init.ref]p3
Index: lib/Sema/SemaInit.cpp
===
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -7696,6 +7696,12 @@
 
   case FK_ReferenceInitDropsQualifiers: {
 QualType SourceType = Args[0]->getType();
+
+// For braced initializer lists, we want to get the type
+// of its (only) element, and not the "type" of the list itself.
+if (const auto *List = dyn_cast(Args[0]))
+  SourceType = List->getInit(0)->getType();
+
 QualType NonRefType = DestType.getNonReferenceType();
 Qualifiers DroppedQualifiers =
 SourceType.getQualifiers() - NonRefType.getQualifiers();


Index: test/SemaCXX/references.cpp
===
--- test/SemaCXX/references.cpp
+++ test/SemaCXX/references.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 
 int g(int);
 
 void f() {
@@ -55,6 +56,13 @@
   //  const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
   const volatile int cvi = 1;
   const int& r = cvi; // expected-error{{binding value of type 'const volatile int' to reference to type 'const int' drops 'volatile' qualifier}}
+
+#if __cplusplus >= 201103L
+  const int& r2{cvi}; // expected-error{{binding value of type 'const volatile int' to reference to type 'const int' drops 'volatile' qualifier}}
+
+  const int a = 2;
+  int& r3{a}; // expected-error{{binding value of type 'const int' to reference to type 'int' drops 'const'}}
+#endif
 }
 
 // C++ [dcl.init.ref]p3
Index: lib/Sema/SemaInit.cpp
===
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -7696,6 +7696,12 @@
 
   case FK_ReferenceInitDropsQualifiers: {
 QualType SourceType = Args[0]->getType();
+
+// For braced initializer lists, we want to get the type
+// of its (only) element, and not the "type" of the list itself.
+if (const auto *List = dyn_cast(Args[0]))
+  SourceType = List->getInit(0)->getType();
+
 QualType NonRefType = DestType.getNonReferenceType();
 Qualifiers DroppedQualifiers =
 SourceType.getQualifiers() - NonRefType.getQualifiers();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40445: [C++17] Allow an empty expression in an if init statement

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: lib/Parse/ParseExprCXX.cpp:1760
+if (InitStmt && TryConsumeToken(tok::semi)) {
+  WarnOnInit();
+  return ParseCXXCondition(nullptr, Loc, CK);

Please create a NullStmt here (`Actions.ActOnNullStmt`), rather than producing 
an AST that's indistinguishable from one where the init statement was omitted.



Comment at: lib/Parse/ParseExprCXX.cpp:1780-1783
 Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
 ? diag::warn_cxx14_compat_init_statement
 : diag::ext_init_statement)
 << (CK == Sema::ConditionKind::Switch);

Use `WarnOnInit()` here.



Comment at: test/CXX/stmt.stmt/stmt.select/p3.cpp:70-71
+
+// TODO: This is needed because clang can't seem to diagnose invalid syntax 
after the
+// last loop above. It would be nice to remove this.
+void whileInitStatement2() {

I think error recovery thought that a `)` was omitted before the `;`, so it 
imagined we had:

 ```
  while (Var + Var); Var--) {}
```

Then it thought that a `;` was omitted before the `)`, so it imagined we had:

 ```
  while (Var + Var); Var--; ) {}
```

Then it saw a statement beginning with a `)`, and decided to skip to the next 
statement, which would skip past the `)`, the `{`, the `}`, and whatever 
statement you put next in the function.

Maybe we should parse as if an //init-statement// were permitted on a `while` 
loop (and produce an error after the fact if there's one present). But that 
should be done in a separate patch if you're interested in working on it.


https://reviews.llvm.org/D40445



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


[PATCH] D38216: [C++17] Fix class template argument deduction for default constructors without an initializer

2018-01-04 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 128662.
Rakete marked an inline comment as done.
Rakete added a comment.

Rebased + friendly 2018 ping


https://reviews.llvm.org/D38216

Files:
  lib/Sema/SemaDecl.cpp
  test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
  test/Parser/cxx1z-class-template-argument-deduction.cpp


Index: test/Parser/cxx1z-class-template-argument-deduction.cpp
===
--- test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -52,7 +52,7 @@
 
   operator A(); // expected-error {{requires template arguments; argument 
deduction not allowed in conversion function type}}
 
-  static A x; // expected-error {{declaration of variable 'x' with deduced 
type 'A' requires an initializer}}
+  static A x;
   static constexpr A y = 0;
 };
 
@@ -114,7 +114,6 @@
 (void)A{n};
 (void)new A(n);
 (void)new A{n};
-// FIXME: We should diagnose the lack of an initializer here.
 (void)new A;
   }
 }
@@ -127,7 +126,7 @@
 
   auto k() -> A; // expected-error{{requires template arguments}}
 
-  A a; // expected-error {{declaration of variable 'a' with deduced type 'A' 
requires an initializer}}
+  A a;
   A b = 0;
   const A c = 0;
   A (parens) = 0; // expected-error {{cannot use parentheses when declaring 
variable with deduced class template specialization type}}
Index: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
===
--- test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
+++ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
@@ -5,14 +5,13 @@
 A(int) -> A;
 
 static constexpr inline const volatile A a = {}; // ok, specifiers are 
permitted
-// FIXME: There isn't really a good reason to reject this.
-A b; // expected-error {{requires an initializer}}
+A b;
 A c [[]] {};
 
 A d = {}, e = {};
 A f(0), g{}; // expected-error {{template arguments deduced as 'A' in 
declaration of 'f' and deduced as 'A' in declaration of 'g'}}
 
 struct B {
-  static A a; // expected-error {{requires an initializer}}
+  static A a;
 };
-extern A x; // expected-error {{requires an initializer}}
+extern A x;
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -10053,14 +10053,18 @@
   assert(Deduced && "deduceVarTypeFromInitializer for non-deduced type");
 
   // C++11 [dcl.spec.auto]p3
-  if (!Init) {
+  // Except for class argument deduction.
+  if (!Init && !isa(Deduced)) {
 assert(VDecl && "no init for init capture deduction?");
 Diag(VDecl->getLocation(), diag::err_auto_var_requires_init)
   << VDecl->getDeclName() << Type;
 return QualType();
   }
 
-  ArrayRef DeduceInits = Init;
+  ArrayRef DeduceInits;
+  if (Init)
+DeduceInits = Init;
+
   if (DirectInit) {
 if (auto *PL = dyn_cast_or_null(Init))
   DeduceInits = PL->exprs();


Index: test/Parser/cxx1z-class-template-argument-deduction.cpp
===
--- test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -52,7 +52,7 @@
 
   operator A(); // expected-error {{requires template arguments; argument deduction not allowed in conversion function type}}
 
-  static A x; // expected-error {{declaration of variable 'x' with deduced type 'A' requires an initializer}}
+  static A x;
   static constexpr A y = 0;
 };
 
@@ -114,7 +114,6 @@
 (void)A{n};
 (void)new A(n);
 (void)new A{n};
-// FIXME: We should diagnose the lack of an initializer here.
 (void)new A;
   }
 }
@@ -127,7 +126,7 @@
 
   auto k() -> A; // expected-error{{requires template arguments}}
 
-  A a; // expected-error {{declaration of variable 'a' with deduced type 'A' requires an initializer}}
+  A a;
   A b = 0;
   const A c = 0;
   A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
Index: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
===
--- test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
+++ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
@@ -5,14 +5,13 @@
 A(int) -> A;
 
 static constexpr inline const volatile A a = {}; // ok, specifiers are permitted
-// FIXME: There isn't really a good reason to reject this.
-A b; // expected-error {{requires an initializer}}
+A b;
 A c [[]] {};
 
 A d = {}, e = {};
 A f(0), g{}; // expected-error {{template arguments deduced as 'A' in declaration of 'f' and deduced as 'A' in declaration of 'g'}}
 
 struct B {
-  static A a; // expected-error {{requires an initializer}}
+  static A a;
 };
-extern A x; // expected-error {{requires an initializer}}
+e

[PATCH] D39679: [C++11] Fix warning when dropping cv-qualifiers when assigning to a reference with a braced initializer list

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: lib/Sema/SemaInit.cpp:7691-7695
   case FK_RValueReferenceBindingToLValue:
 S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref)
   << DestType.getNonReferenceType() << Args[0]->getType()
   << Args[0]->getSourceRange();
 break;

Same problem exists here, and probably in a lot of these diagnostics. For 
example:

 *`int a; int &&b = {a};` says "cannot bind to lvalue of type 'void'")
 * `void f(int); void f() { int &&b = {f}; }` asserts due to not unwrapping the 
`InitListExpr` before trying to diagnose

Can you try to address this more generally? Perhaps: add an `Expr *OnlyArg`, 
which is null if `Args.size() != 1`, is the list element if `Args.size() == 1` 
and is an `InitListExpr` with a single element, and is otherwise `Args[0]`, and 
change all the diagnostics that are talking about a one-and-only argument to 
use `OnlyArg`?


https://reviews.llvm.org/D39679



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


[PATCH] D41743: Debug Info: Support DW_AT_calling_convention on composite types.

2018-01-04 Thread Adrian Prantl via Phabricator via cfe-commits
aprantl created this revision.
aprantl added reviewers: echristo, dblaikie, probinson.
aprantl added a project: debug-info.
Herald added a subscriber: JDevlieghere.

This implements the DWARF 5 feature described at
http://www.dwarfstd.org/ShowIssue.php?issue=141215.1

This allows a consumer to understand whether a composite data type is
trivially copyable and thus should be passed by value instead of by
reference. The canonical example is being able to distinguish the
following two types:

  // S is not trivially copyable because of the explicit destructor.
  struct S {
 ~S() {}
  };
  
  // T is a POD type.
  struct T {
~T() = default;
  };

To avoid bloating the debug info with calling convention attributes,
this patch only adds them were the calling convention is not obvious
from the context.

Implicitly by value is everything that clearly looks like a C struct, i.e.:

- Non-C++ record types.
- Types that define none of destructor, copy/move constructor, copy/move 
assignment operator.

Implicitly by reference is everything clearly looks like a non-pod type:

- Types that define a destructor, a copy constructor, and a copy assignment 
operator.


Repository:
  rL LLVM

https://reviews.llvm.org/D41743

Files:
  lib/CodeGen/CGDebugInfo.cpp
  test/CodeGenCXX/debug-info-composite-cc.cpp

Index: test/CodeGenCXX/debug-info-composite-cc.cpp
===
--- /dev/null
+++ test/CodeGenCXX/debug-info-composite-cc.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+// Not trivially copyable because of the explicit destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefDtor",{{.*size: [0-9]+, elem}}
+struct RefDtor {
+  int i;
+  ~RefDtor() {}
+} refDtor;
+
+// Not trivially copyable because of the explicit copy constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopy",{{.*size: [0-9]+, elem}}
+struct RefCopy {
+  int i;
+  RefCopy() {}
+  RefCopy(RefCopy &Copy) {}
+} refCopy;
+
+// Not trivially copyable because of the explicit move constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefMove",{{.*}}flags: DIFlagTypePassByReference
+struct RefMove {
+  int i;
+  RefMove(){}
+  RefMove(RefMove &&Move) {}
+} refMove;
+
+// Not trivially copyable because of the explicit copy assignment.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopyAss",{{.*size: [0-9]+, elem}}
+struct RefCopyAss {
+  int i;
+  RefCopyAss &operator= (RefCopyAss &Copy) { return *this; }
+} refCopyAss;
+
+
+// POD-like type even though it defines a destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Podlike", {{.*}}flags: DIFlagTypePassByValue
+struct Podlike {
+  int i;
+  Podlike() = default;
+  Podlike(Podlike &&Move) = default;
+  ~Podlike() = default;
+} podlike;
+
+
+// This is a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Pod",{{.*size: [0-9]+, elem}}
+struct Pod {
+  int i;
+} pod;
+
+// This is definitely not a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Complex",{{.*size: [0-9]+, elem}}
+struct Complex {
+  Complex() {}
+  Complex(Complex &Copy) : i(Copy.i) {};
+  int i;
+} complex;
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -2803,9 +2803,35 @@
 
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
 
+  // Explicitly record the calling convention unless it is obvious
+  // from context.
+  // Implicitly by value is everything that clearly looks like a C struct, i.e.:
+  //   - Non-C++ record types.
+  //   - Types that define none of destructor, copy/move constructor,
+  // copy/move assignment operator.
+  // Implicitly by reference is everything clearly looks like a non-pod type:
+  //  - Types that define a destructor, a copy constructor, and a copy
+  //assignment operator.
+  auto Flags = llvm::DINode::FlagZero;
+  if (auto CXXRD = dyn_cast(RD)) {
+if (CXXRD->isTriviallyCopyable()) {
+  if (CXXRD->hasUserDeclaredDestructor() ||
+  CXXRD->hasUserDeclaredCopyConstructor() ||
+  CXXRD->hasUserDeclaredMoveConstructor() ||
+  CXXRD->hasUserDeclaredCopyAssignment() ||
+  CXXRD->hasUserDeclaredMoveAssignment())
+Flags |= llvm::DINode::FlagTypePassByValue;
+} else {
+  if (!CXXRD->hasUserDeclaredDestructor() &&
+  !CXXRD->hasUserDeclaredCopyConstructor() &&
+  !CXXRD->hasUserDeclaredCopyAssignment())
+Flags |= llvm::DINode::FlagTypePassByReference;
+}
+  }
+
   llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
   getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
-  llvm::DINode::FlagZero, FullName);
+  Flags, FullName);
 
   // Elements of composite types usually have back to the type, creating
   // uniquing cycles.  Distinct nodes are more efficient

r321834 - Make attribute instantiation instantiate all attributes, not just the first of

2018-01-04 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Thu Jan  4 15:42:29 2018
New Revision: 321834

URL: http://llvm.org/viewvc/llvm-project?rev=321834&view=rev
Log:
Make attribute instantiation instantiate all attributes, not just the first of
each kind.

Attribute instantiation would previously default to instantiating each kind of
attribute only once. This was overridden by a flag whose intended purpose was
to permit attributes from a prior declaration to be inherited onto a new
declaration even if that new declaration had its own copy of the attribute.
This is the wrong behavior: when instantiating attributes from a template, we
should always instantiate all the attributes that were written on that
template.

This patch renames the flag in the Attr class (and TableGen sources) to more
clearly identify what it's actually for, and removes the usage of the flag from
template instantiation. I also removed the flag from AlignedAttr, which was
only added to work around the incorrect suppression of duplicate attribute
instantiation.

Added:
cfe/trunk/test/SemaTemplate/warn-thread-safety-analysis.cpp
Modified:
cfe/trunk/include/clang/AST/Attr.h
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaTemplate/attributes.cpp
cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp

Modified: cfe/trunk/include/clang/AST/Attr.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=321834&r1=321833&r2=321834&view=diff
==
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Thu Jan  4 15:42:29 2018
@@ -52,8 +52,10 @@ protected:
   unsigned Inherited : 1;
   unsigned IsPackExpansion : 1;
   unsigned Implicit : 1;
+  // FIXME: These are properties of the attribute kind, not state for this
+  // instance of the attribute.
   unsigned IsLateParsed : 1;
-  unsigned DuplicatesAllowed : 1;
+  unsigned InheritEvenIfAlreadyPresent : 1;
 
   void *operator new(size_t bytes) noexcept {
 llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
@@ -74,10 +76,10 @@ public:
 
 protected:
   Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
-   bool IsLateParsed, bool DuplicatesAllowed)
+   bool IsLateParsed)
 : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
   Inherited(false), IsPackExpansion(false), Implicit(false),
-  IsLateParsed(IsLateParsed), DuplicatesAllowed(DuplicatesAllowed) {}
+  IsLateParsed(IsLateParsed), InheritEvenIfAlreadyPresent(false) {}
 
 public:
 
@@ -109,18 +111,13 @@ public:
 
   // Pretty print this attribute.
   void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
-
-  /// \brief By default, attributes cannot be duplicated when being merged;
-  /// however, an attribute can override this. Returns true if the attribute
-  /// can be duplicated when merging.
-  bool duplicatesAllowed() const { return DuplicatesAllowed; }
 };
 
 class StmtAttr : public Attr {
 protected:
   StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
-  bool IsLateParsed, bool DuplicatesAllowed)
-  : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {}
+  bool IsLateParsed)
+  : Attr(AK, R, SpellingListIndex, IsLateParsed) {}
 
 public:
   static bool classof(const Attr *A) {
@@ -132,12 +129,20 @@ public:
 class InheritableAttr : public Attr {
 protected:
   InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
-  bool IsLateParsed, bool DuplicatesAllowed)
-  : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {}
+  bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
+  : Attr(AK, R, SpellingListIndex, IsLateParsed) {
+this->InheritEvenIfAlreadyPresent = InheritEvenIfAlreadyPresent;
+  }
 
 public:
   void setInherited(bool I) { Inherited = I; }
 
+  /// Should this attribute be inherited from a prior declaration even if it's
+  /// explicitly provided in the current declaration?
+  bool shouldInheritEvenIfAlreadyPresent() const {
+return InheritEvenIfAlreadyPresent;
+  }
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Attr *A) {
 return A->getKind() >= attr::FirstInheritableAttr &&
@@ -148,9 +153,9 @@ public:
 class InheritableParamAttr : public InheritableAttr {
 protected:
   InheritableParamAttr(attr::Kind AK, SourceRange R, unsigned 
SpellingListIndex,
-   bool IsLateParsed, bool DuplicatesAllowed)
+   bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
   : InheritableAttr(AK, R, SpellingListIndex, IsLateParsed,
-DuplicatesAllowed) {}
+InheritEvenIfAlreadyPresent) {}
 
 public:
   // Implement isa/cast/dyncast/etc.
@@ -166,9 +171,9 @@ class ParameterABIAttr : public Inherita
 p

[PATCH] D41736: make attribute instantiation instantiate all attributes

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith closed this revision.
rsmith added a comment.

Committed as r321834.


Repository:
  rC Clang

https://reviews.llvm.org/D41736



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


[PATCH] D41743: Debug Info: Support DW_AT_calling_convention on composite types.

2018-01-04 Thread Adrian Prantl via Phabricator via cfe-commits
aprantl added a comment.

I related https://reviews.llvm.org/D41039 (Add support for attribute 
"trivial_abi") which will also benefit from this feature. It is not a hard 
dependency though, this patch is also useful for standard C++.


Repository:
  rL LLVM

https://reviews.llvm.org/D41743



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


[PATCH] D37442: [C++17] Disallow lambdas in template parameters (PR33696).

2018-01-04 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 128667.
Rakete added a comment.

Rebased + friendly 2018 ping


https://reviews.llvm.org/D37442

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseStmt.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/TreeTransform.h
  test/CXX/expr/expr.prim/expr.prim.lambda/p2-template-parameter.cpp

Index: test/CXX/expr/expr.prim/expr.prim.lambda/p2-template-parameter.cpp
===
--- test/CXX/expr/expr.prim/expr.prim.lambda/p2-template-parameter.cpp
+++ test/CXX/expr/expr.prim/expr.prim.lambda/p2-template-parameter.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++17 %s -verify
+
+template struct Nothing {};
+
+void pr33696() {
+Nothing<[]() { return 0; }()> nothing; // expected-error{{a lambda expression cannot appear in this context}}
+}
+
Index: lib/Sema/TreeTransform.h
===
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -5507,7 +5507,7 @@
   // decltype expressions are not potentially evaluated contexts
   EnterExpressionEvaluationContext Unevaluated(
   SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
-  /*IsDecltype=*/true);
+  Sema::ExpressionType::Decltype);
 
   ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
   if (E.isInvalid())
Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -6195,7 +6195,7 @@
   if (RD->isInvalidDecl() || RD->isDependentContext())
 return E;
 
-  bool IsDecltype = ExprEvalContexts.back().IsDecltype;
+  bool IsDecltype = ExprEvalContexts.back().Type == ExpressionType::Decltype;
   CXXDestructorDecl *Destructor = IsDecltype ? nullptr : LookupDestructor(RD);
 
   if (Destructor) {
@@ -6277,7 +6277,8 @@
 /// are omitted for the 'topmost' call in the decltype expression. If the
 /// topmost call bound a temporary, strip that temporary off the expression.
 ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
-  assert(ExprEvalContexts.back().IsDecltype && "not in a decltype expression");
+  assert(ExprEvalContexts.back().Type == ExpressionType::Decltype &&
+ "not in a decltype expression");
 
   // C++11 [expr.call]p11:
   //   If a function call is a prvalue of object type,
@@ -6319,7 +6320,7 @@
 TopBind = nullptr;
 
   // Disable the special decltype handling now.
-  ExprEvalContexts.back().IsDecltype = false;
+  ExprEvalContexts.back().Type = ExpressionType::Other;
 
   // In MS mode, don't perform any extra checking of call return types within a
   // decltype expression.
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -13703,51 +13703,50 @@
 void
 Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
   Decl *LambdaContextDecl,
-  bool IsDecltype) {
+  ExpressionType Type) {
   ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(), Cleanup,
-LambdaContextDecl, IsDecltype);
+LambdaContextDecl, Type);
   Cleanup.reset();
   if (!MaybeODRUseExprs.empty())
 std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs);
 }
 
 void
 Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
   ReuseLambdaContextDecl_t,
-  bool IsDecltype) {
+  ExpressionType Type) {
   Decl *ClosureContextDecl = ExprEvalContexts.back().ManglingContextDecl;
-  PushExpressionEvaluationContext(NewContext, ClosureContextDecl, IsDecltype);
+  PushExpressionEvaluationContext(NewContext, ClosureContextDecl, Type);
 }
 
 void Sema::PopExpressionEvaluationContext() {
   ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back();
   unsigned NumTypos = Rec.NumTypos;
 
   if (!Rec.Lambdas.empty()) {
-if (Rec.isUnevaluated() || Rec.isConstantEvaluated()) {
+if (Rec.Type == ExpressionType::TemplateParameter || Rec.isUnevaluated() ||
+(Rec.isConstantEvaluated() && !getLangOpts().CPlusPlus17)) {
   unsigned D;
   if (Rec.isUnevaluated()) {
 // C++11 [expr.prim.lambda]p2:
 //   A lambda-expression shall not appear in an unevaluated operand
 //   (Clause 5).
 D = diag::err_lambda_unevaluated_operand;
-  } else {
+  } else if (Rec.isConstantEvaluated() && !getLangOpts().CPlusPlus17) {
 // C++1y [expr.const]p2:
 //   A conditional-expression e is a core constant expression unless 

[PATCH] D41733: [Driver] Suggest correctly spelled driver options

2018-01-04 Thread Brian Gesiak via Phabricator via cfe-commits
modocache added a comment.

Thank you, @bruno! Good idea, I'll add a `-cc1` invocation test.




Comment at: lib/Driver/Driver.cpp:191
 if (A->getOption().hasFlag(options::Unsupported)) {
-  Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args);
-  ContainsError |= Diags.getDiagnosticLevel(diag::err_drv_unsupported_opt,
-SourceLocation()) >
+  unsigned DiagID;
+  auto ArgString = A->getAsString(Args);

jroelofs wrote:
> No need for this variable.
There's a call below to `Diags.getDiagnosticsLevel`, which takes this ID as an 
argument. Are you suggesting I leave that line alone, and have it use the 
diagnostic level of `err_drv_unsupported_opt`, even if 
`err_drv_unsupported_opt_with_suggestion` is actually emitted here? That seems 
reasonable to me, but just want to make sure that's what you had in mind.


Repository:
  rC Clang

https://reviews.llvm.org/D41733



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


[PATCH] D36357: Added a better diagnostic when using the delete operator with lambdas

2018-01-04 Thread Nicolas Lesser via Phabricator via cfe-commits
Rakete updated this revision to Diff 128668.
Rakete added a comment.

Rebased + friendly 2018 ping :)


https://reviews.llvm.org/D36357

Files:
  include/clang/Basic/DiagnosticParseKinds.td
  lib/Parse/ParseExprCXX.cpp
  test/Parser/cxx0x-lambda-expressions.cpp
  test/SemaCXX/new-delete-0x.cpp


Index: test/SemaCXX/new-delete-0x.cpp
===
--- test/SemaCXX/new-delete-0x.cpp
+++ test/SemaCXX/new-delete-0x.cpp
@@ -34,6 +34,6 @@
 void bad_deletes()
 {
   // 'delete []' is always array delete, per [expr.delete]p1.
-  // FIXME: Give a better diagnostic.
-  delete []{ return (int*)0; }(); // expected-error {{expected expression}}
+  delete []{ return (int*)0; }(); // expected-error {{'[]' after delete 
interpreted as 'delete[]'}}
+  // expected-note@-1 {{add parentheses around the lambda}}
 }
Index: test/Parser/cxx0x-lambda-expressions.cpp
===
--- test/Parser/cxx0x-lambda-expressions.cpp
+++ test/Parser/cxx0x-lambda-expressions.cpp
@@ -53,7 +53,8 @@
   void delete_lambda(int *p) {
 delete [] p;
 delete [] (int*) { new int }; // ok, compound-literal, not lambda
-delete [] { return new int; } (); // expected-error{{expected expression}}
+delete [] { return new int; } (); // expected-error {{'[]' after delete 
interpreted as 'delete[]'}}
+// expected-note@-1 {{add parentheses around the lambda}}
 delete [&] { return new int; } (); // ok, lambda
   }
 
Index: lib/Parse/ParseExprCXX.cpp
===
--- lib/Parse/ParseExprCXX.cpp
+++ lib/Parse/ParseExprCXX.cpp
@@ -2901,15 +2901,45 @@
 //   [Footnote: A lambda expression with a lambda-introducer that consists
 //  of empty square brackets can follow the delete keyword if
 //  the lambda expression is enclosed in parentheses.]
-// FIXME: Produce a better diagnostic if the '[]' is unambiguously a
-//lambda-introducer.
-ArrayDelete = true;
-BalancedDelimiterTracker T(*this, tok::l_square);
+TentativeParsingAction TPA(*this);
 
-T.consumeOpen();
-T.consumeClose();
-if (T.getCloseLocation().isInvalid())
-  return ExprError();
+// Basic lookahead to check if we have a lambda expression. If we
+// encounter two braces with a semicolon, we can be pretty sure
+// that this is a lambda, not say a compound literal. 
+if (!SkipUntil(tok::l_brace, SkipUntilFlags::StopAtSemi) ||
+(NextToken().isNot(tok::r_brace) && !SkipUntil(tok::semi)) ||
+!SkipUntil(tok::r_brace, SkipUntilFlags::StopAtSemi)) {
+  TPA.Revert();
+  ArrayDelete = true;
+  BalancedDelimiterTracker T(*this, tok::l_square);
+
+  T.consumeOpen();
+  T.consumeClose();
+  if (T.getCloseLocation().isInvalid())
+return ExprError();
+} else {
+  TPA.Revert();
+
+  // Warn if the non-capturing lambda isn't surrounded by parenthesis
+  // to disambiguate it from 'delete[]'.
+  ExprResult Lambda = TryParseLambdaExpression();
+  if (!Lambda.isInvalid()) {
+SourceLocation StartLoc = Lambda.get()->getLocStart();
+Diag(Start, diag::err_lambda_after_delete)
+<< SourceRange(Start, StartLoc.getLocWithOffset(1));
+
+SourceLocation BeforeBracket = StartLoc.getLocWithOffset(-1);
+Diag(BeforeBracket, diag::note_lambda_after_delete)
+<< FixItHint::CreateInsertion(BeforeBracket, "(")
+<< FixItHint::CreateInsertion(
+   Lambda.get()->getLocEnd().getLocWithOffset(1), ")");
+
+// Evaluate any postfix expressions used on the lambda.
+Lambda = ParsePostfixExpressionSuffix(Lambda);
+return Actions.ActOnCXXDelete(Start, UseGlobal, /*ArrayForm=*/false,
+  Lambda.get());
+  }
+}
   }
 
   ExprResult Operand(ParseCastExpression(false));
Index: include/clang/Basic/DiagnosticParseKinds.td
===
--- include/clang/Basic/DiagnosticParseKinds.td
+++ include/clang/Basic/DiagnosticParseKinds.td
@@ -99,6 +99,10 @@
   InGroup, DefaultIgnore;
 def ext_alignof_expr : ExtWarn<
   "%0 applied to an expression is a GNU extension">, 
InGroup;
+def err_lambda_after_delete : Error<
+  "'[]' after delete interpreted as 'delete[]'">;
+def note_lambda_after_delete : Note<
+  "add parentheses around the lambda">;
 
 def warn_microsoft_dependent_exists : Warning<
   "dependent %select{__if_not_exists|__if_exists}0 declarations are ignored">, 


Index: test/SemaCXX/new-delete-0x.cpp
===
--- test/SemaCXX/new-delete-0x.cpp
+++ test/SemaCXX/new-delete-0x.cpp
@@ -34,6 +34,6 @@
 void bad_deletes()
 {
   // 'delete []' is always array delete, per [expr.delete]p1.
-  // FIXME: Give a better diagnostic.
-  delete []{ return (in

[PATCH] D41743: Debug Info: Support DW_AT_calling_convention on composite types.

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: lib/CodeGen/CGDebugInfo.cpp:2812-2814
+  // Implicitly by reference is everything clearly looks like a non-pod type:
+  //  - Types that define a destructor, a copy constructor, and a copy
+  //assignment operator.

I do not believe this is sufficient. Consider:

```
struct A {
  A(const A&) = default;
  A(A&);
};
struct B : A {};
```

Now, `A` is passed indirectly, because it has a non-trivial copy constructor 
(`A::A(A&)`). But `B` is passed directly, because it only has a trivial copy 
constructor, despite having an `A` subobject.

I would not expect debuggers to get intricacies like this right. (In general, 
determining how to pass a class like `B` can require performing template 
instantiation, which it's clearly not reasonable to expect a debugger to do.)

If you want to give the debugger a hint for any type that's non-POD (as the 
comment says), then use `CXXRecordDecl::isPOD` to determine that. I think it is 
reasonable to believe that a debugger will figure out that objects of POD types 
are passed direct.



Comment at: lib/CodeGen/CGDebugInfo.cpp:2817
+  if (auto CXXRD = dyn_cast(RD)) {
+if (CXXRD->isTriviallyCopyable()) {
+  if (CXXRD->hasUserDeclaredDestructor() ||

"isTriviallyCopyable()" is the wrong thing to check here. The best you can do 
to get a per-type "calling convention" value is to call 
`CGCXXABI::getRecordArgABI`.

However, that does not tell the full story: in particular, in the MS ABI, 
member functions always return objects of class type indirectly, regardless of 
whether they could otherwise be returned in registers. If DWARF 5 allows you to 
override the calling convention on a particular usage of a type, you can check 
whether a function's return type should be indirect by calling 
`CGCXXABI::classifyReturnType`.



Comment at: lib/CodeGen/CGDebugInfo.cpp:2821-2822
+  CXXRD->hasUserDeclaredMoveConstructor() ||
+  CXXRD->hasUserDeclaredCopyAssignment() ||
+  CXXRD->hasUserDeclaredMoveAssignment())
+Flags |= llvm::DINode::FlagTypePassByValue;

The assignment operators are irrelevant here. Does any debugger really base its 
calling convention decision on their existence?



Comment at: lib/CodeGen/CGDebugInfo.cpp:2825-2827
+  if (!CXXRD->hasUserDeclaredDestructor() &&
+  !CXXRD->hasUserDeclaredCopyConstructor() &&
+  !CXXRD->hasUserDeclaredCopyAssignment())

Why are you not checking for move operations on this side?


Repository:
  rL LLVM

https://reviews.llvm.org/D41743



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


[PATCH] D41743: Debug Info: Support DW_AT_calling_convention on composite types.

2018-01-04 Thread Adrian Prantl via Phabricator via cfe-commits
aprantl added a comment.

Thanks!  I think you got me convinced that we should probably stick the calling 
convention attribute unconditionally on all C++ types. At least in DWARF 5 it 
should be part of the abbreviation and thus almost free.


Repository:
  rL LLVM

https://reviews.llvm.org/D41743



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


[PATCH] D37442: [C++17] Disallow lambdas in template parameters (PR33696).

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

Thanks, looks good other than `ExpressionType`. This is fine to commit with 
either of the names I suggested; let me know if you have a better alternative :)




Comment at: include/clang/Sema/Sema.h:935-939
+  /// \brief Describes whether we are in an expression that needs
+  /// special handling.
+  enum class ExpressionType {
+Decltype, TemplateParameter, Other
+  };

This name is too vague as a member of Sema, but would be OK as a member of 
`ExpressionEvaluationContextRecord`, or if renamed to something like 
`ExpressionEvaluationContextExprKind`. (Also, we generally use `Kind` rather 
than `Type` for situations like this.)


https://reviews.llvm.org/D37442



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


[PATCH] D41746: Make std::get_temporary_buffer respect overaligned types when possible

2018-01-04 Thread Chris Kennelly via Phabricator via cfe-commits
ckennelly created this revision.
ckennelly added reviewers: EricWF, mclow.lists.

Repository:
  rCXX libc++

https://reviews.llvm.org/D41746

Files:
  include/memory
  test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp


Index: test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
===
--- /dev/null
+++ test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
@@ -0,0 +1,33 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// 
+
+// template 
+//   pair
+//   get_temporary_buffer(ptrdiff_t n);
+//
+// template 
+//   void
+//   return_temporary_buffer(T* p);
+
+#include 
+#include 
+
+struct alignas(32) A {
+int field;
+};
+
+int main()
+{
+std::pair ip = std::get_temporary_buffer(5);
+assert(!(ip.first == nullptr) ^ (ip.second == 0));
+assert(reinterpret_cast(ip.first) % alignof(A) == 0);
+std::return_temporary_buffer(ip.first);
+}
Index: include/memory
===
--- include/memory
+++ include/memory
@@ -2003,7 +2003,31 @@
 __n = __m;
 while (__n > 0)
 {
+#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
+{
+std::align_val_t __al = std::align_val_t(alignof(_Tp));
+__r.first = static_cast<_Tp*>(::operator new(
+__n * sizeof(_Tp), __al, nothrow));
+} else {
+__r.first = static_cast<_Tp*>(::operator new(
+__n * sizeof(_Tp), nothrow));
+}
+#else
+#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
+if (__alignof__(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
+#else
+if (__alignof__(_Tp) > __alignof__(std::max_align_t))
+#endif
+{
+// Since aligned operator new is unavailable, return an empty
+// buffer rather than one with invalid alignment.
+return __r;
+}
+
 __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), 
nothrow));
+#endif
+
 if (__r.first)
 {
 __r.second = __n;
@@ -2016,7 +2040,18 @@
 
 template 
 inline _LIBCPP_INLINE_VISIBILITY
-void return_temporary_buffer(_Tp* __p) _NOEXCEPT {::operator delete(__p);}
+void return_temporary_buffer(_Tp* __p) _NOEXCEPT
+{
+#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
+{
+std::align_val_t __al = std::align_val_t(alignof(_Tp));
+::operator delete(__p, __al);
+return;
+}
+#endif
+::operator delete(__p);
+}
 
 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
 template 


Index: test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
===
--- /dev/null
+++ test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
@@ -0,0 +1,33 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// 
+
+// template 
+//   pair
+//   get_temporary_buffer(ptrdiff_t n);
+//
+// template 
+//   void
+//   return_temporary_buffer(T* p);
+
+#include 
+#include 
+
+struct alignas(32) A {
+int field;
+};
+
+int main()
+{
+std::pair ip = std::get_temporary_buffer(5);
+assert(!(ip.first == nullptr) ^ (ip.second == 0));
+assert(reinterpret_cast(ip.first) % alignof(A) == 0);
+std::return_temporary_buffer(ip.first);
+}
Index: include/memory
===
--- include/memory
+++ include/memory
@@ -2003,7 +2003,31 @@
 __n = __m;
 while (__n > 0)
 {
+#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
+{
+std::align_val_t __al = std::align_val_t(alignof(_Tp));
+__r.first = static_cast<_Tp*>(::operator new(
+__n * sizeof(_Tp), __al, nothrow));
+} else {
+__r.first = static_cast<_Tp*>(::operator new(
+__n * sizeof(_Tp), nothrow));
+}
+#else
+#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
+if (__alignof__(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
+#else
+if (__alignof__(_Tp) > __alignof__(std::max_align_t))
+#endif
+{
+// Since aligned operator new is unavailable, return an empty
+ 

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2018-01-04 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 128679.
timshen added a comment.

Rebase.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -0,0 +1,121 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+#include 
+#include 
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(!is_simd_mask::value, "");
+
+#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
+!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+static_assert(is_simd_mask_v>, "");
+

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-01-04 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 128680.
timshen added a comment.

Rebase. Also modify the simd reference implementation to separate the stored 
type and value_type (which could be bool later).


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/utility
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
@@ -0,0 +1,92 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // stores [simd.store]
+// template  void copy_to(U* mem, Flags f) const;
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd a([](int i) { return 4 - i; });
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned<32>);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+#endif
+}
+
+void test_converting_store() {
+  float buffer[4] = {0.};
+  fixed_size_simd a([](int i) { return 1 << i; });
+  a.copy_to(buffer, element_aligned_tag());
+  assert(buffer[0] == 1.);
+  assert(buffer[1] == 2.);
+  assert(buffer[2] == 4.);
+  assert(buffer[3] == 8.);
+}
+
+int main() {
+  test_store();
+  test_converting_store();
+}
Index: libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
@@ -0,0 +1,118 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.load]
+// template  void copy_from(const U* mem, Flags f);
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval>().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval>().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+  supported_load((unsigned int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+
+  not_suppo

[PATCH] D41733: [Driver] Suggest correctly spelled driver options

2018-01-04 Thread Brian Gesiak via Phabricator via cfe-commits
modocache updated this revision to Diff 128681.
modocache added a comment.

Add 'did you mean' suggestions for -cc1 invocations as well.


Repository:
  rC Clang

https://reviews.llvm.org/D41733

Files:
  include/clang/Basic/DiagnosticDriverKinds.td
  lib/Driver/Driver.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/Driver/unknown-arg.c
  test/Driver/unsupported-option.c
  test/Frontend/unknown-arg.c

Index: test/Frontend/unknown-arg.c
===
--- /dev/null
+++ test/Frontend/unknown-arg.c
@@ -0,0 +1,7 @@
+// RUN: not %clang_cc1 %s --helium -### 2>&1 | \
+// RUN: FileCheck %s
+// RUN: not %clang_cc1 %s --hel[ -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=DID-YOU-MEAN
+
+// CHECK: error: unknown argument: '--helium'
+// DID-YOU-MEAN: error: unknown argument '--hel[', did you mean '--help'?
Index: test/Driver/unsupported-option.c
===
--- /dev/null
+++ test/Driver/unsupported-option.c
@@ -0,0 +1,7 @@
+// RUN: not %clang %s --hedonism -### 2>&1 | \
+// RUN: FileCheck %s
+// RUN: not %clang %s --hell -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=DID-YOU-MEAN
+
+// CHECK: error: unsupported option '--hedonism'
+// DID-YOU-MEAN: error: unsupported option '--hell', did you mean '--help'?
Index: test/Driver/unknown-arg.c
===
--- test/Driver/unknown-arg.c
+++ test/Driver/unknown-arg.c
@@ -1,9 +1,15 @@
 // RUN: not %clang %s -cake-is-lie -%0 -%d - -munknown-to-clang-option -print-stats -funknown-to-clang-option -### 2>&1 | \
 // RUN: FileCheck %s
+// RUN: not %clang %s -stdlibs=foo -hell -### 2>&1 | \
+// RUN: FileCheck %s --check-prefix=DID-YOU-MEAN
 // RUN: %clang_cl -cake-is-lie -%0 -%d - -munknown-to-clang-option -print-stats -funknown-to-clang-option -### -c -- %s 2>&1 | \
 // RUN: FileCheck %s --check-prefix=CL
+// RUN: %clang_cl -Brepo -### -- %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CL-DID-YOU-MEAN
 // RUN: not %clang_cl -cake-is-lie -%0 -%d - -munknown-to-clang-option -print-stats -funknown-to-clang-option -c -Werror=unknown-argument -### -- %s 2>&1 | \
 // RUN: FileCheck %s --check-prefix=CL-ERROR
+// RUN: not %clang_cl -helo -Werror=unknown-argument -### -- %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CL-ERROR-DID-YOU-MEAN
 // RUN: %clang_cl -cake-is-lie -%0 -%d - -munknown-to-clang-option -print-stats -funknown-to-clang-option -c -Wno-unknown-argument -### -- %s 2>&1 | \
 // RUN: FileCheck %s --check-prefix=SILENT
 
@@ -14,20 +20,24 @@
 // CHECK: error: unknown argument: '-munknown-to-clang-option'
 // CHECK: error: unknown argument: '-print-stats'
 // CHECK: error: unknown argument: '-funknown-to-clang-option'
+// DID-YOU-MEAN: error: unknown argument '-stdlibs=foo', did you mean '-stdlib=foo'?
+// DID-YOU-MEAN: error: unknown argument '-hell', did you mean '-help'?
 // CL: warning: unknown argument ignored in clang-cl: '-cake-is-lie'
 // CL: warning: unknown argument ignored in clang-cl: '-%0'
 // CL: warning: unknown argument ignored in clang-cl: '-%d'
 // CL: warning: unknown argument ignored in clang-cl: '-'
 // CL: warning: unknown argument ignored in clang-cl: '-munknown-to-clang-option'
 // CL: warning: unknown argument ignored in clang-cl: '-print-stats'
 // CL: warning: unknown argument ignored in clang-cl: '-funknown-to-clang-option'
+// CL-DID-YOU-MEAN: warning: unknown argument ignored in clang-cl '-Brepo' (did you mean '-Brepro'?)
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-cake-is-lie'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-%0'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-%d'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-munknown-to-clang-option'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-print-stats'
 // CL-ERROR: error: unknown argument ignored in clang-cl: '-funknown-to-clang-option'
+// CL-ERROR-DID-YOU-MEAN: error: unknown argument ignored in clang-cl '-helo' (did you mean '-help'?)
 // SILENT-NOT: error:
 // SILENT-NOT: warning:
 
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2757,7 +2757,13 @@
 
   // Issue errors on unknown arguments.
   for (const Arg *A : Args.filtered(OPT_UNKNOWN)) {
-Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args);
+auto ArgString = A->getAsString(Args);
+std::string Nearest;
+if (Opts->findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1)
+  Diags.Report(diag::err_drv_unknown_argument) << ArgString;
+else
+  Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
+  << ArgString << Nearest;
 Success = false;
   }
 
Index: lib/Driver/Driver.cpp

[PATCH] D41538: [analyzer] Fix some checker's output plist not containing the checker name #2

2018-01-04 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ accepted this revision.
NoQ added inline comments.
This revision is now accepted and ready to land.



Comment at: include/clang/StaticAnalyzer/Core/BugReporter/BugType.h:51
   StringRef getCategory() const { return Category; }
-  StringRef getCheckName() const { return Check.getName(); }
+  StringRef getCheckName() const {
+// FIXME: This is a workaround to ensure that Check is initialized 

xazax.hun wrote:
> NoQ wrote:
> > I suggest:
> > 
> > ```
> > if (Checker)
> >   return Checker->getCheckname().getName();
> > return Check.getName();
> > ```
> > 
> > Like, what's the point of storing the StringRef if we can retrieve it any 
> > time anyway?
> > 
> > I guess `Checker` does live long enough?
> I slightly modified your snippet to preserve the assertion that can be useful 
> to not to reintroduce this bug in the future.
Yep, totally!



Comment at: lib/StaticAnalyzer/Checkers/ValistChecker.cpp:277
+  BT_leakedvalist.reset(new BugType(
+  CheckNames[ReportUninit ? CK_Uninitialized : CK_Unterminated],
+  "Leaked va_list", categories::MemoryError));

xazax.hun wrote:
> NoQ wrote:
> > a.sidorin wrote:
> > > xazax.hun wrote:
> > > > a.sidorin wrote:
> > > > > If I understand correctly, if we report uninitialized and then 
> > > > > unterminated, the second report will have wrong CheckName because it 
> > > > > is never reset.
> > > > That is right. Unfortunately, If unterminated check is not turned on 
> > > > but uninitialized is, we can end up with empty check names. I replaced 
> > > > this workaround with a slightly more robust one.
> > > Maybe we should use different BugTypes for Uninitialized and Unterminated?
> > Yep, this rings my bells too. We shouldn't race on how do we initialize a 
> > `BugType` depending on what bug is encountered first in the translation 
> > unit.
> Maybe I am missing something but right now there is no race on how we 
> initialize the `BugType`. The result of the initialization can depend on, 
> however, the set of checks that are registered. I agree that this is 
> unfortunate but introducing a new `BugType` does not solve this problem or at 
> least it is not apparent for me how would it solve this. One option would be 
> to simply not report these issues unless the corresponding check is 
> registered. The other option would be to make this depend on a new check name 
> that needs to be enabled.
Aha, that's right, yep, so this BugType's checker name would be different 
depending on which checks are enabled, not on bug first encountered, sorry. So 
it'd only have any effect if someone is grepping through bug types and turns 
these checkers on and off individually at the same time. Still worth a FIXME i 
guess? Is it hard to make a third bugtype with a hardcoded name that doesn't 
rely on the checker?


https://reviews.llvm.org/D41538



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


[PATCH] D41747: [libcxx] implement simd_mask<> and operators.

2018-01-04 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added reviewers: mclow.lists, EricWF.
Herald added a subscriber: sanjoy.

simd_mask stores a simd, where U has the same length of T, but 
is an unsigned integer. Then all functionality of simd_mask can be 
implemented in terms of simd.

For reference, Vc seems to store an int as a bitset. This results into 
inefficient code:

- https://godbolt.org/g/e4uDPM storing int is slow.
- https://godbolt.org/g/hT7SYT storing simd has zero cost.


https://reviews.llvm.org/D41747

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.access/a.out
  libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/default.pass.cpp
  
libcxx/test/std/experimental/simd/simd.mask.cons/fixed_size_conversion.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
@@ -0,0 +1,82 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_to(value_type* mem, Flags) const;
+
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd_mask a;
+  a[0] = false;
+  a[1] = true;
+  a[2] = true;
+  a[3] = false;
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned<32>);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+#endif
+}
+
+int main() { test_store(); }
Index: libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
@@ -0,0 +1,105 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_from(const value_type* mem, Flags);
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval>().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval>().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+
+  not_supported_load((bool*)nullptr, int());
+}
+
+void test_load() {
+ 

[PATCH] D41743: Debug Info: Support DW_AT_calling_convention on composite types.

2018-01-04 Thread Adrian Prantl via Phabricator via cfe-commits
aprantl updated this revision to Diff 128686.
aprantl added a comment.

Just unconditionally emit the flags for all CXXRecordDecls. Richard convinced 
me that a debugger does not want to be in the business of determining the 
correct calling convention.


https://reviews.llvm.org/D41743

Files:
  lib/CodeGen/CGDebugInfo.cpp
  test/CodeGenCXX/debug-info-composite-cc.cpp


Index: test/CodeGenCXX/debug-info-composite-cc.cpp
===
--- /dev/null
+++ test/CodeGenCXX/debug-info-composite-cc.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple 
%itanium_abi_triple %s -o - | FileCheck %s
+
+// Not trivially copyable because of the explicit destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefDtor",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefDtor {
+  int i;
+  ~RefDtor() {}
+} refDtor;
+
+// Not trivially copyable because of the explicit copy constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopy",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefCopy {
+  int i;
+  RefCopy() = default;
+  RefCopy(RefCopy &Copy) {}
+} refCopy;
+
+// Not trivially copyable because of the explicit move constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefMove",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefMove {
+  int i;
+  RefMove() = default;
+  RefMove(RefMove &&Move) {}
+} refMove;
+
+// POD-like type even though it defines a destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Podlike", {{.*}}flags: 
DIFlagTypePassByValue
+struct Podlike {
+  int i;
+  Podlike() = default;
+  Podlike(Podlike &&Move) = default;
+  ~Podlike() = default;
+} podlike;
+
+
+// This is a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Pod",{{.*}}flags: 
DIFlagTypePassByValue
+struct Pod {
+  int i;
+} pod;
+
+// This is definitely not a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Complex",{{.*}}flags: 
DIFlagTypePassByReference
+struct Complex {
+  Complex() {}
+  Complex(Complex &Copy) : i(Copy.i) {};
+  int i;
+} complex;
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -2803,9 +2803,18 @@
 
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
 
+  // Explicitly record the calling convention for C++ records.
+  auto Flags = llvm::DINode::FlagZero;
+  if (auto CXXRD = dyn_cast(RD)) {
+if (CGM.getCXXABI().getRecordArgABI(CXXRD) == CGCXXABI::RAA_Indirect)
+  Flags |= llvm::DINode::FlagTypePassByReference;
+else
+  Flags |= llvm::DINode::FlagTypePassByValue;
+  }
+
   llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
   getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
-  llvm::DINode::FlagZero, FullName);
+  Flags, FullName);
 
   // Elements of composite types usually have back to the type, creating
   // uniquing cycles.  Distinct nodes are more efficient.


Index: test/CodeGenCXX/debug-info-composite-cc.cpp
===
--- /dev/null
+++ test/CodeGenCXX/debug-info-composite-cc.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+// Not trivially copyable because of the explicit destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefDtor",{{.*}}flags: DIFlagTypePassByReference
+struct RefDtor {
+  int i;
+  ~RefDtor() {}
+} refDtor;
+
+// Not trivially copyable because of the explicit copy constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopy",{{.*}}flags: DIFlagTypePassByReference
+struct RefCopy {
+  int i;
+  RefCopy() = default;
+  RefCopy(RefCopy &Copy) {}
+} refCopy;
+
+// Not trivially copyable because of the explicit move constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefMove",{{.*}}flags: DIFlagTypePassByReference
+struct RefMove {
+  int i;
+  RefMove() = default;
+  RefMove(RefMove &&Move) {}
+} refMove;
+
+// POD-like type even though it defines a destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Podlike", {{.*}}flags: DIFlagTypePassByValue
+struct Podlike {
+  int i;
+  Podlike() = default;
+  Podlike(Podlike &&Move) = default;
+  ~Podlike() = default;
+} podlike;
+
+
+// This is a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Pod",{{.*}}flags: DIFlagTypePassByValue
+struct Pod {
+  int i;
+} pod;
+
+// This is definitely not a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Complex",{{.*}}flags: DIFlagTypePassByReference
+struct Complex {
+  Complex() {}
+  Complex(Complex &Copy) : i(Copy.i) {};
+  int i;
+} complex;
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -2803,9 +2803,18 @@
 
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, Th

[PATCH] D41747: [libcxx] implement simd_mask<> and operators.

2018-01-04 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 128687.
timshen added a comment.

Remove unintended binary file.


https://reviews.llvm.org/D41747

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/default.pass.cpp
  
libcxx/test/std/experimental/simd/simd.mask.cons/fixed_size_conversion.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
@@ -0,0 +1,82 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_to(value_type* mem, Flags) const;
+
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd_mask a;
+  a[0] = false;
+  a[1] = true;
+  a[2] = true;
+  a[3] = false;
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned<32>);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+#endif
+}
+
+int main() { test_store(); }
Index: libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
@@ -0,0 +1,105 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_from(const value_type* mem, Flags);
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval>().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval>().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+
+  not_supported_load((bool*)nullptr, int());
+}
+
+void test_load() {
+  alignas(32) bool buffer[] = {false, true, true, false};
+  {
+fixed_size_simd_mask a;
+a.copy_from(buffer, element_aligned_tag());
+assert(!a[0]);
+assert(a[1]);
+assert(a[2]);
+assert(!a[3]);
+  }
+  {
+fixed_size_simd_mask a;
+a.copy_from(buffer, vector_aligned_tag());
+assert(!a[0]);
+assert(a[1]);
+assert(a[2]);
+assert(!a[3]);
+  }
+  {
+fixed_size_simd_mask a;
+a.copy_

[PATCH] D41748: [libcxx] [test] Fix Xxx_scan tests using nonstandard things and MSVC++ warnings

2018-01-04 Thread Billy Robert O'Neal III via Phabricator via cfe-commits
BillyONeal created this revision.
BillyONeal added reviewers: mclow.lists, EricWF.

- These tests use function objects from functional, back_inserter from 
iterator, and equal from algorithm, so add those headers.
- The use of iota targeting vector with an int parameter 
triggers warnings on MSVC++ assigning an into a unsigned char&; so change the 
parameter to unsigned char with a static_cast.
- Avoid naming unary_function in identity here as that is removed in '17. (This 
also fixes naming _VSTD, _NOEXCEPT_, and other libcxx-isms)


https://reviews.llvm.org/D41748

Files:
  test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp
  test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_init_op.pass.cpp
  test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan.pass.cpp
  test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op.pass.cpp
  test/std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op_init.pass.cpp
  
test/std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_init_bop_uop.pass.cpp
  
test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop.pass.cpp
  
test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop_init.pass.cpp

Index: test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop_init.pass.cpp
===
--- test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop_init.pass.cpp
+++ test/std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop_init.pass.cpp
@@ -20,26 +20,15 @@
 
 
 #include 
-#include 
+#include 
 #include 
+#include 
+#include 
+#include 
 
 #include "test_iterators.h"
 
-template 
-struct identity : std::unary_function
-{
-constexpr const T& operator()(const T& x) const { return x;}
-};
-
-template <>
-struct identity
-{
-template 
-constexpr auto operator()(T&& x) const
-_NOEXCEPT_(noexcept(_VSTD::forward(x)))
--> decltype(_VSTD::forward(x))
-{ return_VSTD::forward(x); }
-};
+const auto identity = [](auto&& x) { return std::forward(x); };
 
 template 
 void
@@ -82,12 +71,12 @@
 static_assert(sa == sizeof(mResN2) / sizeof(mResN2[0]));   // just to be sure
 
 for (unsigned int i = 0; i < sa; ++i ) {
-test(Iter(ia), Iter(ia + i), std::plus<>(),   identity<>(),0, pResI0, pResI0 + i);
-test(Iter(ia), Iter(ia + i), std::multiplies<>(), identity<>(),0, mResI0, mResI0 + i);
+test(Iter(ia), Iter(ia + i), std::plus<>(),   identity,0, pResI0, pResI0 + i);
+test(Iter(ia), Iter(ia + i), std::multiplies<>(), identity,0, mResI0, mResI0 + i);
 test(Iter(ia), Iter(ia + i), std::plus<>(),   std::negate<>(), 0, pResN0, pResN0 + i);
 test(Iter(ia), Iter(ia + i), std::multiplies<>(), std::negate<>(), 0, mResN0, mResN0 + i);
-test(Iter(ia), Iter(ia + i), std::plus<>(),   identity<>(),2, pResI2, pResI2 + i);
-test(Iter(ia), Iter(ia + i), std::multiplies<>(), identity<>(),2, mResI2, mResI2 + i);
+test(Iter(ia), Iter(ia + i), std::plus<>(),   identity,2, pResI2, pResI2 + i);
+test(Iter(ia), Iter(ia + i), std::multiplies<>(), identity,2, mResI2, mResI2 + i);
 test(Iter(ia), Iter(ia + i), std::plus<>(),   std::negate<>(), 2, pResN2, pResN2 + i);
 test(Iter(ia), Iter(ia + i), std::multiplies<>(), std::negate<>(), 2, mResN2, mResN2 + i);
 }
@@ -101,39 +90,39 @@
 {
 std::vector v(10);
 std::fill(v.begin(), v.end(), 3);
-std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), identity<>(), 50);
+std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), identity, 50);
 for (size_t i = 0; i < v.size(); ++i)
 assert(v[i] == 50 + (int) (i + 1) * 3);
 }
 
 {
 std::vector v(10);
 std::iota(v.begin(), v.end(), 0);
-std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), identity<>(), 30);
+std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), identity, 30);
 for (size_t i = 0; i < v.size(); ++i)
 assert(v[i] == 30 + triangle(i));
 }
 
 {
 std::vector v(10);
 std::iota(v.begin(), v.end(), 1);
-std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), identity<>(), 40);
+std::transform_inclusive_scan(v.begin(), v.end(), v.begin(), std::plus<>(), identity, 40);
 for (size_t i = 0; i < v.size(); ++i)
 assert(v[i] == 40 + triangle(i + 1));
 }
 
 {
 std::vector v, res;
-std::transform_inclusive_scan(v.begin(), v.end(), std::back_inserter(res), std::plus<>(), identity<>(), 1);
+std::transform_inclusive_scan(v.begin(), v.end(), std::back_inserter(res), std::plus<>(), identity, 1);
 assert(res.empty());
 }
 
 //  Make sure th

[PATCH] D41749: [analyzer] suppress nullability inference from a macro when result is used in another macro

2018-01-04 Thread George Karpenkov via Phabricator via cfe-commits
george.karpenkov created this revision.
george.karpenkov added reviewers: dcoughlin, NoQ.
Herald added subscribers: a.sidorin, szepet, xazax.hun.

The current code used to not suppress the report, if the dereference was 
performed in a macro, assuming it is that same macro.
However, the assumption might not be correct, and XNU has quite a bit of code 
where dereference is actually performed in a different macro.

As the code uses macro name and not a unique identifier it might be fragile, 
but in a worst-case scenario we would simply emit an extra diagnostic.

rdar://36160245


https://reviews.llvm.org/D41749

Files:
  lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
  test/Analysis/inlining/false-positive-suppression.c


Index: test/Analysis/inlining/false-positive-suppression.c
===
--- test/Analysis/inlining/false-positive-suppression.c
+++ test/Analysis/inlining/false-positive-suppression.c
@@ -171,6 +171,15 @@
   (void)i;
 }
 
+// No warning should be emitted if dereference is performed from a different
+// macro.
+#define MACRO_CHECK(a) if (a) {}
+#define MACRO_DEREF(a) (*a)
+int testDifferentMacro(int *p) {
+  MACRO_CHECK(p);
+  return MACRO_DEREF(p); // no-warning
+}
+
 // --
 // "Suppression suppression"
 // --
Index: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
===
--- lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -841,6 +841,13 @@
   return "IDCVisitor";
 }
 
+/// \return name of the macro inside the location \p Loc.
+static StringRef getMacroName(SourceLocation Loc,
+BugReporterContext &BRC) {
+  return Lexer::getImmediateMacroName(
+  Loc, BRC.getSourceManager(), BRC.getASTContext().getLangOpts());
+}
+
 std::shared_ptr
 SuppressInlineDefensiveChecksVisitor::VisitNode(const ExplodedNode *Succ,
 const ExplodedNode *Pred,
@@ -880,9 +887,6 @@
 if (!BugPoint)
   return nullptr;
 
-SourceLocation BugLoc = BugPoint->getStmt()->getLocStart();
-if (BugLoc.isMacroID())
-  return nullptr;
 
 ProgramPoint CurPoint = Succ->getLocation();
 const Stmt *CurTerminatorStmt = nullptr;
@@ -909,7 +913,13 @@
   SrcMgr::SLocEntry SE = SMgr.getSLocEntry(TLInfo.first);
   const SrcMgr::ExpansionInfo &EInfo = SE.getExpansion();
   if (EInfo.isFunctionMacroExpansion()) {
-BR.markInvalid("Suppress Macro IDC", CurLC);
+SourceLocation BugLoc = BugPoint->getStmt()->getLocStart();
+
+// Suppress reports unless we are in that same macro.
+if (!BugLoc.isMacroID() ||
+getMacroName(BugLoc, BRC) != getMacroName(TerminatorLoc, BRC)) {
+  BR.markInvalid("Suppress Macro IDC", CurLC);
+}
 return nullptr;
   }
 }


Index: test/Analysis/inlining/false-positive-suppression.c
===
--- test/Analysis/inlining/false-positive-suppression.c
+++ test/Analysis/inlining/false-positive-suppression.c
@@ -171,6 +171,15 @@
   (void)i;
 }
 
+// No warning should be emitted if dereference is performed from a different
+// macro.
+#define MACRO_CHECK(a) if (a) {}
+#define MACRO_DEREF(a) (*a)
+int testDifferentMacro(int *p) {
+  MACRO_CHECK(p);
+  return MACRO_DEREF(p); // no-warning
+}
+
 // --
 // "Suppression suppression"
 // --
Index: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
===
--- lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -841,6 +841,13 @@
   return "IDCVisitor";
 }
 
+/// \return name of the macro inside the location \p Loc.
+static StringRef getMacroName(SourceLocation Loc,
+BugReporterContext &BRC) {
+  return Lexer::getImmediateMacroName(
+  Loc, BRC.getSourceManager(), BRC.getASTContext().getLangOpts());
+}
+
 std::shared_ptr
 SuppressInlineDefensiveChecksVisitor::VisitNode(const ExplodedNode *Succ,
 const ExplodedNode *Pred,
@@ -880,9 +887,6 @@
 if (!BugPoint)
   return nullptr;
 
-SourceLocation BugLoc = BugPoint->getStmt()->getLocStart();
-if (BugLoc.isMacroID())
-  return nullptr;
 
 ProgramPoint CurPoint = Succ->getLocation();
 const Stmt *CurTerminatorStmt = nullptr;
@@ -909,7 +913,13 @@
   SrcMgr::SLocEntry SE = SMgr.getSLocEntry(TLInfo.first);
   const SrcMgr::ExpansionInfo &EInfo = SE.getExpansion();
   if (EInfo.isFunctionMacroExpansion()) {
-BR.markInvalid("Suppress Macro IDC", CurLC);
+SourceLocation BugLoc = BugPoint->getStmt()->getLocStart();
+
+// Suppress reports unless we are in that same macro.
+if (!BugLoc.isMacroID() ||
+getMacroName(BugLoc, BRC) !

[PATCH] D41743: Debug Info: Support DW_AT_calling_convention on composite types.

2018-01-04 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

LGTM, thanks!


https://reviews.llvm.org/D41743



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


r321845 - Debug Info: Support DW_AT_calling_convention on composite types.

2018-01-04 Thread Adrian Prantl via cfe-commits
Author: adrian
Date: Thu Jan  4 17:13:52 2018
New Revision: 321845

URL: http://llvm.org/viewvc/llvm-project?rev=321845&view=rev
Log:
Debug Info: Support DW_AT_calling_convention on composite types.
This implements the DWARF 5 feature described at
http://www.dwarfstd.org/ShowIssue.php?issue=141215.1

This allows a consumer to understand whether a composite data type is
trivially copyable and thus should be passed by value instead of by
reference. The canonical example is being able to distinguish the
following two types:

  // S is not trivially copyable because of the explicit destructor.
  struct S {
 ~S() {}
  };

  // T is a POD type.
  struct T {
~T() = default;
  };


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

Added:
cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp
Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=321845&r1=321844&r2=321845&view=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Jan  4 17:13:52 2018
@@ -2803,9 +2803,18 @@ llvm::DICompositeType *CGDebugInfo::Crea
 
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
 
+  // Explicitly record the calling convention for C++ records.
+  auto Flags = llvm::DINode::FlagZero;
+  if (auto CXXRD = dyn_cast(RD)) {
+if (CGM.getCXXABI().getRecordArgABI(CXXRD) == CGCXXABI::RAA_Indirect)
+  Flags |= llvm::DINode::FlagTypePassByReference;
+else
+  Flags |= llvm::DINode::FlagTypePassByValue;
+  }
+
   llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
   getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
-  llvm::DINode::FlagZero, FullName);
+  Flags, FullName);
 
   // Elements of composite types usually have back to the type, creating
   // uniquing cycles.  Distinct nodes are more efficient.

Added: cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp?rev=321845&view=auto
==
--- cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp Thu Jan  4 17:13:52 
2018
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple 
%itanium_abi_triple %s -o - | FileCheck %s
+
+// Not trivially copyable because of the explicit destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefDtor",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefDtor {
+  int i;
+  ~RefDtor() {}
+} refDtor;
+
+// Not trivially copyable because of the explicit copy constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopy",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefCopy {
+  int i;
+  RefCopy() = default;
+  RefCopy(RefCopy &Copy) {}
+} refCopy;
+
+// Not trivially copyable because of the explicit move constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefMove",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefMove {
+  int i;
+  RefMove() = default;
+  RefMove(RefMove &&Move) {}
+} refMove;
+
+// POD-like type even though it defines a destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Podlike", {{.*}}flags: 
DIFlagTypePassByValue
+struct Podlike {
+  int i;
+  Podlike() = default;
+  Podlike(Podlike &&Move) = default;
+  ~Podlike() = default;
+} podlike;
+
+
+// This is a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Pod",{{.*}}flags: 
DIFlagTypePassByValue
+struct Pod {
+  int i;
+} pod;
+
+// This is definitely not a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Complex",{{.*}}flags: 
DIFlagTypePassByReference
+struct Complex {
+  Complex() {}
+  Complex(Complex &Copy) : i(Copy.i) {};
+  int i;
+} complex;


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


[PATCH] D41743: Debug Info: Support DW_AT_calling_convention on composite types.

2018-01-04 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL321844: Debug Info: Support DW_AT_calling_convention on 
composite types. (authored by adrian, committed by ).
Herald added a reviewer: deadalnix.

Changed prior to commit:
  https://reviews.llvm.org/D41743?vs=128686&id=128689#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D41743

Files:
  llvm/trunk/include/llvm-c/DebugInfo.h
  llvm/trunk/include/llvm/IR/DebugInfoFlags.def
  llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
  llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
  llvm/trunk/lib/IR/Verifier.cpp
  llvm/trunk/test/DebugInfo/Generic/pass-by-value.ll
  llvm/trunk/test/Verifier/cc-flags.ll

Index: llvm/trunk/include/llvm-c/DebugInfo.h
===
--- llvm/trunk/include/llvm-c/DebugInfo.h
+++ llvm/trunk/include/llvm-c/DebugInfo.h
@@ -52,6 +52,8 @@
   LLVMDIFlagBitField = 1 << 19,
   LLVMDIFlagNoReturn = 1 << 20,
   LLVMDIFlagMainSubprogram = 1 << 21,
+  LLVMDIFlagTypePassByValue = 1 << 22,
+  LLVMDIFlagTypePassByReference = 1 << 23,
   LLVMDIFlagIndirectVirtualBase = (1 << 2) | (1 << 5),
   LLVMDIFlagAccessibility = LLVMDIFlagPrivate | LLVMDIFlagProtected |
 LLVMDIFlagPublic,
Index: llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
===
--- llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
+++ llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
@@ -633,6 +633,10 @@
   bool isStaticMember() const { return getFlags() & FlagStaticMember; }
   bool isLValueReference() const { return getFlags() & FlagLValueReference; }
   bool isRValueReference() const { return getFlags() & FlagRValueReference; }
+  bool isTypePassByValue() const { return getFlags() & FlagTypePassByValue; }
+  bool isTypePassByReference() const {
+return getFlags() & FlagTypePassByReference;
+  }
 
   static bool classof(const Metadata *MD) {
 switch (MD->getMetadataID()) {
Index: llvm/trunk/include/llvm/IR/DebugInfoFlags.def
===
--- llvm/trunk/include/llvm/IR/DebugInfoFlags.def
+++ llvm/trunk/include/llvm/IR/DebugInfoFlags.def
@@ -43,6 +43,8 @@
 HANDLE_DI_FLAG((1 << 19), BitField)
 HANDLE_DI_FLAG((1 << 20), NoReturn)
 HANDLE_DI_FLAG((1 << 21), MainSubprogram)
+HANDLE_DI_FLAG((1 << 22), TypePassByValue)
+HANDLE_DI_FLAG((1 << 23), TypePassByReference)
 
 // To avoid needing a dedicated value for IndirectVirtualBase, we use
 // the bitwise or of Virtual and FwdDecl, which does not otherwise
@@ -52,7 +54,7 @@
 #ifdef DI_FLAG_LARGEST_NEEDED
 // intended to be used with ADT/BitmaskEnum.h
 // NOTE: always must be equal to largest flag, check this when adding new flag
-HANDLE_DI_FLAG((1 << 21), Largest)
+HANDLE_DI_FLAG((1 << 23), Largest)
 #undef DI_FLAG_LARGEST_NEEDED
 #endif
 
Index: llvm/trunk/test/DebugInfo/Generic/pass-by-value.ll
===
--- llvm/trunk/test/DebugInfo/Generic/pass-by-value.ll
+++ llvm/trunk/test/DebugInfo/Generic/pass-by-value.ll
@@ -0,0 +1,63 @@
+; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck %s
+;
+; // S is not trivially copyable.
+; struct S {
+;~S() {}
+; };
+;
+; // T is a POD.
+; struct T {
+;~T() = default;
+; };
+;  
+; S s;
+; T t;
+;
+; CHECK: DW_TAG_structure_type
+; CHECK-NEXT: DW_AT_calling_convention	(DW_CC_pass_by_reference)
+; CHECK-NEXT: DW_AT_name	("S")
+;
+; CHECK: DW_TAG_structure_type
+; CHECK-NEXT: DW_AT_calling_convention	(DW_CC_pass_by_value)
+; CHECK-NEXT: DW_AT_name	("T")
+
+source_filename = "pass.cpp"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.13.0"
+
+%struct.S = type { i8 }
+%struct.T = type { i8 }
+
+@s = global %struct.S zeroinitializer, align 1, !dbg !0
+@__dso_handle = external hidden global i8
+@t = global %struct.T zeroinitializer, align 1, !dbg !6
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!20, !21, !22, !23}
+!llvm.ident = !{!24}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "s", scope: !2, file: !3, line: 9, type: !14, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 (trunk 321763) (llvm/trunk 321758)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "pass.cpp", directory: "/")
+!4 = !{}
+!5 = !{!0, !6}
+!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
+!7 = distinct !DIGlobalVariable(name: "t", scope: !2, file: !3, line: 10, type: !8, isLocal: false, isDefinition: true)
+!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "T", file: !3, line: 5, size: 8, elements: !9, identifier: "_ZTS1T", flags: DIFlagTypePassByValue)
+!9 = !{!10}
+!10 = !DISubprogram(name: "~T", scope: !8, file: !

[PATCH] D41039: Add support for attribute "trivial_abi"

2018-01-04 Thread Phabricator via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rC321845: Debug Info: Support DW_AT_calling_convention on 
composite types. (authored by adrian, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D41039?vs=128642&id=128690#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D41039

Files:
  lib/CodeGen/CGDebugInfo.cpp
  test/CodeGenCXX/debug-info-composite-cc.cpp


Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -2803,9 +2803,18 @@
 
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
 
+  // Explicitly record the calling convention for C++ records.
+  auto Flags = llvm::DINode::FlagZero;
+  if (auto CXXRD = dyn_cast(RD)) {
+if (CGM.getCXXABI().getRecordArgABI(CXXRD) == CGCXXABI::RAA_Indirect)
+  Flags |= llvm::DINode::FlagTypePassByReference;
+else
+  Flags |= llvm::DINode::FlagTypePassByValue;
+  }
+
   llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
   getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
-  llvm::DINode::FlagZero, FullName);
+  Flags, FullName);
 
   // Elements of composite types usually have back to the type, creating
   // uniquing cycles.  Distinct nodes are more efficient.
Index: test/CodeGenCXX/debug-info-composite-cc.cpp
===
--- test/CodeGenCXX/debug-info-composite-cc.cpp
+++ test/CodeGenCXX/debug-info-composite-cc.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple 
%itanium_abi_triple %s -o - | FileCheck %s
+
+// Not trivially copyable because of the explicit destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefDtor",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefDtor {
+  int i;
+  ~RefDtor() {}
+} refDtor;
+
+// Not trivially copyable because of the explicit copy constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopy",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefCopy {
+  int i;
+  RefCopy() = default;
+  RefCopy(RefCopy &Copy) {}
+} refCopy;
+
+// Not trivially copyable because of the explicit move constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefMove",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefMove {
+  int i;
+  RefMove() = default;
+  RefMove(RefMove &&Move) {}
+} refMove;
+
+// POD-like type even though it defines a destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Podlike", {{.*}}flags: 
DIFlagTypePassByValue
+struct Podlike {
+  int i;
+  Podlike() = default;
+  Podlike(Podlike &&Move) = default;
+  ~Podlike() = default;
+} podlike;
+
+
+// This is a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Pod",{{.*}}flags: 
DIFlagTypePassByValue
+struct Pod {
+  int i;
+} pod;
+
+// This is definitely not a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Complex",{{.*}}flags: 
DIFlagTypePassByReference
+struct Complex {
+  Complex() {}
+  Complex(Complex &Copy) : i(Copy.i) {};
+  int i;
+} complex;


Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -2803,9 +2803,18 @@
 
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
 
+  // Explicitly record the calling convention for C++ records.
+  auto Flags = llvm::DINode::FlagZero;
+  if (auto CXXRD = dyn_cast(RD)) {
+if (CGM.getCXXABI().getRecordArgABI(CXXRD) == CGCXXABI::RAA_Indirect)
+  Flags |= llvm::DINode::FlagTypePassByReference;
+else
+  Flags |= llvm::DINode::FlagTypePassByValue;
+  }
+
   llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
   getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
-  llvm::DINode::FlagZero, FullName);
+  Flags, FullName);
 
   // Elements of composite types usually have back to the type, creating
   // uniquing cycles.  Distinct nodes are more efficient.
Index: test/CodeGenCXX/debug-info-composite-cc.cpp
===
--- test/CodeGenCXX/debug-info-composite-cc.cpp
+++ test/CodeGenCXX/debug-info-composite-cc.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+// Not trivially copyable because of the explicit destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefDtor",{{.*}}flags: DIFlagTypePassByReference
+struct RefDtor {
+  int i;
+  ~RefDtor() {}
+} refDtor;
+
+// Not trivially copyable because of the explicit copy constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopy",{{.*}}flags: DIFlagTypePassByReference
+struct RefCopy {
+  int i;
+  RefCopy() = default;
+  RefCopy(RefCopy &Copy) {}
+} refCopy;
+
+// 

[PATCH] D41039: Add support for attribute "trivial_abi"

2018-01-04 Thread Phabricator via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rL321845: Debug Info: Support DW_AT_calling_convention on 
composite types. (authored by adrian, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D41039?vs=128642&id=128691#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D41039

Files:
  cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
  cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp


Index: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
===
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
@@ -2803,9 +2803,18 @@
 
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
 
+  // Explicitly record the calling convention for C++ records.
+  auto Flags = llvm::DINode::FlagZero;
+  if (auto CXXRD = dyn_cast(RD)) {
+if (CGM.getCXXABI().getRecordArgABI(CXXRD) == CGCXXABI::RAA_Indirect)
+  Flags |= llvm::DINode::FlagTypePassByReference;
+else
+  Flags |= llvm::DINode::FlagTypePassByValue;
+  }
+
   llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
   getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
-  llvm::DINode::FlagZero, FullName);
+  Flags, FullName);
 
   // Elements of composite types usually have back to the type, creating
   // uniquing cycles.  Distinct nodes are more efficient.
Index: cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp
===
--- cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp
+++ cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple 
%itanium_abi_triple %s -o - | FileCheck %s
+
+// Not trivially copyable because of the explicit destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefDtor",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefDtor {
+  int i;
+  ~RefDtor() {}
+} refDtor;
+
+// Not trivially copyable because of the explicit copy constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopy",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefCopy {
+  int i;
+  RefCopy() = default;
+  RefCopy(RefCopy &Copy) {}
+} refCopy;
+
+// Not trivially copyable because of the explicit move constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefMove",{{.*}}flags: 
DIFlagTypePassByReference
+struct RefMove {
+  int i;
+  RefMove() = default;
+  RefMove(RefMove &&Move) {}
+} refMove;
+
+// POD-like type even though it defines a destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Podlike", {{.*}}flags: 
DIFlagTypePassByValue
+struct Podlike {
+  int i;
+  Podlike() = default;
+  Podlike(Podlike &&Move) = default;
+  ~Podlike() = default;
+} podlike;
+
+
+// This is a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Pod",{{.*}}flags: 
DIFlagTypePassByValue
+struct Pod {
+  int i;
+} pod;
+
+// This is definitely not a POD type.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Complex",{{.*}}flags: 
DIFlagTypePassByReference
+struct Complex {
+  Complex() {}
+  Complex(Complex &Copy) : i(Copy.i) {};
+  int i;
+} complex;


Index: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
===
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
@@ -2803,9 +2803,18 @@
 
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
 
+  // Explicitly record the calling convention for C++ records.
+  auto Flags = llvm::DINode::FlagZero;
+  if (auto CXXRD = dyn_cast(RD)) {
+if (CGM.getCXXABI().getRecordArgABI(CXXRD) == CGCXXABI::RAA_Indirect)
+  Flags |= llvm::DINode::FlagTypePassByReference;
+else
+  Flags |= llvm::DINode::FlagTypePassByValue;
+  }
+
   llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
   getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
-  llvm::DINode::FlagZero, FullName);
+  Flags, FullName);
 
   // Elements of composite types usually have back to the type, creating
   // uniquing cycles.  Distinct nodes are more efficient.
Index: cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp
===
--- cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp
+++ cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+// Not trivially copyable because of the explicit destructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefDtor",{{.*}}flags: DIFlagTypePassByReference
+struct RefDtor {
+  int i;
+  ~RefDtor() {}
+} refDtor;
+
+// Not trivially copyable because of the explicit copy constructor.
+// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopy

[PATCH] D41039: Add support for attribute "trivial_abi"

2018-01-04 Thread Adrian Prantl via Phabricator via cfe-commits
aprantl reopened this revision.
aprantl added a comment.

I'm sorry, I made a copy&paste error in a the commit message for 
https://reviews.llvm.org/D41743 and accidentally associated that commit with 
this review. I suppose I should learn to use arcanist.
Reopening, and my apologies for the noise!


Repository:
  rL LLVM

https://reviews.llvm.org/D41039



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


[PATCH] D41039: Add support for attribute "trivial_abi"

2018-01-04 Thread Adrian Prantl via Phabricator via cfe-commits
aprantl added a comment.

Unfortunately it looks like I do not have permission to re-upload Akira's last 
patch to this review.


Repository:
  rL LLVM

https://reviews.llvm.org/D41039



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


[PATCH] D41311: [CodeGen] Fix crash when a function taking transparent union is redeclared.

2018-01-04 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai added a subscriber: ahatanak.
vsapsai added a comment.

Add Akira as __fp16 expert to make sure I don't break some edge cases.


https://reviews.llvm.org/D41311



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


[PATCH] D41039: Add support for attribute "trivial_abi"

2018-01-04 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak updated this revision to Diff 128694.
ahatanak added a comment.

No worries. Upload the patch again.


https://reviews.llvm.org/D41039

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclCXX.h
  include/clang/AST/Type.h
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/DeclCXX.cpp
  lib/AST/Type.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/MicrosoftCXXABI.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaType.cpp
  test/CodeGenCXX/trivial_abi.cpp
  test/Misc/pragma-attribute-supported-attributes-list.test
  test/SemaObjCXX/attr-trivial-abi.mm

Index: test/SemaObjCXX/attr-trivial-abi.mm
===
--- /dev/null
+++ test/SemaObjCXX/attr-trivial-abi.mm
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -std=c++11 -fobjc-runtime-has-weak -fobjc-weak -fobjc-arc -fsyntax-only -verify %s
+
+void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}}
+
+struct [[clang::trivial_abi]] S0 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S1 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S2 { // expected-warning {{'trivial_abi' cannot be applied to 'S2'}}
+  __weak id a;
+};
+
+struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}}
+  virtual void m();
+};
+
+struct S4 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}}
+};
+
+struct __attribute__((trivial_abi)) S9 : public S4 {
+};
+
+struct S6 {
+  __weak id a;
+};
+
+struct __attribute__((trivial_abi)) S7 { // expected-warning {{'trivial_abi' cannot be applied to 'S7'}}
+  S6 a;
+};
+
+struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}}
+  int a;
+};
+
+template
+struct __attribute__((trivial_abi)) S10 {
+  T p;
+};
+
+S10 p1;
+
+// Do not warn when 'trivial_abi' is used to annotate a template class.
+S10<__weak id> p2;
Index: test/Misc/pragma-attribute-supported-attributes-list.test
===
--- test/Misc/pragma-attribute-supported-attributes-list.test
+++ test/Misc/pragma-attribute-supported-attributes-list.test
@@ -2,7 +2,7 @@
 
 // The number of supported attributes should never go down!
 
-// CHECK: #pragma clang attribute supports 66 attributes:
+// CHECK: #pragma clang attribute supports 67 attributes:
 // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function)
 // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function)
 // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function)
@@ -66,6 +66,7 @@
 // CHECK-NEXT: TLSModel (SubjectMatchRule_variable_is_thread_local)
 // CHECK-NEXT: Target (SubjectMatchRule_function)
 // CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member)
+// CHECK-NEXT: TrivialABI (SubjectMatchRule_record)
 // CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType)
 // CHECK-NEXT: XRayInstrument (SubjectMatchRule_function, SubjectMatchRule_objc_method)
 // CHECK-NEXT: XRayLogArgs (SubjectMatchRule_function, SubjectMatchRule_objc_method)
Index: test/CodeGenCXX/trivial_abi.cpp
===
--- /dev/null
+++ test/CodeGenCXX/trivial_abi.cpp
@@ -0,0 +1,196 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: %[[STRUCT_SMALL:.*]] = type { i32* }
+// CHECK: %[[STRUCT_LARGE:.*]] = type { i32*, [128 x i32] }
+// CHECK: %[[STRUCT_TRIVIAL:.*]] = type { i32 }
+// CHECK: %[[STRUCT_NONTRIVIAL:.*]] = type { i32 }
+
+struct __attribute__((trivial_abi)) Small {
+  int *p;
+  Small();
+  ~Small();
+  Small(const Small &);
+  Small &operator=(const Small &);
+};
+
+struct __attribute__((trivial_abi)) Large {
+  int *p;
+  int a[128];
+  Large();
+  ~Large();
+  Large(const Large &);
+  Large &operator=(const Large &);
+};
+
+struct Trivial {
+  int a;
+};
+
+struct NonTrivial {
+  NonTrivial();
+  ~NonTrivial();
+  int a;
+};
+
+struct HasTrivial {
+  Small s;
+  Trivial m;
+};
+
+struct HasNonTrivial {
+  Small s;
+  NonTrivial m;
+};
+
+// CHECK: define void @_Z14testParamSmall5Small(i64 %[[A_COERCE:.*]])
+// CHECK: %[[A:.*]] = alloca %[[STRUCT_SMALL]], align 8
+// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[A]], i32 0, i32 0
+// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[A_COERCE]] to i32*
+// CHECK: store i32* %[[COERCE_VAL_IP]], i32** %[[COERCE_DIVE]], align 8
+// CHECK: %[[CALL:.*]] = call %[[STRUCT_SMALL]]* @_ZN5SmallD1Ev(%[[STRUCT_SMALL]]* %[[A]])
+// CHECK: ret void
+// CHECK: }
+
+void testParamSmall(Small a) {
+}
+
+// CHECK: define i64 @_Z15testReturnSmallv()
+

r321846 - Remove redundant test

2018-01-04 Thread Adrian Prantl via cfe-commits
Author: adrian
Date: Thu Jan  4 17:28:59 2018
New Revision: 321846

URL: http://llvm.org/viewvc/llvm-project?rev=321846&view=rev
Log:
Remove redundant test

Modified:
cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp

Modified: cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp?rev=321846&r1=321845&r2=321846&view=diff
==
--- cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/debug-info-composite-cc.cpp Thu Jan  4 17:28:59 
2018
@@ -15,14 +15,6 @@ struct RefCopy {
   RefCopy(RefCopy &Copy) {}
 } refCopy;
 
-// Not trivially copyable because of the explicit move constructor.
-// CHECK-DAG: !DICompositeType({{.*}}, name: "RefMove",{{.*}}flags: 
DIFlagTypePassByReference
-struct RefMove {
-  int i;
-  RefMove() = default;
-  RefMove(RefMove &&Move) {}
-} refMove;
-
 // POD-like type even though it defines a destructor.
 // CHECK-DAG: !DICompositeType({{.*}}, name: "Podlike", {{.*}}flags: 
DIFlagTypePassByValue
 struct Podlike {


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


[PATCH] D41372: [libcxx] Fix transform_reduce mishandling move-only types, and nonstandard macro use in tests.

2018-01-04 Thread Billy Robert O'Neal III via Phabricator via cfe-commits
BillyONeal updated this revision to Diff 128695.
BillyONeal added a comment.

Moved things to MoveOnly.h.


https://reviews.llvm.org/D41372

Files:
  include/numeric
  
test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
  
test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
  
test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
  test/support/MoveOnly.h

Index: test/support/MoveOnly.h
===
--- test/support/MoveOnly.h
+++ test/support/MoveOnly.h
@@ -19,7 +19,6 @@
 
 class MoveOnly
 {
-friend class MoveOnly2;
 MoveOnly(const MoveOnly&);
 MoveOnly& operator=(const MoveOnly&);
 
@@ -35,6 +34,8 @@
 
 bool operator==(const MoveOnly& x) const {return data_ == x.data_;}
 bool operator< (const MoveOnly& x) const {return data_ <  x.data_;}
+MoveOnly operator+(const MoveOnly& x) const { return MoveOnly{data_ + x.data_}; }
+MoveOnly operator*(const MoveOnly& x) const { return MoveOnly{data_ * x.data_}; }
 };
 
 namespace std {
Index: test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
===
--- test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
+++ test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
@@ -19,7 +19,9 @@
 
 #include 
 #include 
+#include 
 
+#include "MoveOnly.h"
 #include "test_iterators.h"
 
 template 
@@ -58,6 +60,16 @@
decltype(std::transform_reduce(p, p, p, Init{}, std::plus<>(), std::multiplies<>()))> );
 }
 
+void test_move_only_types()
+{
+MoveOnly ia[] = {{1}, {2}, {3}};
+MoveOnly ib[] = {{1}, {2}, {3}};
+assert(14 ==
+std::transform_reduce(std::begin(ia), std::end(ia), std::begin(ib), MoveOnly{0},
+[](const MoveOnly& lhs, const MoveOnly& rhs) { return MoveOnly{lhs.get() + rhs.get()}; },
+[](const MoveOnly& lhs, const MoveOnly& rhs) { return MoveOnly{lhs.get() * rhs.get()}; }).get());
+}
+
 int main()
 {
 test_return_type();
@@ -94,4 +106,6 @@
 test();
 test<  int*, const unsigned int *>();
 test<  int*,   unsigned int *>();
+
+test_move_only_types();
 }
Index: test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
===
--- test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
+++ test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
@@ -17,7 +17,9 @@
 
 #include 
 #include 
+#include 
 
+#include "MoveOnly.h"
 #include "test_iterators.h"
 
 template 
@@ -56,6 +58,14 @@
decltype(std::transform_reduce(p, p, p, Init{}))> );
 }
 
+void test_move_only_types()
+{
+MoveOnly ia[] = {{1}, {2}, {3}};
+MoveOnly ib[] = {{1}, {2}, {3}};
+assert(14 ==
+std::transform_reduce(std::begin(ia), std::end(ia), std::begin(ib), MoveOnly{0}).get());
+}
+
 int main()
 {
 test_return_type();
@@ -92,4 +102,6 @@
 test();
 test<  int*, const unsigned int *>();
 test<  int*,   unsigned int *>();
+
+test_move_only_types();
 }
Index: test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
===
--- test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
+++ test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
@@ -18,40 +18,26 @@
 
 #include 
 #include 
+#include 
+#include 
 
+#include "MoveOnly.h"
 #include "test_iterators.h"
 
-template 
-struct identity : std::unary_function
-{
-constexpr const T& operator()(const T& x) const { return x;}
-};
-
-template <>
-struct identity
+struct identity
 {
 template 
-constexpr auto operator()(T&& x) const
-_NOEXCEPT_(noexcept(_VSTD::forward(x)))
--> decltype(_VSTD::forward(x))
-{ return_VSTD::forward(x); }
+constexpr decltype(auto) operator()(T&& x) const {
+return std::forward(x);
+}
 };
 
-
-template 
 struct twice
-{
-constexpr const T operator()(const T& x) const noexcept { return 2 * x; }
-};
-
-template <>
-struct twice
 {
 template 
-constexpr auto operator()(const T& x) const
-_NOEXCEPT_(noexcept(2 * x))
--> decltype(2 * x)
-{ return2 * x; }
+constexpr auto operator()(const T& x) const {
+return 2 * x;
+}
 };
 
 template 
@@ -70,31 +56,40 @@
 int ia[]  = {1, 2, 3, 4, 5, 6};
 unsigned sa = sizeof(ia) / sizeof(ia[0]);
 
-test(Iter(ia), Iter(ia),0, std::plus<>(),   identity<>(),   0);
-test(Iter(ia), I

[libcxx] r321848 - Add move-only types test for transform_reduce bop/uop.

2018-01-04 Thread Billy Robert O'Neal III via cfe-commits
Author: bion
Date: Thu Jan  4 17:31:50 2018
New Revision: 321848

URL: http://llvm.org/viewvc/llvm-project?rev=321848&view=rev
Log:
Add move-only types test for transform_reduce bop/uop.

Modified:

libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp

Modified: 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp?rev=321848&r1=321847&r2=321848&view=diff
==
--- 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
 Thu Jan  4 17:31:50 2018
@@ -19,7 +19,9 @@
 #include 
 #include 
 #include 
+#include 
 
+#include "MoveOnly.h"
 #include "test_iterators.h"
 
 struct identity
@@ -81,6 +83,15 @@ void test_return_type()
  decltype(std::transform_reduce(p, p, Init{}, std::plus<>(), 
identity()))> );
 }
 
+void test_move_only_types()
+{
+MoveOnly ia[] = {{1}, {2}, {3}};
+assert(60 ==
+std::transform_reduce(std::begin(ia), std::end(ia), MoveOnly{0},
+[](const MoveOnly& lhs, const MoveOnly& rhs) { return 
MoveOnly{lhs.get() + rhs.get()}; },
+[](const MoveOnly& target) { return MoveOnly{target.get() * 10}; 
}).get());
+}
+
 int main()
 {
 test_return_type();
@@ -105,4 +116,6 @@ int main()
 unsigned res = std::transform_reduce(v.begin(), v.end(), 1U, 
std::multiplies<>(), twice());
 assert(res == 46080);   // 6! * 64 will not fit into a char
 }
+
+test_move_only_types();
 }


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


[libcxx] r321847 - Fix nonstandard bits in transform_reduce_iter_iter_init_bop_uop.

2018-01-04 Thread Billy Robert O'Neal III via cfe-commits
Author: bion
Date: Thu Jan  4 17:31:47 2018
New Revision: 321847

URL: http://llvm.org/viewvc/llvm-project?rev=321847&view=rev
Log:
Fix nonstandard bits in transform_reduce_iter_iter_init_bop_uop.

* _VSTD should be std.
*  is needed for forward.
* unary_function is no longer standard (and unnecessary for this, a C++17-only 
test)

Modified:

libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp

Modified: 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp?rev=321847&r1=321846&r2=321847&view=diff
==
--- 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp
 Thu Jan  4 17:31:47 2018
@@ -18,40 +18,24 @@
 
 #include 
 #include 
+#include 
 
 #include "test_iterators.h"
 
-template 
-struct identity : std::unary_function
-{
-constexpr const T& operator()(const T& x) const { return x;}
-};
-
-template <>
-struct identity
+struct identity
 {
 template 
-constexpr auto operator()(T&& x) const
-_NOEXCEPT_(noexcept(_VSTD::forward(x)))
--> decltype(_VSTD::forward(x))
-{ return_VSTD::forward(x); }
+constexpr decltype(auto) operator()(T&& x) const {
+return std::forward(x);
+}
 };
 
-
-template 
 struct twice
 {
-constexpr const T operator()(const T& x) const noexcept { return 2 * x; }
-};
-
-template <>
-struct twice
-{
 template 
-constexpr auto operator()(const T& x) const
-_NOEXCEPT_(noexcept(2 * x))
--> decltype(2 * x)
-{ return2 * x; }
+constexpr auto operator()(const T& x) const {
+return 2 * x;
+}
 };
 
 template 
@@ -70,23 +54,23 @@ test()
 int ia[]  = {1, 2, 3, 4, 5, 6};
 unsigned sa = sizeof(ia) / sizeof(ia[0]);
 
-test(Iter(ia), Iter(ia),0, std::plus<>(),   identity<>(),   0);
-test(Iter(ia), Iter(ia),1, std::multiplies<>(), identity<>(),   1);
-test(Iter(ia), Iter(ia+1),  0, std::multiplies<>(), identity<>(),   0);
-test(Iter(ia), Iter(ia+1),  2, std::plus<>(),   identity<>(),   3);
-test(Iter(ia), Iter(ia+2),  0, std::plus<>(),   identity<>(),   3);
-test(Iter(ia), Iter(ia+2),  3, std::multiplies<>(), identity<>(),   6);
-test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), identity<>(),2880);
-test(Iter(ia), Iter(ia+sa), 4, std::plus<>(),   identity<>(),  25);
-
-test(Iter(ia), Iter(ia),0, std::plus<>(),   twice<>(),   0);
-test(Iter(ia), Iter(ia),1, std::multiplies<>(), twice<>(),   1);
-test(Iter(ia), Iter(ia+1),  0, std::multiplies<>(), twice<>(),   0);
-test(Iter(ia), Iter(ia+1),  2, std::plus<>(),   twice<>(),   4);
-test(Iter(ia), Iter(ia+2),  0, std::plus<>(),   twice<>(),   6);
-test(Iter(ia), Iter(ia+2),  3, std::multiplies<>(), twice<>(),  24);
-test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), twice<>(),  184320); 
// 64 * 2880
-test(Iter(ia), Iter(ia+sa), 4, std::plus<>(),   twice<>(),  46);
+test(Iter(ia), Iter(ia),0, std::plus<>(),   identity(),   0);
+test(Iter(ia), Iter(ia),1, std::multiplies<>(), identity(),   1);
+test(Iter(ia), Iter(ia+1),  0, std::multiplies<>(), identity(),   0);
+test(Iter(ia), Iter(ia+1),  2, std::plus<>(),   identity(),   3);
+test(Iter(ia), Iter(ia+2),  0, std::plus<>(),   identity(),   3);
+test(Iter(ia), Iter(ia+2),  3, std::multiplies<>(), identity(),   6);
+test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), identity(),2880);
+test(Iter(ia), Iter(ia+sa), 4, std::plus<>(),   identity(),  25);
+
+test(Iter(ia), Iter(ia),0, std::plus<>(),   twice(),   0);
+test(Iter(ia), Iter(ia),1, std::multiplies<>(), twice(),   1);
+test(Iter(ia), Iter(ia+1),  0, std::multiplies<>(), twice(),   0);
+test(Iter(ia), Iter(ia+1),  2, std::plus<>(),   twice(),   4);
+test(Iter(ia), Iter(ia+2),  0, std::plus<>(),   twice(),   6);
+test(Iter(ia), Iter(ia+2),  3, std::multiplies<>(), twice(),  24);
+test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), twice(),  184320); // 
64 * 2880
+test(Iter(ia), Iter(ia+sa), 4, std::plus<>(),   twice(),  46);
 }
 
 template 
@@ -94,7 +78,7 @@ void test_return_type()
 {
 T *p = nullptr;
 static_assert( std::is_same_v(), 
identity<>()))> );
+ decltype(std::transform_reduce(p, p, Init{}, std::plus<>(), 
identity()))> );
 }
 
 int main()
@@ -118,

[libcxx] r321852 - Move + and * operators of MoveOnly into MoveOnly.h.

2018-01-04 Thread Billy Robert O'Neal III via cfe-commits
Author: bion
Date: Thu Jan  4 17:32:00 2018
New Revision: 321852

URL: http://llvm.org/viewvc/llvm-project?rev=321852&view=rev
Log:
Move + and * operators of MoveOnly into MoveOnly.h.

Modified:

libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
libcxx/trunk/test/support/MoveOnly.h

Modified: 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp?rev=321852&r1=321851&r2=321852&view=diff
==
--- 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
 Thu Jan  4 17:32:00 2018
@@ -58,16 +58,6 @@ void test_return_type()
decltype(std::transform_reduce(p, p, p, Init{}))> );
 }
 
-inline MoveOnly operator+(const MoveOnly& lhs, const MoveOnly& rhs)
-{
-return MoveOnly{lhs.get() + rhs.get()};
-}
-
-inline MoveOnly operator*(const MoveOnly& lhs, const MoveOnly& rhs)
-{
-return MoveOnly{lhs.get() * rhs.get()};
-}
-
 void test_move_only_types()
 {
 MoveOnly ia[] = {{1}, {2}, {3}};

Modified: libcxx/trunk/test/support/MoveOnly.h
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/MoveOnly.h?rev=321852&r1=321851&r2=321852&view=diff
==
--- libcxx/trunk/test/support/MoveOnly.h (original)
+++ libcxx/trunk/test/support/MoveOnly.h Thu Jan  4 17:32:00 2018
@@ -19,7 +19,6 @@
 
 class MoveOnly
 {
-friend class MoveOnly2;
 MoveOnly(const MoveOnly&);
 MoveOnly& operator=(const MoveOnly&);
 
@@ -35,6 +34,8 @@ public:
 
 bool operator==(const MoveOnly& x) const {return data_ == x.data_;}
 bool operator< (const MoveOnly& x) const {return data_ <  x.data_;}
+MoveOnly operator+(const MoveOnly& x) const { return MoveOnly{data_ + 
x.data_}; }
+MoveOnly operator*(const MoveOnly& x) const { return MoveOnly{data_ * 
x.data_}; }
 };
 
 namespace std {


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


[libcxx] r321849 - Add move-only types test to transform_reduce iter iter iter init op op.

2018-01-04 Thread Billy Robert O'Neal III via cfe-commits
Author: bion
Date: Thu Jan  4 17:31:52 2018
New Revision: 321849

URL: http://llvm.org/viewvc/llvm-project?rev=321849&view=rev
Log:
Add move-only types test to transform_reduce iter iter iter init op op.

Modified:

libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp

Modified: 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp?rev=321849&r1=321848&r2=321849&view=diff
==
--- 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp
 Thu Jan  4 17:31:52 2018
@@ -19,7 +19,9 @@
 
 #include 
 #include 
+#include 
 
+#include "MoveOnly.h"
 #include "test_iterators.h"
 
 template 
@@ -58,6 +60,16 @@ void test_return_type()
decltype(std::transform_reduce(p, p, p, Init{}, std::plus<>(), 
std::multiplies<>()))> );
 }
 
+void test_move_only_types()
+{
+MoveOnly ia[] = {{1}, {2}, {3}};
+MoveOnly ib[] = {{1}, {2}, {3}};
+assert(14 ==
+std::transform_reduce(std::begin(ia), std::end(ia), std::begin(ib), 
MoveOnly{0},
+[](const MoveOnly& lhs, const MoveOnly& rhs) { return 
MoveOnly{lhs.get() + rhs.get()}; },
+[](const MoveOnly& lhs, const MoveOnly& rhs) { return 
MoveOnly{lhs.get() * rhs.get()}; }).get());
+}
+
 int main()
 {
 test_return_type();
@@ -94,4 +106,6 @@ int main()
 test();
 test<  int*, const unsigned int *>();
 test<  int*,   unsigned int *>();
+
+test_move_only_types();
 }


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


[libcxx] r321850 - Automated trailing whitespace removal by VS Code.

2018-01-04 Thread Billy Robert O'Neal III via cfe-commits
Author: bion
Date: Thu Jan  4 17:31:55 2018
New Revision: 321850

URL: http://llvm.org/viewvc/llvm-project?rev=321850&view=rev
Log:
Automated trailing whitespace removal by VS Code.

Modified:
libcxx/trunk/include/numeric

Modified: libcxx/trunk/include/numeric
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/numeric?rev=321850&r1=321849&r2=321850&view=diff
==
--- libcxx/trunk/include/numeric (original)
+++ libcxx/trunk/include/numeric Thu Jan  4 17:31:55 2018
@@ -51,7 +51,7 @@ template
 T
 transform_reduce(InputIterator1 first1, InputIterator1 last1,
@@ -75,10 +75,10 @@ template
 OutputIterator
-exclusive_scan(InputIterator first, InputIterator last, 
+exclusive_scan(InputIterator first, InputIterator last,
OutputIterator result, T init, BinaryOperation binary_op); 
// C++17
 
 template
@@ -108,7 +108,7 @@ template
OutputIterator
@@ -196,7 +196,7 @@ inline _LIBCPP_INLINE_VISIBILITY
 typename iterator_traits<_InputIterator>::value_type
 reduce(_InputIterator __first, _InputIterator __last)
 {
-return _VSTD::reduce(__first, __last, 
+return _VSTD::reduce(__first, __last,
typename iterator_traits<_InputIterator>::value_type{});
 }
 #endif
@@ -226,7 +226,7 @@ inner_product(_InputIterator1 __first1,
 template 
 inline _LIBCPP_INLINE_VISIBILITY
 _Tp
-transform_reduce(_InputIterator __first, _InputIterator __last, 
+transform_reduce(_InputIterator __first, _InputIterator __last,
_Tp __init,  _BinaryOp __b, _UnaryOp __u)
 {
 for (; __first != __last; ++__first)
@@ -234,7 +234,7 @@ transform_reduce(_InputIterator __first,
 return __init;
 }
 
-template 
 inline _LIBCPP_INLINE_VISIBILITY
 _Tp
@@ -249,7 +249,7 @@ transform_reduce(_InputIterator1 __first
 template 
 inline _LIBCPP_INLINE_VISIBILITY
 _Tp
-transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1, 
+transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
  _InputIterator2 __first2, _Tp __init)
 {
 return _VSTD::transform_reduce(__first1, __last1, __first2, __init, 
@@ -298,7 +298,7 @@ partial_sum(_InputIterator __first, _Inp
 template 
 inline _LIBCPP_INLINE_VISIBILITY
 _OutputIterator
-exclusive_scan(_InputIterator __first, _InputIterator __last, 
+exclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp __init, _BinaryOp __b)
 {
 if (__first != __last)
@@ -318,14 +318,14 @@ exclusive_scan(_InputIterator __first, _
 template 
 inline _LIBCPP_INLINE_VISIBILITY
 _OutputIterator
-exclusive_scan(_InputIterator __first, _InputIterator __last, 
+exclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp __init)
 {
 return _VSTD::exclusive_scan(__first, __last, __result, __init, 
_VSTD::plus<>());
 }
 
 template 
-_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, 
+_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOp __b,  _Tp 
__init)
 {
 for (; __first != __last; ++__first, (void) ++__result) {
@@ -336,7 +336,7 @@ _OutputIterator inclusive_scan(_InputIte
 }
 
 template 
-_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, 
+_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOp __b)
 {
 if (__first != __last) {
@@ -350,17 +350,17 @@ _OutputIterator inclusive_scan(_InputIte
 }
 
 template 
-_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last, 
+_OutputIterator inclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result)
 {
 return _VSTD::inclusive_scan(__first, __last, __result, std::plus<>());
 }
 
-template 
 inline _LIBCPP_INLINE_VISIBILITY
 _OutputIterator
-transform_exclusive_scan(_InputIterator __first, _InputIterator __last, 
+transform_exclusive_scan(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp __init,
_BinaryOp __b, _UnaryOp __u)
 {
@@ -379,7 +379,7 @@ transform_exclusive_scan(_InputIterator
 }
 
 template 
-_OutputIterator transform_inclusive_scan(_InputIterator __first, 
_InputIterator __last, 
+_OutputIterator transform_inclusive_scan(_InputIterator __first, 
_InputIterator __last,
_OutputIterator __result, _BinaryOp __b, _UnaryOp 
__u, _Tp __init)
 {
 for (; __first != __last; ++__first, (void) ++__result) {
@@ -391,7 +391,7 @@ _OutputIterator transform_inclusive_scan
 }
 
 template 
-_OutputIterator transform_inclusive_scan(_InputIterator __first, 
_InputIterator __last, 
+_OutputIterator transform_inclusive_scan(_InputIterator __first, 
_InputIterator __last,
 

[libcxx] r321851 - Fix incorrect handling of move-only types in transform_reduce iter iter iter init, and add test.

2018-01-04 Thread Billy Robert O'Neal III via cfe-commits
Author: bion
Date: Thu Jan  4 17:31:57 2018
New Revision: 321851

URL: http://llvm.org/viewvc/llvm-project?rev=321851&view=rev
Log:
Fix incorrect handling of move-only types in transform_reduce iter iter iter 
init, and add test.

Modified:
libcxx/trunk/include/numeric

libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp

Modified: libcxx/trunk/include/numeric
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/numeric?rev=321851&r1=321850&r2=321851&view=diff
==
--- libcxx/trunk/include/numeric (original)
+++ libcxx/trunk/include/numeric Thu Jan  4 17:31:57 2018
@@ -252,7 +252,7 @@ _Tp
 transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
  _InputIterator2 __first2, _Tp __init)
 {
-return _VSTD::transform_reduce(__first1, __last1, __first2, __init, 
+return _VSTD::transform_reduce(__first1, __last1, __first2, 
_VSTD::move(__init),
_VSTD::plus<>(), _VSTD::multiplies<>());
 }
 #endif

Modified: 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp?rev=321851&r1=321850&r2=321851&view=diff
==
--- 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp
 Thu Jan  4 17:31:57 2018
@@ -17,7 +17,9 @@
 
 #include 
 #include 
+#include 
 
+#include "MoveOnly.h"
 #include "test_iterators.h"
 
 template 
@@ -56,6 +58,24 @@ void test_return_type()
decltype(std::transform_reduce(p, p, p, Init{}))> );
 }
 
+inline MoveOnly operator+(const MoveOnly& lhs, const MoveOnly& rhs)
+{
+return MoveOnly{lhs.get() + rhs.get()};
+}
+
+inline MoveOnly operator*(const MoveOnly& lhs, const MoveOnly& rhs)
+{
+return MoveOnly{lhs.get() * rhs.get()};
+}
+
+void test_move_only_types()
+{
+MoveOnly ia[] = {{1}, {2}, {3}};
+MoveOnly ib[] = {{1}, {2}, {3}};
+assert(14 ==
+std::transform_reduce(std::begin(ia), std::end(ia), std::begin(ib), 
MoveOnly{0}).get());
+}
+
 int main()
 {
 test_return_type();
@@ -92,4 +112,6 @@ int main()
 test();
 test<  int*, const unsigned int *>();
 test<  int*,   unsigned int *>();
+
+test_move_only_types();
 }


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


[PATCH] D41750: Fix TLS support check for Darwin 32-bit simulator targets.

2018-01-04 Thread Volodymyr Sapsai via Phabricator via cfe-commits
vsapsai created this revision.
vsapsai added reviewers: arphaman, bob.wilson.

Also instead of checking architecture explicitly, use recently added
"simulator" environment in the triple.

rdar://problem/35083787


https://reviews.llvm.org/D41750

Files:
  clang/lib/Basic/Targets/OSTargets.h
  clang/test/Sema/darwin-tls.c


Index: clang/test/Sema/darwin-tls.c
===
--- clang/test/Sema/darwin-tls.c
+++ clang/test/Sema/darwin-tls.c
@@ -1,12 +1,18 @@
 // RUN: not %clang_cc1 -fsyntax-only -triple x86_64-apple-macosx10.6 %s 2>&1 | 
FileCheck %s --check-prefix NO-TLS
 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-macosx10.7 %s 2>&1 | 
FileCheck %s --check-prefix TLS
+
 // RUN: not %clang_cc1 -fsyntax-only -triple arm64-apple-ios7.1 %s 2>&1 | 
FileCheck %s --check-prefix NO-TLS
 // RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-ios8.0 %s 2>&1 | 
FileCheck %s --check-prefix TLS
 // RUN: not %clang_cc1 -fsyntax-only -triple thumbv7s-apple-ios8.3 %s 2>&1 | 
FileCheck %s --check-prefix NO-TLS
 // RUN: %clang_cc1 -fsyntax-only -triple thumbv7s-apple-ios9.0 %s 2>&1 | 
FileCheck %s --check-prefix TLS
 // RUN: %clang_cc1 -fsyntax-only -triple armv7-apple-ios9.0 %s 2>&1 | 
FileCheck %s --check-prefix TLS
+// RUN: not %clang_cc1 -fsyntax-only -triple i386-apple-ios9.0-simulator %s 
2>&1 | FileCheck %s --check-prefix NO-TLS
+// RUN: %clang_cc1 -fsyntax-only -triple i386-apple-ios10.0-simulator %s 2>&1 
| FileCheck %s --check-prefix TLS
+
 // RUN: not %clang_cc1 -fsyntax-only -triple thumbv7k-apple-watchos1.0 %s 2>&1 
| FileCheck %s --check-prefix NO-TLS
 // RUN: %clang_cc1 -fsyntax-only -triple thumbv7k-apple-watchos2.0 %s 2>&1 | 
FileCheck %s --check-prefix TLS
+// RUN: not %clang_cc1 -fsyntax-only -triple i386-apple-watchos2.0-simulator 
%s 2>&1 | FileCheck %s --check-prefix NO-TLS
+// RUN: %clang_cc1 -fsyntax-only -triple i386-apple-watchos3.0-simulator %s 
2>&1 | FileCheck %s --check-prefix TLS
 
 
 __thread int a;
Index: clang/lib/Basic/Targets/OSTargets.h
===
--- clang/lib/Basic/Targets/OSTargets.h
+++ clang/lib/Basic/Targets/OSTargets.h
@@ -95,16 +95,22 @@
 if (Triple.isMacOSX())
   this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
 else if (Triple.isiOS()) {
-  // 64-bit iOS supported it from 8 onwards, 32-bit from 9 onwards.
-  if (Triple.getArch() == llvm::Triple::x86_64 ||
-  Triple.getArch() == llvm::Triple::aarch64)
+  // 64-bit iOS supported it from 8 onwards, 32-bit device from 9 onwards,
+  // 32-bit simulator from 10 onwards.
+  if (Triple.isArch64Bit())
 this->TLSSupported = !Triple.isOSVersionLT(8);
-  else if (Triple.getArch() == llvm::Triple::x86 ||
-   Triple.getArch() == llvm::Triple::arm ||
-   Triple.getArch() == llvm::Triple::thumb)
-this->TLSSupported = !Triple.isOSVersionLT(9);
-} else if (Triple.isWatchOS())
-  this->TLSSupported = !Triple.isOSVersionLT(2);
+  else if (Triple.isArch32Bit()) {
+if (!Triple.isSimulatorEnvironment())
+  this->TLSSupported = !Triple.isOSVersionLT(9);
+else
+  this->TLSSupported = !Triple.isOSVersionLT(10);
+  }
+} else if (Triple.isWatchOS()) {
+  if (!Triple.isSimulatorEnvironment())
+this->TLSSupported = !Triple.isOSVersionLT(2);
+  else
+this->TLSSupported = !Triple.isOSVersionLT(3);
+}
 
 this->MCountName = "\01mcount";
   }


Index: clang/test/Sema/darwin-tls.c
===
--- clang/test/Sema/darwin-tls.c
+++ clang/test/Sema/darwin-tls.c
@@ -1,12 +1,18 @@
 // RUN: not %clang_cc1 -fsyntax-only -triple x86_64-apple-macosx10.6 %s 2>&1 | FileCheck %s --check-prefix NO-TLS
 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-macosx10.7 %s 2>&1 | FileCheck %s --check-prefix TLS
+
 // RUN: not %clang_cc1 -fsyntax-only -triple arm64-apple-ios7.1 %s 2>&1 | FileCheck %s --check-prefix NO-TLS
 // RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-ios8.0 %s 2>&1 | FileCheck %s --check-prefix TLS
 // RUN: not %clang_cc1 -fsyntax-only -triple thumbv7s-apple-ios8.3 %s 2>&1 | FileCheck %s --check-prefix NO-TLS
 // RUN: %clang_cc1 -fsyntax-only -triple thumbv7s-apple-ios9.0 %s 2>&1 | FileCheck %s --check-prefix TLS
 // RUN: %clang_cc1 -fsyntax-only -triple armv7-apple-ios9.0 %s 2>&1 | FileCheck %s --check-prefix TLS
+// RUN: not %clang_cc1 -fsyntax-only -triple i386-apple-ios9.0-simulator %s 2>&1 | FileCheck %s --check-prefix NO-TLS
+// RUN: %clang_cc1 -fsyntax-only -triple i386-apple-ios10.0-simulator %s 2>&1 | FileCheck %s --check-prefix TLS
+
 // RUN: not %clang_cc1 -fsyntax-only -triple thumbv7k-apple-watchos1.0 %s 2>&1 | FileCheck %s --check-prefix NO-TLS
 // RUN: %clang_cc1 -fsyntax-only -triple thumbv7k-apple-watchos2.0 %s 2>&1 | FileCheck %s --check-prefix TLS
+// RUN: not %clang_cc1 -fsyntax-only -triple i386-

[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.

2018-01-04 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd added a comment.

Looking over this patch again, I think I really would prefer that this was 
split up into two patches.  The first one should be entirely mechanical, 
replacing `n64` with `newabi`.  The second patch would actually make the 
changes that you are are after.  That would really help with focusing what the 
issue here actually is.  I don't see anything technically that is an issue (I 
admit I didn't verify the sizes, but the assertions should hopefully catch 
that).  Beyond that split up, Id like to get a signoff from @sdardis for the 
MIPS specific bits, but from the libunwind side, LGTM.


https://reviews.llvm.org/D39074



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


[PATCH] D41751: [analyzer] [NFS] Minor refactoring of trackNullOrUndefValue

2018-01-04 Thread George Karpenkov via Phabricator via cfe-commits
george.karpenkov created this revision.
george.karpenkov added reviewers: dcoughlin, NoQ.
Herald added subscribers: a.sidorin, szepet, xazax.hun.

Simple refactoring attempt: factor out some code, remove some repetition, use 
`auto` where appropriate.


https://reviews.llvm.org/D41751

Files:
  lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Index: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
===
--- lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -988,59 +988,89 @@
   return Ex;
 }
 
+/// Walk through nodes until we get one that matches the statement exactly.
+/// Alternately, if we hit a known lvalue for the statement, we know we've
+/// gone too far (though we can likely track the lvalue better anyway).
+static const ExplodedNode* findNodeForStatement(const ExplodedNode *N,
+const Stmt *S,
+const Expr *Inner) {
+  do {
+const ProgramPoint &pp = N->getLocation();
+if (auto ps = pp.getAs()) {
+  if (ps->getStmt() == S || ps->getStmt() == Inner)
+break;
+} else if (auto CEE = pp.getAs()) {
+  if (CEE->getCalleeContext()->getCallSite() == S ||
+  CEE->getCalleeContext()->getCallSite() == Inner)
+break;
+}
+N = N->getFirstPred();
+  } while (N);
+  return N;
+}
+
+/// Find the ExplodedNode where the lvalue (the value of 'Ex')
+/// was computed.
+static const ExplodedNode* findNodeForExpression(const ExplodedNode *N,
+const Expr *Inner) {
+  while (N) {
+if (auto P = N->getLocation().getAs()) {
+  if (P->getStmt() == Inner)
+break;
+}
+N = N->getFirstPred();
+  }
+  assert(N && "Unable to find the lvalue node.");
+  return N;
+
+}
+
+/// Performing operator `&' on an lvalue expression is essentially a no-op.
+/// Then, if we are taking addresses of fields or elements, these are also
+/// unlikely to matter.
+static const Expr* peelOfOuterAddrOf(const Expr* Ex) {
+  Ex = Ex->IgnoreParenCasts();
+
+  // FIXME: There's a hack in our Store implementation that always computes
+  // field offsets around null pointers as if they are always equal to 0.
+  // The idea here is to report accesses to fields as null dereferences
+  // even though the pointer value that's being dereferenced is actually
+  // the offset of the field rather than exactly 0.
+  // See the FIXME in StoreManager's getLValueFieldOrIvar() method.
+  // This code interacts heavily with this hack; otherwise the value
+  // would not be null at all for most fields, so we'd be unable to track it.
+  if (const auto *Op = dyn_cast(Ex))
+if (Op->getOpcode() == UO_AddrOf && Op->getSubExpr()->isLValue())
+  if (const Expr *DerefEx = bugreporter::getDerefExpr(Op->getSubExpr()))
+return DerefEx;
+  return Ex;
+
+}
+
 bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
 const Stmt *S,
 BugReport &report, bool IsArg,
 bool EnableNullFPSuppression) {
   if (!S || !N)
 return false;
 
-  if (const Expr *Ex = dyn_cast(S))
+  if (const auto *Ex = dyn_cast(S))
 S = peelOffOuterExpr(Ex, N);
 
   const Expr *Inner = nullptr;
-  if (const Expr *Ex = dyn_cast(S)) {
+  if (const auto *Ex = dyn_cast(S)) {
+Ex = peelOfOuterAddrOf(Ex);
 Ex = Ex->IgnoreParenCasts();
 
-// Performing operator `&' on an lvalue expression is essentially a no-op.
-// Then, if we are taking addresses of fields or elements, these are also
-// unlikely to matter.
-// FIXME: There's a hack in our Store implementation that always computes
-// field offsets around null pointers as if they are always equal to 0.
-// The idea here is to report accesses to fields as null dereferences
-// even though the pointer value that's being dereferenced is actually
-// the offset of the field rather than exactly 0.
-// See the FIXME in StoreManager's getLValueFieldOrIvar() method.
-// This code interacts heavily with this hack; otherwise the value
-// would not be null at all for most fields, so we'd be unable to track it.
-if (const auto *Op = dyn_cast(Ex))
-  if (Op->getOpcode() == UO_AddrOf && Op->getSubExpr()->isLValue())
-if (const Expr *DerefEx = getDerefExpr(Op->getSubExpr()))
-  Ex = DerefEx;
-
-if (Ex && (ExplodedGraph::isInterestingLValueExpr(Ex) || CallEvent::isCallStmt(Ex)))
+if (Ex && (ExplodedGraph::isInterestingLValueExpr(Ex)
+  || CallEvent::isCallStmt(Ex)))
   Inner = Ex;
   }
 
   if (IsArg && !Inner) {
 assert(N->getLocation().getAs() && "Tracking arg but not at call");
   } else {
-// Walk through nodes until we get one that matches the statement exactly.
-// Alternately, if we hit a known lvalue for the statement, we know we've
-// gone t

[PATCH] D41754: [CMake] Collect target names in the global LLVM_RUNTIMES property

2018-01-04 Thread Petr Hosek via Phabricator via cfe-commits
phosek created this revision.
phosek added a reviewer: beanz.
Herald added subscribers: cfe-commits, mgorny.

This allows exporting the runtimes targets using the CMake export.


Repository:
  rCXXA libc++abi

https://reviews.llvm.org/D41754

Files:
  src/CMakeLists.txt


Index: src/CMakeLists.txt
===
--- src/CMakeLists.txt
+++ src/CMakeLists.txt
@@ -184,6 +184,7 @@
 LIBRARY DESTINATION 
${LIBCXXABI_INSTALL_PREFIX}lib${LIBCXXABI_LIBDIR_SUFFIX} COMPONENT cxxabi
 ARCHIVE DESTINATION 
${LIBCXXABI_INSTALL_PREFIX}lib${LIBCXXABI_LIBDIR_SUFFIX} COMPONENT cxxabi
 )
+  set_property(GLOBAL APPEND PROPERTY LLVM_RUNTIMES ${LIBCXXABI_TARGETS})
 endif()
 
 if (NOT CMAKE_CONFIGURATION_TYPES AND LIBCXXABI_INSTALL_LIBRARY)


Index: src/CMakeLists.txt
===
--- src/CMakeLists.txt
+++ src/CMakeLists.txt
@@ -184,6 +184,7 @@
 LIBRARY DESTINATION ${LIBCXXABI_INSTALL_PREFIX}lib${LIBCXXABI_LIBDIR_SUFFIX} COMPONENT cxxabi
 ARCHIVE DESTINATION ${LIBCXXABI_INSTALL_PREFIX}lib${LIBCXXABI_LIBDIR_SUFFIX} COMPONENT cxxabi
 )
+  set_property(GLOBAL APPEND PROPERTY LLVM_RUNTIMES ${LIBCXXABI_TARGETS})
 endif()
 
 if (NOT CMAKE_CONFIGURATION_TYPES AND LIBCXXABI_INSTALL_LIBRARY)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41755: [CMake] Collect target names in the global LLVM_RUNTIMES property

2018-01-04 Thread Petr Hosek via Phabricator via cfe-commits
phosek created this revision.
phosek added a reviewer: beanz.
Herald added subscribers: cfe-commits, mgorny.

This allows exporting the runtimes targets using the CMake export.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41755

Files:
  lib/CMakeLists.txt


Index: lib/CMakeLists.txt
===
--- lib/CMakeLists.txt
+++ lib/CMakeLists.txt
@@ -360,6 +360,7 @@
 LIBRARY DESTINATION ${LIBCXX_INSTALL_PREFIX}lib${LIBCXX_LIBDIR_SUFFIX} 
COMPONENT cxx
 ARCHIVE DESTINATION ${LIBCXX_INSTALL_PREFIX}lib${LIBCXX_LIBDIR_SUFFIX} 
COMPONENT cxx
 )
+  set_property(GLOBAL APPEND PROPERTY LLVM_RUNTIMES ${LIBCXX_TARGETS} 
${experimental_lib})
   # NOTE: This install command must go after the cxx install command otherwise
   # it will not be executed after the library symlinks are installed.
   if (LIBCXX_ENABLE_SHARED AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT)


Index: lib/CMakeLists.txt
===
--- lib/CMakeLists.txt
+++ lib/CMakeLists.txt
@@ -360,6 +360,7 @@
 LIBRARY DESTINATION ${LIBCXX_INSTALL_PREFIX}lib${LIBCXX_LIBDIR_SUFFIX} COMPONENT cxx
 ARCHIVE DESTINATION ${LIBCXX_INSTALL_PREFIX}lib${LIBCXX_LIBDIR_SUFFIX} COMPONENT cxx
 )
+  set_property(GLOBAL APPEND PROPERTY LLVM_RUNTIMES ${LIBCXX_TARGETS} ${experimental_lib})
   # NOTE: This install command must go after the cxx install command otherwise
   # it will not be executed after the library symlinks are installed.
   if (LIBCXX_ENABLE_SHARED AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   >