r305272 - clang-format: add option to merge empty function body
Author: typz Date: Tue Jun 13 02:02:43 2017 New Revision: 305272 URL: http://llvm.org/viewvc/llvm-project?rev=305272&view=rev Log: clang-format: add option to merge empty function body Summary: This option supplements the AllowShortFunctionsOnASingleLine flag, to merge empty function body at the beginning of the line: e.g. when the function is not short-enough and breaking braces after function. int f() {} Reviewers: krasimir, djasper Reviewed By: djasper Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D33447 Modified: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=305272&r1=305271&r2=305272&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Tue Jun 13 02:02:43 2017 @@ -688,6 +688,18 @@ struct FormatStyle { bool BeforeElse; /// \brief Indent the wrapped braces themselves. bool IndentBraces; +/// \brief If ``false``, empty function body can be put on a single line. +/// This option is used only if the opening brace of the function has +/// already been wrapped, i.e. the `AfterFunction` brace wrapping mode is +/// set, and the function could/should not be put on a single line (as per +/// `AllowShortFunctionsOnASingleLine` and constructor formatting options). +/// \code +/// int f() vs. inf f() +/// {} { +/// } +/// \endcode +/// +bool SplitEmptyFunctionBody; }; /// \brief Control of individual brace wrapping cases. Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=305272&r1=305271&r2=305272&view=diff == --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Tue Jun 13 02:02:43 2017 @@ -410,6 +410,7 @@ template <> struct MappingTraitshttp://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=305272&r1=305271&r2=305272&view=diff == --- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Tue Jun 13 02:02:43 2017 @@ -186,6 +186,12 @@ private: ? 0 : Limit - TheLine->Last->TotalLength; +if (TheLine->Last->is(TT_FunctionLBrace) && +TheLine->First == TheLine->Last && +!Style.BraceWrapping.SplitEmptyFunctionBody && +I[1]->First->is(tok::r_brace)) + return tryMergeSimpleBlock(I, E, Limit); + // FIXME: TheLine->Level != 0 might or might not be the right check to do. // If necessary, change to something smarter. bool MergeShortFunctions = @@ -215,7 +221,10 @@ private: Limit -= 2; unsigned MergedLines = 0; - if (MergeShortFunctions) { + if (MergeShortFunctions || + (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty && + I[1]->First == I[1]->Last && I + 2 != E && + I[2]->First->is(tok::r_brace))) { MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); // If we managed to merge the block, count the function header, which is // on a separate line. Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=305272&r1=305271&r2=305272&view=diff == --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Tue Jun 13 02:02:43 2017 @@ -6239,6 +6239,35 @@ TEST_F(FormatTest, PullTrivialFunctionDe getLLVMStyleWithColumns(23)); } +TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) { + FormatStyle MergeEmptyOnly = getLLVMStyle(); + MergeEmptyOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; + verifyFormat("class C {\n" + " int f() {}\n" + "};", + MergeEmptyOnly); + verifyFormat("class C {\n" + " int f() {\n" + "return 42;\n" + " }\n" + "};", + MergeEmptyOnly); + verifyFormat("int f() {}", MergeEmptyOnly); + verifyFormat("int f() {\n" + " return 42;\n" + "}", + MergeEmptyOnly); + + // Also verify behavior when BraceWrapping.AfterFunction = true + MergeEmptyOnly.BreakBeforeBraces = FormatStyle::BS_Custom; + MergeEmptyOnly.BraceWrapping.AfterFunction = true; + verify
[PATCH] D33447: clang-format: add option to merge empty function body
This revision was automatically updated to reflect the committed changes. Closed by commit rL305272: clang-format: add option to merge empty function body (authored by Typz). Changed prior to commit: https://reviews.llvm.org/D33447?vs=100420&id=102294#toc Repository: rL LLVM https://reviews.llvm.org/D33447 Files: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp cfe/trunk/unittests/Format/FormatTest.cpp Index: cfe/trunk/include/clang/Format/Format.h === --- cfe/trunk/include/clang/Format/Format.h +++ cfe/trunk/include/clang/Format/Format.h @@ -688,6 +688,18 @@ bool BeforeElse; /// \brief Indent the wrapped braces themselves. bool IndentBraces; +/// \brief If ``false``, empty function body can be put on a single line. +/// This option is used only if the opening brace of the function has +/// already been wrapped, i.e. the `AfterFunction` brace wrapping mode is +/// set, and the function could/should not be put on a single line (as per +/// `AllowShortFunctionsOnASingleLine` and constructor formatting options). +/// \code +/// int f() vs. inf f() +/// {} { +/// } +/// \endcode +/// +bool SplitEmptyFunctionBody; }; /// \brief Control of individual brace wrapping cases. Index: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp === --- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp +++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp @@ -186,6 +186,12 @@ ? 0 : Limit - TheLine->Last->TotalLength; +if (TheLine->Last->is(TT_FunctionLBrace) && +TheLine->First == TheLine->Last && +!Style.BraceWrapping.SplitEmptyFunctionBody && +I[1]->First->is(tok::r_brace)) + return tryMergeSimpleBlock(I, E, Limit); + // FIXME: TheLine->Level != 0 might or might not be the right check to do. // If necessary, change to something smarter. bool MergeShortFunctions = @@ -215,7 +221,10 @@ Limit -= 2; unsigned MergedLines = 0; - if (MergeShortFunctions) { + if (MergeShortFunctions || + (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty && + I[1]->First == I[1]->Last && I + 2 != E && + I[2]->First->is(tok::r_brace))) { MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); // If we managed to merge the block, count the function header, which is // on a separate line. Index: cfe/trunk/lib/Format/Format.cpp === --- cfe/trunk/lib/Format/Format.cpp +++ cfe/trunk/lib/Format/Format.cpp @@ -410,6 +410,7 @@ IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch); IO.mapOptional("BeforeElse", Wrapping.BeforeElse); IO.mapOptional("IndentBraces", Wrapping.IndentBraces); +IO.mapOptional("SplitEmptyFunctionBody", Wrapping.SplitEmptyFunctionBody); } }; @@ -485,7 +486,7 @@ return Style; FormatStyle Expanded = Style; Expanded.BraceWrapping = {false, false, false, false, false, false, -false, false, false, false, false}; +false, false, false, false, false, true}; switch (Style.BreakBeforeBraces) { case FormatStyle::BS_Linux: Expanded.BraceWrapping.AfterClass = true; @@ -498,6 +499,7 @@ Expanded.BraceWrapping.AfterFunction = true; Expanded.BraceWrapping.AfterStruct = true; Expanded.BraceWrapping.AfterUnion = true; +Expanded.BraceWrapping.SplitEmptyFunctionBody = false; break; case FormatStyle::BS_Stroustrup: Expanded.BraceWrapping.AfterFunction = true; @@ -517,7 +519,7 @@ break; case FormatStyle::BS_GNU: Expanded.BraceWrapping = {true, true, true, true, true, true, - true, true, true, true, true}; + true, true, true, true, true, true}; break; case FormatStyle::BS_WebKit: Expanded.BraceWrapping.AfterFunction = true; @@ -554,7 +556,7 @@ LLVMStyle.BreakBeforeTernaryOperators = true; LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; LLVMStyle.BraceWrapping = {false, false, false, false, false, false, - false, false, false, false, false}; + false, false, false, false, false, true}; LLVMStyle.BreakAfterJavaFieldAnnotations = false; LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; LLVMStyle.BreakBeforeInheritanceComma = false; Index: cfe/trunk/unittests/Format/FormatTest.cpp === --- cfe/trunk/unittests/Format/FormatTest.cpp +++ cfe/trunk/unittests/Format/FormatTest.cpp @@ -6239,6 +6239,35 @@ getLLVMStyleWithColumns(23))
[PATCH] D34052: [XRay][clang] Support capturing the implicit `this` argument to C++ class member functions
dberris added a comment. In https://reviews.llvm.org/D34052#778670, @dblaikie wrote: > I take it there's already handling for these attributes on non-member > functions? Yes, we're just extending it to also apply to the case where it doesn't support this one case where we actually do need the implicit this argument > There's probably a reason this code can't be wherever that code is & subtract > one from the index? (reducing code duplication by having all the error > handling, etc, in one place/once) I tried doing it for the `checkFunctionOrMethodNumParams` function, but it ended up being much more complicated. :( The choice is between adding a bool argument (e.g. AllowImplicitThis) in `checkFunctionOrMethodParameterIndex(...)` that's default to always true (to preserve existing behaviour) but the checks and implementation of that template has a number of assumptions as to whether the index is valid for member functions. I can change this so that the logic is contained in `checkFunctionOrMethodParameterIndex(...)` if that's more readable? https://reviews.llvm.org/D34052 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32480: clang-format: Add CompactNamespaces option
djasper added a comment. Ok. Works for me. https://reviews.llvm.org/D32480 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D34052: [XRay][clang] Support capturing the implicit `this` argument to C++ class member functions
hard to say if it's more readable without seeing it - if you could attach a patch, if it's easy enough/you worked it up before, might be worth comparing/contrasting On Tue, Jun 13, 2017 at 12:28 AM Dean Michael Berris via Phabricator < revi...@reviews.llvm.org> wrote: > dberris added a comment. > > In https://reviews.llvm.org/D34052#778670, @dblaikie wrote: > > > I take it there's already handling for these attributes on non-member > functions? > > > Yes, we're just extending it to also apply to the case where it doesn't > support this one case where we actually do need the implicit this argument > > > There's probably a reason this code can't be wherever that code is & > subtract one from the index? (reducing code duplication by having all the > error handling, etc, in one place/once) > > I tried doing it for the `checkFunctionOrMethodNumParams` function, but it > ended up being much more complicated. :( > > The choice is between adding a bool argument (e.g. AllowImplicitThis) in > `checkFunctionOrMethodParameterIndex(...)` that's default to always true > (to preserve existing behaviour) but the checks and implementation of that > template has a number of assumptions as to whether the index is valid for > member functions. > > I can change this so that the logic is contained in > `checkFunctionOrMethodParameterIndex(...)` if that's more readable? > > > https://reviews.llvm.org/D34052 > > > > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxxabi] r305278 - Set a default value for LIBCXXABI_LIBDIR_SUFFIX, fixes installing into lib64 after r304374
Author: ismail Date: Tue Jun 13 03:16:44 2017 New Revision: 305278 URL: http://llvm.org/viewvc/llvm-project?rev=305278&view=rev Log: Set a default value for LIBCXXABI_LIBDIR_SUFFIX, fixes installing into lib64 after r304374 Modified: libcxxabi/trunk/CMakeLists.txt Modified: libcxxabi/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/CMakeLists.txt?rev=305278&r1=305277&r2=305278&view=diff == --- libcxxabi/trunk/CMakeLists.txt (original) +++ libcxxabi/trunk/CMakeLists.txt Tue Jun 13 03:16:44 2017 @@ -67,6 +67,8 @@ option(LIBCXXABI_ENABLE_NEW_DELETE_DEFIN provides these definitions" ON) option(LIBCXXABI_BUILD_32_BITS "Build 32 bit libc++abi." ${LLVM_BUILD_32_BITS}) option(LIBCXXABI_INCLUDE_TESTS "Generate build targets for the libc++abi unit tests." ${LLVM_INCLUDE_TESTS}) +set(LIBCXXABI_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING +"Define suffix of library directory name (32/64)") set(LIBCXXABI_TARGET_TRIPLE "" CACHE STRING "Target triple for cross compiling.") set(LIBCXXABI_GCC_TOOLCHAIN "" CACHE PATH "GCC toolchain for cross compiling.") set(LIBCXXABI_SYSROOT "" CACHE PATH "Sysroot for cross compiling.") ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r305279 - [clangd] Use 'std::string' for VFSTag instead of 'int'
Author: ibiryukov Date: Tue Jun 13 03:24:48 2017 New Revision: 305279 URL: http://llvm.org/viewvc/llvm-project?rev=305279&view=rev Log: [clangd] Use 'std::string' for VFSTag instead of 'int' Reviewers: krasimir Reviewed By: krasimir Subscribers: klimek, cfe-commits Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D34106 Modified: clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Modified: clang-tools-extra/trunk/clangd/ClangdServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=305279&r1=305278&r2=305279&view=diff == --- clang-tools-extra/trunk/clangd/ClangdServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.h Tue Jun 13 03:24:48 2017 @@ -43,20 +43,22 @@ size_t positionToOffset(StringRef Code, Position offsetToPosition(StringRef Code, size_t Offset); /// A tag supplied by the FileSytemProvider. -typedef int VFSTag; +typedef std::string VFSTag; /// A value of an arbitrary type and VFSTag that was supplied by the /// FileSystemProvider when this value was computed. template class Tagged { public: template - Tagged(U &&Value, VFSTag Tag) : Value(std::forward(Value)), Tag(Tag) {} + Tagged(U &&Value, VFSTag Tag) + : Value(std::forward(Value)), Tag(std::move(Tag)) {} template Tagged(const Tagged &Other) : Value(Other.Value), Tag(Other.Tag) {} template - Tagged(Tagged &&Other) : Value(std::move(Other.Value)), Tag(Other.Tag) {} + Tagged(Tagged &&Other) + : Value(std::move(Other.Value)), Tag(std::move(Other.Tag)) {} T Value; VFSTag Tag; Modified: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp?rev=305279&r1=305278&r2=305279&view=diff == --- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Tue Jun 13 03:24:48 2017 @@ -386,13 +386,13 @@ TEST_F(ClangdVFSTest, CheckVersions) { auto FooCpp = getVirtualTestFilePath("foo.cpp"); const auto SourceContents = "int a;"; FS->Files[FooCpp] = SourceContents; - FS->Tag = 123; + FS->Tag = "123"; Server.addDocument(FooCpp, SourceContents); EXPECT_EQ(DiagConsumer->lastVFSTag(), FS->Tag); EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); - FS->Tag = 321; + FS->Tag = "321"; Server.addDocument(FooCpp, SourceContents); EXPECT_EQ(DiagConsumer->lastVFSTag(), FS->Tag); EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34106: [clangd] Use 'std::string' for VFSTag instead of 'int'
This revision was automatically updated to reflect the committed changes. Closed by commit rL305279: [clangd] Use 'std::string' for VFSTag instead of 'int' (authored by ibiryukov). Changed prior to commit: https://reviews.llvm.org/D34106?vs=102189&id=102298#toc Repository: rL LLVM https://reviews.llvm.org/D34106 Files: clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Index: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp === --- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp @@ -386,13 +386,13 @@ auto FooCpp = getVirtualTestFilePath("foo.cpp"); const auto SourceContents = "int a;"; FS->Files[FooCpp] = SourceContents; - FS->Tag = 123; + FS->Tag = "123"; Server.addDocument(FooCpp, SourceContents); EXPECT_EQ(DiagConsumer->lastVFSTag(), FS->Tag); EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); - FS->Tag = 321; + FS->Tag = "321"; Server.addDocument(FooCpp, SourceContents); EXPECT_EQ(DiagConsumer->lastVFSTag(), FS->Tag); EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); Index: clang-tools-extra/trunk/clangd/ClangdServer.h === --- clang-tools-extra/trunk/clangd/ClangdServer.h +++ clang-tools-extra/trunk/clangd/ClangdServer.h @@ -43,20 +43,22 @@ Position offsetToPosition(StringRef Code, size_t Offset); /// A tag supplied by the FileSytemProvider. -typedef int VFSTag; +typedef std::string VFSTag; /// A value of an arbitrary type and VFSTag that was supplied by the /// FileSystemProvider when this value was computed. template class Tagged { public: template - Tagged(U &&Value, VFSTag Tag) : Value(std::forward(Value)), Tag(Tag) {} + Tagged(U &&Value, VFSTag Tag) + : Value(std::forward(Value)), Tag(std::move(Tag)) {} template Tagged(const Tagged &Other) : Value(Other.Value), Tag(Other.Tag) {} template - Tagged(Tagged &&Other) : Value(std::move(Other.Value)), Tag(Other.Tag) {} + Tagged(Tagged &&Other) + : Value(std::move(Other.Value)), Tag(std::move(Other.Tag)) {} T Value; VFSTag Tag; Index: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp === --- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp @@ -386,13 +386,13 @@ auto FooCpp = getVirtualTestFilePath("foo.cpp"); const auto SourceContents = "int a;"; FS->Files[FooCpp] = SourceContents; - FS->Tag = 123; + FS->Tag = "123"; Server.addDocument(FooCpp, SourceContents); EXPECT_EQ(DiagConsumer->lastVFSTag(), FS->Tag); EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); - FS->Tag = 321; + FS->Tag = "321"; Server.addDocument(FooCpp, SourceContents); EXPECT_EQ(DiagConsumer->lastVFSTag(), FS->Tag); EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); Index: clang-tools-extra/trunk/clangd/ClangdServer.h === --- clang-tools-extra/trunk/clangd/ClangdServer.h +++ clang-tools-extra/trunk/clangd/ClangdServer.h @@ -43,20 +43,22 @@ Position offsetToPosition(StringRef Code, size_t Offset); /// A tag supplied by the FileSytemProvider. -typedef int VFSTag; +typedef std::string VFSTag; /// A value of an arbitrary type and VFSTag that was supplied by the /// FileSystemProvider when this value was computed. template class Tagged { public: template - Tagged(U &&Value, VFSTag Tag) : Value(std::forward(Value)), Tag(Tag) {} + Tagged(U &&Value, VFSTag Tag) + : Value(std::forward(Value)), Tag(std::move(Tag)) {} template Tagged(const Tagged &Other) : Value(Other.Value), Tag(Other.Tag) {} template - Tagged(Tagged &&Other) : Value(std::move(Other.Value)), Tag(Other.Tag) {} + Tagged(Tagged &&Other) + : Value(std::move(Other.Value)), Tag(std::move(Other.Tag)) {} T Value; VFSTag Tag; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34107: [clangd] Allow to override contents of the file during completion.
ilya-biryukov updated this revision to Diff 102300. ilya-biryukov marked 2 inline comments as done. ilya-biryukov added a comment. Fixed formatting, added a space (see krasimir's comment) https://reviews.llvm.org/D34107 Files: clangd/ClangdServer.cpp clangd/ClangdServer.h unittests/clangd/ClangdTests.cpp Index: unittests/clangd/ClangdTests.cpp === --- unittests/clangd/ClangdTests.cpp +++ unittests/clangd/ClangdTests.cpp @@ -398,5 +398,69 @@ EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); } +class ClangdCompletionTest : public ClangdVFSTest { +protected: + bool ContainsItem(std::vector const &Items, StringRef Name) { +for (const auto &Item : Items) { + if (Item.insertText == Name) +return true; +} +return false; + } +}; + +TEST_F(ClangdCompletionTest, CheckContentsOverride) { + MockFSProvider *FS; + + ClangdServer Server(llvm::make_unique(), + llvm::make_unique(), + getAndMove(llvm::make_unique(), FS), + /*RunSynchronously=*/false); + + auto FooCpp = getVirtualTestFilePath("foo.cpp"); + const auto SourceContents = R"cpp( +int aba; +int b = ; +)cpp"; + + const auto OverridenSourceContents = R"cpp( +int cbc; +int b = ; +)cpp"; + // Complete after '=' sign. We need to be careful to keep the SourceContents' + // size the same. + // We complete on the 3rd line (2nd in zero-based numbering), because raw + // string literal of the SourceContents starts with a newline(it's easy to + // miss). + Position CompletePos = {2, 8}; + FS->Files[FooCpp] = SourceContents; + + Server.addDocument(FooCpp, SourceContents); + + { +auto CodeCompletionResults1 = +Server.codeComplete(FooCpp, CompletePos, None).Value; +EXPECT_TRUE(ContainsItem(CodeCompletionResults1, "aba")); +EXPECT_FALSE(ContainsItem(CodeCompletionResults1, "cbc")); + } + + { +auto CodeCompletionResultsOverriden = +Server +.codeComplete(FooCpp, CompletePos, + StringRef(OverridenSourceContents)) +.Value; +EXPECT_TRUE(ContainsItem(CodeCompletionResultsOverriden, "cbc")); +EXPECT_FALSE(ContainsItem(CodeCompletionResultsOverriden, "aba")); + } + + { +auto CodeCompletionResults2 = +Server.codeComplete(FooCpp, CompletePos, None).Value; +EXPECT_TRUE(ContainsItem(CodeCompletionResults2, "aba")); +EXPECT_FALSE(ContainsItem(CodeCompletionResults2, "cbc")); + } +} + } // namespace clangd } // namespace clang Index: clangd/ClangdServer.h === --- clangd/ClangdServer.h +++ clangd/ClangdServer.h @@ -150,8 +150,15 @@ /// Force \p File to be reparsed using the latest contents. void forceReparse(PathRef File); - /// Run code completion for \p File at \p Pos. - Tagged> codeComplete(PathRef File, Position Pos); + /// Run code completion for \p File at \p Pos. If \p OverridenContents is not + /// None, they will used only for code completion, i.e. no diagnostics update + /// will be scheduled and a draft for \p File will not be updated. + /// If \p OverridenContents is None, contents of the current draft for \p File + /// will be used. + /// This method should only be called for currently tracked files. + Tagged> + codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents = llvm::None); /// Run formatting for \p Rng inside \p File. std::vector formatRange(PathRef File, Range Rng); Index: clangd/ClangdServer.cpp === --- clangd/ClangdServer.cpp +++ clangd/ClangdServer.cpp @@ -184,17 +184,27 @@ addDocument(File, getDocument(File)); } -Tagged> ClangdServer::codeComplete(PathRef File, - Position Pos) { - auto FileContents = DraftMgr.getDraft(File); - assert(FileContents.Draft && "codeComplete is called for non-added document"); +Tagged> +ClangdServer::codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents) { + if (!OverridenContents) { +auto FileContents = DraftMgr.getDraft(File); +assert(FileContents.Draft && + "codeComplete is called for non-added document"); + +OverridenContents = *FileContents.Draft; + } std::vector Result; auto TaggedFS = FSProvider->getTaggedFileSystem(); - Units.runOnUnitWithoutReparse( - File, *FileContents.Draft, *CDB, PCHs, TaggedFS.Value, [&](ClangdUnit &Unit) { -Result = Unit.codeComplete(*FileContents.Draft, Pos, TaggedFS.Value); - }); + // It would be nice to use runOnUnitWithoutReparse here, but we can't + // guarantee the correctness of code completion cache here if we don't do the + // reparse. + Units.runOnUnit(File, *OverridenContents, *CDB, PCHs, TaggedFS.Value, + [&
[PATCH] D34107: [clangd] Allow to override contents of the file during completion.
ilya-biryukov added inline comments. Comment at: unittests/clangd/ClangdTests.cpp:452 + StringRef(OverridenSourceContents)) +.Value; +EXPECT_TRUE(ContainsItem(CodeCompletionResultsOverriden, "cbc")); krasimir wrote: > Is this how clang-format formats this chain? :( Yes :'( https://reviews.llvm.org/D34107 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34107: [clangd] Allow to override contents of the file during completion.
This revision was automatically updated to reflect the committed changes. Closed by commit rL305280: [clangd] Allow to override contents of the file during completion. (authored by ibiryukov). Changed prior to commit: https://reviews.llvm.org/D34107?vs=102300&id=102301#toc Repository: rL LLVM https://reviews.llvm.org/D34107 Files: clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Index: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp === --- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp @@ -398,5 +398,69 @@ EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); } +class ClangdCompletionTest : public ClangdVFSTest { +protected: + bool ContainsItem(std::vector const &Items, StringRef Name) { +for (const auto &Item : Items) { + if (Item.insertText == Name) +return true; +} +return false; + } +}; + +TEST_F(ClangdCompletionTest, CheckContentsOverride) { + MockFSProvider *FS; + + ClangdServer Server(llvm::make_unique(), + llvm::make_unique(), + getAndMove(llvm::make_unique(), FS), + /*RunSynchronously=*/false); + + auto FooCpp = getVirtualTestFilePath("foo.cpp"); + const auto SourceContents = R"cpp( +int aba; +int b = ; +)cpp"; + + const auto OverridenSourceContents = R"cpp( +int cbc; +int b = ; +)cpp"; + // Complete after '=' sign. We need to be careful to keep the SourceContents' + // size the same. + // We complete on the 3rd line (2nd in zero-based numbering), because raw + // string literal of the SourceContents starts with a newline(it's easy to + // miss). + Position CompletePos = {2, 8}; + FS->Files[FooCpp] = SourceContents; + + Server.addDocument(FooCpp, SourceContents); + + { +auto CodeCompletionResults1 = +Server.codeComplete(FooCpp, CompletePos, None).Value; +EXPECT_TRUE(ContainsItem(CodeCompletionResults1, "aba")); +EXPECT_FALSE(ContainsItem(CodeCompletionResults1, "cbc")); + } + + { +auto CodeCompletionResultsOverriden = +Server +.codeComplete(FooCpp, CompletePos, + StringRef(OverridenSourceContents)) +.Value; +EXPECT_TRUE(ContainsItem(CodeCompletionResultsOverriden, "cbc")); +EXPECT_FALSE(ContainsItem(CodeCompletionResultsOverriden, "aba")); + } + + { +auto CodeCompletionResults2 = +Server.codeComplete(FooCpp, CompletePos, None).Value; +EXPECT_TRUE(ContainsItem(CodeCompletionResults2, "aba")); +EXPECT_FALSE(ContainsItem(CodeCompletionResults2, "cbc")); + } +} + } // namespace clangd } // namespace clang Index: clang-tools-extra/trunk/clangd/ClangdServer.h === --- clang-tools-extra/trunk/clangd/ClangdServer.h +++ clang-tools-extra/trunk/clangd/ClangdServer.h @@ -152,8 +152,15 @@ /// Force \p File to be reparsed using the latest contents. void forceReparse(PathRef File); - /// Run code completion for \p File at \p Pos. - Tagged> codeComplete(PathRef File, Position Pos); + /// Run code completion for \p File at \p Pos. If \p OverridenContents is not + /// None, they will used only for code completion, i.e. no diagnostics update + /// will be scheduled and a draft for \p File will not be updated. + /// If \p OverridenContents is None, contents of the current draft for \p File + /// will be used. + /// This method should only be called for currently tracked files. + Tagged> + codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents = llvm::None); /// Run formatting for \p Rng inside \p File. std::vector formatRange(PathRef File, Range Rng); Index: clang-tools-extra/trunk/clangd/ClangdServer.cpp === --- clang-tools-extra/trunk/clangd/ClangdServer.cpp +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp @@ -184,17 +184,27 @@ addDocument(File, getDocument(File)); } -Tagged> ClangdServer::codeComplete(PathRef File, - Position Pos) { - auto FileContents = DraftMgr.getDraft(File); - assert(FileContents.Draft && "codeComplete is called for non-added document"); +Tagged> +ClangdServer::codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents) { + if (!OverridenContents) { +auto FileContents = DraftMgr.getDraft(File); +assert(FileContents.Draft && + "codeComplete is called for non-added document"); + +OverridenContents = *FileContents.Draft; + } std::vector Result; auto TaggedFS = FSProvider->getTaggedFileSystem(); - Units.runOnUnitWithoutReparse( - File, *FileContents.Draft, *CDB,
[clang-tools-extra] r305280 - [clangd] Allow to override contents of the file during completion.
Author: ibiryukov Date: Tue Jun 13 03:32:27 2017 New Revision: 305280 URL: http://llvm.org/viewvc/llvm-project?rev=305280&view=rev Log: [clangd] Allow to override contents of the file during completion. Reviewers: krasimir Reviewed By: krasimir Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D34107 Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=305280&r1=305279&r2=305280&view=diff == --- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Tue Jun 13 03:32:27 2017 @@ -184,17 +184,27 @@ void ClangdServer::forceReparse(PathRef addDocument(File, getDocument(File)); } -Tagged> ClangdServer::codeComplete(PathRef File, - Position Pos) { - auto FileContents = DraftMgr.getDraft(File); - assert(FileContents.Draft && "codeComplete is called for non-added document"); +Tagged> +ClangdServer::codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents) { + if (!OverridenContents) { +auto FileContents = DraftMgr.getDraft(File); +assert(FileContents.Draft && + "codeComplete is called for non-added document"); + +OverridenContents = *FileContents.Draft; + } std::vector Result; auto TaggedFS = FSProvider->getTaggedFileSystem(); - Units.runOnUnitWithoutReparse( - File, *FileContents.Draft, *CDB, PCHs, TaggedFS.Value, [&](ClangdUnit &Unit) { -Result = Unit.codeComplete(*FileContents.Draft, Pos, TaggedFS.Value); - }); + // It would be nice to use runOnUnitWithoutReparse here, but we can't + // guarantee the correctness of code completion cache here if we don't do the + // reparse. + Units.runOnUnit(File, *OverridenContents, *CDB, PCHs, TaggedFS.Value, + [&](ClangdUnit &Unit) { +Result = Unit.codeComplete(*OverridenContents, Pos, + TaggedFS.Value); + }); return make_tagged(std::move(Result), TaggedFS.Tag); } Modified: clang-tools-extra/trunk/clangd/ClangdServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=305280&r1=305279&r2=305280&view=diff == --- clang-tools-extra/trunk/clangd/ClangdServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.h Tue Jun 13 03:32:27 2017 @@ -152,8 +152,15 @@ public: /// Force \p File to be reparsed using the latest contents. void forceReparse(PathRef File); - /// Run code completion for \p File at \p Pos. - Tagged> codeComplete(PathRef File, Position Pos); + /// Run code completion for \p File at \p Pos. If \p OverridenContents is not + /// None, they will used only for code completion, i.e. no diagnostics update + /// will be scheduled and a draft for \p File will not be updated. + /// If \p OverridenContents is None, contents of the current draft for \p File + /// will be used. + /// This method should only be called for currently tracked files. + Tagged> + codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents = llvm::None); /// Run formatting for \p Rng inside \p File. std::vector formatRange(PathRef File, Range Rng); Modified: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp?rev=305280&r1=305279&r2=305280&view=diff == --- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Tue Jun 13 03:32:27 2017 @@ -398,5 +398,69 @@ TEST_F(ClangdVFSTest, CheckVersions) { EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); } +class ClangdCompletionTest : public ClangdVFSTest { +protected: + bool ContainsItem(std::vector const &Items, StringRef Name) { +for (const auto &Item : Items) { + if (Item.insertText == Name) +return true; +} +return false; + } +}; + +TEST_F(ClangdCompletionTest, CheckContentsOverride) { + MockFSProvider *FS; + + ClangdServer Server(llvm::make_unique(), + llvm::make_unique(), + getAndMove(llvm::make_unique(), FS), + /*RunSynchronously=*/false); + + auto FooCpp = getVirtualTestFilePath("foo.cpp"); + const auto SourceContents = R"cpp( +int aba; +int b = ; +)cpp"; + + const auto OverridenSourceContents = R
[PATCH] D32942: [clang-tidy] readability-function-size: add NestingThreshold param.
malcolm.parsons added a comment. In https://reviews.llvm.org/D32942#777001, @lebedev.ri wrote: > Which makes sense, since in AST, they are nested: They're not nested in the formatting, so I don't think it makes sense. Repository: rL LLVM https://reviews.llvm.org/D32942 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33526: Fix spurious Wunused-lambda-capture warning
malcolm.parsons added a comment. I don't understand why init captures have this problem. The variable is defined within the context of the lambda, but it's not within the context of the templated method. Are you working around a bug somewhere else? Repository: rL LLVM https://reviews.llvm.org/D33526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32439: Fix for incorrect source position of dependent c'tor initializer (bug:26195)
Serge_Preis added a reviewer: arphaman. Serge_Preis added a comment. Hello, would you please review my small fix for incorrect source positions for certain entities. The changes were submitted more than a month ago and I understand you all are busy people, but I hope this review won't take long. Thank you, Serge. https://reviews.llvm.org/D32439 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32428: Fix for Itanium mangler issue with templates (bug: 31405)
Serge_Preis added a reviewer: rsmith. Serge_Preis added a comment. Would you please take a look into proposed minor changes to avoid mangler assertion in some template cases. https://reviews.llvm.org/D32428 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r305283 - Revert "[clangd] Allow to override contents of the file during completion."
Author: ibiryukov Date: Tue Jun 13 05:01:11 2017 New Revision: 305283 URL: http://llvm.org/viewvc/llvm-project?rev=305283&view=rev Log: Revert "[clangd] Allow to override contents of the file during completion." This caused buildbots failures, reverting until we'll find out what's wrong. Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=305283&r1=305282&r2=305283&view=diff == --- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Tue Jun 13 05:01:11 2017 @@ -184,27 +184,17 @@ void ClangdServer::forceReparse(PathRef addDocument(File, getDocument(File)); } -Tagged> -ClangdServer::codeComplete(PathRef File, Position Pos, - llvm::Optional OverridenContents) { - if (!OverridenContents) { -auto FileContents = DraftMgr.getDraft(File); -assert(FileContents.Draft && - "codeComplete is called for non-added document"); - -OverridenContents = *FileContents.Draft; - } +Tagged> ClangdServer::codeComplete(PathRef File, + Position Pos) { + auto FileContents = DraftMgr.getDraft(File); + assert(FileContents.Draft && "codeComplete is called for non-added document"); std::vector Result; auto TaggedFS = FSProvider->getTaggedFileSystem(); - // It would be nice to use runOnUnitWithoutReparse here, but we can't - // guarantee the correctness of code completion cache here if we don't do the - // reparse. - Units.runOnUnit(File, *OverridenContents, *CDB, PCHs, TaggedFS.Value, - [&](ClangdUnit &Unit) { -Result = Unit.codeComplete(*OverridenContents, Pos, - TaggedFS.Value); - }); + Units.runOnUnitWithoutReparse( + File, *FileContents.Draft, *CDB, PCHs, TaggedFS.Value, [&](ClangdUnit &Unit) { +Result = Unit.codeComplete(*FileContents.Draft, Pos, TaggedFS.Value); + }); return make_tagged(std::move(Result), TaggedFS.Tag); } Modified: clang-tools-extra/trunk/clangd/ClangdServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=305283&r1=305282&r2=305283&view=diff == --- clang-tools-extra/trunk/clangd/ClangdServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.h Tue Jun 13 05:01:11 2017 @@ -152,15 +152,8 @@ public: /// Force \p File to be reparsed using the latest contents. void forceReparse(PathRef File); - /// Run code completion for \p File at \p Pos. If \p OverridenContents is not - /// None, they will used only for code completion, i.e. no diagnostics update - /// will be scheduled and a draft for \p File will not be updated. - /// If \p OverridenContents is None, contents of the current draft for \p File - /// will be used. - /// This method should only be called for currently tracked files. - Tagged> - codeComplete(PathRef File, Position Pos, - llvm::Optional OverridenContents = llvm::None); + /// Run code completion for \p File at \p Pos. + Tagged> codeComplete(PathRef File, Position Pos); /// Run formatting for \p Rng inside \p File. std::vector formatRange(PathRef File, Range Rng); Modified: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp?rev=305283&r1=305282&r2=305283&view=diff == --- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Tue Jun 13 05:01:11 2017 @@ -398,69 +398,5 @@ TEST_F(ClangdVFSTest, CheckVersions) { EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); } -class ClangdCompletionTest : public ClangdVFSTest { -protected: - bool ContainsItem(std::vector const &Items, StringRef Name) { -for (const auto &Item : Items) { - if (Item.insertText == Name) -return true; -} -return false; - } -}; - -TEST_F(ClangdCompletionTest, CheckContentsOverride) { - MockFSProvider *FS; - - ClangdServer Server(llvm::make_unique(), - llvm::make_unique(), - getAndMove(llvm::make_unique(), FS), - /*RunSynchronously=*/false); - - auto FooCpp = getVirtualTestFilePath("foo.cpp"); - const auto SourceContents = R"cpp( -int aba; -int b = ; -)cpp"; - - const auto OverridenSourceContents = R"cpp( -int cbc; -int b = ; -)cpp"; - // Comp
[PATCH] D33526: Fix spurious Wunused-lambda-capture warning
kongyi added a comment. For normal captures, variables are safe to eliminate if they are non-ODR used or totally unused. However for init captures, non-ODR usage still depends on the capture; they are only safe to eliminate if totally unused. Repository: rL LLVM https://reviews.llvm.org/D33526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33526: Fix spurious Wunused-lambda-capture warning
malcolm.parsons accepted this revision. malcolm.parsons added a comment. This revision is now accepted and ready to land. LGTM! Repository: rL LLVM https://reviews.llvm.org/D33526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33852: Enable __declspec(selectany) on linux
Prazek added inline comments. Comment at: include/clang/Basic/Attr.td:2421 -def SelectAny : InheritableAttr, TargetSpecificAttr { +def SelectAny : InheritableAttr, TargetSpecificAttr { let Spellings = [Declspec<"selectany">, GCC<"selectany">]; rnk wrote: > davide wrote: > > Prazek wrote: > > > majnemer wrote: > > > > selectany should work on targets other than "x86", "x86_64", "arm", > > > > "thumb", etc. I think it is only necessary to require that it be a COFF > > > > or ELF target. > > > Should we allow other OSes than Win32 and Linux? > > I guess everything ELF should be allowed. > Why not use weak_odr / linkonce_odr on MachO? Microsoft builds Office for Mac > and I suspect they use `__declspec(selectany)`. I think this is what would happen right now. The question is - should we warn about using declspec on macho? Beause not using comdat looks like "not supporting" it, but I am not sure about it. https://reviews.llvm.org/D33852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33681: Allow function declaration with empty argument list.
bader updated this revision to Diff 102319. bader added a comment. Update one more test missed in the first version of the patch. Actually it looks like a bug in Parser. Clang interprets following statement as variable declaration. extern pipe write_only int get_pipe(); So the type of the pipe element is function prototype: `int get_pipe()`. If I understand the intention correctly, clang is expected to treat this expression function declaration with pipe return type, which elements are `int`. Would it acceptable to commit this patch as is and file another bug on Parser? I need more time to think how to resolve this ambiguity. https://reviews.llvm.org/D33681 Files: lib/Sema/SemaType.cpp test/SemaOpenCL/function-no-args.cl test/SemaOpenCL/invalid-pipes-cl2.0.cl Index: test/SemaOpenCL/invalid-pipes-cl2.0.cl === --- test/SemaOpenCL/invalid-pipes-cl2.0.cl +++ test/SemaOpenCL/invalid-pipes-cl2.0.cl @@ -3,7 +3,7 @@ global pipe int gp;// expected-error {{type '__global read_only pipe int' can only be used as a function parameter in OpenCL}} global reserve_id_t rid; // expected-error {{the '__global reserve_id_t' type cannot be used to declare a program scope variable}} -extern pipe write_only int get_pipe(); // expected-error {{type '__global write_only pipe int ()' can only be used as a function parameter in OpenCL}} +extern pipe write_only int get_pipe(); // expected-error {{type '__global write_only pipe int (void)' can only be used as a function parameter in OpenCL}} kernel void test_invalid_reserved_id(reserve_id_t ID) { // expected-error {{'reserve_id_t' cannot be used as the type of a kernel parameter}} } Index: test/SemaOpenCL/function-no-args.cl === --- /dev/null +++ test/SemaOpenCL/function-no-args.cl @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -verify -pedantic -fsyntax-only -cl-std=CL2.0 %s +// expected-no-diagnostics + +global int gi; +int my_func(); +int my_func() { + gi = 2; + return gi; +} Index: lib/Sema/SemaType.cpp === --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -4355,7 +4355,7 @@ FunctionType::ExtInfo EI(getCCForDeclaratorChunk(S, D, FTI, chunkIndex)); - if (!FTI.NumParams && !FTI.isVariadic && !LangOpts.CPlusPlus) { + if (!FTI.NumParams && !FTI.isVariadic && !LangOpts.CPlusPlus && !LangOpts.OpenCL) { // Simple void foo(), where the incoming T is the result type. T = Context.getFunctionNoProtoType(T, EI); } else { Index: test/SemaOpenCL/invalid-pipes-cl2.0.cl === --- test/SemaOpenCL/invalid-pipes-cl2.0.cl +++ test/SemaOpenCL/invalid-pipes-cl2.0.cl @@ -3,7 +3,7 @@ global pipe int gp;// expected-error {{type '__global read_only pipe int' can only be used as a function parameter in OpenCL}} global reserve_id_t rid; // expected-error {{the '__global reserve_id_t' type cannot be used to declare a program scope variable}} -extern pipe write_only int get_pipe(); // expected-error {{type '__global write_only pipe int ()' can only be used as a function parameter in OpenCL}} +extern pipe write_only int get_pipe(); // expected-error {{type '__global write_only pipe int (void)' can only be used as a function parameter in OpenCL}} kernel void test_invalid_reserved_id(reserve_id_t ID) { // expected-error {{'reserve_id_t' cannot be used as the type of a kernel parameter}} } Index: test/SemaOpenCL/function-no-args.cl === --- /dev/null +++ test/SemaOpenCL/function-no-args.cl @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -verify -pedantic -fsyntax-only -cl-std=CL2.0 %s +// expected-no-diagnostics + +global int gi; +int my_func(); +int my_func() { + gi = 2; + return gi; +} Index: lib/Sema/SemaType.cpp === --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -4355,7 +4355,7 @@ FunctionType::ExtInfo EI(getCCForDeclaratorChunk(S, D, FTI, chunkIndex)); - if (!FTI.NumParams && !FTI.isVariadic && !LangOpts.CPlusPlus) { + if (!FTI.NumParams && !FTI.isVariadic && !LangOpts.CPlusPlus && !LangOpts.OpenCL) { // Simple void foo(), where the incoming T is the result type. T = Context.getFunctionNoProtoType(T, EI); } else { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r305287 - Revert "Revert r301742 which made ExprConstant checking apply to all full-exprs."
Author: rovka Date: Tue Jun 13 07:50:06 2017 New Revision: 305287 URL: http://llvm.org/viewvc/llvm-project?rev=305287&view=rev Log: Revert "Revert r301742 which made ExprConstant checking apply to all full-exprs." This reverts commit r305239 because it broke the buildbots (the diag-flags.cpp test is failing). Modified: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/Sema/SemaChecking.cpp cfe/trunk/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp cfe/trunk/test/OpenMP/distribute_simd_aligned_messages.cpp cfe/trunk/test/OpenMP/for_simd_aligned_messages.cpp cfe/trunk/test/OpenMP/parallel_for_simd_aligned_messages.cpp cfe/trunk/test/OpenMP/simd_aligned_messages.cpp cfe/trunk/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp cfe/trunk/test/OpenMP/target_simd_aligned_messages.cpp cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_simd_aligned_messages.cpp cfe/trunk/test/OpenMP/target_teams_distribute_simd_aligned_messages.cpp cfe/trunk/test/OpenMP/taskloop_simd_aligned_messages.cpp cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_aligned_messages.cpp cfe/trunk/test/OpenMP/teams_distribute_simd_aligned_messages.cpp cfe/trunk/test/Sema/integer-overflow.c Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=305287&r1=305286&r2=305287&view=diff == --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Tue Jun 13 07:50:06 2017 @@ -10273,7 +10273,6 @@ private: void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS); void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation()); void CheckBoolLikeConversion(Expr *E, SourceLocation CC); - void CheckForIntOverflow(Expr *E); void CheckUnsequencedOperations(Expr *E); /// \brief Perform semantic checks on a completed expression. This will either Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=305287&r1=305286&r2=305287&view=diff == --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Jun 13 07:50:06 2017 @@ -6226,6 +6226,10 @@ bool RecordExprEvaluator::VisitInitListE // the initializer list. ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy : Field->getType()); const Expr *Init = HaveInit ? E->getInit(ElementNo++) : &VIE; +if (Init->isValueDependent()) { + Success = false; + continue; +} // Temporarily override This, in case there's a CXXDefaultInitExpr in here. ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This, @@ -9936,7 +9940,8 @@ static bool EvaluateAsRValue(EvalInfo &I } static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, - const ASTContext &Ctx, bool &IsConst) { + const ASTContext &Ctx, bool &IsConst, + bool IsCheckingForOverflow) { // Fast-path evaluations of integer literals, since we sometimes see files // containing vast quantities of these. if (const IntegerLiteral *L = dyn_cast(Exp)) { @@ -9957,7 +9962,7 @@ static bool FastEvaluateAsRValue(const E // performance problems. Only do so in C++11 for now. if (Exp->isRValue() && (Exp->getType()->isArrayType() || Exp->getType()->isRecordType()) && - !Ctx.getLangOpts().CPlusPlus11) { + !Ctx.getLangOpts().CPlusPlus11 && !IsCheckingForOverflow) { IsConst = false; return true; } @@ -9972,7 +9977,7 @@ static bool FastEvaluateAsRValue(const E /// will be applied to the result. bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const { bool IsConst; - if (FastEvaluateAsRValue(this, Result, Ctx, IsConst)) + if (FastEvaluateAsRValue(this, Result, Ctx, IsConst, false)) return IsConst; EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects); @@ -10097,7 +10102,7 @@ APSInt Expr::EvaluateKnownConstInt(const void Expr::EvaluateForOverflow(const ASTContext &Ctx) const { bool IsConst; EvalResult EvalResult; - if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst)) { + if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst, true)) { EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow); (void)::EvaluateAsRValue(Info, this, EvalResult.Val); } Modified: cfe/trunk/lib/Sema/SemaChecking.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=305287&r1=305286&r2=305287&view=diff == --- cfe/trunk/lib/Sema/SemaChecking.cpp (original) +++ cfe/trunk/lib/Sema/Sema
Re: r305239 - Revert r301742 which made ExprConstant checking apply to all full-exprs.
Hi, I reverted r305287, since the bots were red for a very long time. More bots with the same error: http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15-full/builds/7727 http://lab.llvm.org:8011/builders/clang-x86-windows-msvc2015/builds/5503 http://lab.llvm.org:8011/builders/clang-hexagon-elf/builds/9097 Cheers, Diana On 13 June 2017 at 07:12, NAKAMURA Takumi via cfe-commits wrote: > It triggered a test failure for targeting i686 (seems also for arm) > See also; http://bb.pgr.jp/builders/test-clang-i686-linux-RA/builds/3566 > > On Tue, Jun 13, 2017 at 6:59 AM Nick Lewycky via cfe-commits > wrote: >> >> Author: nicholas >> Date: Mon Jun 12 16:59:18 2017 >> New Revision: 305239 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=305239&view=rev >> Log: >> Revert r301742 which made ExprConstant checking apply to all full-exprs. >> >> This patch also exposed pre-existing bugs in clang, see PR32864 and >> PR33140#c3 . >> >> Modified: >> cfe/trunk/include/clang/Sema/Sema.h >> cfe/trunk/lib/AST/ExprConstant.cpp >> cfe/trunk/lib/Sema/SemaChecking.cpp >> >> cfe/trunk/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp >> cfe/trunk/test/OpenMP/distribute_simd_aligned_messages.cpp >> cfe/trunk/test/OpenMP/for_simd_aligned_messages.cpp >> cfe/trunk/test/OpenMP/parallel_for_simd_aligned_messages.cpp >> cfe/trunk/test/OpenMP/simd_aligned_messages.cpp >> cfe/trunk/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp >> cfe/trunk/test/OpenMP/target_simd_aligned_messages.cpp >> >> cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_simd_aligned_messages.cpp >> >> cfe/trunk/test/OpenMP/target_teams_distribute_simd_aligned_messages.cpp >> cfe/trunk/test/OpenMP/taskloop_simd_aligned_messages.cpp >> >> cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_aligned_messages.cpp >> cfe/trunk/test/OpenMP/teams_distribute_simd_aligned_messages.cpp >> cfe/trunk/test/Sema/integer-overflow.c >> >> Modified: cfe/trunk/include/clang/Sema/Sema.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=305239&r1=305238&r2=305239&view=diff >> >> == >> --- cfe/trunk/include/clang/Sema/Sema.h (original) >> +++ cfe/trunk/include/clang/Sema/Sema.h Mon Jun 12 16:59:18 2017 >> @@ -10273,6 +10273,7 @@ private: >>void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS); >>void CheckImplicitConversions(Expr *E, SourceLocation CC = >> SourceLocation()); >>void CheckBoolLikeConversion(Expr *E, SourceLocation CC); >> + void CheckForIntOverflow(Expr *E); >>void CheckUnsequencedOperations(Expr *E); >> >>/// \brief Perform semantic checks on a completed expression. This will >> either >> >> Modified: cfe/trunk/lib/AST/ExprConstant.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=305239&r1=305238&r2=305239&view=diff >> >> == >> --- cfe/trunk/lib/AST/ExprConstant.cpp (original) >> +++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Jun 12 16:59:18 2017 >> @@ -6226,10 +6226,6 @@ bool RecordExprEvaluator::VisitInitListE >> // the initializer list. >> ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy : >> Field->getType()); >> const Expr *Init = HaveInit ? E->getInit(ElementNo++) : &VIE; >> -if (Init->isValueDependent()) { >> - Success = false; >> - continue; >> -} >> >> // Temporarily override This, in case there's a CXXDefaultInitExpr in >> here. >> ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This, >> @@ -9940,8 +9936,7 @@ static bool EvaluateAsRValue(EvalInfo &I >> } >> >> static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult >> &Result, >> - const ASTContext &Ctx, bool &IsConst, >> - bool IsCheckingForOverflow) { >> + const ASTContext &Ctx, bool &IsConst) { >>// Fast-path evaluations of integer literals, since we sometimes see >> files >>// containing vast quantities of these. >>if (const IntegerLiteral *L = dyn_cast(Exp)) { >> @@ -9962,7 +9957,7 @@ static bool FastEvaluateAsRValue(const E >>// performance problems. Only do so in C++11 for now. >>if (Exp->isRValue() && (Exp->getType()->isArrayType() || >>Exp->getType()->isRecordType()) && >> - !Ctx.getLangOpts().CPlusPlus11 && !IsCheckingForOverflow) { >> + !Ctx.getLangOpts().CPlusPlus11) { >> IsConst = false; >> return true; >>} >> @@ -9977,7 +9972,7 @@ static bool FastEvaluateAsRValue(const E >> /// will be applied to the result. >> bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) >> const { >>bool IsConst; >> - if (FastEvaluateAsRValue(this, Result, Ctx, IsConst, false)) >> + if (FastEvaluateAsRValue(this, Result, Ctx, Is
[PATCH] D34146: [clangd] Allow to override contents of the file during completion.
ilya-biryukov created this revision. This is a reapplied r305280 with a fix to the crash found by build bots (StringRef to an out-of-scope local std::string). https://reviews.llvm.org/D34146 Files: clangd/ClangdServer.cpp clangd/ClangdServer.h unittests/clangd/ClangdTests.cpp Index: unittests/clangd/ClangdTests.cpp === --- unittests/clangd/ClangdTests.cpp +++ unittests/clangd/ClangdTests.cpp @@ -398,5 +398,69 @@ EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); } +class ClangdCompletionTest : public ClangdVFSTest { +protected: + bool ContainsItem(std::vector const &Items, StringRef Name) { +for (const auto &Item : Items) { + if (Item.insertText == Name) +return true; +} +return false; + } +}; + +TEST_F(ClangdCompletionTest, CheckContentsOverride) { + MockFSProvider *FS; + + ClangdServer Server(llvm::make_unique(), + llvm::make_unique(), + getAndMove(llvm::make_unique(), FS), + /*RunSynchronously=*/false); + + auto FooCpp = getVirtualTestFilePath("foo.cpp"); + const auto SourceContents = R"cpp( +int aba; +int b = ; +)cpp"; + + const auto OverridenSourceContents = R"cpp( +int cbc; +int b = ; +)cpp"; + // Complete after '=' sign. We need to be careful to keep the SourceContents' + // size the same. + // We complete on the 3rd line (2nd in zero-based numbering), because raw + // string literal of the SourceContents starts with a newline(it's easy to + // miss). + Position CompletePos = {2, 8}; + FS->Files[FooCpp] = SourceContents; + + Server.addDocument(FooCpp, SourceContents); + + { +auto CodeCompletionResults1 = +Server.codeComplete(FooCpp, CompletePos, None).Value; +EXPECT_TRUE(ContainsItem(CodeCompletionResults1, "aba")); +EXPECT_FALSE(ContainsItem(CodeCompletionResults1, "cbc")); + } + + { +auto CodeCompletionResultsOverriden = +Server +.codeComplete(FooCpp, CompletePos, + StringRef(OverridenSourceContents)) +.Value; +EXPECT_TRUE(ContainsItem(CodeCompletionResultsOverriden, "cbc")); +EXPECT_FALSE(ContainsItem(CodeCompletionResultsOverriden, "aba")); + } + + { +auto CodeCompletionResults2 = +Server.codeComplete(FooCpp, CompletePos, None).Value; +EXPECT_TRUE(ContainsItem(CodeCompletionResults2, "aba")); +EXPECT_FALSE(ContainsItem(CodeCompletionResults2, "cbc")); + } +} + } // namespace clangd } // namespace clang Index: clangd/ClangdServer.h === --- clangd/ClangdServer.h +++ clangd/ClangdServer.h @@ -152,8 +152,15 @@ /// Force \p File to be reparsed using the latest contents. void forceReparse(PathRef File); - /// Run code completion for \p File at \p Pos. - Tagged> codeComplete(PathRef File, Position Pos); + /// Run code completion for \p File at \p Pos. If \p OverridenContents is not + /// None, they will used only for code completion, i.e. no diagnostics update + /// will be scheduled and a draft for \p File will not be updated. + /// If \p OverridenContents is None, contents of the current draft for \p File + /// will be used. + /// This method should only be called for currently tracked files. + Tagged> + codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents = llvm::None); /// Run formatting for \p Rng inside \p File. std::vector formatRange(PathRef File, Range Rng); Index: clangd/ClangdServer.cpp === --- clangd/ClangdServer.cpp +++ clangd/ClangdServer.cpp @@ -184,17 +184,29 @@ addDocument(File, getDocument(File)); } -Tagged> ClangdServer::codeComplete(PathRef File, - Position Pos) { - auto FileContents = DraftMgr.getDraft(File); - assert(FileContents.Draft && "codeComplete is called for non-added document"); +Tagged> +ClangdServer::codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents) { + std::string DraftStorage; + if (!OverridenContents) { +auto FileContents = DraftMgr.getDraft(File); +assert(FileContents.Draft && + "codeComplete is called for non-added document"); + +DraftStorage = std::move(*FileContents.Draft); +OverridenContents = DraftStorage; + } std::vector Result; auto TaggedFS = FSProvider->getTaggedFileSystem(); - Units.runOnUnitWithoutReparse( - File, *FileContents.Draft, *CDB, PCHs, TaggedFS.Value, [&](ClangdUnit &Unit) { -Result = Unit.codeComplete(*FileContents.Draft, Pos, TaggedFS.Value); - }); + // It would be nice to use runOnUnitWithoutReparse here, but we can't + // guarantee the correctness of code completion cache here if we don't do the + // reparse. + Units.runOnUnit(File, *OverridenContents, *CDB
[PATCH] D34146: [clangd] Allow to override contents of the file during completion.
ilya-biryukov added inline comments. Comment at: clangd/ClangdServer.cpp:190 + llvm::Optional OverridenContents) { + std::string DraftStorage; + if (!OverridenContents) { This is the relevant line that changed from the previous review. https://reviews.llvm.org/D34146 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r305291 - [clangd] Allow to override contents of the file during completion.
Author: ibiryukov Date: Tue Jun 13 09:15:56 2017 New Revision: 305291 URL: http://llvm.org/viewvc/llvm-project?rev=305291&view=rev Log: [clangd] Allow to override contents of the file during completion. Summary: This is a reapplied r305280 with a fix to the crash found by build bots (StringRef to an out-of-scope local std::string). Reviewers: krasimir Reviewed By: krasimir Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D34146 Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=305291&r1=305290&r2=305291&view=diff == --- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Tue Jun 13 09:15:56 2017 @@ -184,17 +184,29 @@ void ClangdServer::forceReparse(PathRef addDocument(File, getDocument(File)); } -Tagged> ClangdServer::codeComplete(PathRef File, - Position Pos) { - auto FileContents = DraftMgr.getDraft(File); - assert(FileContents.Draft && "codeComplete is called for non-added document"); +Tagged> +ClangdServer::codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents) { + std::string DraftStorage; + if (!OverridenContents) { +auto FileContents = DraftMgr.getDraft(File); +assert(FileContents.Draft && + "codeComplete is called for non-added document"); + +DraftStorage = std::move(*FileContents.Draft); +OverridenContents = DraftStorage; + } std::vector Result; auto TaggedFS = FSProvider->getTaggedFileSystem(); - Units.runOnUnitWithoutReparse( - File, *FileContents.Draft, *CDB, PCHs, TaggedFS.Value, [&](ClangdUnit &Unit) { -Result = Unit.codeComplete(*FileContents.Draft, Pos, TaggedFS.Value); - }); + // It would be nice to use runOnUnitWithoutReparse here, but we can't + // guarantee the correctness of code completion cache here if we don't do the + // reparse. + Units.runOnUnit(File, *OverridenContents, *CDB, PCHs, TaggedFS.Value, + [&](ClangdUnit &Unit) { +Result = Unit.codeComplete(*OverridenContents, Pos, + TaggedFS.Value); + }); return make_tagged(std::move(Result), TaggedFS.Tag); } Modified: clang-tools-extra/trunk/clangd/ClangdServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=305291&r1=305290&r2=305291&view=diff == --- clang-tools-extra/trunk/clangd/ClangdServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.h Tue Jun 13 09:15:56 2017 @@ -152,8 +152,15 @@ public: /// Force \p File to be reparsed using the latest contents. void forceReparse(PathRef File); - /// Run code completion for \p File at \p Pos. - Tagged> codeComplete(PathRef File, Position Pos); + /// Run code completion for \p File at \p Pos. If \p OverridenContents is not + /// None, they will used only for code completion, i.e. no diagnostics update + /// will be scheduled and a draft for \p File will not be updated. + /// If \p OverridenContents is None, contents of the current draft for \p File + /// will be used. + /// This method should only be called for currently tracked files. + Tagged> + codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents = llvm::None); /// Run formatting for \p Rng inside \p File. std::vector formatRange(PathRef File, Range Rng); Modified: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp?rev=305291&r1=305290&r2=305291&view=diff == --- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Tue Jun 13 09:15:56 2017 @@ -398,5 +398,69 @@ TEST_F(ClangdVFSTest, CheckVersions) { EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); } +class ClangdCompletionTest : public ClangdVFSTest { +protected: + bool ContainsItem(std::vector const &Items, StringRef Name) { +for (const auto &Item : Items) { + if (Item.insertText == Name) +return true; +} +return false; + } +}; + +TEST_F(ClangdCompletionTest, CheckContentsOverride) { + MockFSProvider *FS; + + ClangdServer Server(llvm::make_unique(), + llvm::make_unique(), + getAndMove(llvm::make_unique(), FS), +
[PATCH] D34146: [clangd] Allow to override contents of the file during completion.
This revision was automatically updated to reflect the committed changes. Closed by commit rL305291: [clangd] Allow to override contents of the file during completion. (authored by ibiryukov). Changed prior to commit: https://reviews.llvm.org/D34146?vs=102328&id=102331#toc Repository: rL LLVM https://reviews.llvm.org/D34146 Files: clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Index: clang-tools-extra/trunk/clangd/ClangdServer.h === --- clang-tools-extra/trunk/clangd/ClangdServer.h +++ clang-tools-extra/trunk/clangd/ClangdServer.h @@ -152,8 +152,15 @@ /// Force \p File to be reparsed using the latest contents. void forceReparse(PathRef File); - /// Run code completion for \p File at \p Pos. - Tagged> codeComplete(PathRef File, Position Pos); + /// Run code completion for \p File at \p Pos. If \p OverridenContents is not + /// None, they will used only for code completion, i.e. no diagnostics update + /// will be scheduled and a draft for \p File will not be updated. + /// If \p OverridenContents is None, contents of the current draft for \p File + /// will be used. + /// This method should only be called for currently tracked files. + Tagged> + codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents = llvm::None); /// Run formatting for \p Rng inside \p File. std::vector formatRange(PathRef File, Range Rng); Index: clang-tools-extra/trunk/clangd/ClangdServer.cpp === --- clang-tools-extra/trunk/clangd/ClangdServer.cpp +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp @@ -184,17 +184,29 @@ addDocument(File, getDocument(File)); } -Tagged> ClangdServer::codeComplete(PathRef File, - Position Pos) { - auto FileContents = DraftMgr.getDraft(File); - assert(FileContents.Draft && "codeComplete is called for non-added document"); +Tagged> +ClangdServer::codeComplete(PathRef File, Position Pos, + llvm::Optional OverridenContents) { + std::string DraftStorage; + if (!OverridenContents) { +auto FileContents = DraftMgr.getDraft(File); +assert(FileContents.Draft && + "codeComplete is called for non-added document"); + +DraftStorage = std::move(*FileContents.Draft); +OverridenContents = DraftStorage; + } std::vector Result; auto TaggedFS = FSProvider->getTaggedFileSystem(); - Units.runOnUnitWithoutReparse( - File, *FileContents.Draft, *CDB, PCHs, TaggedFS.Value, [&](ClangdUnit &Unit) { -Result = Unit.codeComplete(*FileContents.Draft, Pos, TaggedFS.Value); - }); + // It would be nice to use runOnUnitWithoutReparse here, but we can't + // guarantee the correctness of code completion cache here if we don't do the + // reparse. + Units.runOnUnit(File, *OverridenContents, *CDB, PCHs, TaggedFS.Value, + [&](ClangdUnit &Unit) { +Result = Unit.codeComplete(*OverridenContents, Pos, + TaggedFS.Value); + }); return make_tagged(std::move(Result), TaggedFS.Tag); } Index: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp === --- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp @@ -398,5 +398,69 @@ EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS->Tag); } +class ClangdCompletionTest : public ClangdVFSTest { +protected: + bool ContainsItem(std::vector const &Items, StringRef Name) { +for (const auto &Item : Items) { + if (Item.insertText == Name) +return true; +} +return false; + } +}; + +TEST_F(ClangdCompletionTest, CheckContentsOverride) { + MockFSProvider *FS; + + ClangdServer Server(llvm::make_unique(), + llvm::make_unique(), + getAndMove(llvm::make_unique(), FS), + /*RunSynchronously=*/false); + + auto FooCpp = getVirtualTestFilePath("foo.cpp"); + const auto SourceContents = R"cpp( +int aba; +int b = ; +)cpp"; + + const auto OverridenSourceContents = R"cpp( +int cbc; +int b = ; +)cpp"; + // Complete after '=' sign. We need to be careful to keep the SourceContents' + // size the same. + // We complete on the 3rd line (2nd in zero-based numbering), because raw + // string literal of the SourceContents starts with a newline(it's easy to + // miss). + Position CompletePos = {2, 8}; + FS->Files[FooCpp] = SourceContents; + + Server.addDocument(FooCpp, SourceContents); + + { +auto CodeCompletionResults1 = +Server.codeComplete(FooCpp, CompletePos, None).Value; +EXPECT_TRUE(ContainsItem(CodeCompletionResu
[PATCH] D32146: PR32476: __nop_locale_mgmt.h not needed with newlib 2.5+
mclow.lists added a comment. This change looks fine to me - but I don't have the different newlib versions to test against. Once everyone else is happy with the version detection, then I'm good with this. https://reviews.llvm.org/D32146 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34038: Implement the non-parallel versions of exclusive_scan and transform_exclusive_scan
mclow.lists accepted this revision. mclow.lists added a comment. This revision is now accepted and ready to land. This was committed as r305136 https://reviews.llvm.org/D34038 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32146: PR32476: __nop_locale_mgmt.h not needed with newlib 2.5+
MartinO accepted this revision. MartinO added a comment. This revision is now accepted and ready to land. `Looks good. Previously I had also got a check for 'defined(__NEWLIB_MINOR__)' but I realise that was not necessary` https://reviews.llvm.org/D32146 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [clang-tools-extra] r303735 - Modify test so that it looks for patterns in stderr as well
I cannot reproduce such fail, so I can only guess how changes made in https://reviews.llvm.org/rL303756 and https://reviews.llvm.org/rL303741 could cause such problem. Behavior of `Driver::BuildCompilation` is changed so that it returns null pointer if errors occur during driver argument parse. It is called in `CompilationDatabase.cpp` from `stripPositionalArgs`. The call stack at this point is: stripPositionalArgs clang::tooling::FixedCompilationDatabase::loadFromCommandLine clang::tooling::CommonOptionsParser::CommonOptionsParser clang::tidy::clangTidyMain main `FixedCompilationDatabase::loadFromCommandLine` returns null and CommonOptionsParser uses another method to create compilation database. The output "Compile command not found" means that no input file were found in `ClangTool::run`. Maybe some file names are nulls? Thanks, --Serge 2017-06-13 3:42 GMT+07:00 David Blaikie : > I've been seeing errors from this test recently: > > Command Output (stderr): > -- > 1 error generated. > Error while processing /usr/local/google/home/blaikie/dev/llvm/src/tools/ > clang/tools/extra/test/clang-tidy/diagnostic.cpp.nonexistent.cpp. > /usr/local/google/home/blaikie/dev/llvm/src/tools/ > clang/tools/extra/test/clang-tidy/diagnostic.cpp:10:12: error: expected > string not found in input > // CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to > 'int' changes value from 1.5 to 1 [clang-diagnostic-literal-conversion] >^ > :2:1: note: scanning from here > Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/ > clang/tools/extra/test/clang-tidy/diagnostic.cpp. Compile command not > found. > ^ > :2:1: note: with expression "@LINE+2" equal to "12" > Skipping /usr/local/google/home/blaikie/dev/llvm/src/tools/ > clang/tools/extra/test/clang-tidy/diagnostic.cpp. Compile command not > found. > ^ > > > Specifically, the output is: > $ ./bin/clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' > /usr/local/google/home/blaikie/dev/llvm/src/tools/ > clang/tools/extra/test/clang-tidy/diagnostic.cpp -- -fan-unknown-option > 2>&1error: unknown argument: > '-fan-unknown-option' >Skipping /usr/local/google/home/ > blaikie/dev/llvm/src/tools/clang/tools/extra/test/clang-tidy/diagnostic.cpp. > Compile command not found. > > > Does this look like it might be related to any of your changes in this > area? Perhaps the error due to unknown argument is causing clang-tidy not > to continue on to run the check & report the warning? > > > On Wed, May 24, 2017 at 3:51 AM Serge Pavlov via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> Author: sepavloff >> Date: Wed May 24 05:50:56 2017 >> New Revision: 303735 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=303735&view=rev >> Log: >> Modify test so that it looks for patterns in stderr as well >> >> With the change https://reviews.llvm.org/D33013 driver will not build >> compilation object if command line is invalid, in particular, if >> unrecognized option is provided. In such cases it will prints diagnostics >> on stderr. The test 'clang-tidy/diagnostic.cpp' checks reaction on >> unrecognized option and will fail when D33013 is applied because it checks >> only stdout for test patterns and expects the name of diagnostic category >> prepared by clang-tidy. With this change the test makes more general check >> and must work in either case. >> >> Differential Revision: https://reviews.llvm.org/D33173 >> >> Modified: >> clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp >> >> Modified: clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp >> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/ >> trunk/test/clang-tidy/diagnostic.cpp?rev=303735&r1= >> 303734&r2=303735&view=diff >> >> == >> --- clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp (original) >> +++ clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp Wed May 24 >> 05:50:56 2017 >> @@ -1,11 +1,11 @@ >> // RUN: clang-tidy -checks='-*,modernize-use-override' >> %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 >> -implicit-check-not='{{warning:|error:}}' %s >> -// RUN: clang-tidy >> -checks='-*,clang-diagnostic-*,google-explicit-constructor' >> %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2 >> -implicit-check-not='{{warning:|error:}}' %s >> -// RUN: clang-tidy -checks='-*,google-explicit- >> constructor,clang-diagnostic-literal-conversion' %s -- >> -fan-unknown-option | FileCheck -check-prefix=CHECK3 >> -implicit-check-not='{{warning:|error:}}' >> %s >> +// RUN: clang-tidy >> -checks='-*,clang-diagnostic-*,google-explicit-constructor' >> %s -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK2 >> -implicit-check-not='{{warning:|error:}}' %s >> +// RUN: clang-tidy -checks='-*,google-explicit- >> constructor,clang-diagnostic-literal-conversion' %s -- >> -fan-unknown-option 2>&1 | Fi
[libcxx] r305292 - Fix bug 33389 - __is_transparent check requires too much
Author: marshall Date: Tue Jun 13 09:34:58 2017 New Revision: 305292 URL: http://llvm.org/viewvc/llvm-project?rev=305292&view=rev Log: Fix bug 33389 - __is_transparent check requires too much Modified: libcxx/trunk/include/__functional_base libcxx/trunk/test/std/containers/associative/map/map.ops/count0.pass.cpp libcxx/trunk/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp libcxx/trunk/test/std/containers/associative/map/map.ops/find0.pass.cpp libcxx/trunk/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp libcxx/trunk/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp libcxx/trunk/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp libcxx/trunk/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp libcxx/trunk/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp libcxx/trunk/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp libcxx/trunk/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp libcxx/trunk/test/support/is_transparent.h Modified: libcxx/trunk/include/__functional_base URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__functional_base?rev=305292&r1=305291&r2=305292&view=diff == --- libcxx/trunk/include/__functional_base (original) +++ libcxx/trunk/include/__functional_base Tue Jun 13 09:34:58 2017 @@ -548,16 +548,13 @@ template void cref(const _Tp #endif #if _LIBCPP_STD_VER > 11 -template -struct __is_transparent -{ -private: -struct __two {char __lx; char __lxx;}; -template static __two __test(...); -template static char __test(typename _Up::is_transparent* = 0); -public: -static const bool value = sizeof(__test<_Tp1>(0)) == 1; -}; +template +struct __is_transparent : false_type {}; + +template +struct __is_transparent<_Tp, _Up, +typename __void_t::type> + : true_type {}; #endif // allocator_arg_t Modified: libcxx/trunk/test/std/containers/associative/map/map.ops/count0.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/associative/map/map.ops/count0.pass.cpp?rev=305292&r1=305291&r2=305292&view=diff == --- libcxx/trunk/test/std/containers/associative/map/map.ops/count0.pass.cpp (original) +++ libcxx/trunk/test/std/containers/associative/map/map.ops/count0.pass.cpp Tue Jun 13 09:34:58 2017 @@ -28,7 +28,12 @@ int main() { +{ typedef std::map M; - M().count(C2Int{5}); +} +{ +typedef std::map M; +M().count(C2Int{5}); +} } Modified: libcxx/trunk/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp?rev=305292&r1=305291&r2=305292&view=diff == --- libcxx/trunk/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp (original) +++ libcxx/trunk/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp Tue Jun 13 09:34:58 2017 @@ -28,7 +28,12 @@ int main() { +{ typedef std::map M; - M().equal_range(C2Int{5}); +} +{ +typedef std::map M; +M().equal_range(C2Int{5}); +} } Modified: libcxx/trunk/test/std/containers/associative/map/map.ops/find0.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/associative/map/map.ops/find0.pass.cpp?rev=305292&r1=305291&r2=305292&view=diff == --- libcxx/trunk/test/std/containers/associative/map/map.ops/find0.pass.cpp (original) +++ libcxx/trunk/test/std/containers/associative/map/map.ops/find0.pass.cpp Tue Jun 13 09:34:58 2017 @@ -28,7 +28,12 @@ int main() { +{ typedef std::map M; - M().find(C2Int{5}); +} +{ +typedef std::map M; +M().find(C2Int{5}); +} } Modified: libcxx/trunk/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp?rev=305292&r1=305291&r2=305292&view=diff == --- libcxx/trunk/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp (original) +++ libcxx/trunk/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp Tue Jun 13 09:34:58 2017 @@ -28,7 +28,12 @@ int main() { +{ typedef std::map M; - M().lower_bound(C2Int{5}); +} +{ +typedef std::map M; +M().lower_bound(C2Int{5}); +} } Modified: libcxx/trunk/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp URL: ht
[PATCH] D34148: [clangd] Store references instead of unique_ptrs in ClangdServer.
ilya-biryukov created this revision. ClangdServer was owning objects passed to it in constructor for no good reason. Lots of stuff was moved from the heap to the stack thanks to this change. https://reviews.llvm.org/D34148 Files: clangd/ClangdLSPServer.cpp clangd/ClangdLSPServer.h clangd/ClangdServer.cpp clangd/ClangdServer.h unittests/clangd/ClangdTests.cpp Index: unittests/clangd/ClangdTests.cpp === --- unittests/clangd/ClangdTests.cpp +++ unittests/clangd/ClangdTests.cpp @@ -214,11 +214,6 @@ return replacePtrsInDump(DumpWithMemLocs); } -template -std::unique_ptr getAndMove(std::unique_ptr Ptr, T *&Output) { - Output = Ptr.get(); - return Ptr; -} } // namespace class ClangdVFSTest : public ::testing::Test { @@ -243,22 +238,19 @@ PathRef SourceFileRelPath, StringRef SourceContents, std::vector> ExtraFiles = {}, bool ExpectErrors = false) { -MockFSProvider *FS; -ErrorCheckingDiagConsumer *DiagConsumer; -ClangdServer Server( -llvm::make_unique(), -getAndMove(llvm::make_unique(), - DiagConsumer), -getAndMove(llvm::make_unique(), FS), -/*RunSynchronously=*/false); +MockFSProvider FS; +ErrorCheckingDiagConsumer DiagConsumer; +MockCompilationDatabase CDB; +ClangdServer Server(CDB, DiagConsumer, FS, +/*RunSynchronously=*/false); for (const auto &FileWithContents : ExtraFiles) - FS->Files[getVirtualTestFilePath(FileWithContents.first)] = + FS.Files[getVirtualTestFilePath(FileWithContents.first)] = FileWithContents.second; auto SourceFilename = getVirtualTestFilePath(SourceFileRelPath); Server.addDocument(SourceFilename, SourceContents); auto Result = dumpASTWithoutMemoryLocs(Server, SourceFilename); -EXPECT_EQ(ExpectErrors, DiagConsumer->hadErrorInLastDiags()); +EXPECT_EQ(ExpectErrors, DiagConsumer.hadErrorInLastDiags()); return Result; } }; @@ -299,13 +291,11 @@ } TEST_F(ClangdVFSTest, Reparse) { - MockFSProvider *FS; - ErrorCheckingDiagConsumer *DiagConsumer; - ClangdServer Server( - llvm::make_unique(), - getAndMove(llvm::make_unique(), DiagConsumer), - getAndMove(llvm::make_unique(), FS), - /*RunSynchronously=*/false); + MockFSProvider FS; + ErrorCheckingDiagConsumer DiagConsumer; + MockCompilationDatabase CDB; + ClangdServer Server(CDB, DiagConsumer, FS, + /*RunSynchronously=*/false); const auto SourceContents = R"cpp( #include "foo.h" @@ -315,34 +305,32 @@ auto FooCpp = getVirtualTestFilePath("foo.cpp"); auto FooH = getVirtualTestFilePath("foo.h"); - FS->Files[FooH] = "int a;"; - FS->Files[FooCpp] = SourceContents; + FS.Files[FooH] = "int a;"; + FS.Files[FooCpp] = SourceContents; Server.addDocument(FooCpp, SourceContents); auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp); - EXPECT_FALSE(DiagConsumer->hadErrorInLastDiags()); + EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags()); Server.addDocument(FooCpp, ""); auto DumpParseEmpty = dumpASTWithoutMemoryLocs(Server, FooCpp); - EXPECT_FALSE(DiagConsumer->hadErrorInLastDiags()); + EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags()); Server.addDocument(FooCpp, SourceContents); auto DumpParse2 = dumpASTWithoutMemoryLocs(Server, FooCpp); - EXPECT_FALSE(DiagConsumer->hadErrorInLastDiags()); + EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags()); EXPECT_EQ(DumpParse1, DumpParse2); EXPECT_NE(DumpParse1, DumpParseEmpty); } TEST_F(ClangdVFSTest, ReparseOnHeaderChange) { - MockFSProvider *FS; - ErrorCheckingDiagConsumer *DiagConsumer; + MockFSProvider FS; + ErrorCheckingDiagConsumer DiagConsumer; + MockCompilationDatabase CDB; - ClangdServer Server( - llvm::make_unique(), - getAndMove(llvm::make_unique(), DiagConsumer), - getAndMove(llvm::make_unique(), FS), - /*RunSynchronously=*/false); + ClangdServer Server(CDB, DiagConsumer, FS, + /*RunSynchronously=*/false); const auto SourceContents = R"cpp( #include "foo.h" @@ -352,50 +340,47 @@ auto FooCpp = getVirtualTestFilePath("foo.cpp"); auto FooH = getVirtualTestFilePath("foo.h"); - FS->Files[FooH] = "int a;"; - FS->Files[FooCpp] = SourceContents; + FS.Files[FooH] = "int a;"; + FS.Files[FooCpp] = SourceContents; Server.addDocument(FooCpp, SourceContents); auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp); - EXPECT_FALSE(DiagConsumer->hadErrorInLastDiags()); + EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags()); - FS->Files[FooH] = ""; + FS.Files[FooH] = ""; Server.forceReparse(FooCpp); auto DumpParseDifferent = dumpASTWithoutMemoryLocs(Server, FooCpp); - EXPECT_TRUE(DiagConsumer->hadErrorInLastDiags()); + EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags()); - FS->Files[FooH] = "int a;"; + FS.Files[FooH] = "int a;"; Server.forceReparse(FooCpp);
r305293 - [clang-format] Document the StartOfTokenColumn parameter, NFC
Author: krasimir Date: Tue Jun 13 09:58:55 2017 New Revision: 305293 URL: http://llvm.org/viewvc/llvm-project?rev=305293&view=rev Log: [clang-format] Document the StartOfTokenColumn parameter, NFC Modified: cfe/trunk/lib/Format/WhitespaceManager.h Modified: cfe/trunk/lib/Format/WhitespaceManager.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/WhitespaceManager.h?rev=305293&r1=305292&r2=305293&view=diff == --- cfe/trunk/lib/Format/WhitespaceManager.h (original) +++ cfe/trunk/lib/Format/WhitespaceManager.h Tue Jun 13 09:58:55 2017 @@ -43,6 +43,10 @@ public: /// \brief Replaces the whitespace in front of \p Tok. Only call once for /// each \c AnnotatedToken. + /// + /// \p StartOfTokenColumn is the column at which the token will start after + /// this replacement. It is needed for determining how \p Spaces is turned + /// into tabs and spaces for some format styles. void replaceWhitespace(FormatToken &Tok, unsigned Newlines, unsigned Spaces, unsigned StartOfTokenColumn, bool InPPDirective = false); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34148: [clangd] Store references instead of unique_ptrs in ClangdServer.
krasimir added inline comments. Comment at: clangd/ClangdLSPServer.h:75 + LSPDiagnosticsConsumer DiagConsumer; + RealFileSystemProvider FSProvider; + This approach is still inflexible. I'd make ClangdLSPServer : public DiagnosticsConsumer and pass references to the CompilationDatabase and to the FileSystemProvider to its constructor. I'd create these two in ClangdMain.cpp. https://reviews.llvm.org/D34148 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34148: [clangd] Store references instead of unique_ptrs in ClangdServer.
krasimir accepted this revision. krasimir added a comment. This revision is now accepted and ready to land. But, of course, that can be done in a separate commit. https://reviews.llvm.org/D34148 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r305294 - Add comma to comment.
Author: gbercea Date: Tue Jun 13 10:35:27 2017 New Revision: 305294 URL: http://llvm.org/viewvc/llvm-project?rev=305294&view=rev Log: Add comma to comment. Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=305294&r1=305293&r2=305294&view=diff == --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original) +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Tue Jun 13 10:35:27 2017 @@ -6327,7 +6327,7 @@ bool CGOpenMPRuntime::emitTargetGlobalVa } } - // If we are in target mode we do not emit any global (declare target is not + // If we are in target mode, we do not emit any global (declare target is not // implemented yet). Therefore we signal that GD was processed in this case. return true; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r305298 - [clangd] Store references instead of unique_ptrs in ClangdServer.
Author: ibiryukov Date: Tue Jun 13 10:59:43 2017 New Revision: 305298 URL: http://llvm.org/viewvc/llvm-project?rev=305298&view=rev Log: [clangd] Store references instead of unique_ptrs in ClangdServer. Summary: ClangdServer owned objects passed to it in constructor for no good reason. Lots of stuff was moved from the heap to the stack thanks to this change. Reviewers: krasimir Reviewed By: krasimir Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D34148 Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp clang-tools-extra/trunk/clangd/ClangdLSPServer.h clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=305298&r1=305297&r2=305298&view=diff == --- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Tue Jun 13 10:59:43 2017 @@ -38,18 +38,14 @@ replacementsToEdits(StringRef Code, } // namespace -class ClangdLSPServer::LSPDiagnosticsConsumer : public DiagnosticsConsumer { -public: - LSPDiagnosticsConsumer(ClangdLSPServer &Server) : Server(Server) {} - - virtual void onDiagnosticsReady(PathRef File, - Tagged> Diagnostics) { -Server.consumeDiagnostics(File, Diagnostics.Value); - } - -private: - ClangdLSPServer &Server; -}; +ClangdLSPServer::LSPDiagnosticsConsumer::LSPDiagnosticsConsumer( +ClangdLSPServer &Server) +: Server(Server) {} + +void ClangdLSPServer::LSPDiagnosticsConsumer::onDiagnosticsReady( +PathRef File, Tagged> Diagnostics) { + Server.consumeDiagnostics(File, Diagnostics.Value); +} class ClangdLSPServer::LSPProtocolCallbacks : public ProtocolCallbacks { public: @@ -196,11 +192,8 @@ void ClangdLSPServer::LSPProtocolCallbac } ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, bool RunSynchronously) -: Out(Out), - Server(llvm::make_unique(), - llvm::make_unique(*this), - llvm::make_unique(), - RunSynchronously) {} +: Out(Out), DiagConsumer(*this), + Server(CDB, DiagConsumer, FSProvider, RunSynchronously) {} void ClangdLSPServer::run(std::istream &In) { assert(!IsDone && "Run was called before"); Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.h?rev=305298&r1=305297&r2=305298&view=diff == --- clang-tools-extra/trunk/clangd/ClangdLSPServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.h Tue Jun 13 10:59:43 2017 @@ -11,6 +11,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H #include "ClangdServer.h" +#include "GlobalCompilationDatabase.h" #include "Path.h" #include "Protocol.h" #include "clang/Tooling/Core/Replacement.h" @@ -34,7 +35,17 @@ public: private: class LSPProtocolCallbacks; - class LSPDiagnosticsConsumer; + class LSPDiagnosticsConsumer : public DiagnosticsConsumer { + public: +LSPDiagnosticsConsumer(ClangdLSPServer &Server); + +virtual void +onDiagnosticsReady(PathRef File, + Tagged> Diagnostics); + + private: +ClangdLSPServer &Server; + }; std::vector getFixIts(StringRef File, const clangd::Diagnostic &D); @@ -56,6 +67,13 @@ private: DiagnosticToReplacementMap; /// Caches FixIts per file and diagnostics llvm::StringMap FixItsMap; + + // Various ClangdServer parameters go here. It's important they're created + // before ClangdServer. + DirectoryBasedGlobalCompilationDatabase CDB; + LSPDiagnosticsConsumer DiagConsumer; + RealFileSystemProvider FSProvider; + // Server must be the last member of the class to allow its destructor to exit // the worker thread that may otherwise run an async callback on partially // destructed instance of ClangdLSPServer. Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=305298&r1=305297&r2=305298&view=diff == --- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Tue Jun 13 10:59:43 2017 @@ -138,12 +138,11 @@ void ClangdScheduler::addToEnd(std::func RequestCV.notify_one(); } -ClangdServer::ClangdServer(std::unique_ptr CDB, - std::unique_ptr DiagConsumer, - std::unique_ptr FSProvider, +ClangdServer::ClangdServer(GlobalCompilationDatabase &CDB, + DiagnosticsConsumer &DiagConsum
[PATCH] D34148: [clangd] Store references instead of unique_ptrs in ClangdServer.
This revision was automatically updated to reflect the committed changes. Closed by commit rL305298: [clangd] Store references instead of unique_ptrs in ClangdServer. (authored by ibiryukov). Changed prior to commit: https://reviews.llvm.org/D34148?vs=102333&id=102344#toc Repository: rL LLVM https://reviews.llvm.org/D34148 Files: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp clang-tools-extra/trunk/clangd/ClangdLSPServer.h clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Index: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp === --- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp @@ -214,11 +214,6 @@ return replacePtrsInDump(DumpWithMemLocs); } -template -std::unique_ptr getAndMove(std::unique_ptr Ptr, T *&Output) { - Output = Ptr.get(); - return Ptr; -} } // namespace class ClangdVFSTest : public ::testing::Test { @@ -243,22 +238,19 @@ PathRef SourceFileRelPath, StringRef SourceContents, std::vector> ExtraFiles = {}, bool ExpectErrors = false) { -MockFSProvider *FS; -ErrorCheckingDiagConsumer *DiagConsumer; -ClangdServer Server( -llvm::make_unique(), -getAndMove(llvm::make_unique(), - DiagConsumer), -getAndMove(llvm::make_unique(), FS), -/*RunSynchronously=*/false); +MockFSProvider FS; +ErrorCheckingDiagConsumer DiagConsumer; +MockCompilationDatabase CDB; +ClangdServer Server(CDB, DiagConsumer, FS, +/*RunSynchronously=*/false); for (const auto &FileWithContents : ExtraFiles) - FS->Files[getVirtualTestFilePath(FileWithContents.first)] = + FS.Files[getVirtualTestFilePath(FileWithContents.first)] = FileWithContents.second; auto SourceFilename = getVirtualTestFilePath(SourceFileRelPath); Server.addDocument(SourceFilename, SourceContents); auto Result = dumpASTWithoutMemoryLocs(Server, SourceFilename); -EXPECT_EQ(ExpectErrors, DiagConsumer->hadErrorInLastDiags()); +EXPECT_EQ(ExpectErrors, DiagConsumer.hadErrorInLastDiags()); return Result; } }; @@ -299,13 +291,11 @@ } TEST_F(ClangdVFSTest, Reparse) { - MockFSProvider *FS; - ErrorCheckingDiagConsumer *DiagConsumer; - ClangdServer Server( - llvm::make_unique(), - getAndMove(llvm::make_unique(), DiagConsumer), - getAndMove(llvm::make_unique(), FS), - /*RunSynchronously=*/false); + MockFSProvider FS; + ErrorCheckingDiagConsumer DiagConsumer; + MockCompilationDatabase CDB; + ClangdServer Server(CDB, DiagConsumer, FS, + /*RunSynchronously=*/false); const auto SourceContents = R"cpp( #include "foo.h" @@ -315,34 +305,32 @@ auto FooCpp = getVirtualTestFilePath("foo.cpp"); auto FooH = getVirtualTestFilePath("foo.h"); - FS->Files[FooH] = "int a;"; - FS->Files[FooCpp] = SourceContents; + FS.Files[FooH] = "int a;"; + FS.Files[FooCpp] = SourceContents; Server.addDocument(FooCpp, SourceContents); auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp); - EXPECT_FALSE(DiagConsumer->hadErrorInLastDiags()); + EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags()); Server.addDocument(FooCpp, ""); auto DumpParseEmpty = dumpASTWithoutMemoryLocs(Server, FooCpp); - EXPECT_FALSE(DiagConsumer->hadErrorInLastDiags()); + EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags()); Server.addDocument(FooCpp, SourceContents); auto DumpParse2 = dumpASTWithoutMemoryLocs(Server, FooCpp); - EXPECT_FALSE(DiagConsumer->hadErrorInLastDiags()); + EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags()); EXPECT_EQ(DumpParse1, DumpParse2); EXPECT_NE(DumpParse1, DumpParseEmpty); } TEST_F(ClangdVFSTest, ReparseOnHeaderChange) { - MockFSProvider *FS; - ErrorCheckingDiagConsumer *DiagConsumer; + MockFSProvider FS; + ErrorCheckingDiagConsumer DiagConsumer; + MockCompilationDatabase CDB; - ClangdServer Server( - llvm::make_unique(), - getAndMove(llvm::make_unique(), DiagConsumer), - getAndMove(llvm::make_unique(), FS), - /*RunSynchronously=*/false); + ClangdServer Server(CDB, DiagConsumer, FS, + /*RunSynchronously=*/false); const auto SourceContents = R"cpp( #include "foo.h" @@ -352,50 +340,47 @@ auto FooCpp = getVirtualTestFilePath("foo.cpp"); auto FooH = getVirtualTestFilePath("foo.h"); - FS->Files[FooH] = "int a;"; - FS->Files[FooCpp] = SourceContents; + FS.Files[FooH] = "int a;"; + FS.Files[FooCpp] = SourceContents; Server.addDocument(FooCpp, SourceContents); auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp); - EXPECT_FALSE(DiagConsumer->hadErrorInLastDiags()); + EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags()); - FS->Files[FooH] = ""; + FS.Files[FooH] = ""; Serv
[clang-tools-extra] r305299 - [clangd] A comment for ClangdServer's constructor. NFC.
Author: ibiryukov Date: Tue Jun 13 11:02:27 2017 New Revision: 305299 URL: http://llvm.org/viewvc/llvm-project?rev=305299&view=rev Log: [clangd] A comment for ClangdServer's constructor. NFC. Modified: clang-tools-extra/trunk/clangd/ClangdServer.h Modified: clang-tools-extra/trunk/clangd/ClangdServer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=305299&r1=305298&r2=305299&view=diff == --- clang-tools-extra/trunk/clangd/ClangdServer.h (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.h Tue Jun 13 11:02:27 2017 @@ -136,6 +136,15 @@ private: /// diagnostics for tracked files). class ClangdServer { public: + /// Creates a new ClangdServer. If \p RunSynchronously is false, no worker + /// thread will be created and all requests will be completed synchronously on + /// the calling thread (this is mostly used for tests). If \p RunSynchronously + /// is true, a worker thread will be created to parse files in the background + /// and provide diagnostics results via DiagConsumer.onDiagnosticsReady + /// callback. File accesses for each instance of parsing will be conducted via + /// a vfs::FileSystem provided by \p FSProvider. Results of code + /// completion/diagnostics also include a tag, that \p FSProvider returns + /// along with the vfs::FileSystem. ClangdServer(GlobalCompilationDatabase &CDB, DiagnosticsConsumer &DiagConsumer, FileSystemProvider &FSProvider, bool RunSynchronously); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32480: clang-format: Add CompactNamespaces option
Typz updated this revision to Diff 102346. Typz added a comment. - make "compacted" namespaces always add at most one level of indentation - compact only namespaces which both start and end on consecutive lines https://reviews.llvm.org/D32480 Files: include/clang/Format/Format.h lib/Format/Format.cpp lib/Format/NamespaceEndCommentsFixer.cpp lib/Format/UnwrappedLineFormatter.cpp lib/Format/UnwrappedLineParser.cpp unittests/Format/FormatTest.cpp Index: unittests/Format/FormatTest.cpp === --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -1309,6 +1309,164 @@ Style)); } +TEST_F(FormatTest, FormatsCompactNamespaces) { + FormatStyle Style = getLLVMStyle(); + Style.CompactNamespaces = true; + + verifyFormat("namespace A { namespace B {\n" + "}} // namespace A::B", + Style); + + EXPECT_EQ("namespace out { namespace in {\n" +"}} // namespace out::in", +format("namespace out {\n" + "namespace in {\n" + "} // namespace in\n" + "} // namespace out", + Style)); + + // Only namespaces which have both consecutive opening and end get compacted + EXPECT_EQ("namespace out {\n" +"namespace in1 {\n" +"} // namespace in1\n" +"namespace in2 {\n" +"} // namespace in2\n" +"} // namespace out", +format("namespace out {\n" + "namespace in1 {\n" + "} // namespace in1\n" + "namespace in2 {\n" + "} // namespace in2\n" + "} // namespace out", + Style)); + + EXPECT_EQ("namespace out {\n" +"int i;\n" +"namespace in {\n" +"int j;\n" +"} // namespace in\n" +"int k;\n" +"} // namespace out", +format("namespace out { int i;\n" + "namespace in { int j; } // namespace in\n" + "int k; } // namespace out", + Style)); + + EXPECT_EQ("namespace A { namespace B { namespace C {\n" +"}}} // namespace A::B::C\n", +format("namespace A { namespace B {\n" + "namespace C {\n" + "}} // namespace B::C\n" + "} // namespace A\n", + Style)); + + EXPECT_EQ("namespace {\n" + "namespace {\n" +"}} // namespace ::", +format("namespace {\n" + "namespace {\n" + "} // namespace \n" + "} // namespace ", + Style)); + + EXPECT_EQ("namespace a { namespace b {\n" + "namespace c {\n" +"}}} // namespace a::b::c", +format("namespace a {\n" + "namespace b {\n" + "namespace c {\n" + "} // namespace c\n" + "} // namespace b\n" + "} // namespace a", + Style)); + + // Missing comments are added + EXPECT_EQ("namespace out { namespace in {\n" + "int i;\n" + "int j;\n" +"}} // namespace out::in", +format("namespace out {\n" + "namespace in {\n" + "int i;\n" + "int j;\n" + "}\n" + "}", + Style)); + + // Incorrect comments are fixed + EXPECT_EQ("namespace out { namespace in {\n" +"}} // namespace out::in", +format("namespace out { namespace in {\n" + "}} // namespace out", + Style)); + EXPECT_EQ("namespace out { namespace in {\n" +"}} // namespace out::in", +format("namespace out { namespace in {\n" + "}} // namespace in", + Style)); + + // Extra semicolon after 'inner' closing brace prevents merging + EXPECT_EQ("namespace out { namespace in {\n" +"}; } // namespace out::in", +format("namespace out {\n" + "namespace in {\n" + "}; // namespace in\n" + "} // namespace out", + Style)); + + // Extra semicolon after 'outer' closing brace is conserved + EXPECT_EQ("namespace out { namespace in {\n" +"}}; // namespace out::in", +format("namespace out {\n" + "namespace in {\n" + "} // namespace in\n" +
[PATCH] D33977: [libcxx][WIP] Experimental support for a scheduler for use in the parallel stl algorithms
erik.pilkington added a comment. Ping! https://reviews.llvm.org/D33977 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34151: [clangd] Add a filename parameter to FileSystemProvider.
ilya-biryukov created this revision. https://reviews.llvm.org/D34151 Files: clangd/ClangdServer.cpp clangd/ClangdServer.h unittests/clangd/ClangdTests.cpp Index: unittests/clangd/ClangdTests.cpp === --- unittests/clangd/ClangdTests.cpp +++ unittests/clangd/ClangdTests.cpp @@ -172,9 +172,13 @@ class MockFSProvider : public FileSystemProvider { public: - Tagged> getTaggedFileSystem() override { + Tagged> + getTaggedFileSystem(PathRef File) override { IntrusiveRefCntPtr MemFS( new vfs::InMemoryFileSystem); +if (ExpectedFile) + EXPECT_EQ(*ExpectedFile, File); + for (auto &FileAndContents : Files) MemFS->addFile(FileAndContents.first(), time_t(), llvm::MemoryBuffer::getMemBuffer(FileAndContents.second, @@ -186,6 +190,7 @@ return make_tagged(OverlayFS, Tag); } + llvm::Optional> ExpectedFile; llvm::StringMap Files; VFSTag Tag = VFSTag(); }; @@ -248,7 +253,10 @@ FileWithContents.second; auto SourceFilename = getVirtualTestFilePath(SourceFileRelPath); + +FS.ExpectedFile = SourceFilename; Server.addDocument(SourceFilename, SourceContents); + auto Result = dumpASTWithoutMemoryLocs(Server, SourceFilename); EXPECT_EQ(ExpectErrors, DiagConsumer.hadErrorInLastDiags()); return Result; @@ -307,6 +315,7 @@ FS.Files[FooH] = "int a;"; FS.Files[FooCpp] = SourceContents; + FS.ExpectedFile = FooCpp; Server.addDocument(FooCpp, SourceContents); auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp); @@ -342,6 +351,7 @@ FS.Files[FooH] = "int a;"; FS.Files[FooCpp] = SourceContents; + FS.ExpectedFile = FooCpp; Server.addDocument(FooCpp, SourceContents); auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp); @@ -371,8 +381,9 @@ auto FooCpp = getVirtualTestFilePath("foo.cpp"); const auto SourceContents = "int a;"; FS.Files[FooCpp] = SourceContents; - FS.Tag = "123"; + FS.ExpectedFile = FooCpp; + FS.Tag = "123"; Server.addDocument(FooCpp, SourceContents); EXPECT_EQ(DiagConsumer.lastVFSTag(), FS.Tag); EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS.Tag); @@ -419,6 +430,7 @@ // miss). Position CompletePos = {2, 8}; FS.Files[FooCpp] = SourceContents; + FS.ExpectedFile = FooCpp; Server.addDocument(FooCpp, SourceContents); Index: clangd/ClangdServer.h === --- clangd/ClangdServer.h +++ clangd/ClangdServer.h @@ -82,16 +82,21 @@ class FileSystemProvider { public: virtual ~FileSystemProvider() = default; + /// Called by ClangdServer to obtain a vfs::FileSystem to be used for parsing. + /// Name of the file that will be parsed is passed in \p File. + /// /// \return A filesystem that will be used for all file accesses in clangd. /// A Tag returned by this method will be propagated to all results of clangd /// that will use this filesystem. - virtual Tagged> getTaggedFileSystem() = 0; + virtual Tagged> + getTaggedFileSystem(PathRef File) = 0; }; class RealFileSystemProvider : public FileSystemProvider { public: /// \return getRealFileSystem() tagged with default tag, i.e. VFSTag() - Tagged> getTaggedFileSystem() override; + Tagged> + getTaggedFileSystem(PathRef File) override; }; class ClangdServer; Index: clangd/ClangdServer.cpp === --- clangd/ClangdServer.cpp +++ clangd/ClangdServer.cpp @@ -59,7 +59,7 @@ } Tagged> -RealFileSystemProvider::getTaggedFileSystem() { +RealFileSystemProvider::getTaggedFileSystem(PathRef File) { return make_tagged(vfs::getRealFileSystem(), VFSTag()); } @@ -156,7 +156,7 @@ assert(FileContents.Draft && "No contents inside a file that was scheduled for reparse"); -auto TaggedFS = FSProvider.getTaggedFileSystem(); +auto TaggedFS = FSProvider.getTaggedFileSystem(FileStr); Units.runOnUnit( FileStr, *FileContents.Draft, CDB, PCHs, TaggedFS.Value, [&](ClangdUnit const &Unit) { @@ -197,7 +197,7 @@ } std::vector Result; - auto TaggedFS = FSProvider.getTaggedFileSystem(); + auto TaggedFS = FSProvider.getTaggedFileSystem(File); // It would be nice to use runOnUnitWithoutReparse here, but we can't // guarantee the correctness of code completion cache here if we don't do the // reparse. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32428: Fix for Itanium mangler issue with templates (bug: 31405)
majnemer accepted this revision. majnemer added a comment. This revision is now accepted and ready to land. LGTM https://reviews.llvm.org/D32428 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34133: Cold attribute on function decls are lost. Fix the problem
davidxl updated this revision to Diff 102358. davidxl added a comment. Herald added a subscriber: javed.absar. Add a test case. https://reviews.llvm.org/D34133 Files: lib/CodeGen/CGCall.cpp test/CodeGen/attributes.c Index: test/CodeGen/attributes.c === --- test/CodeGen/attributes.c +++ test/CodeGen/attributes.c @@ -56,6 +56,13 @@ void t7() __attribute__((noreturn, nothrow)); void t7() { while (1) {} } +// CHECK: define void @t72() [[COLDDEF:#[0-9]+]] { +void t71(void) __attribute__((cold)); +void t72() __attribute__((cold)); +void t72() { t71(); } +// CHECK: call void @t71() [[COLDSITE:#[0-9]+]] +// CHECK: declare void @t71() [[COLDDECL:#[0-9]+]] + // CHECK: define void @t10() [[NUW]] section "SECT" { void t10(void) __attribute__((section("SECT"))); void t10(void) {} @@ -92,3 +99,6 @@ // CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } // CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} } +// CHECK: attributes [[COLDDEF]] = { cold {{.*}}} +// CHECK: attributes [[COLDDECL]] = { cold {{.*}}} +// CHECK: attributes [[COLDSITE]] = { cold {{.*}}} Index: lib/CodeGen/CGCall.cpp === --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1795,6 +1795,8 @@ FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute(llvm::Attribute::NoReturn); +if (TargetDecl->hasAttr()) + FuncAttrs.addAttribute(llvm::Attribute::Cold); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate); if (TargetDecl->hasAttr()) Index: test/CodeGen/attributes.c === --- test/CodeGen/attributes.c +++ test/CodeGen/attributes.c @@ -56,6 +56,13 @@ void t7() __attribute__((noreturn, nothrow)); void t7() { while (1) {} } +// CHECK: define void @t72() [[COLDDEF:#[0-9]+]] { +void t71(void) __attribute__((cold)); +void t72() __attribute__((cold)); +void t72() { t71(); } +// CHECK: call void @t71() [[COLDSITE:#[0-9]+]] +// CHECK: declare void @t71() [[COLDDECL:#[0-9]+]] + // CHECK: define void @t10() [[NUW]] section "SECT" { void t10(void) __attribute__((section("SECT"))); void t10(void) {} @@ -92,3 +99,6 @@ // CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } // CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} } +// CHECK: attributes [[COLDDEF]] = { cold {{.*}}} +// CHECK: attributes [[COLDDECL]] = { cold {{.*}}} +// CHECK: attributes [[COLDSITE]] = { cold {{.*}}} Index: lib/CodeGen/CGCall.cpp === --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1795,6 +1795,8 @@ FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute(llvm::Attribute::NoReturn); +if (TargetDecl->hasAttr()) + FuncAttrs.addAttribute(llvm::Attribute::Cold); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate); if (TargetDecl->hasAttr()) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33304: [clang-tidy][Part1] Add a new module Android and three new checks.
yawanng added inline comments. Comment at: docs/clang-tidy/checks/android-file-open-flag.rst:6 + +A common source of security bugs has been code that opens file without using +the ``O_CLOEXEC`` flag. Without that flag, an opened sensitive file would alexfh wrote: > I'm not sure about using of "has been" here. Maybe just use present tense? > You might want to consult a nearby native speaker though. Alternatively, you > might want to rephrase this as "Opening files using POSIX ``open`` or similar > system calls without specifying the ``O_CLOEXEC`` flag is a common source of > security bugs." I copied these sentences from the requests written by a native speaker, I think. But after talking with another native speaker, yes, present tense seems to be better here. Thanks :) https://reviews.llvm.org/D33304 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33467: Fix LLVM build errors if necent build of GCC 7 is used
v.g.vassilev added a comment. Waiting on resolution to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79162 Repository: rL LLVM https://reviews.llvm.org/D33467 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32046: [Preprocessor]Correct Macro-Arg allocation of StringifiedArguments, correct getNumArguments
erichkeane added a comment. Anyone have a chance to look at this? I'll note that this is in no way MSVC specific, this is a code-health issue. https://reviews.llvm.org/D32046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34082: [Frontend] 'Show hotness' can be used with a sampling profile
davidxl accepted this revision. davidxl added a comment. This revision is now accepted and ready to land. lgtm https://reviews.llvm.org/D34082 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32046: [Preprocessor]Correct Macro-Arg allocation of StringifiedArguments, correct getNumArguments
arphaman added a comment. Can you somehow test this change? Maybe a unittest for `getStringifiedArgument`that ensures that the assertion is triggered after the number of macro arguments is reached? https://reviews.llvm.org/D32046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32046: [Preprocessor]Correct Macro-Arg allocation of StringifiedArguments, correct getNumArguments
erichkeane added a comment. Sure, I'll work on that, thanks! https://reviews.llvm.org/D32046 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32942: [clang-tidy] readability-function-size: add NestingThreshold param.
lebedev.ri added a comment. In https://reviews.llvm.org/D32942#778729, @malcolm.parsons wrote: > In https://reviews.llvm.org/D32942#777001, @lebedev.ri wrote: > > > Which makes sense, since in AST, they are nested: > > > They're not nested in the formatting, so I don't think it makes sense. As usual, all the meaningful review happens post-factum :) So, it should warn on: void yes_nesting() { // 1 if (true) {// 2 int j; } else { if (true) { // 2 or 3? int j; } else { if (true) { // 2 or 4? int j; } else { if (true) { // 2 or 5? int j; } } } } } which is `-FunctionDecl line:12:6 yes_nesting 'void (void)' `-CompoundStmt `-IfStmt |-<<>> |-<<>> |-CXXBoolLiteralExpr '_Bool' true |-CompoundStmt | `-DeclStmt | `-VarDecl col:9 j 'int' `-CompoundStmt `-IfStmt |-<<>> |-<<>> |-CXXBoolLiteralExpr '_Bool' true |-CompoundStmt | `-DeclStmt | `-VarDecl col:11 j 'int' `-CompoundStmt `-IfStmt |-<<>> |-<<>> |-CXXBoolLiteralExpr '_Bool' true |-CompoundStmt | `-DeclStmt | `-VarDecl col:13 j 'int' `-CompoundStmt `-IfStmt |-<<>> |-<<>> |-CXXBoolLiteralExpr '_Bool' true |-CompoundStmt | `-DeclStmt | `-VarDecl col:15 j 'int' `-<<>> but should not on what you/i posted in the previous comment. The difference seems to be some kind of implicit `CompoundStmt` added by `IfStmt`? Assuming that is the case, maybe this is as simple as checking whether this `CompoundStmt` is implicit or not? Best to move open a new bug about this. I'll see what can be done. Repository: rL LLVM https://reviews.llvm.org/D32942 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r305312 - Align definition of DW_OP_plus with DWARF spec [2/3]
Author: fhahn Date: Tue Jun 13 13:06:15 2017 New Revision: 305312 URL: http://llvm.org/viewvc/llvm-project?rev=305312&view=rev Log: Align definition of DW_OP_plus with DWARF spec [2/3] Summary: This patch is part of 3 patches that together form a single patch, but must be introduced in stages in order not to break things. The way that LLVM interprets DW_OP_plus in DIExpression nodes is basically that of the DW_OP_plus_uconst operator since LLVM expects an unsigned constant operand. This unnecessarily restricts the DW_OP_plus operator, preventing it from being used to describe the evaluation of runtime values on the expression stack. These patches try to align the semantics of DW_OP_plus and DW_OP_minus with that of the DWARF definition, which pops two elements off the expression stack, performs the operation and pushes the result back on the stack. This is done in three stages: • The first patch (LLVM) adds support for DW_OP_plus_uconst and changes all uses (and tests) of DW_OP_plus to use DW_OP_plus_uconst. • The second patch (Clang) contains changes to use DW_OP_plus_uconst instead of DW_OP_plus. • The third patch (LLVM) changes the semantics of DW_OP_plus to be in line with it’s DWARF meaning. It also does this for DW_OP_minus. Patch by Sander de Smalen. Reviewers: echristo, pcc, aprantl Reviewed By: aprantl Subscribers: aprantl, cfe-commits Differential Revision: https://reviews.llvm.org/D33893 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=305312&r1=305311&r2=305312&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Jun 13 13:06:15 2017 @@ -3490,13 +3490,13 @@ void CGDebugInfo::EmitDeclare(const VarD if (VD->hasAttr()) { // Here, we need an offset *into* the alloca. CharUnits offset = CharUnits::fromQuantity(32); - Expr.push_back(llvm::dwarf::DW_OP_plus); + Expr.push_back(llvm::dwarf::DW_OP_plus_uconst); // offset of __forwarding field offset = CGM.getContext().toCharUnitsFromBits( CGM.getTarget().getPointerWidth(0)); Expr.push_back(offset.getQuantity()); Expr.push_back(llvm::dwarf::DW_OP_deref); - Expr.push_back(llvm::dwarf::DW_OP_plus); + Expr.push_back(llvm::dwarf::DW_OP_plus_uconst); // offset of x field offset = CGM.getContext().toCharUnitsFromBits(XOffset); Expr.push_back(offset.getQuantity()); @@ -3605,17 +3605,17 @@ void CGDebugInfo::EmitDeclareOfBlockDecl SmallVector addr; addr.push_back(llvm::dwarf::DW_OP_deref); - addr.push_back(llvm::dwarf::DW_OP_plus); + addr.push_back(llvm::dwarf::DW_OP_plus_uconst); addr.push_back(offset.getQuantity()); if (isByRef) { addr.push_back(llvm::dwarf::DW_OP_deref); -addr.push_back(llvm::dwarf::DW_OP_plus); +addr.push_back(llvm::dwarf::DW_OP_plus_uconst); // offset of __forwarding field offset = CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0)); addr.push_back(offset.getQuantity()); addr.push_back(llvm::dwarf::DW_OP_deref); -addr.push_back(llvm::dwarf::DW_OP_plus); +addr.push_back(llvm::dwarf::DW_OP_plus_uconst); // offset of x field offset = CGM.getContext().toCharUnitsFromBits(XOffset); addr.push_back(offset.getQuantity()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34156: [LTO] Add -femit-summary-index flag to emit summary for regular LTO
tobiasvk created this revision. Herald added subscribers: eraman, inglorion. With https://reviews.llvm.org/D33921, we gained the ability to have module summaries in regular LTO modules without triggering ThinLTO compilation. There is however, currently, no way to trigger the emission of a module summary with regular LTO in Clang. This patch adds a flag -femit-summary-index which makes that possible. Why would you want a summary with regular LTO? The Qualcomm Linker performs a two-phase garbage collection (a.k.a. dead stripping): firstly, before LTO compilation, and then again afterwards. The key advantage of already running GC before LTO is that in links that involve a heavy mix of ELF objects and bitcode (a critical use case for us), we can prune some of the dependences between bitcode and ELF and thus internalize more symbols in LTO. For this to work, the linker needs to be able to inspect the reference graphs for bitcode modules and the module summary provides exactly that. https://reviews.llvm.org/D34156 Files: clang/include/clang/Driver/Options.td clang/include/clang/Frontend/CodeGenOptions.def clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGen/emit-summary-index.c clang/test/Misc/thinlto.c Index: clang/test/Misc/thinlto.c === --- clang/test/Misc/thinlto.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %clang_cc1 -flto=thin -emit-llvm-bc < %s | llvm-bcanalyzer -dump | FileCheck %s -// ; Check that the -flto=thin option emits a summary -// CHECK: containsValue("thin"); + if (A && A->containsValue("thin")) +Opts.PrepareForThinLTO = Opts.EmitSummaryIndex = true; Opts.LTOUnit = Args.hasFlag(OPT_flto_unit, OPT_fno_lto_unit, false); if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) { if (IK.getLanguage() != InputKind::LLVM_IR) Index: clang/lib/Driver/ToolChains/Clang.cpp === --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -2057,6 +2057,8 @@ if (JA.getType() == types::TY_LLVM_BC) CmdArgs.push_back("-emit-llvm-uselists"); +Args.AddLastArg(CmdArgs, options::OPT_femit_summary_index); + if (D.isUsingLTO()) { Args.AddLastArg(CmdArgs, options::OPT_flto, options::OPT_flto_EQ); Index: clang/lib/CodeGen/BackendUtil.cpp === --- clang/lib/CodeGen/BackendUtil.cpp +++ clang/lib/CodeGen/BackendUtil.cpp @@ -486,7 +486,7 @@ PMBuilder.Inliner = createFunctionInliningPass( CodeGenOpts.OptimizationLevel, CodeGenOpts.OptimizeSize, (!CodeGenOpts.SampleProfileFile.empty() && - CodeGenOpts.EmitSummaryIndex)); + CodeGenOpts.PrepareForThinLTO)); } PMBuilder.OptLevel = CodeGenOpts.OptimizationLevel; @@ -497,7 +497,7 @@ PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions; - PMBuilder.PrepareForThinLTO = CodeGenOpts.EmitSummaryIndex; + PMBuilder.PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO; PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO; PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; @@ -738,7 +738,7 @@ break; case Backend_EmitBC: -if (CodeGenOpts.EmitSummaryIndex) { +if (CodeGenOpts.PrepareForThinLTO) { if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) { std::error_code EC; ThinLinkOS.reset(new llvm::raw_fd_ostream( @@ -752,10 +752,13 @@ } PerModulePasses.add( createWriteThinLTOBitcodePass(*OS, ThinLinkOS.get())); -} -else +} else { + if (CodeGenOpts.EmitSummaryIndex) + TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); PerModulePasses.add( - createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists)); + createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, + CodeGenOpts.EmitSummaryIndex)); +} break; case Backend_EmitLL: @@ -907,7 +910,7 @@ break; case Backend_EmitBC: -if (CodeGenOpts.EmitSummaryIndex) { +if (CodeGenOpts.PrepareForThinLTO) { if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) { std::error_code EC; ThinLinkOS.emplace(CodeGenOpts.ThinLinkBitcodeFile, EC, @@ -921,8 +924,9 @@ MPM.addPass( ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &*ThinLinkOS : nullptr)); } else { + if (CodeGenOpts.EmitSummaryIndex) + TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, -CodeGenOpts.EmitSummaryIndex, CodeGenOpts.EmitSummaryIndex)); } break; Index: clang/include/clang/Frontend/CodeGenOptions.def ==
[PATCH] D33526: Fix spurious Wunused-lambda-capture warning
This revision was automatically updated to reflect the committed changes. Closed by commit rL305315: Fix spurious Wunused-lambda-capture warning (authored by kongyi). Changed prior to commit: https://reviews.llvm.org/D33526?vs=102099&id=102371#toc Repository: rL LLVM https://reviews.llvm.org/D33526 Files: cfe/trunk/lib/Sema/SemaLambda.cpp cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp Index: cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp === --- cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp +++ cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp @@ -142,11 +142,14 @@ auto implicit_by_reference = [&] { i++; }; auto explicit_by_value_used = [i] { return i + 1; }; + auto explicit_by_value_used_generic = [i](auto c) { return i + 1; }; auto explicit_by_value_used_void = [i] { (void)i; }; + auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}} auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}} auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}} auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}} + auto explicit_by_value_unused_const_generic = [k](auto c) { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}} auto explicit_by_reference_used = [&i] { i++; }; auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}} @@ -161,6 +164,8 @@ auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}} auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{}; auto explicit_initialized_value_with_side_effect = [j = side_effect()]{}; + auto explicit_initialized_value_generic_used = [i = 1](auto c) mutable { i++; }; + auto explicit_initialized_value_generic_unused = [i = 1](auto c) mutable {}; // expected-warning{{lambda capture 'i' is not used}} auto nested = [&i] { auto explicit_by_value_used = [i] { return i + 1; }; Index: cfe/trunk/lib/Sema/SemaLambda.cpp === --- cfe/trunk/lib/Sema/SemaLambda.cpp +++ cfe/trunk/lib/Sema/SemaLambda.cpp @@ -1492,15 +1492,17 @@ bool ExplicitResultType; CleanupInfo LambdaCleanup; bool ContainsUnexpandedParameterPack; + bool IsGenericLambda; { CallOperator = LSI->CallOperator; Class = LSI->Lambda; IntroducerRange = LSI->IntroducerRange; ExplicitParams = LSI->ExplicitParams; ExplicitResultType = !LSI->HasImplicitReturnType; LambdaCleanup = LSI->Cleanup; ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack; - +IsGenericLambda = Class->isGenericLambda(); + CallOperator->setLexicalDeclContext(Class); Decl *TemplateOrNonTemplateCallOperatorDecl = CallOperator->getDescribedFunctionTemplate() @@ -1520,8 +1522,13 @@ bool IsImplicit = I >= LSI->NumExplicitCaptures; // Warn about unused explicit captures. - if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) -DiagnoseUnusedLambdaCapture(From); + if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) { +// Initialized captures that are non-ODR used may not be eliminated. +bool NonODRUsedInitCapture = +IsGenericLambda && From.isNonODRUsed() && From.getInitExpr(); +if (!NonODRUsedInitCapture) + DiagnoseUnusedLambdaCapture(From); + } // Handle 'this' capture. if (From.isThisCapture()) { @@ -1568,8 +1575,7 @@ // same parameter and return types as the closure type's function call // operator. // FIXME: Fix generic lambda to block conversions. -if (getLangOpts().Blocks && getLangOpts().ObjC1 && - !Class->isGenericLambda()) +if (getLangOpts().Blocks && getLangOpts().ObjC1 && !IsGenericLambda) addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator); // Finalize the lambda class. Index: cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp === --- cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp +++ cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp @@ -142,11 +142,14 @@ auto implicit_by_reference = [&] { i++; }; auto explicit_by_value_used = [i] { return i + 1; }; + auto explicit_by_value_used_generic = [i](auto c) { return i + 1; }; auto explicit_by_value_used_void = [i] { (void)i; }; + auto explicit_by_value_unused = [i] {}; // expect
r305315 - Fix spurious Wunused-lambda-capture warning
Author: kongyi Date: Tue Jun 13 13:38:31 2017 New Revision: 305315 URL: http://llvm.org/viewvc/llvm-project?rev=305315&view=rev Log: Fix spurious Wunused-lambda-capture warning Summary: Clang emits unused-lambda-capture warning for captures in generic lambdas even though they are actually used. Fixes PR31815. Reviewers: malcolm.parsons, aaron.ballman, rsmith Reviewed By: malcolm.parsons Subscribers: ahatanak, cfe-commits Differential Revision: https://reviews.llvm.org/D33526 Modified: cfe/trunk/lib/Sema/SemaLambda.cpp cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp Modified: cfe/trunk/lib/Sema/SemaLambda.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=305315&r1=305314&r2=305315&view=diff == --- cfe/trunk/lib/Sema/SemaLambda.cpp (original) +++ cfe/trunk/lib/Sema/SemaLambda.cpp Tue Jun 13 13:38:31 2017 @@ -1492,6 +1492,7 @@ ExprResult Sema::BuildLambdaExpr(SourceL bool ExplicitResultType; CleanupInfo LambdaCleanup; bool ContainsUnexpandedParameterPack; + bool IsGenericLambda; { CallOperator = LSI->CallOperator; Class = LSI->Lambda; @@ -1500,7 +1501,8 @@ ExprResult Sema::BuildLambdaExpr(SourceL ExplicitResultType = !LSI->HasImplicitReturnType; LambdaCleanup = LSI->Cleanup; ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack; - +IsGenericLambda = Class->isGenericLambda(); + CallOperator->setLexicalDeclContext(Class); Decl *TemplateOrNonTemplateCallOperatorDecl = CallOperator->getDescribedFunctionTemplate() @@ -1520,8 +1522,13 @@ ExprResult Sema::BuildLambdaExpr(SourceL bool IsImplicit = I >= LSI->NumExplicitCaptures; // Warn about unused explicit captures. - if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) -DiagnoseUnusedLambdaCapture(From); + if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) { +// Initialized captures that are non-ODR used may not be eliminated. +bool NonODRUsedInitCapture = +IsGenericLambda && From.isNonODRUsed() && From.getInitExpr(); +if (!NonODRUsedInitCapture) + DiagnoseUnusedLambdaCapture(From); + } // Handle 'this' capture. if (From.isThisCapture()) { @@ -1568,8 +1575,7 @@ ExprResult Sema::BuildLambdaExpr(SourceL // same parameter and return types as the closure type's function call // operator. // FIXME: Fix generic lambda to block conversions. -if (getLangOpts().Blocks && getLangOpts().ObjC1 && - !Class->isGenericLambda()) +if (getLangOpts().Blocks && getLangOpts().ObjC1 && !IsGenericLambda) addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator); // Finalize the lambda class. Modified: cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp?rev=305315&r1=305314&r2=305315&view=diff == --- cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp (original) +++ cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp Tue Jun 13 13:38:31 2017 @@ -142,11 +142,14 @@ void test_templated() { auto implicit_by_reference = [&] { i++; }; auto explicit_by_value_used = [i] { return i + 1; }; + auto explicit_by_value_used_generic = [i](auto c) { return i + 1; }; auto explicit_by_value_used_void = [i] { (void)i; }; + auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}} auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}} auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}} auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}} + auto explicit_by_value_unused_const_generic = [k](auto c) { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}} auto explicit_by_reference_used = [&i] { i++; }; auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}} @@ -161,6 +164,8 @@ void test_templated() { auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}} auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{}; auto explicit_initialized_value_with_side_effect = [j = side_effect()]{}; + auto explicit_initialized_value_generic_used = [i = 1](auto c) mutable { i++; }; + auto explicit_initialized_value_generic_unused = [i = 1](auto c) mutable {}; // expe
[PATCH] D28691: Add OpenCL 2.0 atomic builtin functions as Clang builtin
yaxunl updated this revision to Diff 102374. yaxunl marked 11 inline comments as done. yaxunl edited the summary of this revision. yaxunl added a comment. Revised by John's comments. https://reviews.llvm.org/D28691 Files: docs/LanguageExtensions.rst include/clang/AST/Expr.h include/clang/Basic/Builtins.def include/clang/Basic/DiagnosticSemaKinds.td lib/AST/ASTContext.cpp lib/AST/Expr.cpp lib/AST/StmtPrinter.cpp lib/Basic/Targets.cpp lib/CodeGen/CGAtomic.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGExpr.cpp lib/Headers/opencl-c.h lib/Sema/SemaChecking.cpp test/CodeGenOpenCL/atomic-ops-libcall.cl test/CodeGenOpenCL/atomic-ops.cl test/SemaOpenCL/atomic-ops.cl Index: test/SemaOpenCL/atomic-ops.cl === --- /dev/null +++ test/SemaOpenCL/atomic-ops.cl @@ -0,0 +1,146 @@ +// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -verify -fsyntax-only -triple=spir64 +// RUN: %clang_cc1 %s -cl-std=CL2.0 -finclude-default-header -verify -fsyntax-only -triple=amdgcn-amdhsa-amd-opencl + +// Basic parsing/Sema tests for __opencl_atomic_* + +#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable +#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable + +struct S { char c[3]; }; + +char i8; +short i16; +int i32; +int8 i64; + +atomic_int gn; + +void f(atomic_int *i, const atomic_int *ci, + atomic_intptr_t *p, atomic_float *d, + int *I, const int *CI, + intptr_t *P, float *D, struct S *s1, struct S *s2) { + __opencl_atomic_init(I, 5); // expected-error {{pointer to _Atomic}} + __opencl_atomic_init(ci, 5); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} + + __opencl_atomic_load(0); // expected-error {{too few arguments to function}} + __opencl_atomic_load(0,0,0,0); // expected-error {{too many arguments to function}} + __opencl_atomic_store(0,0,0,0); // expected-error {{address argument to atomic builtin must be a pointer}} + __opencl_atomic_store((int*)0,0,0,0); // expected-error {{address argument to atomic operation must be a pointer to _Atomic}} + __opencl_atomic_store(i, 0, memory_order_relaxed, memory_scope_work_item); + __opencl_atomic_store(ci, 0, memory_order_relaxed, memory_scope_work_item); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} + + __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_item); + __opencl_atomic_load(p, memory_order_seq_cst, memory_scope_work_item); + __opencl_atomic_load(d, memory_order_seq_cst, memory_scope_work_item); + __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_item); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} + + __opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_item); + __opencl_atomic_store(p, 1, memory_order_seq_cst, memory_scope_work_item); + (int)__opencl_atomic_store(d, 1, memory_order_seq_cst, memory_scope_work_item); // expected-error {{operand of type 'void'}} + + int exchange_1 = __opencl_atomic_exchange(i, 1, memory_order_seq_cst, memory_scope_work_item); + int exchange_2 = __opencl_atomic_exchange(I, 1, memory_order_seq_cst, memory_scope_work_item); // expected-error {{must be a pointer to _Atomic}} + + __opencl_atomic_fetch_add(i, 1, memory_order_seq_cst, memory_scope_work_item); + __opencl_atomic_fetch_add(p, 1, memory_order_seq_cst, memory_scope_work_item); + __opencl_atomic_fetch_add(d, 1, memory_order_seq_cst, memory_scope_work_item); // expected-error {{must be a pointer to atomic integer or pointer}} + + __opencl_atomic_fetch_and(i, 1, memory_order_seq_cst, memory_scope_work_item); + __opencl_atomic_fetch_and(p, 1, memory_order_seq_cst, memory_scope_work_item); + __opencl_atomic_fetch_and(d, 1, memory_order_seq_cst, memory_scope_work_item); // expected-error {{must be a pointer to atomic integer}} + + bool cmpexch_1 = __opencl_atomic_compare_exchange_strong(i, I, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_item); + bool cmpexch_2 = __opencl_atomic_compare_exchange_strong(p, P, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_item); + bool cmpexch_3 = __opencl_atomic_compare_exchange_strong(d, I, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_item); // expected-warning {{incompatible pointer types}} + (void)__opencl_atomic_compare_exchange_strong(i, CI, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_item); // expected-warning {{passing 'const __generic int *' to parameter of type '__generic int *' discards qualifiers}} + + bool cmpexchw_1 = __opencl_atomic_compare_exchange_weak(i, I, 1, mem
[PATCH] D34158: to support gcc 4.8 (and newer) compatibility on Linux, preinclude
mibintc created this revision. mibintc created this object with visibility "All Users". Herald added subscribers: fedor.sergeev, arichardson, Anastasia, sdardis, klimek. As reported in llvm bugzilla 32377. Here’s a patch to add preinclude of stdc-predef.h for gcc >= 4.8 The gcc documentation says “On GNU/Linux, is pre-included.” See https://gcc.gnu.org/gcc-4.8/porting_to.html The preinclude is inhibited with –ffreestanding. I’m not sure what other toolchains, if any, should support it. I put in some changes for Solaris or MipsLinux but I didn’t debug them and not sure the changes that i slapped in for MipsLinux and Solaris will, or should, work. I could just omit those and let folks interested in the other toolchains to do that, what’s your recommendation for supporting gcc on other platforms besides Linux? I only debugged and verified on Linux. Also, what's the mechanism to restrict the test case to run only on Linux? Basically I fixed the failing test cases by adding either –ffreestanding or –nostdinc which inhibits this behavior. Some of the tests didn't support -ffreestanding but they did accept -nostdinc. Also, I have a few lit tests failing in my sandbox, they'll need to be updated to accomodate the change in the preprocessing. Anyway, hoping for some feedback on this patch. in my sandbox, these tests are failing on Linux so currently it's not ready: Failing Tests (7): Clang Tools :: clang-tidy/llvm-include-order.cpp Clang Tools :: clang-tidy/readability-implicit-bool-cast.cpp Clang Tools :: pp-trace/pp-trace-pragma-general.cpp Clang Tools :: pp-trace/pp-trace-pragma-opencl.cpp Extra Tools Unit Tests :: clangd/ClangdTests/ClangdVFSTest.Parse Extra Tools Unit Tests :: clangd/ClangdTests/ClangdVFSTest.ParseWithHeader Extra Tools Unit Tests :: clangd/ClangdTests/ClangdVFSTest.Reparse Repository: rL LLVM https://reviews.llvm.org/D34158 Files: include/clang/Driver/ToolChain.h lib/Driver/ToolChain.cpp lib/Driver/ToolChains/Gnu.cpp lib/Driver/ToolChains/Gnu.h lib/Driver/ToolChains/Linux.cpp lib/Driver/ToolChains/Linux.h lib/Driver/ToolChains/MipsLinux.cpp lib/Driver/ToolChains/MipsLinux.h lib/Driver/ToolChains/Solaris.cpp test/Driver/clang_cpp.c test/Index/IBOutletCollection.m test/Index/annotate-macro-args.m test/Index/annotate-tokens-pp.c test/Index/annotate-tokens.c test/Index/c-index-getCursor-test.m test/Index/get-cursor-macro-args.m test/Index/get-cursor.cpp unittests/Tooling/TestVisitor.h Index: lib/Driver/ToolChains/MipsLinux.h === --- lib/Driver/ToolChains/MipsLinux.h +++ lib/Driver/ToolChains/MipsLinux.h @@ -28,6 +28,8 @@ void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddGnuIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; Index: lib/Driver/ToolChains/Solaris.cpp === --- lib/Driver/ToolChains/Solaris.cpp +++ lib/Driver/ToolChains/Solaris.cpp @@ -189,5 +189,6 @@ "." + Version.MinorStr + "/include/c++/" + Version.Text + "/" + GCCInstallation.getTriple().str()); +GCCInstallation.AddGnuIncludeArgs(DriverArgs, CC1Args); } } Index: lib/Driver/ToolChains/Linux.h === --- lib/Driver/ToolChains/Linux.h +++ lib/Driver/ToolChains/Linux.h @@ -31,6 +31,8 @@ void addLibStdCxxIncludePaths( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddGnuIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, Index: lib/Driver/ToolChains/MipsLinux.cpp === --- lib/Driver/ToolChains/MipsLinux.cpp +++ lib/Driver/ToolChains/MipsLinux.cpp @@ -64,6 +64,12 @@ } } +void MipsLLVMToolChain::AddGnuIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + if (GCCInstallation.isValid()) +GCCInstallation.AddGnuIncludeArgs(DriverArgs, CC1Args); +} + Tool *MipsLLVMToolChain::buildLinker() const { return new tools::gnutools::Linker(*this); } Index: lib/Driver/ToolChains/Gnu.cpp === --- lib/Driver/ToolChains/Gnu.cpp +++ lib/Driver/ToolChains/Gnu.cpp @@ -1771,6 +1771,16 @@ return
[PATCH] D34156: [LTO] Add -femit-summary-index flag to emit summary for regular LTO
pcc added a comment. Have you considered writing the regular LTO summaries unconditionally if `-flto` was specified? That was how I imagined that the interface would look. Also, how were you planning to expose the reference graph to the linker? I gather from your message that you are teaching your linker to read the module summary index directly from bitcode files. I wonder whether it would be worth trying to avoid needing to read summaries multiple times. The approach that I had in mind was to somehow teach the linker to add regular object files to the combined summary index by creating a "global value summary" for each section, with a reference for each relocation. (This would be similar to how we add regular LTO inputs to the combined summary in https://reviews.llvm.org/D33922.) Then LTO would run as usual. Any regular object sections would then naturally participate in the summary-based dead stripping that LTO already does. https://reviews.llvm.org/D34156 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34158: to support gcc 4.8 (and newer) compatibility on Linux, preinclude
mibintc updated this revision to Diff 102382. mibintc added a comment. forgot to add the new lit test https://reviews.llvm.org/D34158 Files: include/clang/Driver/ToolChain.h lib/Driver/ToolChain.cpp lib/Driver/ToolChains/Gnu.cpp lib/Driver/ToolChains/Gnu.h lib/Driver/ToolChains/Linux.cpp lib/Driver/ToolChains/Linux.h lib/Driver/ToolChains/MipsLinux.cpp lib/Driver/ToolChains/MipsLinux.h lib/Driver/ToolChains/Solaris.cpp test/Driver/clang_cpp.c test/Driver/gcc-predef.c test/Index/IBOutletCollection.m test/Index/annotate-macro-args.m test/Index/annotate-tokens-pp.c test/Index/annotate-tokens.c test/Index/c-index-getCursor-test.m test/Index/get-cursor-macro-args.m test/Index/get-cursor.cpp unittests/Tooling/TestVisitor.h Index: lib/Driver/ToolChains/MipsLinux.h === --- lib/Driver/ToolChains/MipsLinux.h +++ lib/Driver/ToolChains/MipsLinux.h @@ -28,6 +28,8 @@ void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddGnuIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; Index: lib/Driver/ToolChains/Solaris.cpp === --- lib/Driver/ToolChains/Solaris.cpp +++ lib/Driver/ToolChains/Solaris.cpp @@ -189,5 +189,6 @@ "." + Version.MinorStr + "/include/c++/" + Version.Text + "/" + GCCInstallation.getTriple().str()); +GCCInstallation.AddGnuIncludeArgs(DriverArgs, CC1Args); } } Index: lib/Driver/ToolChains/Linux.h === --- lib/Driver/ToolChains/Linux.h +++ lib/Driver/ToolChains/Linux.h @@ -31,6 +31,8 @@ void addLibStdCxxIncludePaths( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddGnuIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, Index: lib/Driver/ToolChains/MipsLinux.cpp === --- lib/Driver/ToolChains/MipsLinux.cpp +++ lib/Driver/ToolChains/MipsLinux.cpp @@ -64,6 +64,12 @@ } } +void MipsLLVMToolChain::AddGnuIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + if (GCCInstallation.isValid()) +GCCInstallation.AddGnuIncludeArgs(DriverArgs, CC1Args); +} + Tool *MipsLLVMToolChain::buildLinker() const { return new tools::gnutools::Linker(*this); } Index: lib/Driver/ToolChains/Gnu.cpp === --- lib/Driver/ToolChains/Gnu.cpp +++ lib/Driver/ToolChains/Gnu.cpp @@ -1771,6 +1771,16 @@ return false; } +void Generic_GCC::GCCInstallationDetector::AddGnuIncludeArgs( +const ArgList &DriverArgs, ArgStringList &CC1Args) const { + if (!DriverArgs.hasArg(options::OPT_ffreestanding) && + !DriverArgs.hasArg(clang::driver::options::OPT_nostdinc) && + !Version.isOlderThan(4, 8, 0)) { +CC1Args.push_back("-include"); +CC1Args.push_back("stdc-predef.h"); + } +} + /*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples( const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple, SmallVectorImpl &LibDirs, Index: lib/Driver/ToolChains/Linux.cpp === --- lib/Driver/ToolChains/Linux.cpp +++ lib/Driver/ToolChains/Linux.cpp @@ -705,6 +705,8 @@ addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); + + GCCInstallation.AddGnuIncludeArgs(DriverArgs, CC1Args); } static std::string DetectLibcxxIncludePath(StringRef base) { @@ -743,6 +745,13 @@ return ""; } +void Linux::AddGnuIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + if (GCCInstallation.isValid()) +GCCInstallation.AddGnuIncludeArgs(DriverArgs, CC1Args); +} + + void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { // We need a detected GCC installation on Linux to provide libstdc++'s Index: lib/Driver/ToolChains/Gnu.h === --- lib/Driver/ToolChains/Gnu.h +++ lib/Driver/ToolChains/Gnu.h @@ -216,
[PATCH] D34158: to support gcc 4.8 (and newer) compatibility on Linux, preinclude
fedor.sergeev added a comment. There is no /usr/include/stdc-predef.h on Solaris and I see no sense in adding this -include for anything except Linux (as docs are rather clear that this functionality is Linux-only). Checked gcc on Solaris11/12 both SPARC and X86 - none are doing stdc-predef.h inclusion (checking with gcc - -dI https://reviews.llvm.org/D34158 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30268: Avoid copy of __atoms when char_type is char
EricWF accepted this revision. EricWF added a comment. This revision is now accepted and ready to land. LGTM. Could you please add the benchmark under `libcxx/benchmarks`. Could you also make sure that the existing tests (under `test/std`) for number parsing have sufficient test coverages for the possible formats it might need to parse? Just to ensure this change isn't missing anything (or the old change isn't) Once again sorry for the massive delay. `` patches are tricky, and I barely understand `` as is. Comment at: libcxx/include/__config:79 #define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION + +#define _LIBCPP_ABI_OPTIMIZED_LOCALE Could you make the macro name slightly more descriptive, in case we have further optimizations to locale :-) Also please add a short comment describing the change. Comment at: libcxx/include/locale:969 +#else +char_type __atoms[26]; string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); Could you lift the `26` into a `const int __atoms_size = 42` that's shared between both `#if` branches? https://reviews.llvm.org/D30268 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
RE: D34158: to support gcc 4.8 (and newer) compatibility on Linux, preinclude
Thanks I'll fix that. -Original Message- From: Fedor Sergeev via Phabricator [mailto:revi...@reviews.llvm.org] Sent: Tuesday, June 13, 2017 3:30 PM To: Blower, Melanie ; zhangsheng...@huawei.com; olivier...@gmail.com; kalinichev.s...@gmail.com; kf...@kde.org; m...@milianw.de; cfe-commits@lists.llvm.org; Keane, Erich Cc: kli...@google.com; simon.dar...@imgtec.com; anastasia.stul...@arm.com; arichardson@gmail.com; fedor.serg...@oracle.com Subject: [PATCH] D34158: to support gcc 4.8 (and newer) compatibility on Linux, preinclude fedor.sergeev added a comment. There is no /usr/include/stdc-predef.h on Solaris and I see no sense in adding this -include for anything except Linux (as docs are rather clear that this functionality is Linux-only). Checked gcc on Solaris11/12 both SPARC and X86 - none are doing stdc-predef.h inclusion (checking with gcc - -dI https://reviews.llvm.org/D34158 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34158: to support gcc 4.8 (and newer) compatibility on Linux, preinclude
fedor.sergeev added inline comments. Comment at: lib/Driver/ToolChains/Gnu.h:219-220 +void AddGnuIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; + To me this does not belong to GCC-Installation-Detector at all, as it does not have anything to do with detection. As I see the only reason for adding it here is to check Version vs 4.8.0. If thats true then adding getVersion() here and using it elsewhere seems a better solution. https://reviews.llvm.org/D34158 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34021: [coroutines] Fix co_await for range statement
EricWF added inline comments. Comment at: include/clang/AST/ExprCXX.h:4136 + : Expr(SC, Resume->getType(), + (Resume->getType()->isLValueReferenceType() ? VK_LValue : + Resume->getType()->isRValueReferenceType() ? VK_XValue : @rsmith Does this make sense, since the resume expression is a function call, or am I way off base in determining the expressions value category? https://reviews.llvm.org/D34021 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34158: to support gcc 4.8 (and newer) compatibility on Linux, preinclude
fedor.sergeev added a comment. > docs are rather clear that this functionality is Linux-only Oh, well, gcc implementation is rather generic, it relies on gcc's config.gcc to detect glibc and then it adds a hook that unconditionally provides stdc-predef.h (TARGET_C_PREINCLUDE). Currently config.gcc does that for the following pattern of triples: *-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu) I'm not sure how far into that do you really want to dive :-/ https://reviews.llvm.org/D34158 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34121: [ubsan] Teach the pointer overflow check that "p - <= p" (PR33430)
dtzWill added a comment. Don't mean to block this, but just FYI I won't be able to look into this carefully until later this week (sorry!). Kicked off a rebuild using these patches just now, though! O:) https://reviews.llvm.org/D34121 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33833: Fix PR 33189: Clang assertion on template destructor declaration
kuang_he added a comment. Can we have this patch reviewed? https://reviews.llvm.org/D33833 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34170: [libcxx] Moving compiler specific test infrastructure to compiler.py
bcraig created this revision. format.py and config.py were routinely reaching into the innards of compiler.py, then setting variables in a very gcc / clang-centric way. Now, all the compiler specific code has been moved to compiler.py. These makes it possible to (in theory) build with MSVC instead, by switching to a different CXXCompilerInterface implementation. This refactor did not attempt to make large, simplifying changes. It is mainly moving code to the right place so that later work can consolidate and clean as needed. As a proof of concept, I was able to switch out CXXCompilerInterface implementations and run the libc++ tests with MSVC 2017 and the MSVC 2017 STL, with 3486/5472 passing (I didn't dive into the failure cases). The MSVC test infrastructure port is not included in this review. https://reviews.llvm.org/D34170 Files: utils/libcxx/compiler.py utils/libcxx/test/config.py utils/libcxx/test/format.py Index: utils/libcxx/test/format.py === --- utils/libcxx/test/format.py +++ utils/libcxx/test/format.py @@ -129,25 +129,11 @@ extra_modules_defines = self._get_parser('MODULES_DEFINES:', parsers).getValue() if '-fmodules' in test.config.available_features: -test_cxx.compile_flags += [('-D%s' % mdef.strip()) for - mdef in extra_modules_defines] -test_cxx.addWarningFlagIfSupported('-Wno-macro-redefined') -# FIXME: libc++ debug tests #define _LIBCPP_ASSERT to override it -# If we see this we need to build the test against uniquely built -# modules. -if is_libcxx_test: -with open(test.getSourcePath(), 'r') as f: -contents = f.read() -if '#define _LIBCPP_ASSERT' in contents: -test_cxx.useModules(False) +test_cxx.add_extra_module_defines(extra_modules_defines, + test.getSourcePath()) if is_objcxx_test: -test_cxx.source_lang = 'objective-c++' -if is_objcxx_arc_test: -test_cxx.compile_flags += ['-fobjc-arc'] -else: -test_cxx.compile_flags += ['-fno-objc-arc'] -test_cxx.link_flags += ['-framework', 'Foundation'] +test_cxx.use_objcxx(is_objcxx_arc_test=is_objcxx_arc_test) # Dispatch the test based on its suffix. if is_sh_test: @@ -231,17 +217,7 @@ 'expected-error', 'expected-no-diagnostics'] use_verify = self.use_verify_for_fail and \ any([tag in contents for tag in verify_tags]) -# FIXME(EricWF): GCC 5 does not evaluate static assertions that -# are dependant on a template parameter when '-fsyntax-only' is passed. -# This is fixed in GCC 6. However for now we only pass "-fsyntax-only" -# when using Clang. -if test_cxx.type != 'gcc': -test_cxx.flags += ['-fsyntax-only'] -if use_verify: -test_cxx.useVerify() -test_cxx.useWarnings() -if '-Wuser-defined-warnings' in test_cxx.warning_flags: -test_cxx.warning_flags += ['-Wno-error=user-defined-warnings'] +test_cxx.configure_for_fail_test(use_verify=use_verify) cmd, out, err, rc = test_cxx.compile(source_path, out=os.devnull) expected_rc = 0 if use_verify else 1 Index: utils/libcxx/test/config.py === --- utils/libcxx/test/config.py +++ utils/libcxx/test/config.py @@ -13,12 +13,8 @@ import pkgutil import pipes import re -import shlex -import shutil import sys -from libcxx.compiler import CXXCompiler -from libcxx.test.target_info import make_target_info from libcxx.test.executor import * from libcxx.test.tracing import * import libcxx.util @@ -57,7 +53,6 @@ self.config = config self.is_windows = platform.system() == 'Windows' self.cxx = None -self.cxx_is_clang_cl = None self.cxx_stdlib_under_test = None self.project_obj_root = None self.libcxx_src_root = None @@ -127,37 +122,28 @@ self.configure_src_root() self.configure_obj_root() self.configure_cxx_stdlib_under_test() -self.configure_cxx_library_root() +self.cxx.configure_cxx_library_root(self) self.configure_use_clang_verify() -self.configure_use_thread_safety() +self.cxx.configure_use_thread_safety(self) self.configure_execute_external() -self.configure_ccache() -self.configure_compile_flags() +self.cxx.configure_ccache(self) +self.cxx.configure_compile_flags(self) self.configure_filesystem_compile_flags() -self.configure_link_flags() +self.cxx.c
[PATCH] D34133: Cold attribute on function decls are lost. Fix the problem
rsmith accepted this revision. rsmith added a comment. This revision is now accepted and ready to land. LGTM https://reviews.llvm.org/D34133 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r305325 - Preserve cold attribute for function decls
Author: davidxl Date: Tue Jun 13 16:14:07 2017 New Revision: 305325 URL: http://llvm.org/viewvc/llvm-project?rev=305325&view=rev Log: Preserve cold attribute for function decls Differential Revision: http://reviews.llvm.org/D34133 Modified: cfe/trunk/lib/CodeGen/CGCall.cpp cfe/trunk/test/CodeGen/attributes.c Modified: cfe/trunk/lib/CodeGen/CGCall.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=305325&r1=305324&r2=305325&view=diff == --- cfe/trunk/lib/CodeGen/CGCall.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Jun 13 16:14:07 2017 @@ -1795,6 +1795,8 @@ void CodeGenModule::ConstructAttributeLi FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute(llvm::Attribute::NoReturn); +if (TargetDecl->hasAttr()) + FuncAttrs.addAttribute(llvm::Attribute::Cold); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate); if (TargetDecl->hasAttr()) Modified: cfe/trunk/test/CodeGen/attributes.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attributes.c?rev=305325&r1=305324&r2=305325&view=diff == --- cfe/trunk/test/CodeGen/attributes.c (original) +++ cfe/trunk/test/CodeGen/attributes.c Tue Jun 13 16:14:07 2017 @@ -56,6 +56,13 @@ void t4() {} void t7() __attribute__((noreturn, nothrow)); void t7() { while (1) {} } +// CHECK: define void @t72() [[COLDDEF:#[0-9]+]] { +void t71(void) __attribute__((cold)); +void t72() __attribute__((cold)); +void t72() { t71(); } +// CHECK: call void @t71() [[COLDSITE:#[0-9]+]] +// CHECK: declare void @t71() [[COLDDECL:#[0-9]+]] + // CHECK: define void @t10() [[NUW]] section "SECT" { void t10(void) __attribute__((section("SECT"))); void t10(void) {} @@ -92,3 +99,6 @@ void __attribute__((section(".bar"))) t2 // CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } // CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} } +// CHECK: attributes [[COLDDEF]] = { cold {{.*}}} +// CHECK: attributes [[COLDDECL]] = { cold {{.*}}} +// CHECK: attributes [[COLDSITE]] = { cold {{.*}}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34133: Cold attribute on function decls are lost. Fix the problem
This revision was automatically updated to reflect the committed changes. Closed by commit rL305325: Preserve cold attribute for function decls (authored by davidxl). Changed prior to commit: https://reviews.llvm.org/D34133?vs=102358&id=102409#toc Repository: rL LLVM https://reviews.llvm.org/D34133 Files: cfe/trunk/lib/CodeGen/CGCall.cpp cfe/trunk/test/CodeGen/attributes.c Index: cfe/trunk/lib/CodeGen/CGCall.cpp === --- cfe/trunk/lib/CodeGen/CGCall.cpp +++ cfe/trunk/lib/CodeGen/CGCall.cpp @@ -1795,6 +1795,8 @@ FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute(llvm::Attribute::NoReturn); +if (TargetDecl->hasAttr()) + FuncAttrs.addAttribute(llvm::Attribute::Cold); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate); if (TargetDecl->hasAttr()) Index: cfe/trunk/test/CodeGen/attributes.c === --- cfe/trunk/test/CodeGen/attributes.c +++ cfe/trunk/test/CodeGen/attributes.c @@ -56,6 +56,13 @@ void t7() __attribute__((noreturn, nothrow)); void t7() { while (1) {} } +// CHECK: define void @t72() [[COLDDEF:#[0-9]+]] { +void t71(void) __attribute__((cold)); +void t72() __attribute__((cold)); +void t72() { t71(); } +// CHECK: call void @t71() [[COLDSITE:#[0-9]+]] +// CHECK: declare void @t71() [[COLDDECL:#[0-9]+]] + // CHECK: define void @t10() [[NUW]] section "SECT" { void t10(void) __attribute__((section("SECT"))); void t10(void) {} @@ -92,3 +99,6 @@ // CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } // CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} } +// CHECK: attributes [[COLDDEF]] = { cold {{.*}}} +// CHECK: attributes [[COLDDECL]] = { cold {{.*}}} +// CHECK: attributes [[COLDSITE]] = { cold {{.*}}} Index: cfe/trunk/lib/CodeGen/CGCall.cpp === --- cfe/trunk/lib/CodeGen/CGCall.cpp +++ cfe/trunk/lib/CodeGen/CGCall.cpp @@ -1795,6 +1795,8 @@ FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute(llvm::Attribute::NoReturn); +if (TargetDecl->hasAttr()) + FuncAttrs.addAttribute(llvm::Attribute::Cold); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate); if (TargetDecl->hasAttr()) Index: cfe/trunk/test/CodeGen/attributes.c === --- cfe/trunk/test/CodeGen/attributes.c +++ cfe/trunk/test/CodeGen/attributes.c @@ -56,6 +56,13 @@ void t7() __attribute__((noreturn, nothrow)); void t7() { while (1) {} } +// CHECK: define void @t72() [[COLDDEF:#[0-9]+]] { +void t71(void) __attribute__((cold)); +void t72() __attribute__((cold)); +void t72() { t71(); } +// CHECK: call void @t71() [[COLDSITE:#[0-9]+]] +// CHECK: declare void @t71() [[COLDDECL:#[0-9]+]] + // CHECK: define void @t10() [[NUW]] section "SECT" { void t10(void) __attribute__((section("SECT"))); void t10(void) {} @@ -92,3 +99,6 @@ // CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } // CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} } +// CHECK: attributes [[COLDDEF]] = { cold {{.*}}} +// CHECK: attributes [[COLDDECL]] = { cold {{.*}}} +// CHECK: attributes [[COLDSITE]] = { cold {{.*}}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34173: [Completion] Code complete the members for a dependent type after a '::'
arphaman created this revision. This is a follow up to r302797 which added support for dependent completions after '.' and '->'. This patch handles the '::' operator. Repository: rL LLVM https://reviews.llvm.org/D34173 Files: lib/Sema/SemaCodeComplete.cpp test/CodeCompletion/member-access.cpp Index: test/CodeCompletion/member-access.cpp === --- test/CodeCompletion/member-access.cpp +++ test/CodeCompletion/member-access.cpp @@ -145,4 +145,22 @@ // CHECK-CC6: o2 : [#BaseTemplate#]o2 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:142:11 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s } + + static void staticFn(T &obj); + + struct Nested { }; }; + +template +void dependentColonColonCompletion() { + Template::staticFn(); +// CHECK-CC7: function : [#void#]function() +// CHECK-CC7: Nested : Nested +// CHECK-CC7: o1 : [#BaseTemplate#]o1 +// CHECK-CC7: o2 : [#BaseTemplate#]o2 +// CHECK-CC7: staticFn : [#void#]staticFn(<#T &obj#>) +// CHECK-CC7: Template : Template +// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:156:16 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s + typename Template::Nested m; +// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:164:25 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s +} Index: lib/Sema/SemaCodeComplete.cpp === --- lib/Sema/SemaCodeComplete.cpp +++ lib/Sema/SemaCodeComplete.cpp @@ -4542,8 +4542,10 @@ bool EnteringContext) { if (!SS.getScopeRep() || !CodeCompleter) return; - - DeclContext *Ctx = computeDeclContext(SS, EnteringContext); + + // Always pretend to enter a context to ensure that a dependent type + // resolves to a dependent record. + DeclContext *Ctx = computeDeclContext(SS, /*EnteringContext=*/true); if (!Ctx) return; @@ -4573,7 +4575,9 @@ Results.ExitScope(); CodeCompletionDeclConsumer Consumer(Results, CurContext); - LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer); + LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer, + /*IncludeGlobalScope=*/true, + /*IncludeDependentBases=*/true); HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), Index: test/CodeCompletion/member-access.cpp === --- test/CodeCompletion/member-access.cpp +++ test/CodeCompletion/member-access.cpp @@ -145,4 +145,22 @@ // CHECK-CC6: o2 : [#BaseTemplate#]o2 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:142:11 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s } + + static void staticFn(T &obj); + + struct Nested { }; }; + +template +void dependentColonColonCompletion() { + Template::staticFn(); +// CHECK-CC7: function : [#void#]function() +// CHECK-CC7: Nested : Nested +// CHECK-CC7: o1 : [#BaseTemplate#]o1 +// CHECK-CC7: o2 : [#BaseTemplate#]o2 +// CHECK-CC7: staticFn : [#void#]staticFn(<#T &obj#>) +// CHECK-CC7: Template : Template +// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:156:16 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s + typename Template::Nested m; +// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:164:25 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s +} Index: lib/Sema/SemaCodeComplete.cpp === --- lib/Sema/SemaCodeComplete.cpp +++ lib/Sema/SemaCodeComplete.cpp @@ -4542,8 +4542,10 @@ bool EnteringContext) { if (!SS.getScopeRep() || !CodeCompleter) return; - - DeclContext *Ctx = computeDeclContext(SS, EnteringContext); + + // Always pretend to enter a context to ensure that a dependent type + // resolves to a dependent record. + DeclContext *Ctx = computeDeclContext(SS, /*EnteringContext=*/true); if (!Ctx) return; @@ -4573,7 +4575,9 @@ Results.ExitScope(); CodeCompletionDeclConsumer Consumer(Results, CurContext); - LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer); + LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer, + /*IncludeGlobalScope=*/true, + /*IncludeDependentBases=*/true); HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [clang-tools-extra] r303735 - Modify test so that it looks for patterns in stderr as well
Ah, I find that the test passes if I remove the compile_commands.json file from my build directory (I have Ninja configured to generate a compile_commands.json file). Looks like what happens is it finds the compilation database and fails hard when the database doesn't contain a compile command for the file in question. If the database is not found, it falls back to some basic command behavior, perhaps? Is there some way this test could be fixed to cope with this, otherwise it seems to get in the way of people actually using clang tools in their LLVM/Clang build environment? On Tue, Jun 13, 2017 at 7:41 AM Serge Pavlov wrote: > I cannot reproduce such fail, so I can only guess how changes made in > https://reviews.llvm.org/rL303756 and https://reviews.llvm.org/rL303741 > could cause such problem. Behavior of `Driver::BuildCompilation` is changed > so that it returns null pointer if errors occur during driver argument > parse. It is called in `CompilationDatabase.cpp` from > `stripPositionalArgs`. The call stack at this point is: > stripPositionalArgs > clang::tooling::FixedCompilationDatabase::loadFromCommandLine > clang::tooling::CommonOptionsParser::CommonOptionsParser > clang::tidy::clangTidyMain > main > `FixedCompilationDatabase::loadFromCommandLine` returns null and > CommonOptionsParser uses another method to create compilation database. The > output "Compile command not found" means that no input file were found in > `ClangTool::run`. Maybe some file names are nulls? > > > Thanks, > --Serge > > 2017-06-13 3:42 GMT+07:00 David Blaikie : > >> I've been seeing errors from this test recently: >> >> Command Output (stderr): >> -- >> 1 error generated. >> Error while processing >> /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/tools/extra/test/clang-tidy/diagnostic.cpp.nonexistent.cpp. >> /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/tools/extra/test/clang-tidy/diagnostic.cpp:10:12: >> error: expected string not found in input >> // CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to >> 'int' changes value from 1.5 to 1 [clang-diagnostic-literal-conversion] >>^ >> :2:1: note: scanning from here >> Skipping >> /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/tools/extra/test/clang-tidy/diagnostic.cpp. >> Compile command not found. >> ^ >> :2:1: note: with expression "@LINE+2" equal to "12" >> Skipping >> /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/tools/extra/test/clang-tidy/diagnostic.cpp. >> Compile command not found. >> ^ >> >> >> Specifically, the output is: >> $ ./bin/clang-tidy >> -checks='-*,clang-diagnostic-*,google-explicit-constructor' >> /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/tools/extra/test/clang-tidy/diagnostic.cpp >> -- -fan-unknown-option 2>&1error: unknown >> argument: '-fan-unknown-option' >> Skipping >> /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/tools/extra/test/clang-tidy/diagnostic.cpp. >> Compile command not found. >> >> >> Does this look like it might be related to any of your changes in this >> area? Perhaps the error due to unknown argument is causing clang-tidy not >> to continue on to run the check & report the warning? >> >> >> On Wed, May 24, 2017 at 3:51 AM Serge Pavlov via cfe-commits < >> cfe-commits@lists.llvm.org> wrote: >> >>> Author: sepavloff >>> Date: Wed May 24 05:50:56 2017 >>> New Revision: 303735 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=303735&view=rev >>> Log: >>> Modify test so that it looks for patterns in stderr as well >>> >>> With the change https://reviews.llvm.org/D33013 driver will not build >>> compilation object if command line is invalid, in particular, if >>> unrecognized option is provided. In such cases it will prints diagnostics >>> on stderr. The test 'clang-tidy/diagnostic.cpp' checks reaction on >>> unrecognized option and will fail when D33013 is applied because it >>> checks >>> only stdout for test patterns and expects the name of diagnostic category >>> prepared by clang-tidy. With this change the test makes more general >>> check >>> and must work in either case. >>> >>> Differential Revision: https://reviews.llvm.org/D33173 >>> >>> Modified: >>> clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp >>> >>> Modified: clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp?rev=303735&r1=303734&r2=303735&view=diff >>> >>> == >>> --- clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp (original) >>> +++ clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp Wed May 24 >>> 05:50:56 2017 >>> @@ -1,11 +1,11 @@ >>> // RUN: clang-tidy -checks='-*,modernize-use-override' >>> %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 >>> -implicit-check-not='{{warning:|error:}}' %s
[PATCH] D33989: [OpenCL] Allow targets to select address space per type
yaxunl added a comment. Can you add missing types to test/CodeGenOpenCL/opencl_types.cl ? Comment at: include/clang/Basic/TargetInfo.h:1034 + virtual LangAS::ID getOpenCLTypeAddrSpace(BuiltinType::Kind K) const { +switch (K) { +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ I think it is a good idea to make this function a central place for all OpenCL types. Can you also add sampler and pipe type then update CGOpenCLRuntime::getPipeType and CGOpenCLRuntime::getSamplerType to use this function to get address space for sampler and pipe? Comment at: include/clang/Basic/TargetInfo.h:1041 +default: + return LangAS::Default; +} I think the default (including even_t, clk_event_t, queue_t, reserved_id_t) should be global since these opaque OpenCL objects are pointers to some shared resources. These pointers may be an automatic variable themselves but the memory they point to should be global. Since these objects are dynamically allocated, assuming them in private address space implies runtime needs to maintain a private memory pool for each work item and allocate objects from there. Considering the huge number of work items in typical OpenCL applications, it would be very inefficient to implement these objects in private memory pool. On the other hand, a global memory pool seems much reasonable. Anastasia/Alexey, any comments on this? Thanks. Comment at: lib/AST/ASTContext.cpp:1775 case BuiltinType::OCLSampler: { - auto AS = getTargetAddressSpace(LangAS::opencl_constant); + AS = getTargetAddressSpace(LangAS::opencl_constant); Width = Target->getPointerWidth(AS); All OpenCL types may be unified as ``` AS = getOpenCLTypeAddrSpace(TK); Width = Target->getPointerWidth(AS); Align = Target->getPointerAlign(AS); ``` where `TK = cast(T)->getKind();` Comment at: lib/Basic/Targets.cpp:2376 +default: + return LangAS::Default; +} should return TargetInfo::getOpenCLTypeAddrSpace https://reviews.llvm.org/D33989 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34175: [driver][macOS] Pick the system version for the deployment target if the SDK is newer than the system
arphaman created this revision. This patch improves the driver by making sure that it picks the system version for the deployment target when the version of the macOS SDK is newer than the system version. Repository: rL LLVM https://reviews.llvm.org/D34175 Files: lib/Driver/ToolChains/Darwin.cpp test/Driver/darwin-sdkroot.c Index: test/Driver/darwin-sdkroot.c === --- test/Driver/darwin-sdkroot.c +++ test/Driver/darwin-sdkroot.c @@ -74,3 +74,12 @@ // CHECK-MACOSX: "-triple" "x86_64-apple-macosx10.10.0" // CHECK-MACOSX: ld // CHECK-MACOSX: "-macosx_version_min" "10.10.0" + +// Ensure that we never pick a version that's based on the SDK that's newer than +// the system version: +// RUN: rm -rf %t/SDKs/MacOSX10.99.99.sdk +// RUN: mkdir -p %t/SDKs/MacOSX10.99.99.sdk +// RUN: %clang -target x86_64-apple-darwin -isysroot %t/SDKs/MacOSX10.99.99.sdk %s -### 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-MACOSX-SYSTEM-VERSION %s + +// CHECK-MACOSX-SYSTEM-VERSION-NOT: 10.99.99" Index: lib/Driver/ToolChains/Darwin.cpp === --- lib/Driver/ToolChains/Darwin.cpp +++ lib/Driver/ToolChains/Darwin.cpp @@ -1118,6 +1118,26 @@ } } +/// Returns the most appropriate macOS target version for the current process. +/// +/// If the macOS SDK version is the same or earlier than the system version, +/// then the SDK version is returned. Otherwise the system version is returned. +static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) { + unsigned Major, Minor, Micro; + llvm::Triple(llvm::sys::getProcessTriple()) + .getMacOSXVersion(Major, Minor, Micro); + VersionTuple SystemVersion(Major, Minor, Micro); + bool HadExtra; + if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro, + HadExtra) || + HadExtra || Major != 10 || Minor >= 100 || Micro >= 100) +return MacOSSDKVersion; + VersionTuple SDKVersion(Major, Minor, Micro); + if (SDKVersion > SystemVersion) +return SystemVersion.getAsString(); + return MacOSSDKVersion; +} + void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { const OptTable &Opts = getDriver().getOpts(); @@ -1210,7 +1230,7 @@ SDK.startswith("iPhoneSimulator")) iOSTarget = Version; else if (SDK.startswith("MacOSX")) - OSXTarget = Version; + OSXTarget = getSystemOrSDKMacOSVersion(Version); else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator")) WatchOSTarget = Version; Index: test/Driver/darwin-sdkroot.c === --- test/Driver/darwin-sdkroot.c +++ test/Driver/darwin-sdkroot.c @@ -74,3 +74,12 @@ // CHECK-MACOSX: "-triple" "x86_64-apple-macosx10.10.0" // CHECK-MACOSX: ld // CHECK-MACOSX: "-macosx_version_min" "10.10.0" + +// Ensure that we never pick a version that's based on the SDK that's newer than +// the system version: +// RUN: rm -rf %t/SDKs/MacOSX10.99.99.sdk +// RUN: mkdir -p %t/SDKs/MacOSX10.99.99.sdk +// RUN: %clang -target x86_64-apple-darwin -isysroot %t/SDKs/MacOSX10.99.99.sdk %s -### 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-MACOSX-SYSTEM-VERSION %s + +// CHECK-MACOSX-SYSTEM-VERSION-NOT: 10.99.99" Index: lib/Driver/ToolChains/Darwin.cpp === --- lib/Driver/ToolChains/Darwin.cpp +++ lib/Driver/ToolChains/Darwin.cpp @@ -1118,6 +1118,26 @@ } } +/// Returns the most appropriate macOS target version for the current process. +/// +/// If the macOS SDK version is the same or earlier than the system version, +/// then the SDK version is returned. Otherwise the system version is returned. +static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) { + unsigned Major, Minor, Micro; + llvm::Triple(llvm::sys::getProcessTriple()) + .getMacOSXVersion(Major, Minor, Micro); + VersionTuple SystemVersion(Major, Minor, Micro); + bool HadExtra; + if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro, + HadExtra) || + HadExtra || Major != 10 || Minor >= 100 || Micro >= 100) +return MacOSSDKVersion; + VersionTuple SDKVersion(Major, Minor, Micro); + if (SDKVersion > SystemVersion) +return SystemVersion.getAsString(); + return MacOSSDKVersion; +} + void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { const OptTable &Opts = getDriver().getOpts(); @@ -1210,7 +1230,7 @@ SDK.startswith("iPhoneSimulator")) iOSTarget = Version; else if (SDK.startswith("MacOSX")) - OSXTarget = Version; + OSXTarget = getSystemOrSDKMacOSVersion(Version); else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator")
[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier
aaron.ballman added a reviewer: rsmith. aaron.ballman added a comment. Adding Richard to the review for some wider perspective than just mine on the overall design. Comment at: lib/Sema/AnalysisBasedWarnings.cpp:296 + + if (ThrowType->isReferenceType()) +ThrowType = ThrowType->castAs() If `ThrowType` can be null, there should be a null pointer check here. If it cannot be null, you should use `getTypePtr()` above instead of `getTypePtrOrNull()`. Comment at: lib/Sema/AnalysisBasedWarnings.cpp:304 + ->getUnqualifiedDesugaredType(); + if (CaughtType == nullptr || CaughtType == ThrowType) +return true; The check for a null `CaughtType` can be hoisted above the if statements, which can then be simplified. Comment at: lib/Sema/AnalysisBasedWarnings.cpp:312 +isCaught = ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType); + return isCaught; +} There's really no point to using a local variable for this. You can return `true` above and return `false` here. Comment at: lib/Sema/AnalysisBasedWarnings.cpp:315 + +static bool isThrowBeCaughtByHandlers(const CXXThrowExpr *CE, + const CXXTryStmt *TryStmt) { `isThrowCaughtByHandlers` (drop the Be) Comment at: lib/Sema/AnalysisBasedWarnings.cpp:317 + const CXXTryStmt *TryStmt) { + for (unsigned H = 0; H < TryStmt->getNumHandlers(); ++H) { +const CXXCatchStmt *CS = TryStmt->getHandler(H); Can you hoist the `getNumHandlers()` call out? e.g., `for (unsigned H = 0, E = TryStmt->getNumHandlers(); H < E; ++H)` Comment at: lib/Sema/AnalysisBasedWarnings.cpp:318 + for (unsigned H = 0; H < TryStmt->getNumHandlers(); ++H) { +const CXXCatchStmt *CS = TryStmt->getHandler(H); +if (isThrowBeCaught(CE, CS)) No need for the local variable, can just call `getHandler()` in the call expression. Comment at: lib/Sema/AnalysisBasedWarnings.cpp:325 + +static bool doesThrowEscapePath(CFGBlock &Block, SourceLocation *OpLoc) { + bool HasThrowOutFunc = false; Since `OpLoc` cannot be null, pass it by reference instead. Comment at: lib/Sema/AnalysisBasedWarnings.cpp:337 +*OpLoc = CE->getThrowLoc(); +for (const CFGBlock::AdjacentBlock I : Block.succs()) + if (I && I->getTerminator() && isa(I->getTerminator())) { This should use `const CFGBlock::AdjacentBlock &` to avoid the copy, but could also use `const auto &` if you wanted (since it's a range-based for loop). Comment at: lib/Sema/AnalysisBasedWarnings.cpp:338 +for (const CFGBlock::AdjacentBlock I : Block.succs()) + if (I && I->getTerminator() && isa(I->getTerminator())) { +const CXXTryStmt *Terminator = cast(I->getTerminator()); Instead of testing that `I` can be dereferenced (which is a bit odd since `I` is not a pointer, but uses a conversion operator), can you test `I->isReachable()` instead? I think a better way to write this might be: ``` if (!I->isReachable()) continue; if (const CXXTryStmt *Terminator = dyn_cast_or_null(I->getTerminator())) { } ``` Comment at: lib/Sema/AnalysisBasedWarnings.cpp:344 + } + return HasThrowOutFunc; +} There's no need for this local variable. You can return `true` here. Comment at: lib/Sema/AnalysisBasedWarnings.cpp:349 + + const unsigned ExitID = cfg->getExit().getBlockID(); + We don't usually mark locals as `const` unless it's a pointer or reference. Comment at: lib/Sema/AnalysisBasedWarnings.cpp:373 +// changes. +for (const CFGBlock::AdjacentBlock I : CurBlock->succs()) + if (I) { Same comment here as above. Comment at: lib/Sema/AnalysisBasedWarnings.cpp:374 +for (const CFGBlock::AdjacentBlock I : CurBlock->succs()) + if (I) { +unsigned next_ID = (I)->getBlockID(); Same comment here as above. Comment at: lib/Sema/AnalysisBasedWarnings.cpp:375 + if (I) { +unsigned next_ID = (I)->getBlockID(); +if (next_ID == ExitID && CurState == FoundPathForThrow) { You can drop the parens around `I`. Also, `next_ID` should be something like `NextID` per the coding style guidelines. Comment at: lib/Sema/AnalysisBasedWarnings.cpp:405 +AnalysisDeclContext &AC) { + CFG *cfg = AC.getCFG(); + if (!cfg) `cfg` should be renamed per coding style guidelines. How about `BodyCFG`? Comment at: lib/Sema/AnalysisBasedWarnings.cpp:416 +static bool isNoexcept(const FunctionDecl *FD) { + if (const FunctionProtoType *FPT = FD->g
[PATCH] D34121: [ubsan] Teach the pointer overflow check that "p - <= p" (PR33430)
vsk added a comment. In https://reviews.llvm.org/D34121#779347, @dtzWill wrote: > Don't mean to block this, but just FYI I won't be able to look into this > carefully until later this week (sorry!). > > Kicked off a rebuild using these patches just now, though! O:) No problem, thanks for taking a look. https://reviews.llvm.org/D34121 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r305328 - [ODRHash] Add TemplateArgument kind to hash.
Author: rtrieu Date: Tue Jun 13 17:21:18 2017 New Revision: 305328 URL: http://llvm.org/viewvc/llvm-project?rev=305328&view=rev Log: [ODRHash] Add TemplateArgument kind to hash. Modified: cfe/trunk/lib/AST/ODRHash.cpp cfe/trunk/test/Modules/odr_hash.cpp Modified: cfe/trunk/lib/AST/ODRHash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=305328&r1=305327&r2=305328&view=diff == --- cfe/trunk/lib/AST/ODRHash.cpp (original) +++ cfe/trunk/lib/AST/ODRHash.cpp Tue Jun 13 17:21:18 2017 @@ -140,7 +140,11 @@ void ODRHash::AddTemplateName(TemplateNa } } -void ODRHash::AddTemplateArgument(TemplateArgument TA) {} +void ODRHash::AddTemplateArgument(TemplateArgument TA) { + const auto Kind = TA.getKind(); + ID.AddInteger(Kind); +} + void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {} void ODRHash::clear() { Modified: cfe/trunk/test/Modules/odr_hash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=305328&r1=305327&r2=305328&view=diff == --- cfe/trunk/test/Modules/odr_hash.cpp (original) +++ cfe/trunk/test/Modules/odr_hash.cpp Tue Jun 13 17:21:18 2017 @@ -1002,6 +1002,24 @@ S2 s2; #endif } +namespace TemplateArgument { +#if defined(FIRST) +template struct U1{}; +struct S1 { + U1 x; +}; +#elif defined(SECOND) +template struct U1{}; +struct S1 { + U1<1> x; +}; +#else +S1 s1; +// expected-error@first.h:* {{'TemplateArgument::S1::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif +} + // Interesting cases that should not cause errors. struct S should not error // while struct T should error at the access specifier mismatch at the end. namespace AllDecls { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34179: [SEMA] PR32318 Handle -ast-dump-all properly.
hintonda created this revision. Handle -ast-dump-all when passed as the only option. https://reviews.llvm.org/D34179 Files: lib/Frontend/ASTConsumers.cpp test/Coverage/ast-printing.c test/Coverage/ast-printing.cpp Index: test/Coverage/ast-printing.cpp === --- test/Coverage/ast-printing.cpp +++ test/Coverage/ast-printing.cpp @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -std=c++14 -ast-print %t.1.cpp -o %t.2.cpp // RUN: diff %t.1.cpp %t.2.cpp // RUN: %clang_cc1 -std=c++14 -ast-dump %s +// RUN: %clang_cc1 -std=c++14 -ast-dump-all %s // RUN: %clang_cc1 -std=c++14 -print-decl-contexts %s // RUN: %clang_cc1 -std=c++14 -fdump-record-layouts %s Index: test/Coverage/ast-printing.c === --- test/Coverage/ast-printing.c +++ test/Coverage/ast-printing.c @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -ast-print %t.1.c -o %t.2.c // RUN: diff %t.1.c %t.2.c // RUN: %clang_cc1 -ast-dump %s +// RUN: %clang_cc1 -ast-dump-all %s // RUN: %clang_cc1 -print-decl-contexts %s #include "c-language-features.inc" Index: lib/Frontend/ASTConsumers.cpp === --- lib/Frontend/ASTConsumers.cpp +++ lib/Frontend/ASTConsumers.cpp @@ -142,7 +142,7 @@ bool DumpDecls, bool Deserialize, bool DumpLookups) { - assert((DumpDecls || DumpLookups) && "nothing to dump"); + assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump"); return llvm::make_unique(nullptr, Deserialize ? ASTPrinter::DumpFull : DumpDecls ? ASTPrinter::Dump : Index: test/Coverage/ast-printing.cpp === --- test/Coverage/ast-printing.cpp +++ test/Coverage/ast-printing.cpp @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -std=c++14 -ast-print %t.1.cpp -o %t.2.cpp // RUN: diff %t.1.cpp %t.2.cpp // RUN: %clang_cc1 -std=c++14 -ast-dump %s +// RUN: %clang_cc1 -std=c++14 -ast-dump-all %s // RUN: %clang_cc1 -std=c++14 -print-decl-contexts %s // RUN: %clang_cc1 -std=c++14 -fdump-record-layouts %s Index: test/Coverage/ast-printing.c === --- test/Coverage/ast-printing.c +++ test/Coverage/ast-printing.c @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -ast-print %t.1.c -o %t.2.c // RUN: diff %t.1.c %t.2.c // RUN: %clang_cc1 -ast-dump %s +// RUN: %clang_cc1 -ast-dump-all %s // RUN: %clang_cc1 -print-decl-contexts %s #include "c-language-features.inc" Index: lib/Frontend/ASTConsumers.cpp === --- lib/Frontend/ASTConsumers.cpp +++ lib/Frontend/ASTConsumers.cpp @@ -142,7 +142,7 @@ bool DumpDecls, bool Deserialize, bool DumpLookups) { - assert((DumpDecls || DumpLookups) && "nothing to dump"); + assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump"); return llvm::make_unique(nullptr, Deserialize ? ASTPrinter::DumpFull : DumpDecls ? ASTPrinter::Dump : ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34156: [LTO] Add -femit-summary-index flag to emit summary for regular LTO
tobiasvk added a comment. In https://reviews.llvm.org/D34156#779270, @pcc wrote: > Have you considered writing the regular LTO summaries unconditionally if > `-flto` was specified? That was how I imagined that the interface would look. Absolutely, if people are OK with that. I would have enabled it by default in our tree anyway. Let me know if you prefer this (and other people if you have objections). > Also, how were you planning to expose the reference graph to the linker? I > gather from your message that you are teaching your linker to read the module > summary index directly from bitcode files. Yep, pretty much. I have a layer between the linker and LLVM that implements a `getRefsBySymbol` API which lets the linker iterate the reference graph. We've had this out of tree for some time, it's just that your recent patch made it straightforward to implement upstream. > I wonder whether it would be worth trying to avoid needing to read summaries > multiple times. The approach that I had in mind was to somehow teach the > linker to add regular object files to the combined summary index by creating > a "global value summary" for each section, with a reference for each > relocation. (This would be similar to how we add regular LTO inputs to the > combined summary in https://reviews.llvm.org/D33922.) Then LTO would run as > usual. Any regular object sections would then naturally participate in the > summary-based dead stripping that LTO already does. It could be done but I'm skeptical about this from a cost/benefit perspective. We'd only save one additional read of the summaries, which is pretty cheap anyway. The GC logic in the linker is non-trivial and doesn't map particularly well to the combined summary (e.g. we'd have to deal with the liveness of groups of symbols rather than individual ones when symbols share an input section). Thanks, Tobias https://reviews.llvm.org/D34156 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34156: [LTO] Add -femit-summary-index flag to emit summary for regular LTO
pcc added a comment. In https://reviews.llvm.org/D34156#779661, @tobiasvk wrote: > In https://reviews.llvm.org/D34156#779270, @pcc wrote: > > > Have you considered writing the regular LTO summaries unconditionally if > > `-flto` was specified? That was how I imagined that the interface would > > look. > > > Absolutely, if people are OK with that. I would have enabled it by default in > our tree anyway. Let me know if you prefer this (and other people if you have > objections). I'd be fine with it. We may want to make it conditional on the target (e.g. the summary wouldn't be much use on Darwin targets right now), but let's see what others think. >> I wonder whether it would be worth trying to avoid needing to read summaries >> multiple times. The approach that I had in mind was to somehow teach the >> linker to add regular object files to the combined summary index by creating >> a "global value summary" for each section, with a reference for each >> relocation. (This would be similar to how we add regular LTO inputs to the >> combined summary in https://reviews.llvm.org/D33922.) Then LTO would run as >> usual. Any regular object sections would then naturally participate in the >> summary-based dead stripping that LTO already does. > > It could be done but I'm skeptical about this from a cost/benefit > perspective. We'd only save one additional read of the summaries, which is > pretty cheap anyway. The GC logic in the linker is non-trivial and doesn't > map particularly well to the combined summary (e.g. we'd have to deal with > the liveness of groups of symbols rather than individual ones when symbols > share an input section). That's a fair point, and now that I think about it it does seem better for GC to be entirely driven by the linker, as you have done. Longer term we may consider replacing summary-based dead stripping entirely with linker-driven dead stripping. https://reviews.llvm.org/D34156 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34182: [analyzer] Performance optimizations for the CloneChecker
teemperor created this revision. Herald added a subscriber: xazax.hun. This patch aims at optimizing the CloneChecker for larger programs. Before this patch we took around 102 seconds to analyze sqlite3 with a complexity value of 50. After this patch we now take 2.1 seconds to analyze sqlite3. The biggest performance optimization is that we now put the constraint for group size before the constraint for the complexity. The group size constraint is much faster in comparison to the complexity constraint as it only does a simple integer comparison. The complexity constraint on the other hand actually traverses each Stmt and even checks the macro stack, so it is obviously not able to handle larger amounts of incoming clones. The new order filters out all the single-clone groups that the type II constraint generates in a faster way before passing the fewer remaining clones to the complexity constraint. This reduced runtime by around 95%. The other change is that we also delay the verification part of the type II clones back in the chain of constraints. This required to split up the constraint into two parts - a verification and a hash constraint (which is also making it more similar to the original design of the clone detection algorithm). The reasoning for this is the same as before: The verification constraint has to traverse many statements and shouldn't be at the start of the constraint chain. However, as the type II hashing has to be the first step in our algorithm, we have no other choice but split this constrain into two different ones. Now our group size and complexity constrains filter out a chunk of the clones before they reach the slow verification step, which reduces the runtime by around 8%. I also kept the full type II constraint around - that now just calls it's two sub-constraints - in case someone doesn't care about the performance benefits of doing this. https://reviews.llvm.org/D34182 Files: include/clang/Analysis/CloneDetection.h lib/Analysis/CloneDetection.cpp lib/StaticAnalyzer/Checkers/CloneChecker.cpp Index: lib/StaticAnalyzer/Checkers/CloneChecker.cpp === --- lib/StaticAnalyzer/Checkers/CloneChecker.cpp +++ lib/StaticAnalyzer/Checkers/CloneChecker.cpp @@ -78,9 +78,10 @@ // because reportSuspiciousClones() wants to search them for errors. std::vector AllCloneGroups; - Detector.findClones(AllCloneGroups, RecursiveCloneTypeIIConstraint(), - MinComplexityConstraint(MinComplexity), - MinGroupSizeConstraint(2), OnlyLargestCloneConstraint()); + Detector.findClones( + AllCloneGroups, RecursiveCloneTypeIIHashConstraint(), + MinGroupSizeConstraint(2), MinComplexityConstraint(MinComplexity), + RecursiveCloneTypeIIVerifyConstraint(), OnlyLargestCloneConstraint()); if (ReportSuspiciousClones) reportSuspiciousClones(BR, Mgr, AllCloneGroups); Index: lib/Analysis/CloneDetection.cpp === --- lib/Analysis/CloneDetection.cpp +++ lib/Analysis/CloneDetection.cpp @@ -381,9 +381,17 @@ return HashCode; } -size_t RecursiveCloneTypeIIConstraint::saveHash( -const Stmt *S, const Decl *D, -std::vector> &StmtsByHash) { +/// Generates and saves a hash code for the given Stmt. +/// \param S The given Stmt. +/// \param D The Decl containing S. +/// \param StmtsByHash Output parameter that will contain the hash codes for +///each StmtSequence in the given Stmt. +/// \return The hash code of the given Stmt. +/// +/// If the given Stmt is a CompoundStmt, this method will also generate +/// hashes for all possible StmtSequences in the children of this Stmt. +size_t saveHash(const Stmt *S, const Decl *D, +std::vector> &StmtsByHash) { llvm::MD5 Hash; ASTContext &Context = D->getASTContext(); @@ -474,6 +482,14 @@ void RecursiveCloneTypeIIConstraint::constrain( std::vector &Sequences) { + RecursiveCloneTypeIIHashConstraint Hash; + Hash.constrain(Sequences); + RecursiveCloneTypeIIVerifyConstraint Verify; + Verify.constrain(Sequences); +} + +void RecursiveCloneTypeIIHashConstraint::constrain( +std::vector &Sequences) { // FIXME: Maybe we can do this in-place and don't need this additional vector. std::vector Result; @@ -513,8 +529,7 @@ for (; i < StmtsByHash.size(); ++i) { // A different hash value means we have reached the end of the sequence. -if (PrototypeHash != StmtsByHash[i].first || -!areSequencesClones(StmtsByHash[i].second, Current.second)) { +if (PrototypeHash != StmtsByHash[i].first) { // The current sequence could be the start of a new CloneGroup. So we // decrement i so that we visit it again in the outer loop. // Note: i can never be 0 at this point because we are just comparing @@ -537,6 +552,14 @@ Sequences = Result
[PATCH] D33977: [libcxx][WIP] Experimental support for a scheduler for use in the parallel stl algorithms
dexonsmith added a comment. You mention that the lock-free `deque` gives a speedup. I agree that should be left for a follow-up, but what kind of speedup did it give? Have you measured whether the parallel algorithm gives a speedup, compared to a non-parallel algorithm? https://reviews.llvm.org/D33977 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34185: [Parser][ObjC] Avoid crashing when skipping to EOF while parsing an ObjC interface/implementation
arphaman created this revision. This patch fixes a Clang crash that happens when an Objective-C source code contains an `@interface`/`@implementation` declaration that follows unterminated `@implementation` declaration that contains a method with a message send that doesn't have the ']'. The crash happens because the `@interface`/`@implementation` parsing methods encounter an unexpected EOF that is caused by parser's attempt to recover from the missing ']' by skipping to the next ']'/';' (it reaches EOF instead since these tokens are not present). Repository: rL LLVM https://reviews.llvm.org/D34185 Files: lib/Parse/ParseObjc.cpp test/Parser/objc-at-implementation-eof-crash.m test/Parser/objc-at-interface-eof-crash.m Index: test/Parser/objc-at-interface-eof-crash.m === --- /dev/null +++ test/Parser/objc-at-interface-eof-crash.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -verify -Wno-objc-root-class %s + +@interface ClassA + +- (void)fileExistsAtPath:(int)x; + +@end + +@interface ClassB + +@end + +@implementation ClassB // expected-note {{implementation started here}} + +- (void) method:(ClassA *)mgr { // expected-note {{to match this '{'}} + mgr fileExistsAtPath:0 +} // expected-error {{expected ']'}} + +@interface ClassC // expected-error {{missing '@end'}} + +@end // expected-error {{expected '}'}} Index: test/Parser/objc-at-implementation-eof-crash.m === --- /dev/null +++ test/Parser/objc-at-implementation-eof-crash.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -verify -Wno-objc-root-class %s + +@interface ClassA + +- (void)fileExistsAtPath:(int)x; + +@end + +@interface ClassB + +@end + +@implementation ClassB // expected-note {{implementation started here}} + +- (void) method:(ClassA *)mgr { // expected-note {{to match this '{'}} + mgr fileExistsAtPath:0 +} // expected-error {{expected ']'}} + +@implementation ClassC // expected-error {{missing '@end'}} + +@end // expected-error {{expected '}'}} Index: lib/Parse/ParseObjc.cpp === --- lib/Parse/ParseObjc.cpp +++ lib/Parse/ParseObjc.cpp @@ -217,6 +217,8 @@ assert(Tok.isObjCAtKeyword(tok::objc_interface) && "ParseObjCAtInterfaceDeclaration(): Expected @interface"); CheckNestedObjCContexts(AtLoc); + if (isEofOrEom()) +return nullptr; ConsumeToken(); // the "interface" identifier // Code completion after '@interface'. @@ -2101,6 +2103,8 @@ assert(Tok.isObjCAtKeyword(tok::objc_implementation) && "ParseObjCAtImplementationDeclaration(): Expected @implementation"); CheckNestedObjCContexts(AtLoc); + if (isEofOrEom()) +return nullptr; ConsumeToken(); // the "implementation" identifier // Code completion after '@implementation'. Index: test/Parser/objc-at-interface-eof-crash.m === --- /dev/null +++ test/Parser/objc-at-interface-eof-crash.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -verify -Wno-objc-root-class %s + +@interface ClassA + +- (void)fileExistsAtPath:(int)x; + +@end + +@interface ClassB + +@end + +@implementation ClassB // expected-note {{implementation started here}} + +- (void) method:(ClassA *)mgr { // expected-note {{to match this '{'}} + mgr fileExistsAtPath:0 +} // expected-error {{expected ']'}} + +@interface ClassC // expected-error {{missing '@end'}} + +@end // expected-error {{expected '}'}} Index: test/Parser/objc-at-implementation-eof-crash.m === --- /dev/null +++ test/Parser/objc-at-implementation-eof-crash.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -verify -Wno-objc-root-class %s + +@interface ClassA + +- (void)fileExistsAtPath:(int)x; + +@end + +@interface ClassB + +@end + +@implementation ClassB // expected-note {{implementation started here}} + +- (void) method:(ClassA *)mgr { // expected-note {{to match this '{'}} + mgr fileExistsAtPath:0 +} // expected-error {{expected ']'}} + +@implementation ClassC // expected-error {{missing '@end'}} + +@end // expected-error {{expected '}'}} Index: lib/Parse/ParseObjc.cpp === --- lib/Parse/ParseObjc.cpp +++ lib/Parse/ParseObjc.cpp @@ -217,6 +217,8 @@ assert(Tok.isObjCAtKeyword(tok::objc_interface) && "ParseObjCAtInterfaceDeclaration(): Expected @interface"); CheckNestedObjCContexts(AtLoc); + if (isEofOrEom()) +return nullptr; ConsumeToken(); // the "interface" identifier // Code completion after '@interface'. @@ -2101,6 +2103,8 @@ assert(Tok.isObjCAtKeyword(tok::objc_implementation) && "ParseObjCAtImplementationDeclaration(): Expected @implementation"); CheckNestedObjCContexts(AtLoc); + if (isEofOrEom()) +return nullptr; ConsumeToken(); // the "implementation" identifier // Code completion after '@imple
[PATCH] D32046: [Preprocessor]Correct Macro-Arg allocation of StringifiedArguments, correct getNumArguments
erichkeane updated this revision to Diff 102458. erichkeane added a comment. Added unit test to validate that this still works throughout the range of arguments, and asserts as soon as you get to the end as requested. https://reviews.llvm.org/D32046 Files: include/clang/Lex/MacroArgs.h lib/Lex/MacroArgs.cpp unittests/Lex/LexerTest.cpp Index: unittests/Lex/LexerTest.cpp === --- unittests/Lex/LexerTest.cpp +++ unittests/Lex/LexerTest.cpp @@ -21,6 +21,8 @@ #include "clang/Lex/ModuleLoader.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" +#include "clang/Lex/MacroArgs.h" +#include "clang/Lex/MacroInfo.h" #include "gtest/gtest.h" using namespace clang; @@ -41,26 +43,31 @@ Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); } - std::vector Lex(StringRef Source) { + std::unique_ptr CreatePP(StringRef Source, TrivialModuleLoader& ModLoader) { std::unique_ptr Buf = llvm::MemoryBuffer::getMemBuffer(Source); SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); -TrivialModuleLoader ModLoader; MemoryBufferCache PCMCache; HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, Diags, LangOpts, Target.get()); -Preprocessor PP(std::make_shared(), Diags, LangOpts, -SourceMgr, PCMCache, HeaderInfo, ModLoader, -/*IILookup =*/nullptr, -/*OwnsHeaderSearch =*/false); -PP.Initialize(*Target); -PP.EnterMainSourceFile(); +std::unique_ptr PP = llvm::make_unique( +std::make_shared(), Diags, LangOpts, SourceMgr, +PCMCache, HeaderInfo, ModLoader, +/*IILookup =*/nullptr, +/*OwnsHeaderSearch =*/false); +PP->Initialize(*Target); +PP->EnterMainSourceFile(); +return PP; + } + std::vector Lex(StringRef Source) { +TrivialModuleLoader ModLoader; +auto PP = CreatePP(Source, ModLoader); std::vector toks; while (1) { Token tok; - PP.Lex(tok); + PP->Lex(tok); if (tok.is(tok::eof)) break; toks.push_back(tok); @@ -365,4 +372,48 @@ EXPECT_EQ(SourceMgr.getFileIDSize(SourceMgr.getFileID(helper1ArgLoc)), 8U); } +TEST_F(LexerTest, DontOverallocateStringifyArgs) { + TrivialModuleLoader ModLoader; + auto PP = CreatePP("\"StrArg\", 5, 'C'", ModLoader); + + llvm::BumpPtrAllocator Allocator; + std::array ArgList; + MacroInfo *MI = PP->AllocateMacroInfo({}); + MI->setIsFunctionLike(); + MI->setArgumentList(ArgList, Allocator); + EXPECT_EQ(3, MI->getNumArgs()); + EXPECT_TRUE(MI->isFunctionLike()); + + Token Eof; + Eof.setKind(tok::eof); + std::vector ArgTokens; + while (1) { +Token tok; +PP->Lex(tok); +if (tok.is(tok::eof)) { + ArgTokens.push_back(Eof); + break; +} +if (tok.is(tok::comma)) + ArgTokens.push_back(Eof); +else + ArgTokens.push_back(tok); + } + + MacroArgs *MA = MacroArgs::create(MI, ArgTokens, false, *PP); + Token Result = MA->getStringifiedArgument(0, *PP, {}, {}); + EXPECT_EQ(tok::string_literal, Result.getKind()); + EXPECT_STREQ("\"\\\"StrArg\\\"\"", Result.getLiteralData()); + Result = MA->getStringifiedArgument(1, *PP, {}, {}); + EXPECT_EQ(tok::string_literal, Result.getKind()); + EXPECT_STREQ("\"5\"", Result.getLiteralData()); + Result = MA->getStringifiedArgument(2, *PP, {}, {}); + EXPECT_EQ(tok::string_literal, Result.getKind()); + EXPECT_STREQ("\"'C'\"", Result.getLiteralData()); +#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST + EXPECT_DEATH(MA->getStringifiedArgument(3, *PP, {}, {}), + "Invalid argument number!"); +#endif +} + } // anonymous namespace Index: lib/Lex/MacroArgs.cpp === --- lib/Lex/MacroArgs.cpp +++ lib/Lex/MacroArgs.cpp @@ -44,20 +44,22 @@ // Otherwise, use the best fit. ClosestMatch = (*Entry)->NumUnexpArgTokens; } - + MacroArgs *Result; if (!ResultEnt) { // Allocate memory for a MacroArgs object with the lexer tokens at the end. -Result = (MacroArgs*)malloc(sizeof(MacroArgs) + -UnexpArgTokens.size() * sizeof(Token)); +Result = (MacroArgs *)malloc(sizeof(MacroArgs) + + UnexpArgTokens.size() * sizeof(Token)); // Construct the MacroArgs object. -new (Result) MacroArgs(UnexpArgTokens.size(), VarargsElided); +new (Result) +MacroArgs(UnexpArgTokens.size(), VarargsElided, MI->getNumArgs()); } else { Result = *ResultEnt; // Unlink this node from the preprocessors singly linked list. *ResultEnt = Result->ArgCache; Result->NumUnexpArgTokens = UnexpArgTokens.size(); Result->VarargsElided = VarargsElided; +Result->NumMacroArgs = MI->getNumArgs(); } // Copy the actual unexpanded tokens to immediately after the result ptr. @@ -298,12 +300,
[PATCH] D33976: [clang] Fix format specifiers fixits
mehdi_amini added a comment. In https://reviews.llvm.org/D33976#776486, @mehdi_amini wrote: > In https://reviews.llvm.org/D33976#775918, @alexshap wrote: > > > @mehdi_amini , thanks, i see, regarding the "opposite issue" - probably an > > example / test case would be helpful, that looks like a separate issue. > > Thanks for adding @ahatanak and @arphaman, that would be wonderful if smb > > could look at this diff (which, besides the fix, adds tests) > > > I'll CC you on the bug when I get time to reduce the test case and file the > bug. I finally got to reduce it: https://bugs.llvm.org/show_bug.cgi?id=33447 Repository: rL LLVM https://reviews.llvm.org/D33976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r305352 - Creating release candidate rc3 from release_401 branch
Author: tstellar Date: Tue Jun 13 20:04:51 2017 New Revision: 305352 URL: http://llvm.org/viewvc/llvm-project?rev=305352&view=rev Log: Creating release candidate rc3 from release_401 branch Added: libcxx/tags/RELEASE_401/rc3/ (props changed) - copied from r305351, libcxx/branches/release_40/ Propchange: libcxx/tags/RELEASE_401/rc3/ -- --- svn:mergeinfo (added) +++ svn:mergeinfo Tue Jun 13 20:04:51 2017 @@ -0,0 +1,2 @@ +/libcxx/branches/apple:136569-137939 +/libcxx/trunk:292013,292091,292607,292990,293154,293197,293581,294133,294142,294431 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] r305359 - Creating release candidate rc3 from release_401 branch
Author: tstellar Date: Tue Jun 13 20:05:11 2017 New Revision: 305359 URL: http://llvm.org/viewvc/llvm-project?rev=305359&view=rev Log: Creating release candidate rc3 from release_401 branch Added: libunwind/tags/RELEASE_401/rc3/ (props changed) - copied from r305358, libunwind/branches/release_40/ Propchange: libunwind/tags/RELEASE_401/rc3/ -- svn:mergeinfo = /libunwind/trunk:292723,296358-296359 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxxabi] r305353 - Creating release candidate rc3 from release_401 branch
Author: tstellar Date: Tue Jun 13 20:04:54 2017 New Revision: 305353 URL: http://llvm.org/viewvc/llvm-project?rev=305353&view=rev Log: Creating release candidate rc3 from release_401 branch Added: libcxxabi/tags/RELEASE_401/rc3/ (props changed) - copied from r305352, libcxxabi/branches/release_40/ Propchange: libcxxabi/tags/RELEASE_401/rc3/ -- svn:mergeinfo = /libcxxabi/trunk:292135,292418,292638 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r305360 - [ODRHash] Hash Expr for TemplateArgument::Expression
Author: rtrieu Date: Tue Jun 13 20:28:00 2017 New Revision: 305360 URL: http://llvm.org/viewvc/llvm-project?rev=305360&view=rev Log: [ODRHash] Hash Expr for TemplateArgument::Expression Modified: cfe/trunk/lib/AST/ODRHash.cpp cfe/trunk/test/Modules/odr_hash.cpp Modified: cfe/trunk/lib/AST/ODRHash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=305360&r1=305359&r2=305360&view=diff == --- cfe/trunk/lib/AST/ODRHash.cpp (original) +++ cfe/trunk/lib/AST/ODRHash.cpp Tue Jun 13 20:28:00 2017 @@ -143,6 +143,22 @@ void ODRHash::AddTemplateName(TemplateNa void ODRHash::AddTemplateArgument(TemplateArgument TA) { const auto Kind = TA.getKind(); ID.AddInteger(Kind); + + switch (Kind) { +case TemplateArgument::Null: +case TemplateArgument::Type: +case TemplateArgument::Declaration: +case TemplateArgument::NullPtr: +case TemplateArgument::Integral: +case TemplateArgument::Template: +case TemplateArgument::TemplateExpansion: + break; +case TemplateArgument::Expression: + AddStmt(TA.getAsExpr()); + break; +case TemplateArgument::Pack: + break; + } } void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {} Modified: cfe/trunk/test/Modules/odr_hash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=305360&r1=305359&r2=305360&view=diff == --- cfe/trunk/test/Modules/odr_hash.cpp (original) +++ cfe/trunk/test/Modules/odr_hash.cpp Tue Jun 13 20:28:00 2017 @@ -1018,6 +1018,39 @@ S1 s1; // expected-error@first.h:* {{'TemplateArgument::S1::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S1' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'x' does not match}} #endif + +#if defined(FIRST) +template struct U2{}; +struct S2 { + using T = U2<2>; +}; +#elif defined(SECOND) +template struct U2{}; +struct S2 { + using T = U2<(2)>; +}; +#else +S2 s2; +// expected-error@second.h:* {{'TemplateArgument::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'T' with underlying type 'U2<(2)>'}} +// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U2<2>'}} +#endif + +#if defined(FIRST) +template struct U3{}; +struct S3 { + using T = U3<2>; +}; +#elif defined(SECOND) +template struct U3{}; +struct S3 { + using T = U3<1 + 1>; +}; +#else +S3 s3; +// expected-error@second.h:* {{'TemplateArgument::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'T' with underlying type 'U3<1 + 1>'}} +// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U3<2>'}} +#endif + } // Interesting cases that should not cause errors. struct S should not error ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r284060 - Implement MS _BitScan intrinsics
On Mon, Jun 12, 2017 at 2:01 PM, Erik Schwiebert via cfe-commits wrote: > SGTM too. Regarding Duncan's last question -- I can't think of any such > customer. :) If you all think the right thing for clang to do is to infer > LLP64 behavior on LP64 (Darwin) + ms_extensions, then that is fine with me! SGTM as well! > > Thanks all! > Schwieb > > -Original Message- > From: dexonsm...@apple.com [mailto:dexonsm...@apple.com] > Sent: Monday, June 12, 2017 1:55 PM > To: Reid Kleckner > Cc: Saleem Abdulrasool ; Albert Gutowski > ; David Majnemer ; > cfe-commits ; Erik Schwiebert > > Subject: Re: r284060 - Implement MS _BitScan intrinsics > > >> On Jun 12, 2017, at 12:44, Reid Kleckner wrote: >> >>> On Wed, Jun 7, 2017 at 7:31 PM, Saleem Abdulrasool >>> wrote: >>> I'm worried about changing this signature all the time. I suspect that it >>> will cause the following to be emitted for valid code: >>> >>> warning: incompatible pointer types passing 'unsigned long *' to parameter >>> of type 'unsigned int *' [-Wincompatible-pointer-types] >>> >>> Switching the signature on LP64 sounds much better to me. >> >> Right, we have to do this. It needs to be `long` on Windows. > > SGTM. We'll go that way. +1 here! >> On Jun 8, 2017, at 12:21, Erik Schwiebert wrote: >> >> It’s probably also better to not try to infer our weird desired behavior. It >> should probably be controlled by a specific driver directive, like >> “-fms-extensions-lp64-intrinsics” or something like that. Using a new >> directive means that nobody can accidentally get this behavior if they for >> some reason do want LLP64 behavior with Windows intrinsics. > > This seems overly complicated. Is there a customer that: > - is on LP64, > - is using -fms-extensions, > - is using these intrinsics, and > - wants them to be 64-bit longs instead of 32-bit ints? > Put another way: who would use these intrinsics on LP64 and *not* want to > mimic LLP64? > > If everyone using the intrinsics on LP64 is going to have to specify > -fms-extensions-lp64-intrinsics, then we should just imply it. > ___ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits -- Bruno Cardoso Lopes http://www.brunocardoso.cc ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r305361 - [ODRHash] Hash Template and TemplateExpansion in TemplateArgument.
Author: rtrieu Date: Tue Jun 13 22:17:26 2017 New Revision: 305361 URL: http://llvm.org/viewvc/llvm-project?rev=305361&view=rev Log: [ODRHash] Hash Template and TemplateExpansion in TemplateArgument. Modified: cfe/trunk/lib/AST/ODRHash.cpp cfe/trunk/test/Modules/odr_hash.cpp Modified: cfe/trunk/lib/AST/ODRHash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=305361&r1=305360&r2=305361&view=diff == --- cfe/trunk/lib/AST/ODRHash.cpp (original) +++ cfe/trunk/lib/AST/ODRHash.cpp Tue Jun 13 22:17:26 2017 @@ -150,13 +150,16 @@ void ODRHash::AddTemplateArgument(Templa case TemplateArgument::Declaration: case TemplateArgument::NullPtr: case TemplateArgument::Integral: + break; case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: + AddTemplateName(TA.getAsTemplateOrTemplatePattern()); break; case TemplateArgument::Expression: AddStmt(TA.getAsExpr()); break; case TemplateArgument::Pack: + llvm_unreachable("Pack"); break; } } Modified: cfe/trunk/test/Modules/odr_hash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=305361&r1=305360&r2=305361&view=diff == --- cfe/trunk/test/Modules/odr_hash.cpp (original) +++ cfe/trunk/test/Modules/odr_hash.cpp Tue Jun 13 22:17:26 2017 @@ -1051,6 +1051,24 @@ S3 s3; // expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'U3<2>'}} #endif +#if defined(FIRST) +template struct T4a {}; +template class T> struct U4 {}; +struct S4 { + U4 x; +}; +#elif defined(SECOND) +template struct T4b {}; +template class T> struct U4 {}; +struct S4 { + U4 x; +}; +#else +S4 s4; +// expected-error@first.h:* {{'TemplateArgument::S4::x' from module 'FirstModule' is not present in definition of 'TemplateArgument::S4' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif + } // Interesting cases that should not cause errors. struct S should not error ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r305362 - [ODRHash] Remove debugging code from r305361
Author: rtrieu Date: Tue Jun 13 22:19:58 2017 New Revision: 305362 URL: http://llvm.org/viewvc/llvm-project?rev=305362&view=rev Log: [ODRHash] Remove debugging code from r305361 Modified: cfe/trunk/lib/AST/ODRHash.cpp Modified: cfe/trunk/lib/AST/ODRHash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=305362&r1=305361&r2=305362&view=diff == --- cfe/trunk/lib/AST/ODRHash.cpp (original) +++ cfe/trunk/lib/AST/ODRHash.cpp Tue Jun 13 22:19:58 2017 @@ -159,7 +159,6 @@ void ODRHash::AddTemplateArgument(Templa AddStmt(TA.getAsExpr()); break; case TemplateArgument::Pack: - llvm_unreachable("Pack"); break; } } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34021: [coroutines] Fix co_await for range statement
EricWF updated this revision to Diff 102472. EricWF added a comment. - Remove changes to how `CoroutineSuspendExpr`s `ExprValueType` is calculated. They were incorrect. However this means that Clang still fails to compile `co_await` and `co_yield` expressions where `await_resume` returns an lvalue reference. @GorNishanov Can you take a look at this? Reproducer: struct AwaitResumeReturnsLValue { bool await_ready(); void await_suspend(std::experimental::coroutine_handle<>); int& await_resume(); }; void AwaitReturnsLValue() { AwaitResumeReturnsLValue a; int& x = co_await a; } https://reviews.llvm.org/D34021 Files: include/clang/Sema/Sema.h lib/Sema/SemaCoroutine.cpp lib/Sema/SemaStmt.cpp test/SemaCXX/co_await-range-for.cpp Index: test/SemaCXX/co_await-range-for.cpp === --- /dev/null +++ test/SemaCXX/co_await-range-for.cpp @@ -0,0 +1,165 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts \ +// RUN:-fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify \ +// RUN:-fblocks +#include "Inputs/std-coroutine.h" + +using namespace std::experimental; + + +template +struct Awaiter { + bool await_ready(); + void await_suspend(coroutine_handle<>); + Begin await_resume(); +}; + +template struct BeginTag { BeginTag() = delete; }; +template struct IncTag { IncTag() = delete; }; + +template +struct CoawaitTag { CoawaitTag() = delete; }; + +template +struct Iter { + using value_type = T; + using reference = T &; + using pointer = T *; + + IncTag operator++(); + reference operator*(); + pointer operator->(); +}; +template bool operator==(Iter, Iter); +template bool operator!=(Iter, Iter); + +template +struct Range { + BeginTag> begin(); + Iter end(); +}; + +struct MyForLoopArrayAwaiter { + struct promise_type { +MyForLoopArrayAwaiter get_return_object() { return {}; } +void return_void(); +void unhandled_exception(); +suspend_never initial_suspend(); +suspend_never final_suspend(); +template +Awaiter await_transform(T *) = delete; // expected-note {{explicitly deleted}} + }; +}; +MyForLoopArrayAwaiter g() { + int arr[10] = {0}; + for co_await(auto i : arr) {} + // expected-error@-1 {{call to deleted member function 'await_transform'}} + // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}} +} + +struct ForLoopAwaiterBadBeginTransform { + struct promise_type { +ForLoopAwaiterBadBeginTransform get_return_object(); +void return_void(); +void unhandled_exception(); +suspend_never initial_suspend(); +suspend_never final_suspend(); + +template +Awaiter await_transform(BeginTag) = delete; // expected-note 1+ {{explicitly deleted}} + +template +CoawaitTag await_transform(IncTag); // expected-note 1+ {{candidate}} + }; +}; +ForLoopAwaiterBadBeginTransform bad_begin() { + Range R; + for co_await(auto i : R) {} + // expected-error@-1 {{call to deleted member function 'await_transform'}} + // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}} +} +template +ForLoopAwaiterBadBeginTransform bad_begin_template(Dummy) { + Range R; + for co_await(auto i : R) {} + // expected-error@-1 {{call to deleted member function 'await_transform'}} + // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}} +} +template ForLoopAwaiterBadBeginTransform bad_begin_template(int); // expected-note {{requested here}} + +template +Awaiter operator co_await(CoawaitTag) = delete; +// expected-note@-1 1+ {{explicitly deleted}} + +struct ForLoopAwaiterBadIncTransform { + struct promise_type { +ForLoopAwaiterBadIncTransform get_return_object(); +void return_void(); +void unhandled_exception(); +suspend_never initial_suspend(); +suspend_never final_suspend(); + +template +Awaiter await_transform(BeginTag e); + +template +CoawaitTag await_transform(IncTag); + }; +}; +ForLoopAwaiterBadIncTransform bad_inc_transform() { + Range R; + for co_await(auto i : R) {} + // expected-error@-1 {{overload resolution selected deleted operator 'co_await'}} + // expected-note@-2 {{in implicit call to 'operator++' for iterator of type 'Range'}} +} + +template +ForLoopAwaiterBadIncTransform bad_inc_transform_template(Dummy) { + Range R; + for co_await(auto i : R) {} + // expected-error@-1 {{overload resolution selected deleted operator 'co_await'}} + // expected-note@-2 {{in implicit call to 'operator++' for iterator of type 'Range'}} +} +template ForLoopAwaiterBadIncTransform bad_inc_transform_template(long); // expected-note {{requested here}} + +// Ensure we mark and check the function as a coroutine even if it's +// never instantiated. +template +constexpr void never_instant(T) { + static_assert(sizeof(T) != sizeof(T), "function should not be instantiated"); + for co_await(auto i : foo(T{})) {} +
r305363 - [coroutines] Fix co_await for range statement
Author: ericwf Date: Tue Jun 13 22:24:55 2017 New Revision: 305363 URL: http://llvm.org/viewvc/llvm-project?rev=305363&view=rev Log: [coroutines] Fix co_await for range statement Summary: Currently we build the co_await expressions on the wrong implicit statements of the implicit ranged for; Specifically we build the co_await expression wrapping the range declaration, but it should wrap the begin expression. This patch fixes co_await on range for. Reviewers: rsmith, GorNishanov Reviewed By: GorNishanov Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D34021 Added: cfe/trunk/test/SemaCXX/co_await-range-for.cpp Modified: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaCoroutine.cpp cfe/trunk/lib/Sema/SemaStmt.cpp Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=305363&r1=305362&r2=305363&view=diff == --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Tue Jun 13 22:24:55 2017 @@ -8364,6 +8364,8 @@ public: //======// // C++ Coroutines TS // + bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc, + StringRef Keyword); ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E); ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E); StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E); Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=305363&r1=305362&r2=305363&view=diff == --- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original) +++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Tue Jun 13 22:24:55 2017 @@ -470,11 +470,11 @@ static FunctionScopeInfo *checkCoroutine return ScopeInfo; } -static bool actOnCoroutineBodyStart(Sema &S, Scope *SC, SourceLocation KWLoc, -StringRef Keyword) { - if (!checkCoroutineContext(S, KWLoc, Keyword)) +bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc, + StringRef Keyword) { + if (!checkCoroutineContext(*this, KWLoc, Keyword)) return false; - auto *ScopeInfo = S.getCurFunction(); + auto *ScopeInfo = getCurFunction(); assert(ScopeInfo->CoroutinePromise); // If we have existing coroutine statements then we have already built @@ -484,24 +484,24 @@ static bool actOnCoroutineBodyStart(Sema ScopeInfo->setNeedsCoroutineSuspends(false); - auto *Fn = cast(S.CurContext); + auto *Fn = cast(CurContext); SourceLocation Loc = Fn->getLocation(); // Build the initial suspend point auto buildSuspends = [&](StringRef Name) mutable -> StmtResult { ExprResult Suspend = -buildPromiseCall(S, ScopeInfo->CoroutinePromise, Loc, Name, None); +buildPromiseCall(*this, ScopeInfo->CoroutinePromise, Loc, Name, None); if (Suspend.isInvalid()) return StmtError(); -Suspend = buildOperatorCoawaitCall(S, SC, Loc, Suspend.get()); +Suspend = buildOperatorCoawaitCall(*this, SC, Loc, Suspend.get()); if (Suspend.isInvalid()) return StmtError(); -Suspend = S.BuildResolvedCoawaitExpr(Loc, Suspend.get(), - /*IsImplicit*/ true); -Suspend = S.ActOnFinishFullExpr(Suspend.get()); +Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.get(), + /*IsImplicit*/ true); +Suspend = ActOnFinishFullExpr(Suspend.get()); if (Suspend.isInvalid()) { - S.Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required) + Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required) << ((Name == "initial_suspend") ? 0 : 1); - S.Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword; + Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword; return StmtError(); } return cast(Suspend.get()); @@ -521,7 +521,7 @@ static bool actOnCoroutineBodyStart(Sema } ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) { - if (!actOnCoroutineBodyStart(*this, S, Loc, "co_await")) { + if (!ActOnCoroutineBodyStart(S, Loc, "co_await")) { CorrectDelayedTyposInExpr(E); return ExprError(); } @@ -613,7 +613,7 @@ ExprResult Sema::BuildResolvedCoawaitExp } ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) { - if (!actOnCoroutineBodyStart(*this, S, Loc, "co_yield")) { + if (!ActOnCoroutineBodyStart(S, Loc, "co_yield")) { CorrectDelayedTyposInExpr(E); return ExprError(); } @@ -658,14 +658,15 @@ ExprResult Sema::BuildCoyieldExpr(Source if (RSS.IsInvalid) return ExprError(); - Expr *Res = new (Con
[libcxx] r305365 - Implement the non-parallel versions of reduce and transform_reduce for C++17
Author: marshall Date: Tue Jun 13 23:48:45 2017 New Revision: 305365 URL: http://llvm.org/viewvc/llvm-project?rev=305365&view=rev Log: Implement the non-parallel versions of reduce and transform_reduce for C++17 Added: libcxx/trunk/test/std/numerics/numeric.ops/reduce/ libcxx/trunk/test/std/numerics/numeric.ops/reduce/reduce_iter_iter.pass.cpp libcxx/trunk/test/std/numerics/numeric.ops/reduce/reduce_iter_iter_T.pass.cpp libcxx/trunk/test/std/numerics/numeric.ops/reduce/reduce_iter_iter_T_op.pass.cpp libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/ libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_init_bop_uop.pass.cpp libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init.pass.cpp libcxx/trunk/test/std/numerics/numeric.ops/transform.reduce/transform_reduce_iter_iter_iter_init_op_op.pass.cpp Modified: libcxx/trunk/include/numeric Modified: libcxx/trunk/include/numeric URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/numeric?rev=305365&r1=305364&r2=305365&view=diff == --- libcxx/trunk/include/numeric (original) +++ libcxx/trunk/include/numeric Tue Jun 13 23:48:45 2017 @@ -25,6 +25,18 @@ template +typename iterator_traits::value_type +reduce(InputIterator first, InputIterator last); // C++17 + +template +T +reduce(InputIterator first, InputIterator last, T init); // C++17 + +template +T +reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); // C++17 + template T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); @@ -34,6 +46,23 @@ template +T +transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init); // C++17 + +template +T +transform_reduce(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, + BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); // C++17 + +template +T +transform_reduce(InputIterator first, InputIterator last, T init, + BinaryOperation binary_op, UnaryOperation unary_op); // C++17 + template OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result); @@ -114,6 +143,35 @@ accumulate(_InputIterator __first, _Inpu return __init; } +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +reduce(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOp __b) +{ +for (; __first != __last; ++__first) +__init = __b(__init, *__first); +return __init; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +reduce(_InputIterator __first, _InputIterator __last, _Tp __init) +{ +return _VSTD::reduce(__first, __last, __init, _VSTD::plus<>()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename iterator_traits<_InputIterator>::value_type +reduce(_InputIterator __first, _InputIterator __last) +{ +return _VSTD::reduce(__first, __last, + typename iterator_traits<_InputIterator>::value_type{}); +} +#endif + template inline _LIBCPP_INLINE_VISIBILITY _Tp @@ -135,6 +193,41 @@ inner_product(_InputIterator1 __first1, return __init; } +#if _LIBCPP_STD_VER > 14 +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +transform_reduce(_InputIterator __first, _InputIterator __last, + _Tp __init, _BinaryOp __b, _UnaryOp __u) +{ +for (; __first != __last; ++__first) +__init = __b(__init, __u(*__first)); +return __init; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init, _BinaryOp1 __b1, _BinaryOp2 __b2) +{ +for (; __first1 != __last1; ++__first1, (void) ++__first2) +__init = __b1(__init, __b2(*__first1, *__first2)); +return __init; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +_Tp +transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init) +{ +return _VSTD::transform_reduce(__first1, __last1, __first2, __init, + _VSTD::plus<>(), _VSTD::multiplies<>()); +} +#endif + template inline _LIBCPP_INLINE_VISIBILITY _OutputIterator Added: libcxx/trunk/test/std/numerics/numeric.ops/reduce/reduce_iter_iter.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/numerics/numeric.ops/reduce/reduce_iter_iter.pass.cpp?rev=305365&view=auto == --- libcxx/trunk/test/std/numerics/numeric.ops/reduce/reduce_iter_iter.pass.cpp (added) +++ libcxx/trunk/test/std/numerics/numeric.ops/reduce/reduce_iter_iter.pass.cpp
[libcxx] r305370 - Add an `__is_inplace_index` metafunction.
Author: mpark Date: Wed Jun 14 00:51:18 2017 New Revision: 305370 URL: http://llvm.org/viewvc/llvm-project?rev=305370&view=rev Log: Add an `__is_inplace_index` metafunction. Summary: This is used to constrain `variant`'s converting constructor correctly. Reviewers: EricWF, mclow.lists Reviewed By: EricWF, mclow.lists Differential Revision: https://reviews.llvm.org/D34111 Added: libcxx/trunk/test/libcxx/utilities/utility/__is_inplace_index.pass.cpp libcxx/trunk/test/libcxx/utilities/utility/__is_inplace_type.pass.cpp Modified: libcxx/trunk/include/utility Modified: libcxx/trunk/include/utility URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?rev=305370&r1=305369&r2=305370&view=diff == --- libcxx/trunk/include/utility (original) +++ libcxx/trunk/include/utility Wed Jun 14 00:51:18 2017 @@ -930,6 +930,12 @@ template struct __is_inplace template using __is_inplace_type = __is_inplace_type_imp<__uncvref_t<_Tp>>; +template struct __is_inplace_index_imp : false_type {}; +template struct __is_inplace_index_imp> : true_type {}; + +template +using __is_inplace_index = __is_inplace_index_imp<__uncvref_t<_Tp>>; + #endif // _LIBCPP_STD_VER > 14 template Added: libcxx/trunk/test/libcxx/utilities/utility/__is_inplace_index.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/utilities/utility/__is_inplace_index.pass.cpp?rev=305370&view=auto == --- libcxx/trunk/test/libcxx/utilities/utility/__is_inplace_index.pass.cpp (added) +++ libcxx/trunk/test/libcxx/utilities/utility/__is_inplace_index.pass.cpp Wed Jun 14 00:51:18 2017 @@ -0,0 +1,32 @@ +//===--===// +// +// 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 using __is_inplace_index + +#include + +struct S {}; + +int main() { + using I = std::in_place_index_t<0>; + static_assert( std::__is_inplace_index::value, ""); + static_assert( std::__is_inplace_index::value, ""); + static_assert( std::__is_inplace_index::value, ""); + static_assert( std::__is_inplace_index::value, ""); + static_assert( std::__is_inplace_index::value, ""); + static_assert( std::__is_inplace_index::value, ""); + static_assert( std::__is_inplace_index::value, ""); + static_assert( std::__is_inplace_index::value, ""); + static_assert( std::__is_inplace_index::value, ""); + static_assert(!std::__is_inplace_index>::value, ""); + static_assert(!std::__is_inplace_index::value, ""); + static_assert(!std::__is_inplace_index::value, ""); + static_assert(!std::__is_inplace_index::value, ""); + static_assert(!std::__is_inplace_index::value, ""); +} Added: libcxx/trunk/test/libcxx/utilities/utility/__is_inplace_type.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/utilities/utility/__is_inplace_type.pass.cpp?rev=305370&view=auto == --- libcxx/trunk/test/libcxx/utilities/utility/__is_inplace_type.pass.cpp (added) +++ libcxx/trunk/test/libcxx/utilities/utility/__is_inplace_type.pass.cpp Wed Jun 14 00:51:18 2017 @@ -0,0 +1,32 @@ +//===--===// +// +// 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 using __is_inplace_type + +#include + +struct S {}; + +int main() { + using T = std::in_place_type_t; + static_assert( std::__is_inplace_type::value, ""); + static_assert( std::__is_inplace_type::value, ""); + static_assert( std::__is_inplace_type::value, ""); + static_assert( std::__is_inplace_type::value, ""); + static_assert( std::__is_inplace_type::value, ""); + static_assert( std::__is_inplace_type::value, ""); + static_assert( std::__is_inplace_type::value, ""); + static_assert( std::__is_inplace_type::value, ""); + static_assert( std::__is_inplace_type::value, ""); + static_assert(!std::__is_inplace_type>::value, ""); + static_assert(!std::__is_inplace_type::value, ""); + static_assert(!std::__is_inplace_type::value, ""); + static_assert(!std::__is_inplace_type::value, ""); + static_assert(!std::__is_inplace_type::value, ""); +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34194: [coroutines] Allow co_await and co_yield expressions that return an lvalue to compile
EricWF created this revision. The title says it all. However I can't figure out how to test `int& x = co_yield 42;` since that expression doesn't seem to want to parse. https://reviews.llvm.org/D34194 Files: lib/CodeGen/CGCoroutine.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCoroutines/coro-await.cpp Index: test/CodeGenCoroutines/coro-await.cpp === --- test/CodeGenCoroutines/coro-await.cpp +++ test/CodeGenCoroutines/coro-await.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 \ +// RUN: -emit-llvm %s -o - -disable-llvm-passes -Wno-coroutine -Wno-unused | FileCheck %s namespace std { namespace experimental { @@ -278,3 +279,36 @@ suspend_always lval; co_await lval; } + +struct AwaitResumeReturnsLValue { + bool await_ready(); + void await_suspend(std::experimental::coroutine_handle<>); + int& await_resume(); +}; + + +template<> +struct std::experimental::coroutine_traits { + struct promise_type { +void get_return_object(); +init_susp initial_suspend(); +final_susp final_suspend(); +void return_void(); + }; +}; + +// Verifies that we don't chrash when returning an lvalue from a await_resume() +// expression. +// CHECK-LABEL: define void @_Z18AwaitReturnsLValued(double) +// CHECK-NOT: define +void AwaitReturnsLValue(double) { + AwaitResumeReturnsLValue a; + // CHECK: await.ready: + // CHECK-NEXT: %call13 = call dereferenceable(4) i32* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* %a) + // CHECK-NEXT: store i32* %call13, i32** %x, align 8 + int& x = co_await a; + // CHECK: await2.ready: + // CHECK-NEXT: %call22 = call dereferenceable(4) i32* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* %ref.tmp14) + // CHECK-NEXT: store i32* %call22, i32** %y, align 8 + int& y = co_await AwaitResumeReturnsLValue{}; +} Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2550,9 +2550,11 @@ RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot = AggValueSlot::ignored(), bool ignoreResult = false); + LValue EmitCoawaitLValue(const CoawaitExpr *E); RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot = AggValueSlot::ignored(), bool ignoreResult = false); + LValue EmitCoyieldLValue(const CoyieldExpr *E); RValue EmitCoroutineIntrinsic(const CallExpr *E, unsigned int IID); void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false); Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1158,6 +1158,11 @@ case Expr::MaterializeTemporaryExprClass: return EmitMaterializeTemporaryExpr(cast(E)); + + case Expr::CoawaitExprClass: +return EmitCoawaitLValue(cast(E)); + case Expr::CoyieldExprClass: +return EmitCoyieldLValue(cast(E)); } } Index: lib/CodeGen/CGCoroutine.cpp === --- lib/CodeGen/CGCoroutine.cpp +++ lib/CodeGen/CGCoroutine.cpp @@ -148,10 +148,16 @@ // // See llvm's docs/Coroutines.rst for more details. // -static RValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Coro, +namespace { + struct LValueOrRValue { +LValue LV; +RValue RV; + }; +} +static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Coro, CoroutineSuspendExpr const &S, AwaitKind Kind, AggValueSlot aggSlot, -bool ignoreResult) { +bool ignoreResult, bool forLValue) { auto *E = S.getCommonExpr(); // FIXME: rsmith 5/22/2017. Does it still make sense for us to have a @@ -217,29 +223,65 @@ // Emit await_resume expression. CGF.EmitBlock(ReadyBlock); - return CGF.EmitAnyExpr(S.getResumeExpr(), aggSlot, ignoreResult); + assert(isa(S.getResumeExpr()) || isa(S.getResumeExpr())); + LValueOrRValue Res; + if (forLValue) +Res.LV = CGF.EmitLValue(S.getResumeExpr()); + else +Res.RV = CGF.EmitAnyExpr(S.getResumeExpr(), aggSlot, ignoreResult); + return Res; } RValue CodeGenFunction::EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot, bool ignoreResult) { return emitSuspendExpression(*this, *CurCoro.Data, E, CurCoro.Data->CurrentAwaitKind, aggSlot, - ignoreR
[PATCH] D34194: [coroutines] Allow co_await and co_yield expressions that return an lvalue to compile
EricWF updated this revision to Diff 102485. EricWF edited the summary of this revision. EricWF added a comment. - Fix assertion for co_yield. https://reviews.llvm.org/D34194 Files: lib/AST/ExprClassification.cpp lib/CodeGen/CGCoroutine.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCoroutines/coro-await.cpp Index: test/CodeGenCoroutines/coro-await.cpp === --- test/CodeGenCoroutines/coro-await.cpp +++ test/CodeGenCoroutines/coro-await.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 \ +// RUN: -emit-llvm %s -o - -disable-llvm-passes -Wno-coroutine -Wno-unused | FileCheck %s namespace std { namespace experimental { @@ -278,3 +279,40 @@ suspend_always lval; co_await lval; } + +struct AwaitResumeReturnsLValue { + bool await_ready(); + void await_suspend(std::experimental::coroutine_handle<>); + int& await_resume(); +}; + + +template<> +struct std::experimental::coroutine_traits { + struct promise_type { +void get_return_object(); +init_susp initial_suspend(); +final_susp final_suspend(); +void return_void(); +AwaitResumeReturnsLValue yield_value(int); + }; +}; + +// Verifies that we don't chrash when returning an lvalue from a await_resume() +// expression. +// CHECK-LABEL: define void @_Z18AwaitReturnsLValued(double) +// CHECK-NOT: define +void AwaitReturnsLValue(double) { + AwaitResumeReturnsLValue a; + // CHECK: await.ready: + // CHECK-NEXT: %call13 = call dereferenceable(4) i32* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* %a) + // CHECK-NEXT: store i32* %call13, i32** %x, align 8 + int& x = co_await a; + // CHECK: await2.ready: + // CHECK-NEXT: %call22 = call dereferenceable(4) i32* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* %ref.tmp14) + // CHECK-NEXT: store i32* %call22, i32** %y, align 8 + int& y = co_await AwaitResumeReturnsLValue{}; + // CHECK: yield.ready: + // CHECK-NEXT: %call32 = call dereferenceable(4) i32* @_ZN24AwaitResumeReturnsLValue12await_resumeEv(%struct.AwaitResumeReturnsLValue* %ref.tmp23) + int& z = co_yield 42; +} Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2550,9 +2550,11 @@ RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot = AggValueSlot::ignored(), bool ignoreResult = false); + LValue EmitCoawaitLValue(const CoawaitExpr *E); RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot = AggValueSlot::ignored(), bool ignoreResult = false); + LValue EmitCoyieldLValue(const CoyieldExpr *E); RValue EmitCoroutineIntrinsic(const CallExpr *E, unsigned int IID); void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false); Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1158,6 +1158,11 @@ case Expr::MaterializeTemporaryExprClass: return EmitMaterializeTemporaryExpr(cast(E)); + + case Expr::CoawaitExprClass: +return EmitCoawaitLValue(cast(E)); + case Expr::CoyieldExprClass: +return EmitCoyieldLValue(cast(E)); } } Index: lib/CodeGen/CGCoroutine.cpp === --- lib/CodeGen/CGCoroutine.cpp +++ lib/CodeGen/CGCoroutine.cpp @@ -148,10 +148,16 @@ // // See llvm's docs/Coroutines.rst for more details. // -static RValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Coro, +namespace { + struct LValueOrRValue { +LValue LV; +RValue RV; + }; +} +static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Coro, CoroutineSuspendExpr const &S, AwaitKind Kind, AggValueSlot aggSlot, -bool ignoreResult) { +bool ignoreResult, bool forLValue) { auto *E = S.getCommonExpr(); // FIXME: rsmith 5/22/2017. Does it still make sense for us to have a @@ -217,29 +223,65 @@ // Emit await_resume expression. CGF.EmitBlock(ReadyBlock); - return CGF.EmitAnyExpr(S.getResumeExpr(), aggSlot, ignoreResult); + assert(isa(S.getResumeExpr()) || isa(S.getResumeExpr())); + LValueOrRValue Res; + if (forLValue) +Res.LV = CGF.EmitLValue(S.getResumeExpr()); + else +Res.RV = CGF.EmitAnyExpr(S.getResumeExpr(), aggSlot, ignoreResult); + return Res; } RValue CodeGenFunction::EmitCoawaitExpr(const CoawaitExpr &E,