[PATCH] D46675: [clangd] Add helper for collecting #include directives in file.
ioeric updated this revision to Diff 146074. ioeric added a comment. - Rebase on origin/master Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D46675 Files: clangd/ClangdLSPServer.cpp clangd/ClangdUnit.cpp clangd/ClangdUnit.h clangd/Headers.cpp clangd/Headers.h clangd/SourceCode.cpp clangd/SourceCode.h clangd/XRefs.cpp Index: clangd/XRefs.cpp === --- clangd/XRefs.cpp +++ clangd/XRefs.cpp @@ -234,12 +234,10 @@ std::vector Result; // Handle goto definition for #include. - for (auto &IncludeLoc : AST.getInclusionLocations()) { -Range R = IncludeLoc.first; + for (auto &Inc : AST.getInclusions()) { Position Pos = sourceLocToPosition(SourceMgr, SourceLocationBeg); - -if (R.contains(Pos)) - Result.push_back(Location{URIForFile{IncludeLoc.second}, {}}); +if (!Inc.Resolved.empty() && Inc.R.contains(Pos)) + Result.push_back(Location{URIForFile{Inc.Resolved}, {}}); } if (!Result.empty()) return Result; Index: clangd/SourceCode.h === --- clangd/SourceCode.h +++ clangd/SourceCode.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SOURCECODE_H #include "Protocol.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Tooling/Core/Replacement.h" namespace clang { class SourceManager; @@ -54,6 +55,14 @@ /// qualifier. std::pair splitQualifiedName(llvm::StringRef QName); +TextEdit replacementToEdit(StringRef Code, const tooling::Replacement &R); + +std::vector +replacementsToEdits(StringRef Code, +const std::vector &Replacements); + +std::vector replacementsToEdits(StringRef Code, + const tooling::Replacements &Repls); } // namespace clangd } // namespace clang Index: clangd/SourceCode.cpp === --- clangd/SourceCode.cpp +++ clangd/SourceCode.cpp @@ -166,5 +166,31 @@ return {QName.substr(0, Pos + 2), QName.substr(Pos + 2)}; } +TextEdit replacementToEdit(StringRef Code, const tooling::Replacement &R) { + Range ReplacementRange = { + offsetToPosition(Code, R.getOffset()), + offsetToPosition(Code, R.getOffset() + R.getLength())}; + return {ReplacementRange, R.getReplacementText()}; +} + +std::vector +replacementsToEdits(StringRef Code, +const std::vector &Replacements) { + // Turn the replacements into the format specified by the Language Server + // Protocol. Fuse them into one big JSON array. + std::vector Edits; + for (const auto &R : Replacements) +Edits.push_back(replacementToEdit(Code, R)); + return Edits; +} + +std::vector replacementsToEdits(StringRef Code, + const tooling::Replacements &Repls) { + std::vector Edits; + for (const auto &R : Repls) +Edits.push_back(replacementToEdit(Code, R)); + return Edits; +} + } // namespace clangd } // namespace clang Index: clangd/Headers.h === --- clangd/Headers.h +++ clangd/Headers.h @@ -11,7 +11,9 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEADERS_H #include "Path.h" +#include "Protocol.h" #include "clang/Basic/VirtualFileSystem.h" +#include "clang/Lex/PPCallbacks.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" @@ -32,6 +34,19 @@ bool valid() const; }; +// An #include directive that we found in the main file. +struct Inclusion { + Range R; // Inclusion range. + std::string Written; // Inclusion name as written e.g. . + Path Resolved; // Resolved path of included file. Empty if not resolved. +}; + +/// Returns a PPCallback that collects all inclusions in the main file. +/// Inclusions are added to \p Includes. +std::unique_ptr +collectInclusionsInMainFileCallback(const SourceManager &SM, +std::vector &Inclusions); + /// Determines the preferred way to #include a file, taking into account the /// search path. Usually this will prefer a shorter representation like /// 'Foo/Bar.h' over a longer one like 'Baz/include/Foo/Bar.h'. Index: clangd/Headers.cpp === --- clangd/Headers.cpp +++ clangd/Headers.cpp @@ -10,6 +10,7 @@ #include "Headers.h" #include "Compiler.h" #include "Logger.h" +#include "SourceCode.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendActions.h" @@ -24,26 +25,32 @@ class RecordHeaders : public PPCallbacks { public: - RecordHeaders(llvm::StringSet<> &WrittenHeaders, -llvm::StringSet<> &ResolvedHeaders) - : WrittenHeaders(WrittenHeaders), ResolvedHeaders(ResolvedHeaders) {} + RecordHeaders(const SourceManager &SM, std::vector &Includes) + : SM
[PATCH] D46675: [clangd] Add helper for collecting #include directives in file.
ioeric updated this revision to Diff 146075. ioeric added a comment. - Unmerge https://reviews.llvm.org/D46670 Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D46675 Files: clangd/ClangdUnit.cpp clangd/ClangdUnit.h clangd/Headers.cpp clangd/Headers.h clangd/XRefs.cpp Index: clangd/XRefs.cpp === --- clangd/XRefs.cpp +++ clangd/XRefs.cpp @@ -234,12 +234,10 @@ std::vector Result; // Handle goto definition for #include. - for (auto &IncludeLoc : AST.getInclusionLocations()) { -Range R = IncludeLoc.first; + for (auto &Inc : AST.getInclusions()) { Position Pos = sourceLocToPosition(SourceMgr, SourceLocationBeg); - -if (R.contains(Pos)) - Result.push_back(Location{URIForFile{IncludeLoc.second}, {}}); +if (!Inc.Resolved.empty() && Inc.R.contains(Pos)) + Result.push_back(Location{URIForFile{Inc.Resolved}, {}}); } if (!Result.empty()) return Result; Index: clangd/Headers.h === --- clangd/Headers.h +++ clangd/Headers.h @@ -11,7 +11,9 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEADERS_H #include "Path.h" +#include "Protocol.h" #include "clang/Basic/VirtualFileSystem.h" +#include "clang/Lex/PPCallbacks.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" @@ -32,6 +34,19 @@ bool valid() const; }; +// An #include directive that we found in the main file. +struct Inclusion { + Range R; // Inclusion range. + std::string Written; // Inclusion name as written e.g. . + Path Resolved; // Resolved path of included file. Empty if not resolved. +}; + +/// Returns a PPCallback that collects all inclusions in the main file. +/// Inclusions are added to \p Includes. +std::unique_ptr +collectInclusionsInMainFileCallback(const SourceManager &SM, +std::vector &Inclusions); + /// Determines the preferred way to #include a file, taking into account the /// search path. Usually this will prefer a shorter representation like /// 'Foo/Bar.h' over a longer one like 'Baz/include/Foo/Bar.h'. Index: clangd/Headers.cpp === --- clangd/Headers.cpp +++ clangd/Headers.cpp @@ -10,6 +10,7 @@ #include "Headers.h" #include "Compiler.h" #include "Logger.h" +#include "SourceCode.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendActions.h" @@ -24,26 +25,32 @@ class RecordHeaders : public PPCallbacks { public: - RecordHeaders(llvm::StringSet<> &WrittenHeaders, -llvm::StringSet<> &ResolvedHeaders) - : WrittenHeaders(WrittenHeaders), ResolvedHeaders(ResolvedHeaders) {} + RecordHeaders(const SourceManager &SM, std::vector &Includes) + : SM(SM), Includes(Includes) {} - void InclusionDirective(SourceLocation /*HashLoc*/, - const Token & /*IncludeTok*/, + // Record existing #includes - both written and resolved paths. Only #includes + // in the main file are collected. + void InclusionDirective(SourceLocation HashLoc, const Token & /*IncludeTok*/, llvm::StringRef FileName, bool IsAngled, - CharSourceRange /*FilenameRange*/, - const FileEntry *File, llvm::StringRef /*SearchPath*/, + CharSourceRange FilenameRange, const FileEntry *File, + llvm::StringRef /*SearchPath*/, llvm::StringRef /*RelativePath*/, const Module * /*Imported*/) override { -WrittenHeaders.insert( -(IsAngled ? "<" + FileName + ">" : "\"" + FileName + "\"").str()); -if (File != nullptr && !File->tryGetRealPathName().empty()) - ResolvedHeaders.insert(File->tryGetRealPathName()); +// Only inclusion directives in the main file make sense. The user cannot +// select directives not in the main file. +if (HashLoc.isInvalid() || !SM.isInMainFile(HashLoc)) + return; +std::string Written = +(IsAngled ? "<" + FileName + ">" : "\"" + FileName + "\"").str(); +std::string Resolved = (!File || File->tryGetRealPathName().empty()) + ? "" + : File->tryGetRealPathName(); +Includes.push_back({halfOpenToRange(SM, FilenameRange), Written, Resolved}); } private: - llvm::StringSet<> &WrittenHeaders; - llvm::StringSet<> &ResolvedHeaders; + const SourceManager &SM; + std::vector &Includes; }; } // namespace @@ -57,6 +64,12 @@ (!Verbatim && llvm::sys::path::is_absolute(File)); } +std::unique_ptr +collectInclusionsInMainFileCallback(const SourceManager &SM, +std::vector &Includes) { + return llvm::make_unique(SM, Includes); +} +
[PATCH] D44931: [WebAssembly] Use Windows EH instructions for Wasm EH
aheejin updated this revision to Diff 146076. aheejin added a comment. - getMSVCDispatchBlock -> getFuncletEHDispatchBlock Repository: rC Clang https://reviews.llvm.org/D44931 Files: lib/CodeGen/CGCXXABI.h lib/CodeGen/CGCleanup.cpp lib/CodeGen/CGCleanup.h lib/CodeGen/CGException.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/ItaniumCXXABI.cpp lib/CodeGen/MicrosoftCXXABI.cpp test/CodeGenCXX/wasm-eh.cpp Index: test/CodeGenCXX/wasm-eh.cpp === --- /dev/null +++ test/CodeGenCXX/wasm-eh.cpp @@ -0,0 +1,392 @@ +// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -emit-llvm -o - -std=c++11 | FileCheck %s +// RUN: %clang_cc1 %s -triple wasm64-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -emit-llvm -o - -std=c++11 | FileCheck %s + +void may_throw(); +void dont_throw() noexcept; + +struct Cleanup { + ~Cleanup() { dont_throw(); } +}; + +// Multiple catch clauses w/o catch-all +void test0() { + try { +may_throw(); + } catch (int) { +dont_throw(); + } catch (double) { +dont_throw(); + } +} + +// CHECK-LABEL: define void @_Z5test0v() {{.*}} personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) + +// CHECK: %[[INT_ALLOCA:.*]] = alloca i32 +// CHECK: invoke void @_Z9may_throwv() +// CHECK-NEXT: to label %[[NORMAL_BB:.*]] unwind label %[[CATCHDISPATCH_BB:.*]] + +// CHECK: [[CATCHDISPATCH_BB]]: +// CHECK-NEXT: %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller + +// CHECK: [[CATCHSTART_BB]]: +// CHECK-NEXT: %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* bitcast (i8** @_ZTIi to i8*), i8* bitcast (i8** @_ZTId to i8*)] +// CHECK-NEXT: %[[EXN:.*]] = call i8* @llvm.wasm.get.exception() +// CHECK-NEXT: store i8* %[[EXN]], i8** %exn.slot +// CHECK-NEXT: %[[SELECTOR:.*]] = call i32 @llvm.wasm.get.ehselector() +// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2 +// CHECK-NEXT: %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]] +// CHECK-NEXT: br i1 %[[MATCHES]], label %[[CATCH_INT_BB:.*]], label %[[CATCH_FALLTHROUGH_BB:.*]] + +// CHECK: [[CATCH_INT_BB]]: +// CHECK-NEXT: %[[EXN:.*]] = load i8*, i8** %exn.slot +// CHECK-NEXT: %[[ADDR:.*]] = call i8* @__cxa_begin_catch(i8* %[[EXN]]) {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] +// CHECK-NEXT: %[[ADDR_CAST:.*]] = bitcast i8* %[[ADDR]] to i32* +// CHECK-NEXT: %[[INT_VAL:.*]] = load i32, i32* %[[ADDR_CAST]] +// CHECK-NEXT: store i32 %[[INT_VAL]], i32* %[[INT_ALLOCA]] +// CHECK-NEXT: call void @_Z10dont_throwv() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] +// CHECK-NEXT: call void @__cxa_end_catch() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] +// CHECK-NEXT: catchret from %[[CATCHPAD]] to label %[[CATCHRET_DEST_BB0:.*]] + +// CHECK: [[CATCHRET_DEST_BB0]]: +// CHECK-NEXT: br label %[[TRY_CONT_BB:.*]] + +// CHECK: [[CATCH_FALLTHROUGH_BB]] +// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTId to i8*)) #2 +// CHECK-NEXT: %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]] +// CHECK-NEXT: br i1 %[[MATCHES]], label %[[CATCH_FLOAT_BB:.*]], label %[[RETHROW_BB:.*]] + +// CHECK: [[CATCH_FLOAT_BB]]: +// CHECK: catchret from %[[CATCHPAD]] to label %[[CATCHRET_DEST_BB1:.*]] + +// CHECK: [[CATCHRET_DEST_BB1]]: +// CHECK-NEXT: br label %[[TRY_CONT_BB]] + +// CHECK: [[RETHROW_BB]]: +// CHECK-NEXT: call void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] +// CHECK-NEXT: unreachable + + +// Single catch-all +void test1() { + try { +may_throw(); + } catch (...) { +dont_throw(); + } +} + +// CATCH-LABEL: @_Z5test1v() + +// CHECK: %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller + +// CHECK: [[CATCHSTART_BB]]: +// CHECK-NEXT: %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* null] +// CHECK: br label %[[CATCH_ALL_BB:.*]] + +// CHECK: [[CATCH_ALL_BB]]: +// CHECK: catchret from %[[CATCHPAD]] to label + + +// Multiple catch clauses w/ catch-all +void test2() { + try { +may_throw(); + } catch (int) { +dont_throw(); + } catch (...) { +dont_throw(); + } +} + +// CHECK-LABEL: @_Z5test2v() + +// CHECK: %[[CATCHSWITCH:.*]] = catchswitch within none [label %[[CATCHSTART_BB:.*]]] unwind to caller + +// CHECK: [[CATCHSTART_BB]]: +// CHECK-NEXT: %[[CATCHPAD:.*]] = catchpad within %[[CATCHSWITCH]] [i8* bitcast (i8** @_ZTIi to i8*), i8* null] +// CHECK: br i1 %{{.*}}, label %[[CATCH_INT_BB:.*]], label %[[CATCH_ALL_BB:.*]] + +// CHECK: [[CATCH_INT_BB]]: +// CHECK: catchret from %[[CATCHPAD]] to label + +// CHECK: [[CATCH_ALL_BB]]: +// CHECK: catchret from %[[CATCHPAD]] to label + + +// Cleanup +void test3() { + Cleanup c; + may_throw(); +} + +// CHECK-LABEL: @_Z5test3v() + +// CHECK: invoke void @_Z9may_throwv() +// CHECK-NEXT: to
[PATCH] D46676: [clangd] Remove LSP command-based #include insertion.
ioeric created this revision. ioeric added reviewers: ilya-biryukov, sammccall. Herald added subscribers: cfe-commits, jkorous, MaskRay, klimek. clangd will populate #include insertions as addtionalEdits in completion items. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D46676 Files: clangd/ClangdLSPServer.cpp clangd/ClangdServer.cpp clangd/ClangdServer.h clangd/CodeComplete.cpp clangd/Protocol.cpp clangd/Protocol.h test/clangd/initialize-params-invalid.test test/clangd/initialize-params.test test/clangd/insert-include.test unittests/clangd/ClangdTests.cpp Index: unittests/clangd/ClangdTests.cpp === --- unittests/clangd/ClangdTests.cpp +++ unittests/clangd/ClangdTests.cpp @@ -938,67 +938,6 @@ ASSERT_EQ(DiagConsumer.Count, 2); // Sanity check - we actually ran both? } -TEST_F(ClangdVFSTest, InsertIncludes) { - MockFSProvider FS; - ErrorCheckingDiagConsumer DiagConsumer; - MockCompilationDatabase CDB; - std::string SearchDirArg = (llvm::Twine("-I") + testRoot()).str(); - CDB.ExtraClangFlags.insert(CDB.ExtraClangFlags.end(), {SearchDirArg.c_str()}); - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); - - auto FooCpp = testPath("foo.cpp"); - const auto Code = R"cpp( -#include "x.h" -#include "z.h" - -void f() {} -)cpp"; - FS.Files[FooCpp] = Code; - runAddDocument(Server, FooCpp, Code); - - auto ChangedCode = [&](llvm::StringRef Original, llvm::StringRef Preferred) { -auto Replaces = Server.insertInclude( -FooCpp, Code, Original, Preferred.empty() ? Original : Preferred); -EXPECT_TRUE(static_cast(Replaces)); -auto Changed = tooling::applyAllReplacements(Code, *Replaces); -EXPECT_TRUE(static_cast(Changed)); -return *Changed; - }; - auto Inserted = [&](llvm::StringRef Original, llvm::StringRef Preferred, - llvm::StringRef Expected) { -return llvm::StringRef(ChangedCode(Original, Preferred)) -.contains((llvm::Twine("#include ") + Expected + "").str()); - }; - - EXPECT_TRUE(Inserted("\"y.h\"", /*Preferred=*/"", "\"y.h\"")); - EXPECT_TRUE(Inserted("\"y.h\"", /*Preferred=*/"\"Y.h\"", "\"Y.h\"")); - EXPECT_TRUE(Inserted("", /*Preferred=*/"", "")); - EXPECT_TRUE(Inserted("", /*Preferred=*/"", "")); - - std::string OriginalHeader = URI::createFile(testPath("y.h")).toString(); - std::string PreferredHeader = URI::createFile(testPath("Y.h")).toString(); - EXPECT_TRUE(Inserted(OriginalHeader, - /*Preferred=*/"", "\"y.h\"")); - EXPECT_TRUE(Inserted(OriginalHeader, - /*Preferred=*/"", "")); - EXPECT_TRUE(Inserted(OriginalHeader, PreferredHeader, "\"Y.h\"")); - EXPECT_TRUE(Inserted("", PreferredHeader, "\"Y.h\"")); - auto TestURIHeader = - URI::parse(llvm::formatv("{0}:///x/y/z.h", ClangdTestScheme).str()); - EXPECT_TRUE(static_cast(TestURIHeader)); - EXPECT_TRUE(Inserted(TestURIHeader->toString(), "", "\"x/y/z.h\"")); - - // Check that includes are sorted. - const auto Expected = R"cpp( -#include "x.h" -#include "y.h" -#include "z.h" - -void f() {} -)cpp"; - EXPECT_EQ(Expected, ChangedCode("\"y.h\"", /*Preferred=*/"")); -} - TEST_F(ClangdVFSTest, FormatCode) { MockFSProvider FS; ErrorCheckingDiagConsumer DiagConsumer; Index: test/clangd/insert-include.test === --- test/clangd/insert-include.test +++ /dev/null @@ -1,36 +0,0 @@ -# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s -# RUN: clangd -lit-test -pch-storage=memory < %s | FileCheck -strict-whitespace %s -{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"void f() {}"}}} -{"jsonrpc":"2.0","id":3,"method":"workspace/executeCommand","params":{"arguments":[{"declaringHeader":"\"/usr/include/bits/vector\"", "preferredHeader":"","textDocument":{"uri":"test:///main.cpp"}}],"command":"clangd.insertInclude"}} -# CHECK:"id": 3, -# CHECK-NEXT:"jsonrpc": "2.0", -# CHECK-NEXT:"result": "Inserted header \"/usr/include/bits/vector\" ()" -# CHECK-NEXT: } -# CHECK:"method": "workspace/applyEdit", -# CHECK-NEXT:"params": { -# CHECK-NEXT: "edit": { -# CHECK-NEXT:"changes": { -# CHECK-NEXT: "file://{{.*}}/main.cpp": [ -# CHECK-NEXT:{ -# CHECK-NEXT: "newText": "#include \n", -# CHECK-NEXT: "range": { -# CHECK-NEXT:"end": { -# CHECK-NEXT: "character": 0, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT:}, -# CHECK-NEXT:"start": { -# CHECK-NEXT: "character": 0, -# CHECK-NEXT: "line": 0 -# CHECK-NEXT:} -# CHECK-
r331962 - [X86] ptwrite intrinsic
Author: gbuella Date: Thu May 10 00:28:54 2018 New Revision: 331962 URL: http://llvm.org/viewvc/llvm-project?rev=331962&view=rev Log: [X86] ptwrite intrinsic Reviewers: craig.topper, RKSimon Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D46540 Added: cfe/trunk/lib/Headers/ptwriteintrin.h (with props) cfe/trunk/test/CodeGen/ptwrite.c (with props) Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/include/clang/Basic/BuiltinsX86_64.def cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/Basic/Targets/X86.cpp cfe/trunk/lib/Basic/Targets/X86.h cfe/trunk/lib/Headers/CMakeLists.txt cfe/trunk/lib/Headers/cpuid.h cfe/trunk/lib/Headers/module.modulemap cfe/trunk/lib/Headers/x86intrin.h cfe/trunk/test/Driver/x86-target-features.c cfe/trunk/test/Preprocessor/predefined-arch-macros.c Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=331962&r1=331961&r2=331962&view=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Thu May 10 00:28:54 2018 @@ -1885,6 +1885,9 @@ TARGET_BUILTIN(__builtin_ia32_cldemote, TARGET_BUILTIN(__builtin_ia32_directstore_u32, "vUi*Ui", "n", "movdiri") TARGET_BUILTIN(__builtin_ia32_movdir64b, "vv*vC*", "n", "movdir64b") +// PTWRITE +TARGET_BUILTIN(__builtin_ia32_ptwrite32, "vUi", "n", "ptwrite") + // MSVC TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") Modified: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86_64.def?rev=331962&r1=331961&r2=331962&view=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86_64.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86_64.def Thu May 10 00:28:54 2018 @@ -95,6 +95,7 @@ TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64 TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dULLiIi", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fULLiIi", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_directstore_u64, "vULi*ULi", "n", "movdiri") +TARGET_BUILTIN(__builtin_ia32_ptwrite64, "vULLi", "n", "ptwrite") #undef BUILTIN #undef TARGET_BUILTIN Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=331962&r1=331961&r2=331962&view=diff == --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Thu May 10 00:28:54 2018 @@ -2697,6 +2697,8 @@ def mprefetchwt1 : Flag<["-"], "mprefetc def mno_prefetchwt1 : Flag<["-"], "mno-prefetchwt1">, Group; def mprfchw : Flag<["-"], "mprfchw">, Group; def mno_prfchw : Flag<["-"], "mno-prfchw">, Group; +def mptwrite : Flag<["-"], "mptwrite">, Group; +def mno_ptwrite : Flag<["-"], "mno-ptwrite">, Group; def mrdpid : Flag<["-"], "mrdpid">, Group; def mno_rdpid : Flag<["-"], "mno-rdpid">, Group; def mrdrnd : Flag<["-"], "mrdrnd">, Group; Modified: cfe/trunk/lib/Basic/Targets/X86.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/X86.cpp?rev=331962&r1=331961&r2=331962&view=diff == --- cfe/trunk/lib/Basic/Targets/X86.cpp (original) +++ cfe/trunk/lib/Basic/Targets/X86.cpp Thu May 10 00:28:54 2018 @@ -253,6 +253,7 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "waitpkg", true); LLVM_FALLTHROUGH; case CK_GoldmontPlus: +setFeatureEnabledImpl(Features, "ptwrite", true); setFeatureEnabledImpl(Features, "rdpid", true); setFeatureEnabledImpl(Features, "sgx", true); LLVM_FALLTHROUGH; @@ -830,6 +831,8 @@ bool X86TargetInfo::handleTargetFeatures HasMOVDIR64B = true; } else if (Feature == "+pconfig") { HasPCONFIG = true; +} else if (Feature == "+ptwrite") { + HasPTWRITE = true; } X86SSEEnum Level = llvm::StringSwitch(Feature) @@ -1192,6 +1195,8 @@ void X86TargetInfo::getTargetDefines(con Builder.defineMacro("__MOVDIR64B__"); if (HasPCONFIG) Builder.defineMacro("__PCONFIG__"); + if (HasPTWRITE) +Builder.defineMacro("__PTWRITE__"); // Each case falls through to the previous one here. switch (SSELevel) { @@ -1326,6 +1331,7 @@ bool X86TargetInfo::isValidFeatureName(S .Case("popcnt", true) .Case("prefetchwt1", true) .Case("prfchw", true) + .Case("ptwrite", true) .Case("rdpid", true) .Case("rdrnd", true) .Case("rdseed", true)
[PATCH] D46386: Adding __atomic_fetch_min/max intrinsics to clang
delena updated this revision to Diff 146080. delena added a comment. Given more clarification about memory model of atomic operations. Repository: rC Clang https://reviews.llvm.org/D46386 Files: docs/LanguageExtensions.rst include/clang/Basic/Builtins.def include/clang/Basic/DiagnosticSemaKinds.td lib/AST/Expr.cpp lib/CodeGen/CGAtomic.cpp lib/Sema/SemaChecking.cpp test/CodeGen/Atomics.c test/Sema/atomic-ops.c Index: test/Sema/atomic-ops.c === --- test/Sema/atomic-ops.c +++ test/Sema/atomic-ops.c @@ -173,6 +173,9 @@ __atomic_fetch_sub(P, 3, memory_order_seq_cst); __atomic_fetch_sub(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}} __atomic_fetch_sub(s1, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}} + __atomic_fetch_min(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to signed or unsigned 32-bit integer}} + __atomic_fetch_max(P, 3, memory_order_seq_cst); // expected-error {{must be a pointer to signed or unsigned 32-bit integer}} + __atomic_fetch_max(p, 3); // expected-error {{too few arguments to function call, expected 3, have 2}} __c11_atomic_fetch_and(i, 1, memory_order_seq_cst); __c11_atomic_fetch_and(p, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer}} @@ -456,6 +459,20 @@ (void)__atomic_fetch_nand(p, val, memory_order_acq_rel); (void)__atomic_fetch_nand(p, val, memory_order_seq_cst); + (void)__atomic_fetch_min(p, val, memory_order_relaxed); + (void)__atomic_fetch_min(p, val, memory_order_acquire); + (void)__atomic_fetch_min(p, val, memory_order_consume); + (void)__atomic_fetch_min(p, val, memory_order_release); + (void)__atomic_fetch_min(p, val, memory_order_acq_rel); + (void)__atomic_fetch_min(p, val, memory_order_seq_cst); + + (void)__atomic_fetch_max(p, val, memory_order_relaxed); + (void)__atomic_fetch_max(p, val, memory_order_acquire); + (void)__atomic_fetch_max(p, val, memory_order_consume); + (void)__atomic_fetch_max(p, val, memory_order_release); + (void)__atomic_fetch_max(p, val, memory_order_acq_rel); + (void)__atomic_fetch_max(p, val, memory_order_seq_cst); + (void)__atomic_and_fetch(p, val, memory_order_relaxed); (void)__atomic_and_fetch(p, val, memory_order_acquire); (void)__atomic_and_fetch(p, val, memory_order_consume); Index: test/CodeGen/Atomics.c === --- test/CodeGen/Atomics.c +++ test/CodeGen/Atomics.c @@ -291,3 +291,10 @@ __sync_lock_release (&sll); // CHECK: store atomic {{.*}} release, align 8 __sync_lock_release (&ull); // CHECK: store atomic {{.*}} release, align 8 } + +void test_atomic(void) { + ui = __atomic_fetch_min(&ui, 5, __ATOMIC_RELAXED); // CHECK: atomicrmw umin {{.*}} monotonic + si = __atomic_fetch_min(&si, 5, __ATOMIC_SEQ_CST); // CHECK: atomicrmw min {{.*}} seq_cst + ui = __atomic_fetch_max(&ui, 5, __ATOMIC_ACQUIRE); // CHECK: atomicrmw umax {{.*}} acquire + si = __atomic_fetch_max(&si, 5, __ATOMIC_RELEASE); // CHECK: atomicrmw max {{.*}} release +} Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -3037,6 +3037,7 @@ Op == AtomicExpr::AO__atomic_exchange_n || Op == AtomicExpr::AO__atomic_compare_exchange_n; bool IsAddSub = false; + bool IsMinMax = false; switch (Op) { case AtomicExpr::AO__c11_atomic_init: @@ -3090,6 +3091,12 @@ Form = Arithmetic; break; + case AtomicExpr::AO__atomic_fetch_min: + case AtomicExpr::AO__atomic_fetch_max: +IsMinMax = true; +Form = Arithmetic; +break; + case AtomicExpr::AO__c11_atomic_exchange: case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__atomic_exchange_n: @@ -3172,12 +3179,21 @@ // For an arithmetic operation, the implied arithmetic must be well-formed. if (Form == Arithmetic) { // gcc does not enforce these rules for GNU atomics, but we do so for sanity. -if (IsAddSub && !ValType->isIntegerType() && !ValType->isPointerType()) { +if (IsAddSub && !ValType->isIntegerType() +&& !ValType->isPointerType()) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_atomic_int_or_ptr) << IsC11 << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); } -if (!IsAddSub && !ValType->isIntegerType()) { +if (IsMinMax) { + const BuiltinType *BT = ValType->getAs(); + if (!BT || (BT->getKind() != BuiltinType::Int && + BT->getKind() != BuiltinType::UInt)) { +Diag(DRE->getLocStart(), diag::err_atomic_op_needs_int32_or_ptr); +return ExprError(); + } +} +if (!IsAddSub && !IsMinMax && !ValType->isIntegerType()) { Diag(DRE->getLocStart(), diag::err_atomic_op_bitwi
[PATCH] D46540: [X86] ptwrite intrinsic
This revision was automatically updated to reflect the committed changes. Closed by commit rC331962: [X86] ptwrite intrinsic (authored by GBuella, committed by ). Changed prior to commit: https://reviews.llvm.org/D46540?vs=145681&id=146081#toc Repository: rC Clang https://reviews.llvm.org/D46540 Files: include/clang/Basic/BuiltinsX86.def include/clang/Basic/BuiltinsX86_64.def include/clang/Driver/Options.td lib/Basic/Targets/X86.cpp lib/Basic/Targets/X86.h lib/Headers/CMakeLists.txt lib/Headers/cpuid.h lib/Headers/module.modulemap lib/Headers/ptwriteintrin.h lib/Headers/x86intrin.h test/CodeGen/ptwrite.c test/Driver/x86-target-features.c test/Preprocessor/predefined-arch-macros.c Index: lib/Basic/Targets/X86.h === --- lib/Basic/Targets/X86.h +++ lib/Basic/Targets/X86.h @@ -106,6 +106,7 @@ bool HasWAITPKG = false; bool HasMOVDIRI = false; bool HasMOVDIR64B = false; + bool HasPTWRITE = false; protected: /// Enumeration of all of the X86 CPUs supported by Clang. Index: lib/Basic/Targets/X86.cpp === --- lib/Basic/Targets/X86.cpp +++ lib/Basic/Targets/X86.cpp @@ -253,6 +253,7 @@ setFeatureEnabledImpl(Features, "waitpkg", true); LLVM_FALLTHROUGH; case CK_GoldmontPlus: +setFeatureEnabledImpl(Features, "ptwrite", true); setFeatureEnabledImpl(Features, "rdpid", true); setFeatureEnabledImpl(Features, "sgx", true); LLVM_FALLTHROUGH; @@ -830,6 +831,8 @@ HasMOVDIR64B = true; } else if (Feature == "+pconfig") { HasPCONFIG = true; +} else if (Feature == "+ptwrite") { + HasPTWRITE = true; } X86SSEEnum Level = llvm::StringSwitch(Feature) @@ -1192,6 +1195,8 @@ Builder.defineMacro("__MOVDIR64B__"); if (HasPCONFIG) Builder.defineMacro("__PCONFIG__"); + if (HasPTWRITE) +Builder.defineMacro("__PTWRITE__"); // Each case falls through to the previous one here. switch (SSELevel) { @@ -1326,6 +1331,7 @@ .Case("popcnt", true) .Case("prefetchwt1", true) .Case("prfchw", true) + .Case("ptwrite", true) .Case("rdpid", true) .Case("rdrnd", true) .Case("rdseed", true) @@ -1405,6 +1411,7 @@ .Case("popcnt", HasPOPCNT) .Case("prefetchwt1", HasPREFETCHWT1) .Case("prfchw", HasPRFCHW) + .Case("ptwrite", HasPTWRITE) .Case("rdpid", HasRDPID) .Case("rdrnd", HasRDRND) .Case("rdseed", HasRDSEED) Index: lib/Headers/cpuid.h === --- lib/Headers/cpuid.h +++ lib/Headers/cpuid.h @@ -202,6 +202,9 @@ #define bit_XSAVEC 0x0002 #define bit_XSAVES 0x0008 +/* Features in %eax for leaf 0x14 sub-leaf 0 */ +#define bit_PTWRITE 0x0010 + /* Features in %ecx for leaf 0x8001 */ #define bit_LAHF_LM 0x0001 #define bit_ABM 0x0020 Index: lib/Headers/module.modulemap === --- lib/Headers/module.modulemap +++ lib/Headers/module.modulemap @@ -69,6 +69,7 @@ textual header "movdirintrin.h" textual header "pconfigintrin.h" textual header "sgxintrin.h" +textual header "ptwriteintrin.h" explicit module mm_malloc { requires !freestanding Index: lib/Headers/ptwriteintrin.h === --- lib/Headers/ptwriteintrin.h +++ lib/Headers/ptwriteintrin.h @@ -0,0 +1,51 @@ +/*=== ptwriteintrin.h - PTWRITE intrinsic === + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===---=== + */ + +#ifndef __X86INTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __PTWRITEINTRIN_H +#define __PTWRITEINTRIN_H + +/* Define
[PATCH] D46670: [clangd] Move helpers that convert Replacements to TextEdits to SourceCode.h
ioeric updated this revision to Diff 146082. ioeric added a comment. - [clangd] Add helper for collecting #include directives in file. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D46670 Files: clangd/ClangdLSPServer.cpp clangd/SourceCode.cpp clangd/SourceCode.h Index: clangd/SourceCode.h === --- clangd/SourceCode.h +++ clangd/SourceCode.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SOURCECODE_H #include "Protocol.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Tooling/Core/Replacement.h" namespace clang { class SourceManager; @@ -55,6 +56,15 @@ std::pair splitQualifiedName(llvm::StringRef QName); +TextEdit replacementToEdit(StringRef Code, const tooling::Replacement &R); + +std::vector +replacementsToEdits(StringRef Code, +const std::vector &Replacements); + +std::vector replacementsToEdits(StringRef Code, + const tooling::Replacements &Repls); + } // namespace clangd } // namespace clang #endif Index: clangd/SourceCode.cpp === --- clangd/SourceCode.cpp +++ clangd/SourceCode.cpp @@ -166,5 +166,31 @@ return {QName.substr(0, Pos + 2), QName.substr(Pos + 2)}; } +TextEdit replacementToEdit(StringRef Code, const tooling::Replacement &R) { + Range ReplacementRange = { + offsetToPosition(Code, R.getOffset()), + offsetToPosition(Code, R.getOffset() + R.getLength())}; + return {ReplacementRange, R.getReplacementText()}; +} + +std::vector +replacementsToEdits(StringRef Code, +const std::vector &Replacements) { + // Turn the replacements into the format specified by the Language Server + // Protocol. Fuse them into one big JSON array. + std::vector Edits; + for (const auto &R : Replacements) +Edits.push_back(replacementToEdit(Code, R)); + return Edits; +} + +std::vector replacementsToEdits(StringRef Code, + const tooling::Replacements &Repls) { + std::vector Edits; + for (const auto &R : Repls) +Edits.push_back(replacementToEdit(Code, R)); + return Edits; +} + } // namespace clangd } // namespace clang Index: clangd/ClangdLSPServer.cpp === --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -60,32 +60,6 @@ static URISchemeRegistry::Add X("test", "Test scheme for clangd lit tests."); -TextEdit replacementToEdit(StringRef Code, const tooling::Replacement &R) { - Range ReplacementRange = { - offsetToPosition(Code, R.getOffset()), - offsetToPosition(Code, R.getOffset() + R.getLength())}; - return {ReplacementRange, R.getReplacementText()}; -} - -std::vector -replacementsToEdits(StringRef Code, -const std::vector &Replacements) { - // Turn the replacements into the format specified by the Language Server - // Protocol. Fuse them into one big JSON array. - std::vector Edits; - for (const auto &R : Replacements) -Edits.push_back(replacementToEdit(Code, R)); - return Edits; -} - -std::vector replacementsToEdits(StringRef Code, - const tooling::Replacements &Repls) { - std::vector Edits; - for (const auto &R : Repls) -Edits.push_back(replacementToEdit(Code, R)); - return Edits; -} - SymbolKindBitset defaultSymbolKinds() { SymbolKindBitset Defaults; for (size_t I = SymbolKindMin; I <= static_cast(SymbolKind::Array); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46497: [clangd] Populate #include insertions as additional edits in completion items.
ioeric updated this revision to Diff 146083. ioeric added a comment. - Rebase on https://reviews.llvm.org/D46670, https://reviews.llvm.org/D46675, https://reviews.llvm.org/D46676 Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D46497 Files: clangd/ClangdServer.cpp clangd/CodeComplete.cpp clangd/CodeComplete.h clangd/Headers.cpp clangd/Headers.h clangd/Protocol.h unittests/clangd/CodeCompleteTests.cpp unittests/clangd/HeadersTests.cpp Index: unittests/clangd/HeadersTests.cpp === --- unittests/clangd/HeadersTests.cpp +++ unittests/clangd/HeadersTests.cpp @@ -8,38 +8,96 @@ //===--===// #include "Headers.h" + +#include "Compiler.h" #include "TestFS.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Lex/PreprocessorOptions.h" #include "gmock/gmock.h" #include "gtest/gtest.h" namespace clang { namespace clangd { namespace { +using ::testing::AllOf; +using ::testing::UnorderedElementsAre; + class HeadersTest : public ::testing::Test { public: HeadersTest() { CDB.ExtraClangFlags = {SearchDirArg.c_str()}; FS.Files[MainFile] = ""; +// Make sure directory sub/ exists. +FS.Files[testPath("sub/EMPTY")] = ""; + } + +private: + std::unique_ptr setupClang() { +auto Cmd = CDB.getCompileCommand(MainFile); +assert(static_cast(Cmd)); +auto VFS = FS.getFileSystem(); +VFS->setCurrentWorkingDirectory(Cmd->Directory); + +std::vector Argv; +for (const auto &S : Cmd->CommandLine) + Argv.push_back(S.c_str()); +auto CI = clang::createInvocationFromCommandLine( +Argv, +CompilerInstance::createDiagnostics(new DiagnosticOptions(), +&IgnoreDiags, false), +VFS); +EXPECT_TRUE(static_cast(CI)); +CI->getFrontendOpts().DisableFree = false; + +// The diagnostic options must be set before creating a CompilerInstance. +CI->getDiagnosticOpts().IgnoreWarnings = true; +auto Clang = prepareCompilerInstance( +std::move(CI), /*Preamble=*/nullptr, +llvm::MemoryBuffer::getMemBuffer(FS.Files[MainFile], MainFile), +std::make_shared(), VFS, IgnoreDiags); + +EXPECT_FALSE(Clang->getFrontendOpts().Inputs.empty()); +return Clang; } protected: + std::vector collectIncludes() { +auto Clang = setupClang(); +PreprocessOnlyAction Action; +EXPECT_TRUE( +Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])); +std::vector Inclusions; +Clang->getPreprocessor().addPPCallbacks(collectInclusionsInMainFileCallback( +Clang->getSourceManager(), Inclusions)); +EXPECT_TRUE(Action.Execute()); +Action.EndSourceFile(); +return Inclusions; + } + // Calculates the include path, or returns "" on error. std::string calculate(PathRef Original, PathRef Preferred = "", +const std::vector &Inclusions = {}, bool ExpectError = false) { +auto Clang = setupClang(); +PreprocessOnlyAction Action; +EXPECT_TRUE( +Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])); + if (Preferred.empty()) Preferred = Original; -auto VFS = FS.getFileSystem(); -auto Cmd = CDB.getCompileCommand(MainFile); -assert(static_cast(Cmd)); -VFS->setCurrentWorkingDirectory(Cmd->Directory); auto ToHeaderFile = [](llvm::StringRef Header) { return HeaderFile{Header, /*Verbatim=*/!llvm::sys::path::is_absolute(Header)}; }; -auto Path = calculateIncludePath(MainFile, FS.Files[MainFile], - ToHeaderFile(Original), - ToHeaderFile(Preferred), *Cmd, VFS); + +auto Path = calculateIncludePath( +MainFile, CDB.getCompileCommand(MainFile)->Directory, +Clang->getPreprocessor().getHeaderSearchInfo(), Inclusions, +ToHeaderFile(Original), ToHeaderFile(Preferred)); +Action.EndSourceFile(); if (!Path) { llvm::consumeError(Path.takeError()); EXPECT_TRUE(ExpectError); @@ -49,52 +107,31 @@ } return std::move(*Path); } + MockFSProvider FS; MockCompilationDatabase CDB; std::string MainFile = testPath("main.cpp"); std::string Subdir = testPath("sub"); std::string SearchDirArg = (llvm::Twine("-I") + Subdir).str(); + IgnoringDiagConsumer IgnoreDiags; }; -TEST_F(HeadersTest, InsertInclude) { - std::string Path = testPath("sub/bar.h"); - FS.Files[Path] = ""; - EXPECT_EQ(calculate(Path), "\"bar.h\""); -} +MATCHER_P(Written, Name, "") { return arg.Written == Name; } +MATCHER_P(Resolved, Name, "") { return arg.Resolved == Name; } -TEST_F(HeadersTest, DontInsertDuplicateSameName) { +TEST_F(HeadersTest, CollectR
[PATCH] D46497: [clangd] Populate #include insertions as additional edits in completion items.
ioeric added a comment. This has been split and now depends on https://reviews.llvm.org/D46670, https://reviews.llvm.org/D46675, https://reviews.llvm.org/D46676. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D46497 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45616: [X86] Lower _mm[256|512]_cmp[.]_mask intrinsics to native llvm IR
GBuella added a comment. In https://reviews.llvm.org/D45616#1093514, @efriedma wrote: > There is no difference between "signalling" and "non-signalling" unless > you're using "#pragma STDC FENV_ACCESS", which is currently not supported. > Presumably the work to implement that will include some LLVM IR intrinsic > which can encode the difference, but for now we can ignore it. Does that mean, it is OK to generate the `vcmpltpd` instruction for both of these intrinsic calls: _mm_cmp_ps_mask(a, b, _CMP_EQ_OQ); _mm_cmp_ps_mask(a, b, _CMP_EQ_OS); ? In that case we can lower both of these to `fcmp olt`. I'm still not sure, if this is what a user would expect... Repository: rC Clang https://reviews.llvm.org/D45616 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r331963 - Revert "[Itanium] Emit type info names with external linkage."
Author: ericwf Date: Thu May 10 01:10:57 2018 New Revision: 331963 URL: http://llvm.org/viewvc/llvm-project?rev=331963&view=rev Log: Revert "[Itanium] Emit type info names with external linkage." This reverts commit r331957. It seems to be causing failures on ppc64le-linux. Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=331963&r1=331962&r2=331963&view=diff == --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Thu May 10 01:10:57 2018 @@ -3008,46 +3008,8 @@ void ItaniumRTTIBuilder::BuildVTablePoin /// Return the linkage that the type info and type info name constants /// should have for the given type. -static std::pair -getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) { - llvm::GlobalValue::LinkageTypes TypeLinkage = [&]() { -switch (Ty->getLinkage()) { -case NoLinkage: -case InternalLinkage: -case UniqueExternalLinkage: - return llvm::GlobalValue::InternalLinkage; - -case VisibleNoLinkage: -case ModuleInternalLinkage: -case ModuleLinkage: -case ExternalLinkage: - // RTTI is not enabled, which means that this type info struct is going - // to be used for exception handling. Give it linkonce_odr linkage. - if (!CGM.getLangOpts().RTTI) -return llvm::GlobalValue::LinkOnceODRLinkage; - - if (const RecordType *Record = dyn_cast(Ty)) { -const CXXRecordDecl *RD = cast(Record->getDecl()); -if (RD->hasAttr()) - return llvm::GlobalValue::WeakODRLinkage; -if (CGM.getTriple().isWindowsItaniumEnvironment()) - if (RD->hasAttr() && - ShouldUseExternalRTTIDescriptor(CGM, Ty)) -return llvm::GlobalValue::ExternalLinkage; -// MinGW always uses LinkOnceODRLinkage for type info. -if (RD->isCompleteDefinition() && RD->isDynamicClass() && -!CGM.getContext() - .getTargetInfo() - .getTriple() - .isWindowsGNUEnvironment()) - return CGM.getVTableLinkage(RD); - } - - return llvm::GlobalValue::LinkOnceODRLinkage; -} -llvm_unreachable("Invalid linkage!"); - }(); +static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, + QualType Ty) { // Itanium C++ ABI 2.9.5p7: // In addition, it and all of the intermediate abi::__pointer_type_info // structs in the chain down to the abi::__class_type_info for the @@ -3058,8 +3020,44 @@ getTypeInfoLinkage(CodeGenModule &CGM, Q // complete class RTTI (because the latter need not exist), possibly by // making it a local static object. if (ContainsIncompleteClassType(Ty)) -return {llvm::GlobalValue::InternalLinkage, TypeLinkage}; - return {TypeLinkage, TypeLinkage}; +return llvm::GlobalValue::InternalLinkage; + + switch (Ty->getLinkage()) { + case NoLinkage: + case InternalLinkage: + case UniqueExternalLinkage: +return llvm::GlobalValue::InternalLinkage; + + case VisibleNoLinkage: + case ModuleInternalLinkage: + case ModuleLinkage: + case ExternalLinkage: +// RTTI is not enabled, which means that this type info struct is going +// to be used for exception handling. Give it linkonce_odr linkage. +if (!CGM.getLangOpts().RTTI) + return llvm::GlobalValue::LinkOnceODRLinkage; + +if (const RecordType *Record = dyn_cast(Ty)) { + const CXXRecordDecl *RD = cast(Record->getDecl()); + if (RD->hasAttr()) +return llvm::GlobalValue::WeakODRLinkage; + if (CGM.getTriple().isWindowsItaniumEnvironment()) +if (RD->hasAttr() && +ShouldUseExternalRTTIDescriptor(CGM, Ty)) + return llvm::GlobalValue::ExternalLinkage; + // MinGW always uses LinkOnceODRLinkage for type info. + if (RD->isDynamicClass() && + !CGM.getContext() + .getTargetInfo() + .getTriple() + .isWindowsGNUEnvironment()) +return CGM.getVTableLinkage(RD); +} + +return llvm::GlobalValue::LinkOnceODRLinkage; + } + + llvm_unreachable("Invalid linkage!"); } llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force, @@ -3086,25 +3084,23 @@ llvm::Constant *ItaniumRTTIBuilder::Buil return GetAddrOfExternalRTTIDescriptor(Ty); // Emit the standard library with external linkage. - llvm::GlobalVariable::LinkageTypes InfoLinkage, NameLinkage; + llvm::GlobalVariable::LinkageTypes Linkage; if (IsStdLib) -InfoLinkage = NameLinkage = llvm::GlobalValue::ExternalLinkage; - else { -auto LinkagePair = getTypeInfoLinkage(CGM, Ty); -InfoLinkage = LinkagePair.first; -NameLinkage = LinkagePair.second; - }
[PATCH] D46665: [Itanium] Emit type info names with external linkage.
EricWF reopened this revision. EricWF added a comment. This revision is now accepted and ready to land. Re-opening. I had to revert the last commit since it seemed to cause error (which looked unrelated?) on ppc64le-linux. Repository: rC Clang https://reviews.llvm.org/D46665 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45680: [C++2a] Implement operator<=> Part 2: Operator Rewritting and Overload Resolution.
EricWF updated this revision to Diff 146090. EricWF added a comment. Remove a bunch of nonsense this patch originally had. Specifically remove the bits of overload resolution which disambiguated rewritten expressions after the fact; Instead attempt to validate that the return type of the three-way comparison operand in a rewritten relational or equality can be used with the the specified operand (e.g. `std::strong_equality` cannot be used with a relational operator). https://reviews.llvm.org/D45680 Files: include/clang/AST/ComparisonCategories.h include/clang/AST/Expr.h include/clang/AST/ExprCXX.h include/clang/AST/RecursiveASTVisitor.h include/clang/AST/Stmt.h include/clang/Basic/StmtNodes.td include/clang/Sema/Overload.h include/clang/Sema/Sema.h include/clang/Serialization/ASTBitCodes.h lib/AST/ComparisonCategories.cpp lib/AST/Expr.cpp lib/AST/ExprClassification.cpp lib/AST/ExprConstant.cpp lib/AST/ItaniumMangle.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtProfile.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaExceptionSpec.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp test/CodeGenCXX/cxx2a-compare.cpp test/SemaCXX/compare-cxx2a.cpp Index: test/SemaCXX/compare-cxx2a.cpp === --- test/SemaCXX/compare-cxx2a.cpp +++ test/SemaCXX/compare-cxx2a.cpp @@ -292,20 +292,21 @@ template struct Tag {}; -// expected-note@+1 {{candidate}} -Tag<0> operator<=>(EnumA, EnumA) { - return {}; +std::strong_ordering operator<=>(EnumA, EnumA) { + return std::strong_ordering::equal; } -Tag<1> operator<=>(EnumA, EnumB) { - return {}; +// expected-note@+1 {{candidate function}}, +std::strong_ordering operator<=>(EnumA a, EnumB b) { + return ((int)a <=> (int)b); } void test_enum_ovl_provided() { auto r1 = (EnumA::A <=> EnumA::A); - ASSERT_EXPR_TYPE(r1, Tag<0>); + ASSERT_EXPR_TYPE(r1, std::strong_ordering); auto r2 = (EnumA::A <=> EnumB::B); - ASSERT_EXPR_TYPE(r2, Tag<1>); - (void)(EnumB::B <=> EnumA::A); // expected-error {{invalid operands to binary expression ('EnumCompareTests::EnumB' and 'EnumCompareTests::EnumA')}} + ASSERT_EXPR_TYPE(r2, std::strong_ordering); + (void)(EnumB::B <=> EnumA::A); // OK, chooses reverse order synthesized candidate. + (void)(EnumB::B <=> EnumC::C); // expected-error {{invalid operands to binary expression ('EnumCompareTests::EnumB' and 'EnumCompareTests::EnumC')}} } void enum_float_test() { @@ -421,3 +422,114 @@ } } // namespace ComplexTest + +namespace TestRewritting { + +struct T { + int x; + // expected-note@+1 {{candidate}} + constexpr std::strong_ordering operator<=>(T y) const { +return (x <=> y.x); + } +}; + +struct U { + int x; + // FIXME: This diagnostic is wrong-ish. + // expected-note@+1 {{candidate function not viable: requires single argument 'y', but 2 arguments were provided}} + constexpr std::strong_equality operator<=>(T y) const { +if (x == y.x) + return std::strong_equality::equal; +return std::strong_equality::nonequal; + } +}; + +struct X { int x; }; +struct Y { int x; }; +template +struct Tag {}; +// expected-note@+1 2 {{candidate}} +Tag<0> operator<=>(X, Y) { + return {}; +} +// expected-note@+1 2 {{candidate}} +constexpr auto operator<=>(Y y, X x) { + return y.x <=> x.x; +} + +void foo() { + T t{42}; + T t2{0}; + U u{101}; + auto r1 = (t <=> u); + ASSERT_EXPR_TYPE(r1, std::strong_equality); + auto r2 = (t <=> t2); + ASSERT_EXPR_TYPE(r2, std::strong_ordering); + + auto r3 = t == u; + ASSERT_EXPR_TYPE(r3, bool); + + (void)(t < u); // expected-error {{invalid operands to binary expression ('TestRewritting::T' and 'TestRewritting::U')}} + + constexpr X x{1}; + constexpr Y y{2}; + constexpr auto r4 = (y < x); + static_assert(r4 == false); + constexpr auto r5 = (x < y); + static_assert(r5 == true); +} + +} // namespace TestRewritting + +// The implicit object parameter is not considered when performing partial +// ordering. That makes the reverse synthesized candidates ambiguous with the +// rewritten candidates if any of them resolve to a member function. +namespace TestOvlMatchingIgnoresImplicitObject { +struct U; +struct T { + std::strong_ordering operator<=>(U const &RHS) const; +}; +struct U { + std::strong_ordering operator<=>(T const &RHS) const; +}; + +struct V { + int x; +}; +auto operator<=>(V const &LHS, V &&RHS) { // expected-note 4 {{candidate}} + return LHS.x <=> RHS.x; +} +auto operator<(V const &, V &&) { // expected-note {{candidate}} + return std::strong_equality::equal; +} + +void test() { + // expected-error@+1 {{use of overloaded operator '<' is ambiguous}} + (void)(T{} < U{}); + // expected-error@+1 {{use of overloaded operator '<' is ambiguous}} + (void)(V{} < V{}); + // expected-error@+1 {{use of overloaded operat
[PATCH] D45177: CStringChecker, check strlcpy/strlcat
devnexen added a comment. Thanks ! I would be grateful if anybody could land it for me. https://reviews.llvm.org/D45177 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46241: [CodeGen] Recognize more cases of zero initialization
sepavloff updated this revision to Diff 146091. sepavloff added a comment. Updated patch Try evaluating initializer value only if the initializer type is integral or pointer. It avoids calculation of large value, which then is discarded. Repository: rC Clang https://reviews.llvm.org/D46241 Files: include/clang/AST/Expr.h lib/AST/ExprConstant.cpp lib/CodeGen/CGExprConstant.cpp test/CodeGen/const-init.c test/CodeGen/designated-initializers.c test/CodeGen/union-init2.c test/CodeGenCXX/cxx11-initializer-aggregate.cpp test/CodeGenCXX/cxx1z-initializer-aggregate.cpp test/SemaCXX/large-array-init.cpp Index: test/SemaCXX/large-array-init.cpp === --- test/SemaCXX/large-array-init.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %clang_cc1 -S -o %t.ll -mllvm -debug-only=exprconstant %s 2>&1 | \ -// RUN: FileCheck %s -// REQUIRES: asserts - -struct S { int i; }; - -static struct S arr[1] = {{ 0 }}; -// CHECK: The number of elements to initialize: 1. - -struct S *foo() { return arr; } Index: test/CodeGenCXX/cxx1z-initializer-aggregate.cpp === --- test/CodeGenCXX/cxx1z-initializer-aggregate.cpp +++ test/CodeGenCXX/cxx1z-initializer-aggregate.cpp @@ -17,14 +17,14 @@ C c1 = {}; C c2 = {1}; - // CHECK: @_ZN8Constant2c1E = global { i8 } zeroinitializer, align 1 + // CHECK: @_ZN8Constant2c1E = global %"struct.Constant::C" zeroinitializer, align 1 // CHECK: @_ZN8Constant2c2E = global { i8 } { i8 1 }, align 1 // Test packing bases into tail padding. D d1 = {}; D d2 = {1, 2, 3}; D d3 = {1}; - // CHECK: @_ZN8Constant2d1E = global { i32, i8, i8 } zeroinitializer, align 4 + // CHECK: @_ZN8Constant2d1E = global %"struct.Constant::D" zeroinitializer, align 4 // CHECK: @_ZN8Constant2d2E = global { i32, i8, i8 } { i32 1, i8 2, i8 3 }, align 4 // CHECK: @_ZN8Constant2d3E = global { i32, i8, i8 } { i32 1, i8 0, i8 0 }, align 4 Index: test/CodeGenCXX/cxx11-initializer-aggregate.cpp === --- test/CodeGenCXX/cxx11-initializer-aggregate.cpp +++ test/CodeGenCXX/cxx11-initializer-aggregate.cpp @@ -51,3 +51,30 @@ // meaningful. B b[30] = {}; } + +namespace ZeroInit { + enum { Zero, One }; + constexpr int zero() { return 0; } + constexpr int *null() { return nullptr; } + struct Filler { +int x; +Filler(); + }; + struct S1 { +int x; + }; + + // These declarations, if implemented elementwise, require huge + // amout of memory and compiler time. + unsigned char data_1[1024 * 1024 * 1024 * 2u] = { 0 }; + unsigned char data_2[1024 * 1024 * 1024 * 2u] = { Zero }; + unsigned char data_3[1024][1024][1024] = {{{0}}}; + unsigned char data_4[1024 * 1024 * 1024 * 2u] = { zero() }; + int *data_5[1024 * 1024 * 512] = { nullptr }; + int *data_6[1024 * 1024 * 512] = { null() }; + struct S1 data_7[1024 * 1024 * 512] = {{0}}; + + // This variable must be initialized elementwise. + Filler data_e1[1024] = {}; + // CHECK: getelementptr inbounds {{.*}} @_ZN8ZeroInit7data_e1E +} Index: test/CodeGen/union-init2.c === --- test/CodeGen/union-init2.c +++ test/CodeGen/union-init2.c @@ -5,7 +5,7 @@ union x {long long b;union x* a;} r = {.a = &r}; -// CHECK: global { [3 x i8], [5 x i8] } { [3 x i8] zeroinitializer, [5 x i8] undef } +// CHECK: global %union.z zeroinitializer union z { char a[3]; long long b; Index: test/CodeGen/designated-initializers.c === --- test/CodeGen/designated-initializers.c +++ test/CodeGen/designated-initializers.c @@ -8,7 +8,7 @@ // CHECK: @u = global %union.anon zeroinitializer union { int i; float f; } u = { }; -// CHECK: @u2 = global { i32, [4 x i8] } { i32 0, [4 x i8] undef } +// CHECK: @u2 = global %union.anon.0 zeroinitializer union { int i; double f; } u2 = { }; // CHECK: @u3 = global %union.anon.1 zeroinitializer Index: test/CodeGen/const-init.c === --- test/CodeGen/const-init.c +++ test/CodeGen/const-init.c @@ -167,7 +167,7 @@ int : 1; int x; } a = {}; - // CHECK: @g30.a = internal global %struct.anon.1 <{ i8 undef, i32 0 }>, align 1 + // CHECK: @g30.a = internal global %struct.anon.1 zeroinitializer, align 1 #pragma pack() } Index: lib/CodeGen/CGExprConstant.cpp === --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -1392,20 +1392,40 @@ return type; } +/// Checks if the specified initializer is equivalent to zero initialization. +static bool isZeroInitializer(ConstantEmitter &CE, const Expr *Init) { + if (auto *E = dyn_cast_or_null(Init)) { +CXXConstructorDecl *CD = E->getConstructor(); +return CD->isDefaultConstruc
r331965 - Add support of the next Ubuntu (Ubuntu 18.10 - Cosmic Canimal)
Author: sylvestre Date: Thu May 10 01:45:43 2018 New Revision: 331965 URL: http://llvm.org/viewvc/llvm-project?rev=331965&view=rev Log: Add support of the next Ubuntu (Ubuntu 18.10 - Cosmic Canimal) Patch by Adam Conrad Modified: cfe/trunk/include/clang/Driver/Distro.h cfe/trunk/lib/Driver/Distro.cpp Modified: cfe/trunk/include/clang/Driver/Distro.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Distro.h?rev=331965&r1=331964&r2=331965&view=diff == --- cfe/trunk/include/clang/Driver/Distro.h (original) +++ cfe/trunk/include/clang/Driver/Distro.h Thu May 10 01:45:43 2018 @@ -61,6 +61,7 @@ public: UbuntuZesty, UbuntuArtful, UbuntuBionic, +UbuntuCosmic, UnknownDistro }; @@ -114,7 +115,7 @@ public: } bool IsUbuntu() const { -return DistroVal >= UbuntuHardy && DistroVal <= UbuntuBionic; +return DistroVal >= UbuntuHardy && DistroVal <= UbuntuCosmic; } bool IsAlpineLinux() const { Modified: cfe/trunk/lib/Driver/Distro.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Distro.cpp?rev=331965&r1=331964&r2=331965&view=diff == --- cfe/trunk/lib/Driver/Distro.cpp (original) +++ cfe/trunk/lib/Driver/Distro.cpp Thu May 10 01:45:43 2018 @@ -49,6 +49,7 @@ static Distro::DistroType DetectDistro(v .Case("zesty", Distro::UbuntuZesty) .Case("artful", Distro::UbuntuArtful) .Case("bionic", Distro::UbuntuBionic) + .Case("cosmic", Distro::UbuntuCosmic) .Default(Distro::UnknownDistro); if (Version != Distro::UnknownDistro) return Version; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46683: [X86] Assume alignment of movdir64b dst argument
GBuella created this revision. GBuella added a reviewer: craig.topper. Herald added a subscriber: cfe-commits. Repository: rC Clang https://reviews.llvm.org/D46683 Files: lib/Headers/movdirintrin.h test/CodeGen/builtin-movdir.c Index: test/CodeGen/builtin-movdir.c === --- test/CodeGen/builtin-movdir.c +++ test/CodeGen/builtin-movdir.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -ffreestanding -Wall -pedantic -triple x86_64-unknown-unknown -target-feature +movdiri -target-feature +movdir64b %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_64 --check-prefix=CHECK -// RUN: %clang_cc1 -ffreestanding -Wall -pedantic -triple i386-unknown-unknown -target-feature +movdiri -target-feature +movdir64b %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -ffreestanding -Wall -pedantic -triple i386-unknown-unknown -target-feature +movdiri -target-feature +movdir64b %s -emit-llvm -o - | FileCheck %s --check-prefix=X86 --check-prefix=CHECK #include #include @@ -22,6 +22,11 @@ void test_dir64b(void *dst, const void *src) { // CHECK-LABEL: test_dir64b + // CHECK: [[PTRINT1:%.+]] = ptrtoint + // X86: [[MASKEDPTR1:%.+]] = and i32 [[PTRINT1]], 63 + // X86: [[MASKCOND1:%.+]] = icmp eq i32 [[MASKEDPTR1]], 0 + // X86_64: [[MASKEDPTR1:%.+]] = and i64 [[PTRINT1]], 63 + // X86_64: [[MASKCOND1:%.+]] = icmp eq i64 [[MASKEDPTR1]], 0 // CHECK: call void @llvm.x86.movdir64b _movdir64b(dst, src); } Index: lib/Headers/movdirintrin.h === --- lib/Headers/movdirintrin.h +++ lib/Headers/movdirintrin.h @@ -47,10 +47,15 @@ #endif /* __x86_64__ */ -// Move 64 bytes as direct store +/* + * movdir64b - Move 64 bytes as direct store. + * The destination must be 64 byte aligned, and the store is atomic. + * The source address has no alignment requirement, and the load from + * the source address is not atomic. + */ static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("movdir64b"))) -_movdir64b (void *__dst, const void *__src) +_movdir64b (void *__dst __attribute__((align_value(64))), const void *__src) { __builtin_ia32_movdir64b(__dst, __src); } Index: test/CodeGen/builtin-movdir.c === --- test/CodeGen/builtin-movdir.c +++ test/CodeGen/builtin-movdir.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -ffreestanding -Wall -pedantic -triple x86_64-unknown-unknown -target-feature +movdiri -target-feature +movdir64b %s -emit-llvm -o - | FileCheck %s --check-prefix=X86_64 --check-prefix=CHECK -// RUN: %clang_cc1 -ffreestanding -Wall -pedantic -triple i386-unknown-unknown -target-feature +movdiri -target-feature +movdir64b %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK +// RUN: %clang_cc1 -ffreestanding -Wall -pedantic -triple i386-unknown-unknown -target-feature +movdiri -target-feature +movdir64b %s -emit-llvm -o - | FileCheck %s --check-prefix=X86 --check-prefix=CHECK #include #include @@ -22,6 +22,11 @@ void test_dir64b(void *dst, const void *src) { // CHECK-LABEL: test_dir64b + // CHECK: [[PTRINT1:%.+]] = ptrtoint + // X86: [[MASKEDPTR1:%.+]] = and i32 [[PTRINT1]], 63 + // X86: [[MASKCOND1:%.+]] = icmp eq i32 [[MASKEDPTR1]], 0 + // X86_64: [[MASKEDPTR1:%.+]] = and i64 [[PTRINT1]], 63 + // X86_64: [[MASKCOND1:%.+]] = icmp eq i64 [[MASKEDPTR1]], 0 // CHECK: call void @llvm.x86.movdir64b _movdir64b(dst, src); } Index: lib/Headers/movdirintrin.h === --- lib/Headers/movdirintrin.h +++ lib/Headers/movdirintrin.h @@ -47,10 +47,15 @@ #endif /* __x86_64__ */ -// Move 64 bytes as direct store +/* + * movdir64b - Move 64 bytes as direct store. + * The destination must be 64 byte aligned, and the store is atomic. + * The source address has no alignment requirement, and the load from + * the source address is not atomic. + */ static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("movdir64b"))) -_movdir64b (void *__dst, const void *__src) +_movdir64b (void *__dst __attribute__((align_value(64))), const void *__src) { __builtin_ia32_movdir64b(__dst, __src); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
hfinkel added a comment. In https://reviews.llvm.org/D39053#1093977, @asb wrote: > Just wanted to explicitly say that I'm happy the updated patch reflects the > changes to docs and comments I requested. @hfinkel - are you happy for this > to land now? Yes, go ahead. Some of these benefits might still be capturable using the regular method and backend improvements, but with this under the option it should be easier to identify where those opportunities are. https://reviews.llvm.org/D39053 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46684: [Frontend] Don't skip function body when the return type is dependent on the template parameter.
hokein created this revision. hokein added a reviewer: ilya-biryukov. Otherwise clang will provide an unexpected diagnostic error. Repository: rC Clang https://reviews.llvm.org/D46684 Files: lib/Sema/SemaDecl.cpp test/Index/skipped-auto-fn-templates.cpp Index: test/Index/skipped-auto-fn-templates.cpp === --- /dev/null +++ test/Index/skipped-auto-fn-templates.cpp @@ -0,0 +1,10 @@ +// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source all %s 2>&1 \ +// RUN: | FileCheck %s + +template +auto foo(T a) { + return a; +} + +int b = foo(0); +// CHECK-NOT: error: function 'foo' with deduced return type cannot be used before it is defined Index: lib/Sema/SemaDecl.cpp === --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -12637,8 +12637,12 @@ // rest of the file. // We cannot skip the body of a function with an undeduced return type, // because any callers of that function need to know the type. + // We cannot skip the body of a function template with an 'auto' return type + // which is dependent on a template parameter, we need to see the function + // body before using it. if (const FunctionDecl *FD = D->getAsFunction()) -if (FD->isConstexpr() || FD->getReturnType()->isUndeducedType()) +if (FD->isConstexpr() || FD->getReturnType()->isUndeducedType() || +FD->getReturnType()->isInstantiationDependentType()) return false; return Consumer.shouldSkipFunctionBody(D); } Index: test/Index/skipped-auto-fn-templates.cpp === --- /dev/null +++ test/Index/skipped-auto-fn-templates.cpp @@ -0,0 +1,10 @@ +// RUN: env CINDEXTEST_SKIP_FUNCTION_BODIES=1 c-index-test -test-load-source all %s 2>&1 \ +// RUN: | FileCheck %s + +template +auto foo(T a) { + return a; +} + +int b = foo(0); +// CHECK-NOT: error: function 'foo' with deduced return type cannot be used before it is defined Index: lib/Sema/SemaDecl.cpp === --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -12637,8 +12637,12 @@ // rest of the file. // We cannot skip the body of a function with an undeduced return type, // because any callers of that function need to know the type. + // We cannot skip the body of a function template with an 'auto' return type + // which is dependent on a template parameter, we need to see the function + // body before using it. if (const FunctionDecl *FD = D->getAsFunction()) -if (FD->isConstexpr() || FD->getReturnType()->isUndeducedType()) +if (FD->isConstexpr() || FD->getReturnType()->isUndeducedType() || +FD->getReturnType()->isInstantiationDependentType()) return false; return Consumer.shouldSkipFunctionBody(D); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46685: [CodeGen] Disable structor optimizations at -O0
labath created this revision. labath added reviewers: rjmccall, aprantl. Merging of complete and base structors can degrade debug quality as it will leave the debugger unable to locate the full object structor. This is apparent when evaluating an expression in the debugger which requires constructing an object of class which has had this optimization applied to it. When compiling the expression, we pretend that the class and its methods have been defined in another compilation unit, so the expression compiler assumes the structor definition must be available, whereas in reality the complete structor may have been omitted and all it's uses replaced by the base structor. This improves debug quality on non-darwin platforms (darwin does not have -mconstructor-aliases on by default, so it is spared these problems) and enable us to remove some workarounds from LLDB which attempt to mitigate this issue. This is tested by strenghtening the check in the existing ctor-dtor-alias test. In the other aliasing tests I add -O1 to compiler options to make sure the aliasing kicks in. PS: Of the three ways we can do structor optimizations, only the RAUW actually causes problems as it makes the symbol completely disappear, so technically it should be sufficient to weaken RAUW to one of the other two for -O0, but disabling optimizations completely looked like a more principled solution. Repository: rC Clang https://reviews.llvm.org/D46685 Files: lib/CodeGen/ItaniumCXXABI.cpp test/CodeGenCXX/constructor-alias.cpp test/CodeGenCXX/ctor-dtor-alias.cpp test/CodeGenCXX/dllexport-alias.cpp test/CodeGenCXX/virtual-bases.cpp Index: test/CodeGenCXX/virtual-bases.cpp === --- test/CodeGenCXX/virtual-bases.cpp +++ test/CodeGenCXX/virtual-bases.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck %s struct A { A(); Index: test/CodeGenCXX/dllexport-alias.cpp === --- test/CodeGenCXX/dllexport-alias.cpp +++ test/CodeGenCXX/dllexport-alias.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-windows-gnu -mconstructor-aliases %s -S -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -mconstructor-aliases %s -S -emit-llvm -O1 -disable-llvm-passes -o - | FileCheck %s // This test assumes that the C1 constructor will be aliased to the C2 // constructor, and the D1 destructor to the D2. It then checks that the aliases Index: test/CodeGenCXX/ctor-dtor-alias.cpp === --- test/CodeGenCXX/ctor-dtor-alias.cpp +++ test/CodeGenCXX/ctor-dtor-alias.cpp @@ -77,11 +77,12 @@ // CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test41AD2Ev // CHECK1: define linkonce_odr void @_ZN5test41AD2Ev({{.*}} comdat align - // test that we don't do this optimization at -O0 so that the debugger can - // see both destructors. + // test that we don't do this optimization at -O0 and call the complete + // destructor for B instead. This enables the debugger to see both + // destructors. // NOOPT: define internal void @__cxx_global_var_init.2() - // NOOPT: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD2Ev - // NOOPT: define linkonce_odr void @_ZN5test41BD2Ev({{.*}} comdat align + // NOOPT: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD1Ev + // NOOPT: define linkonce_odr void @_ZN5test41BD1Ev({{.*}} comdat align struct A { virtual ~A() {} }; Index: test/CodeGenCXX/constructor-alias.cpp === --- test/CodeGenCXX/constructor-alias.cpp +++ test/CodeGenCXX/constructor-alias.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -triple mipsel--linux-gnu -mconstructor-aliases -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple mipsel--linux-gnu -mconstructor-aliases -O1 -disable-llvm-passes -o - %s | FileCheck %s // The target attribute code used to get confused with aliases. Make sure // we don't crash when an alias is used. Index: lib/CodeGen/ItaniumCXXABI.cpp === --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -3616,6 +3616,11 @@ if (MD->getParent()->getNumVBases()) return StructorCodegen::Emit; + // Omitting the complete structor can degrade debug quality as the debugger + // cannot locate the complete structor symbol anymore. + if (CGM.getCodeGenOpts().OptimizationLevel == 0) +return StructorCodegen::Emit; + GlobalDecl AliasDecl; if (const auto *DD = dyn_cast(MD)) { AliasDecl = GlobalDecl(DD, Dtor_Complete); Index: test/CodeGenCXX/virtual-bases.cpp === --- test/CodeGe
[PATCH] D46614: [clang] Adding CharacteristicKind to PPCallbacks::InclusionDirective
aaron.ballman added inline comments. Comment at: unittests/Lex/PPCallbacksTest.cpp:140 + std::unique_ptr getPreprocessor(const char *SourceText, +const char *HeaderPath, This function appears to be unused? Comment at: unittests/Lex/PPCallbacksTest.cpp:179 -Preprocessor PP(std::make_shared(), Diags, LangOpts, -SourceMgr, PCMCache, HeaderInfo, ModLoader, -/*IILookup =*/nullptr, -/*OwnsHeaderSearch =*/false); -PP.Initialize(*Target); -InclusionDirectiveCallbacks* Callbacks = new InclusionDirectiveCallbacks; -PP.addPPCallbacks(std::unique_ptr(Callbacks)); +std::unique_ptr PP = llvm::make_unique( +std::make_shared(), Diags, LangOpts, SourceMgr, Did you intend to make use of it here? Comment at: unittests/Lex/PPCallbacksTest.cpp:200 + +std::unique_ptr PP = llvm::make_unique( +std::make_shared(), Diags, LangOpts, SourceMgr, and here? https://reviews.llvm.org/D46614 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46667: [OpenCL, OpenMP] Fix crash when OpenMP used in OpenCL file
Anastasia added a comment. OpenCL C is based on C99, so OpenMP isn't enabled by default. But in your tests you use `-fopenmp` to activate it. OpenCL general philosophy is that vectors are written explicitly, but it's not always very easy. In OpenCL C++ we have added an attribute hint for auto vectorization `cl::vec_type_hint`. It's given to a kernel rather than for a loop though. So I think this `simd` pragma is useful. My only worry is that other OpenMP features might not work well in OpenCL and we have no way to reject them at the moment. Repository: rC Clang https://reviews.llvm.org/D46667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46667: [OpenCL, OpenMP] Fix crash when OpenMP used in OpenCL file
Anastasia added inline comments. Comment at: lib/Sema/SemaDecl.cpp:11348 // initialiser -if (var->getTypeSourceInfo()->getType()->isBlockPointerType() && -!var->hasInit()) { +if (var->getType()->isBlockPointerType() && !var->hasInit()) { Diag(var->getLocation(), diag::err_opencl_invalid_block_declaration) Does `simd` result in block creation? My original understanding of it was that it will result in vector operations, not extra threads. Repository: rC Clang https://reviews.llvm.org/D46667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46667: [OpenCL, OpenMP] Fix crash when OpenMP used in OpenCL file
ABataev added a comment. In https://reviews.llvm.org/D46667#1094340, @Anastasia wrote: > OpenCL C is based on C99, so OpenMP isn't enabled by default. But in your > tests you use `-fopenmp` to activate it. > > OpenCL general philosophy is that vectors are written explicitly, but it's > not always very easy. In OpenCL C++ we have added an attribute hint for auto > vectorization `cl::vec_type_hint`. It's given to a kernel rather than for a > loop though. So I think this `simd` pragma is useful. My only worry is that > other OpenMP features might not work well in OpenCL and we have no way to > reject them at the moment. We have special flag '-fopenmp-simd' to support only simd-based constructs. We can allow to use only this subset of OpenMP in OpenCL programs and disable support for '-fopenmp'. Repository: rC Clang https://reviews.llvm.org/D46667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r331979 - This patch provides that bitfields are splitted even in case
Author: spetrovic Date: Thu May 10 05:31:12 2018 New Revision: 331979 URL: http://llvm.org/viewvc/llvm-project?rev=331979&view=rev Log: This patch provides that bitfields are splitted even in case when current field is not legal integer type. Differential Revision: https://reviews.llvm.org/D39053 Added: cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp Modified: cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=331979&r1=331978&r2=331979&view=diff == --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Thu May 10 05:31:12 2018 @@ -1156,7 +1156,7 @@ def fxray_instrumentation_bundle : def ffine_grained_bitfield_accesses : Flag<["-"], "ffine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, - HelpText<"Use separate accesses for bitfields with legal widths and alignments.">; + HelpText<"Use separate accesses for consecutive bitfield runs with legal widths and alignments.">; def fno_fine_grained_bitfield_accesses : Flag<["-"], "fno-fine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, HelpText<"Use large-integer access for consecutive bitfield runs.">; Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=331979&r1=331978&r2=331979&view=diff == --- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original) +++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Thu May 10 05:31:12 2018 @@ -404,19 +404,20 @@ CGRecordLowering::accumulateBitFields(Re return; } - // Check if current Field is better as a single field run. When current field + // Check if OffsetInRecord is better as a single field run. When OffsetInRecord // has legal integer width, and its bitfield offset is naturally aligned, it // is better to make the bitfield a separate storage component so as it can be // accessed directly with lower cost. - auto IsBetterAsSingleFieldRun = [&](RecordDecl::field_iterator Field) { + auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord, + uint64_t StartBitOffset) { if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses) return false; -unsigned Width = Field->getBitWidthValue(Context); -if (!DataLayout.isLegalInteger(Width)) +if (!DataLayout.isLegalInteger(OffsetInRecord)) return false; -// Make sure Field is natually aligned if it is treated as an IType integer. -if (getFieldBitOffset(*Field) % -Context.toBits(getAlignment(getIntNType(Width))) != +// Make sure StartBitOffset is natually aligned if it is treated as an +// IType integer. + if (StartBitOffset % +Context.toBits(getAlignment(getIntNType(OffsetInRecord))) != 0) return false; return true; @@ -435,14 +436,15 @@ CGRecordLowering::accumulateBitFields(Re Run = Field; StartBitOffset = getFieldBitOffset(*Field); Tail = StartBitOffset + Field->getBitWidthValue(Context); -StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Run); +StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Tail - StartBitOffset, + StartBitOffset); } ++Field; continue; } // If the start field of a new run is better as a single run, or -// if current field is better as a single run, or +// if current field (or consecutive fields) is better as a single run, or // if current field has zero width bitfield and either // UseZeroLengthBitfieldAlignment or UseBitFieldTypeAlignment is set to // true, or @@ -451,7 +453,7 @@ CGRecordLowering::accumulateBitFields(Re // skip the block below and go ahead to emit the storage. // Otherwise, try to add bitfields to the run. if (!StartFieldAsSingleRun && Field != FieldEnd && -!IsBetterAsSingleFieldRun(Field) && +!IsBetterAsSingleFieldRun(Tail - StartBitOffset, StartBitOffset) && (!Field->isZeroLengthBitField(Context) || (!Context.getTargetInfo().useZeroLengthBitfieldAlignment() && !Context.getTargetInfo().useBitFieldTypeAlignment())) && Added: cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp?rev=331979&view=auto == --- cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp (added) +++ cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp Thu May 10 05:31:12 2018 @@ -0,0 +1,22 @@ +// RUN: %clan
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rL331979: This patch provides that bitfields are splitted even in case (authored by spetrovic, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D39053?vs=143918&id=146117#toc Repository: rL LLVM https://reviews.llvm.org/D39053 Files: cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp Index: cfe/trunk/include/clang/Driver/Options.td === --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -1156,7 +1156,7 @@ def ffine_grained_bitfield_accesses : Flag<["-"], "ffine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, - HelpText<"Use separate accesses for bitfields with legal widths and alignments.">; + HelpText<"Use separate accesses for consecutive bitfield runs with legal widths and alignments.">; def fno_fine_grained_bitfield_accesses : Flag<["-"], "fno-fine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, HelpText<"Use large-integer access for consecutive bitfield runs.">; Index: cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp === --- cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp +++ cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \ +// RUN: -emit-llvm -o - %s | FileCheck %s +struct S4 { + unsigned long f1:28; + unsigned long f2:4; + unsigned long f3:12; +}; +struct S4 a4; + +struct S5 { + unsigned long f1:28; + unsigned long f2:4; + unsigned long f3:28; + unsigned long f4:4; + unsigned long f5:12; +}; +struct S5 a5; + +// CHECK: %struct.S4 = type { i32, i16 } +// CHECK-NOT: %struct.S4 = type { i48 } +// CHECK: %struct.S5 = type { i32, i32, i16, [6 x i8] } +// CHECK-NOT: %struct.S5 = type { i80 } \ No newline at end of file Index: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp === --- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -404,19 +404,20 @@ return; } - // Check if current Field is better as a single field run. When current field + // Check if OffsetInRecord is better as a single field run. When OffsetInRecord // has legal integer width, and its bitfield offset is naturally aligned, it // is better to make the bitfield a separate storage component so as it can be // accessed directly with lower cost. - auto IsBetterAsSingleFieldRun = [&](RecordDecl::field_iterator Field) { + auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord, + uint64_t StartBitOffset) { if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses) return false; -unsigned Width = Field->getBitWidthValue(Context); -if (!DataLayout.isLegalInteger(Width)) +if (!DataLayout.isLegalInteger(OffsetInRecord)) return false; -// Make sure Field is natually aligned if it is treated as an IType integer. -if (getFieldBitOffset(*Field) % -Context.toBits(getAlignment(getIntNType(Width))) != +// Make sure StartBitOffset is natually aligned if it is treated as an +// IType integer. + if (StartBitOffset % +Context.toBits(getAlignment(getIntNType(OffsetInRecord))) != 0) return false; return true; @@ -435,23 +436,24 @@ Run = Field; StartBitOffset = getFieldBitOffset(*Field); Tail = StartBitOffset + Field->getBitWidthValue(Context); -StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Run); +StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Tail - StartBitOffset, + StartBitOffset); } ++Field; continue; } // If the start field of a new run is better as a single run, or -// if current field is better as a single run, or +// if current field (or consecutive fields) is better as a single run, or // if current field has zero width bitfield and either // UseZeroLengthBitfieldAlignment or UseBitFieldTypeAlignment is set to // true, or // if the offset of current field is inconsistent with the offset of // previous field plus its offset, // skip the block below and go ahead to emit the storage. // Otherwise, try to add bitfields to the run. if (!StartFieldAsSingleRun && Field != FieldEnd && -!IsBetterAsSingleFieldRun(Field) && +!IsBetterAsSingleFieldRun(Tail - StartBitOffset, StartBitOffset) && (!Field->isZeroLengthBitField(Context) ||
[PATCH] D46667: [OpenCL, OpenMP] Fix crash when OpenMP used in OpenCL file
ABataev added inline comments. Comment at: lib/Sema/SemaDecl.cpp:11348 // initialiser -if (var->getTypeSourceInfo()->getType()->isBlockPointerType() && -!var->hasInit()) { +if (var->getType()->isBlockPointerType() && !var->hasInit()) { Diag(var->getLocation(), diag::err_opencl_invalid_block_declaration) Anastasia wrote: > Does `simd` result in block creation? My original understanding of it was > that it will result in vector operations, not extra threads. Currently all of the OpenMP constructs (even simd) create special lambda-like construct CapturedStmt that are kind of a block. It is required for unified processing of the OpenMP constructs. Comment at: test/SemaOpenCL/omp_simd.cl:1 +// RUN: %clang_cc1 -verify -fopenmp -fsyntax-only -x cl %s +// expected-no-diagnostics It would be good to check that at least -ast-print or -ast-dump works correctly. Repository: rC Clang https://reviews.llvm.org/D46667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46684: [Frontend] Don't skip function body when the return type is dependent on the template parameter.
rsmith added inline comments. Comment at: lib/Sema/SemaDecl.cpp:12645 +if (FD->isConstexpr() || FD->getReturnType()->isUndeducedType() || +FD->getReturnType()->isInstantiationDependentType()) return false; This is a lot broader than necessary; what we should do is to look for a deduced type in the return type. `isUndeducedType` doesn't quite do that for a template because we "deduce" the `auto` as a dependent type early. Repository: rC Clang https://reviews.llvm.org/D46684 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46667: [OpenCL, OpenMP] Fix crash when OpenMP used in OpenCL file
Anastasia added inline comments. Comment at: lib/Sema/SemaDecl.cpp:11348 // initialiser -if (var->getTypeSourceInfo()->getType()->isBlockPointerType() && -!var->hasInit()) { +if (var->getType()->isBlockPointerType() && !var->hasInit()) { Diag(var->getLocation(), diag::err_opencl_invalid_block_declaration) ABataev wrote: > Anastasia wrote: > > Does `simd` result in block creation? My original understanding of it was > > that it will result in vector operations, not extra threads. > Currently all of the OpenMP constructs (even simd) create special lambda-like > construct CapturedStmt that are kind of a block. It is required for unified > processing of the OpenMP constructs. I see. It does add some extra code for captures and extra BBs but most of it seems to be removed with optimizations. Comment at: test/SemaOpenCL/omp_simd.cl:1 +// RUN: %clang_cc1 -verify -fopenmp -fsyntax-only -x cl %s +// expected-no-diagnostics ABataev wrote: > It would be good to check that at least -ast-print or -ast-dump works > correctly. Generated IR seems fine. Might be enough to just convert to IR test? Repository: rC Clang https://reviews.llvm.org/D46667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46386: Adding __atomic_fetch_min/max intrinsics to clang
rjmccall added inline comments. Comment at: docs/LanguageExtensions.rst:1998 +``__ATOMIC_CONSUME``, ``__ATOMIC_ACQUIRE``, ``__ATOMIC_RELEASE``, +``__ATOMIC_ACQ_REL``, or ``__ATOMIC_SEQ_CST`` following C++11 memory model semantics. + rjmccall wrote: > Thank you for adding this documentation. Please do clarify what the memory > ordering semantics actually are when the atomic object does not need to be > updated, though, and verify that target code generation actually obeys that > ordering. For example, if the memory ordering makes this a release > operation, `__atomic_fetch_min` must always store the result back to the > atomic object, even if the new value was actually greater than the stored > value; I believe that would not be required with a relaxed operation. Okay, that's not what I was asking for. It's okay to assume that people understand the basic memory orderings; you don't need to copy/paste generic descriptions of them here. There is something special about min/max vs. the rest of these atomic update operations, however, which is that min and max don't always change the value of the variable. (Technically this is true of corner cases of many of the other operations — for example, you could atomically add 0 to a variable or multiply a variable by 1 — but the basic operation of min/max makes this corner case a lot more important.) I am just asking you to state definitively whether the atomic operation is still appropriately ordered if the object's value does not change. If you don't understand what I'm getting at here, maybe you should just add the relaxed ordering for now. Repository: rC Clang https://reviews.llvm.org/D46386 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D44934: [analyzer] Improve the modeling of `memset()`.
MTC added a comment. ping. Repository: rC Clang https://reviews.llvm.org/D44934 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46694: [diagtool] Install diagtool
JDevlieghere created this revision. JDevlieghere added reviewers: arphaman, dexonsmith, jkorous, rsmith. Herald added a subscriber: mgorny. Although not very well known, diagtool is an incredibly convenient utility for dealing with diagnostics. I believe it's worth adding this to the install target. Repository: rC Clang https://reviews.llvm.org/D46694 Files: clang/tools/diagtool/CMakeLists.txt Index: clang/tools/diagtool/CMakeLists.txt === --- clang/tools/diagtool/CMakeLists.txt +++ clang/tools/diagtool/CMakeLists.txt @@ -17,3 +17,15 @@ clangBasic clangFrontend ) + +if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) + install(TARGETS diagtool +COMPONENT diagtool +RUNTIME DESTINATION bin) + + if (NOT CMAKE_CONFIGURATION_TYPES) +add_llvm_install_targets(install-diagtool + DEPENDS diagtool + COMPONENT diagtool) + endif() +endif() Index: clang/tools/diagtool/CMakeLists.txt === --- clang/tools/diagtool/CMakeLists.txt +++ clang/tools/diagtool/CMakeLists.txt @@ -17,3 +17,15 @@ clangBasic clangFrontend ) + +if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) + install(TARGETS diagtool +COMPONENT diagtool +RUNTIME DESTINATION bin) + + if (NOT CMAKE_CONFIGURATION_TYPES) +add_llvm_install_targets(install-diagtool + DEPENDS diagtool + COMPONENT diagtool) + endif() +endif() ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46241: [CodeGen] Recognize more cases of zero initialization
rjmccall accepted this revision. rjmccall added a comment. This revision is now accepted and ready to land. Thanks, LGTM. Repository: rC Clang https://reviews.llvm.org/D46241 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46643: CodeGen: Emit string literal in constant address space
rjmccall added inline comments. Comment at: lib/CodeGen/CGDecl.cpp:1375 +Loc = Address(EmitCastToVoidPtrInAllocaAddrSpace(Loc.getPointer()), + Loc.getAlignment()); yaxunl wrote: > rjmccall wrote: > > I don't understand why a patch about string literals is changing auto > > variable emission. > It is a bug about alloca revealed by the lit test > > > ``` > char l_array[] = "l_array"; > > ``` > Loc contains the alloca casted to default address space, therefore it needs > to be casted back to alloca address space here, otherwise CreateBitCast > returns invalid bitcast. Unlike lifetime.start, memcpy does not require > alloca address space, so an alternative fix is to let BP take address space > of Loc. Yeah, I think using the address space of Loc is more appropriate. https://reviews.llvm.org/D46643 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46700: [ThinLTO] Add testing of new summary index format to a couple CFI tests
tejohnson created this revision. tejohnson added a reviewer: pcc. Herald added subscribers: eraman, inglorion, mehdi_amini. Adds testing of combined index summary entries in disassembly format to CFI tests that were already testing the bitcode format. Depends on https://reviews.llvm.org/D46699. Repository: rC Clang https://reviews.llvm.org/D46700 Files: test/CodeGen/thinlto-distributed-cfi-devirt.ll test/CodeGen/thinlto-distributed-cfi.ll Index: test/CodeGen/thinlto-distributed-cfi.ll === --- test/CodeGen/thinlto-distributed-cfi.ll +++ test/CodeGen/thinlto-distributed-cfi.ll @@ -20,6 +20,11 @@ ; CHECK: blob data = '_ZTS1A' ; CHECK-LABEL: Index: test/CodeGen/thinlto-distributed-cfi.ll === --- test/CodeGen/thinlto-distributed-cfi.ll +++ test/CodeGen/thinlto-distributed-cfi.ll @@ -20,6 +20,11 @@ ; CHECK: blob data = '_ZTS1A' ; CHECK-LABEL: ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46685: [CodeGen] Disable structor optimizations at -O0
rjmccall added a comment. Can we suppress this optimization only when we can't emit an alias? An alias shouldn't degrade debugging experience, and it's good to emit less code at -O0. Repository: rC Clang https://reviews.llvm.org/D46685 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46540: [X86] ptwrite intrinsic
Hahnfeld added a comment. In https://reviews.llvm.org/D46540#1092620, @GBuella wrote: > In https://reviews.llvm.org/D46540#1091625, @Hahnfeld wrote: > > > Could you maybe add some short summaries to your patches? It's hard for > > non-Intel employees to guess what all these instructions do... > > > Well, I was thinking I could copy-paste this from > https://software.intel.com/en-us/articles/intel-sdm : > "This instruction reads data in the source operand and sends it to the Intel > Processor Trace hardware to be encoded > in a PTW packet if TriggerEn, ContextEn, FilterEn, and PTWEn are all set to > 1. For more details on these values, see > Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3C, > Section 35.2.2, “Software Trace > Instrumentation with PTWRITE”." > > Do you think this would really help anyone? It appears to be just meaningless > without larger context. > Those who ever need this, need to read a lot of these manuals anyways, I > think noone in practice is going to be enlightened by such a short > description. > > That of course makes a lot more sense with simpler instructions, e.g. > movdir64b - I can just describe that as something like "atomically moving 64 > bytes". My 2 cents: I actually think this is worth a bit because it gives additional information so the reader can at least put the instruction into a category. Repository: rC Clang https://reviews.llvm.org/D46540 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45463: [AST] Print correct tag decl for tag specifier
jdenny updated this revision to Diff 146145. jdenny edited the summary of this revision. jdenny added a comment. I've implemented the suggestion to use ElaboratedType. See the last paragraph of the revised summary for details. There might be trouble for CXPrintingPolicyProperty users. That is, this patch shifts the semantics of IncludeTagDefinition away from the documented semantics and from what the name implies. Then again, both were already misleading for a tag type without a member list (that is, definition). I see a few possible paths: 1. Update the documentation for IncludeTagDefinition and assume the new behavior was the expected behavior all along. 2. #1 and rename IncludeTagDefinition to something like OwnedTagDeclaration. 3. Add OwnedTagDeclaration alongside IncludeTagDefinition. CXPrintingPolicyProperty users could set either. We'd have to decide which would have precedence. Internally, we would change Decl::printGroup to set OwnedTagDeclaration instead of IncludeTagDefinition, which otherwise would not be used internally. https://reviews.llvm.org/D45463 Files: include/clang/AST/ASTContext.h include/clang/AST/Type.h include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/ASTImporter.cpp lib/AST/TypePrinter.cpp lib/Sema/SemaType.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/Misc/ast-print-enum-decl.c test/Misc/ast-print-record-decl.c Index: test/Misc/ast-print-record-decl.c === --- /dev/null +++ test/Misc/ast-print-record-decl.c @@ -0,0 +1,251 @@ +// Check struct: +// +// First check compiling and printing of this file. +// +// RUN: %clang -Xclang -verify -S -emit-llvm -DKW=struct -DBASES= -o - %s \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print -DKW=struct -DBASES= %s > %t.c +// RUN: FileCheck --check-prefixes=CHECK,PRINT -DKW=struct -DBASES= %s \ +// RUN: --input-file %t.c +// +// Now check compiling and printing of the printed file. +// +// RUN: echo "// expected""-warning@* 10 {{'T' is deprecated}}" >> %t.c +// RUN: echo "// expected""-note@* 10 {{'T' has been explicitly marked deprecated here}}" >> %t.c +// +// RUN: %clang -Xclang -verify -S -emit-llvm -o - %t.c \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print %t.c \ +// RUN: | FileCheck --check-prefixes=CHECK,PRINT -DKW=struct -DBASES= %s + +// Repeat for union: +// +// First check compiling and printing of this file. +// +// RUN: %clang -Xclang -verify -S -emit-llvm -DKW=union -DBASES= -o - %s \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print -DKW=union -DBASES= %s > %t.c +// RUN: FileCheck --check-prefixes=CHECK,PRINT -DKW=union -DBASES= %s \ +// RUN: --input-file %t.c +// +// Now check compiling and printing of the printed file. +// +// RUN: echo "// expected""-warning@* 10 {{'T' is deprecated}}" >> %t.c +// RUN: echo "// expected""-note@* 10 {{'T' has been explicitly marked deprecated here}}" >> %t.c +// +// RUN: %clang -Xclang -verify -S -emit-llvm -o - %t.c \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print %t.c \ +// RUN: | FileCheck --check-prefixes=CHECK,PRINT -DKW=union -DBASES= %s + +// Repeat for C++ (BASES helps ensure we're printing as C++ not as C): +// +// First check compiling and printing of this file. +// +// RUN: %clang -Xclang -verify -S -emit-llvm -DKW=struct -DBASES=' : B' -o - \ +// RUN:-xc++ %s \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print -DKW=struct -DBASES=' : B' -xc++ %s \ +// RUN: > %t.cpp +// RUN: FileCheck --check-prefixes=CHECK,PRINT,CXX -DKW=struct \ +// RUN: -DBASES=' : B' %s --input-file %t.cpp +// +// Now check compiling and printing of the printed file. +// +// RUN: echo "// expected""-warning@* 10 {{'T' is deprecated}}" >> %t.cpp +// RUN: echo "// expected""-note@* 10 {{'T' has been explicitly marked deprecated here}}" >> %t.cpp +// +// RUN: %clang -Xclang -verify -S -emit-llvm -o - %t.cpp \ +// RUN: | FileCheck --check-prefixes=CHECK,LLVM %s +// +// RUN: %clang_cc1 -verify -ast-print %t.cpp \ +// RUN: | FileCheck --check-prefixes=CHECK,PRINT,CXX -DKW=struct \ +// RUN: -DBASES=' : B' %s + +// END. + +#ifndef KW +# error KW undefined +# define KW struct // help syntax checkers +#endif + +#ifndef BASES +# error BASES undefined +# define BASES // help syntax checkers +#endif + +struct B {}; + +// CHECK-LABEL: defFirst +void defFirst() { + // PRINT-NEXT: [[KW]] + // PRINT-DAG: __attribute__((aligned(16))) + // PRINT-DAG: __attribute__((deprecated(""))) + // PRINT-NOT: __attribute__ + // PRINT-SAME: T[[BASES]] { + // PRINT-NEXT: int i; + // PRINT-NEXT: } *p0; + // expected-warning@+2 {{'T' i
[PATCH] D46694: [diagtool] Install diagtool
dexonsmith added a comment. This SGTM, but I wouldn't mind hearing from others. I wonder if this is worth a quick RFC on cfe-dev? Repository: rC Clang https://reviews.llvm.org/D46694 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r332000 - More notes on Rapperswil issues
Author: marshall Date: Thu May 10 10:07:38 2018 New Revision: 332000 URL: http://llvm.org/viewvc/llvm-project?rev=332000&view=rev Log: More notes on Rapperswil issues Modified: libcxx/trunk/www/upcoming_meeting.html Modified: libcxx/trunk/www/upcoming_meeting.html URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/upcoming_meeting.html?rev=332000&r1=331999&r2=332000&view=diff == --- libcxx/trunk/www/upcoming_meeting.html (original) +++ libcxx/trunk/www/upcoming_meeting.html Thu May 10 10:07:38 2018 @@ -70,7 +70,7 @@ https://wg21.link/LWG3076";>3076basic_string CTAD ambiguityRapperswil https://wg21.link/LWG3079";>3079LWG 2935 forgot to fix the existing_p overloads of create_directoryRapperswil https://wg21.link/LWG3080";>3080Floating point from_chars pattern specification breaks round-trippingRapperswil -https://wg21.link/LWG3083";>3083What should ios::iword(-1) do?Rapperswil +https://wg21.link/LWG3083";>3083What should ios::iword(-1) do?RapperswilNothing to do https://wg21.link/LWG3094";>3094[time.duration.io]p4 makes surprising claims about encodingRapperswil https://wg21.link/LWG3100";>3100Unnecessary and confusing "empty span" wordingRapperswilNothing to do https://wg21.link/LWG3102";>3102Clarify span iterator and const_iterator behaviorRapperswil @@ -92,17 +92,17 @@ Comments about the issues 2139 - I think that this is just wording cleanup. -2970 - -3058 - +2970 - I think that we already do this - checking with Michael. +3058 - We don't do the parallel algos yet 3062 - This should be very easy. 3067 - Adding restrictions; no code changes needed. 3071 - This is just wording cleanup. -3074 - +3074 - Large change, that looks straightforward. 3076 - -3079 - -3080 - -3083 - -3094 - +3079 - Eric? +3080 - We don't have a from_chars implementation yet. +3083 - This is just wording cleanup. +3094 - We haven't implemented Howard's date library yet. 3100 - This is just wording cleanup. 3102 - This should be just adding tests. 3104 - We already do this. @@ -117,7 +117,7 @@ 2936 - Eric - don't we do this already? -Last Updated: 7-May-2018 +Last Updated: 10-May-2018 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46683: [X86] Assume alignment of movdir64b dst argument
craig.topper added a comment. What effect does this have? Repository: rC Clang https://reviews.llvm.org/D46683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45920: [analyzer] Move RangeSet related declarations into the RangedConstraintManager header.
mikhail.ramalho commandeered this revision. mikhail.ramalho added a reviewer: rnkovacs. mikhail.ramalho added a comment. Commandeering the PR because of GSoC. Repository: rC Clang https://reviews.llvm.org/D45920 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45517: [analyzer] WIP: False positive refutation with Z3
mikhail.ramalho added a comment. Commandeering the PR because of GSoC. https://reviews.llvm.org/D45517 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46614: [clang] Adding CharacteristicKind to PPCallbacks::InclusionDirective
juliehockett updated this revision to Diff 146158. juliehockett marked 3 inline comments as done. juliehockett added a comment. Removing unused function https://reviews.llvm.org/D46614 Files: include/clang/Lex/PPCallbacks.h include/clang/Lex/PreprocessingRecord.h lib/CodeGen/MacroPPCallbacks.cpp lib/CodeGen/MacroPPCallbacks.h lib/Frontend/DependencyFile.cpp lib/Frontend/DependencyGraph.cpp lib/Frontend/ModuleDependencyCollector.cpp lib/Frontend/PrintPreprocessedOutput.cpp lib/Frontend/Rewrite/InclusionRewriter.cpp lib/Lex/PPDirectives.cpp lib/Lex/PreprocessingRecord.cpp tools/libclang/Indexing.cpp unittests/Lex/PPCallbacksTest.cpp Index: unittests/Lex/PPCallbacksTest.cpp === --- unittests/Lex/PPCallbacksTest.cpp +++ unittests/Lex/PPCallbacksTest.cpp @@ -39,16 +39,18 @@ StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported) override { - this->HashLoc = HashLoc; - this->IncludeTok = IncludeTok; - this->FileName = FileName.str(); - this->IsAngled = IsAngled; - this->FilenameRange = FilenameRange; - this->File = File; - this->SearchPath = SearchPath.str(); - this->RelativePath = RelativePath.str(); - this->Imported = Imported; + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override { +this->HashLoc = HashLoc; +this->IncludeTok = IncludeTok; +this->FileName = FileName.str(); +this->IsAngled = IsAngled; +this->FilenameRange = FilenameRange; +this->File = File; +this->SearchPath = SearchPath.str(); +this->RelativePath = RelativePath.str(); +this->Imported = Imported; +this->FileType = FileType; } SourceLocation HashLoc; @@ -60,6 +62,7 @@ SmallString<16> SearchPath; SmallString<16> RelativePath; const Module* Imported; + SrcMgr::CharacteristicKind FileType; }; // Stub to collect data from PragmaOpenCLExtension callbacks. @@ -149,26 +152,52 @@ Diags, LangOpts, Target.get()); AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader); -Preprocessor PP(std::make_shared(), Diags, LangOpts, -SourceMgr, PCMCache, HeaderInfo, ModLoader, -/*IILookup =*/nullptr, -/*OwnsHeaderSearch =*/false); -PP.Initialize(*Target); -InclusionDirectiveCallbacks* Callbacks = new InclusionDirectiveCallbacks; -PP.addPPCallbacks(std::unique_ptr(Callbacks)); +std::unique_ptr PP = llvm::make_unique( +std::make_shared(), Diags, LangOpts, SourceMgr, +PCMCache, HeaderInfo, ModLoader, +/*IILookup =*/nullptr, +/*OwnsHeaderSearch =*/false); +return InclusionDirectiveCallback(PP.get())->FilenameRange; + } + + SrcMgr::CharacteristicKind InclusionDirectiveCharacteristicKind( + const char *SourceText, const char *HeaderPath, bool SystemHeader) { +std::unique_ptr Buf = +llvm::MemoryBuffer::getMemBuffer(SourceText); +SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); + +TrivialModuleLoader ModLoader; +MemoryBufferCache PCMCache; +HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, +Diags, LangOpts, Target.get()); +AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader); + +std::unique_ptr PP = llvm::make_unique( +std::make_shared(), Diags, LangOpts, SourceMgr, +PCMCache, HeaderInfo, ModLoader, +/*IILookup =*/nullptr, +/*OwnsHeaderSearch =*/false); +return InclusionDirectiveCallback(PP.get())->FileType; + } + + InclusionDirectiveCallbacks *InclusionDirectiveCallback(Preprocessor *PP) { +PP->Initialize(*Target); +InclusionDirectiveCallbacks* Callbacks = new InclusionDirectiveCallbacks; +PP->addPPCallbacks(std::unique_ptr(Callbacks)); + // Lex source text. -PP.EnterMainSourceFile(); +PP->EnterMainSourceFile(); while (true) { Token Tok; - PP.Lex(Tok); + PP->Lex(Tok); if (Tok.is(tok::eof)) break; } // Callbacks have been executed at this point -- return filename range. -return Callbacks->FilenameRange; +return Callbacks; } PragmaOpenCLExtensionCallbacks::CallbackParameters @@ -222,6 +251,15 @@ } }; +TEST_F(PPCallbacksTest, UserFileCharacteristics) { + const char *Source = "#include \"quoted.h\"\n"; + + SrcMgr::CharacteristicKind Kind = + InclusionDirectiveCharacteristicKind(Source, "/quoted.h", false); + + ASSERT_EQ(SrcMgr::CharacteristicKind::C_User, Kind); +} + TEST_F(PPCallbacksTest, QuotedFilename) { const char* Source = "#include \"quoted.h\"\n"; Index: tools/libclang/Indexing.cpp
[PATCH] D46614: [clang] Adding CharacteristicKind to PPCallbacks::InclusionDirective
aaron.ballman added inline comments. Comment at: unittests/Lex/PPCallbacksTest.cpp:155-160 +std::unique_ptr PP = llvm::make_unique( +std::make_shared(), Diags, LangOpts, SourceMgr, +PCMCache, HeaderInfo, ModLoader, +/*IILookup =*/nullptr, +/*OwnsHeaderSearch =*/false); +return InclusionDirectiveCallback(PP.get())->FilenameRange; I'm likely just missing something, but why is the `unique_ptr` required at all? The `Preprocessor` object will be destroyed on exit from this function, so it seems like it could be an automatic variable that's passed by reference to `InclusionDirectiveCallback()`, and same below. https://reviews.llvm.org/D46614 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r332016 - [OPENMP, NVPTX] Initial support for L2 parallelism in SPMD mode.
Author: abataev Date: Thu May 10 11:32:08 2018 New Revision: 332016 URL: http://llvm.org/viewvc/llvm-project?rev=332016&view=rev Log: [OPENMP, NVPTX] Initial support for L2 parallelism in SPMD mode. Added initial support for L2 parallelism in SPMD mode. Note, though, that the orphaned parallel directives are not currently supported in SPMD mode. Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.h cfe/trunk/test/OpenMP/nvptx_parallel_codegen.cpp cfe/trunk/test/OpenMP/nvptx_target_teams_codegen.cpp cfe/trunk/test/OpenMP/nvptx_target_teams_distribute_parallel_for_generic_mode_codegen.cpp cfe/trunk/test/OpenMP/target_parallel_debug_codegen.cpp Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp?rev=332016&r1=332015&r2=332016&view=diff == --- cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp (original) +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp Thu May 10 11:32:08 2018 @@ -140,13 +140,15 @@ public: /// to emit optimized code. class ExecutionModeRAII { private: - bool SavedMode; - bool &Mode; + CGOpenMPRuntimeNVPTX::ExecutionMode SavedMode; + CGOpenMPRuntimeNVPTX::ExecutionMode &Mode; public: - ExecutionModeRAII(bool &Mode, bool NewMode) : Mode(Mode) { + ExecutionModeRAII(CGOpenMPRuntimeNVPTX::ExecutionMode &Mode, bool IsSPMD) + : Mode(Mode) { SavedMode = Mode; -Mode = NewMode; +Mode = IsSPMD ? CGOpenMPRuntimeNVPTX::EM_SPMD + : CGOpenMPRuntimeNVPTX::EM_NonSPMD; } ~ExecutionModeRAII() { Mode = SavedMode; } }; @@ -579,8 +581,9 @@ void CGOpenMPRuntimeNVPTX::WorkerFunctio WorkerFn->setDoesNotRecurse(); } -bool CGOpenMPRuntimeNVPTX::isInSpmdExecutionMode() const { - return IsInSPMDExecutionMode; +CGOpenMPRuntimeNVPTX::ExecutionMode +CGOpenMPRuntimeNVPTX::getExecutionMode() const { + return CurrentExecutionMode; } static CGOpenMPRuntimeNVPTX::DataSharingMode @@ -589,34 +592,96 @@ getDataSharingMode(CodeGenModule &CGM) { : CGOpenMPRuntimeNVPTX::Generic; } -/// Check for inner (nested) SPMD construct, if any -static bool hasNestedSPMDDirective(const OMPExecutableDirective &D) { - const auto *CS = D.getCapturedStmt(OMPD_target); - const auto *Body = CS->getCapturedStmt()->IgnoreContainers(); - const Stmt *ChildStmt = nullptr; +/// Checks if the \p Body is the \a CompoundStmt and returns its child statement +/// iff there is only one. +static const Stmt *getSingleCompoundChild(const Stmt *Body) { if (const auto *C = dyn_cast(Body)) if (C->size() == 1) - ChildStmt = C->body_front(); - if (!ChildStmt) -return false; + return C->body_front(); + return Body; +} + +/// Check if the parallel directive has an 'if' clause with non-constant or +/// false condition. +static bool hasParallelIfClause(ASTContext &Ctx, +const OMPExecutableDirective &D) { + for (const auto *C : D.getClausesOfKind()) { +OpenMPDirectiveKind NameModifier = C->getNameModifier(); +if (NameModifier != OMPD_parallel && NameModifier != OMPD_unknown) + continue; +const Expr *Cond = C->getCondition(); +bool Result; +if (!Cond->EvaluateAsBooleanCondition(Result, Ctx) || !Result) + return true; + } + return false; +} + +/// Check for inner (nested) SPMD construct, if any +static bool hasNestedSPMDDirective(ASTContext &Ctx, + const OMPExecutableDirective &D) { + const auto *CS = D.getInnermostCapturedStmt(); + const auto *Body = CS->getCapturedStmt()->IgnoreContainers(); + const Stmt *ChildStmt = getSingleCompoundChild(Body); if (const auto *NestedDir = dyn_cast(ChildStmt)) { OpenMPDirectiveKind DKind = NestedDir->getDirectiveKind(); -// TODO: add further analysis for inner teams|distribute directives, if any. switch (D.getDirectiveKind()) { case OMPD_target: - return (isOpenMPParallelDirective(DKind) && - !isOpenMPTeamsDirective(DKind) && - !isOpenMPDistributeDirective(DKind)) || - isOpenMPSimdDirective(DKind) || - DKind == OMPD_teams_distribute_parallel_for; + if ((isOpenMPParallelDirective(DKind) && + !hasParallelIfClause(Ctx, *NestedDir)) || + isOpenMPSimdDirective(DKind)) +return true; + if (DKind == OMPD_teams || DKind == OMPD_teams_distribute) { +Body = NestedDir->getInnermostCapturedStmt()->IgnoreContainers(); +if (!Body) + return false; +ChildStmt = getSingleCompoundChild(Body); +if (const auto *NND = dyn_cast(ChildStmt)) { + DKind = NND->getDirectiveKind(); + if ((isOpenMPParallelDirective(DKind) && + !hasParallelIfClause(Ctx, *NND)) || + isOpenMPSimdDirective(DKind)) +
[PATCH] D46614: [clang] Adding CharacteristicKind to PPCallbacks::InclusionDirective
juliehockett updated this revision to Diff 146175. https://reviews.llvm.org/D46614 Files: include/clang/Lex/PPCallbacks.h include/clang/Lex/PreprocessingRecord.h lib/CodeGen/MacroPPCallbacks.cpp lib/CodeGen/MacroPPCallbacks.h lib/Frontend/DependencyFile.cpp lib/Frontend/DependencyGraph.cpp lib/Frontend/ModuleDependencyCollector.cpp lib/Frontend/PrintPreprocessedOutput.cpp lib/Frontend/Rewrite/InclusionRewriter.cpp lib/Lex/PPDirectives.cpp lib/Lex/PreprocessingRecord.cpp tools/libclang/Indexing.cpp unittests/Lex/PPCallbacksTest.cpp Index: unittests/Lex/PPCallbacksTest.cpp === --- unittests/Lex/PPCallbacksTest.cpp +++ unittests/Lex/PPCallbacksTest.cpp @@ -39,16 +39,18 @@ StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported) override { - this->HashLoc = HashLoc; - this->IncludeTok = IncludeTok; - this->FileName = FileName.str(); - this->IsAngled = IsAngled; - this->FilenameRange = FilenameRange; - this->File = File; - this->SearchPath = SearchPath.str(); - this->RelativePath = RelativePath.str(); - this->Imported = Imported; + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override { +this->HashLoc = HashLoc; +this->IncludeTok = IncludeTok; +this->FileName = FileName.str(); +this->IsAngled = IsAngled; +this->FilenameRange = FilenameRange; +this->File = File; +this->SearchPath = SearchPath.str(); +this->RelativePath = RelativePath.str(); +this->Imported = Imported; +this->FileType = FileType; } SourceLocation HashLoc; @@ -60,6 +62,7 @@ SmallString<16> SearchPath; SmallString<16> RelativePath; const Module* Imported; + SrcMgr::CharacteristicKind FileType; }; // Stub to collect data from PragmaOpenCLExtension callbacks. @@ -153,6 +156,30 @@ SourceMgr, PCMCache, HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); +return InclusionDirectiveCallback(PP)->FilenameRange; + } + + SrcMgr::CharacteristicKind InclusionDirectiveCharacteristicKind( + const char *SourceText, const char *HeaderPath, bool SystemHeader) { +std::unique_ptr Buf = +llvm::MemoryBuffer::getMemBuffer(SourceText); +SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); + +TrivialModuleLoader ModLoader; +MemoryBufferCache PCMCache; + +HeaderSearch HeaderInfo(std::make_shared(), SourceMgr, +Diags, LangOpts, Target.get()); +AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader); + +Preprocessor PP(std::make_shared(), Diags, LangOpts, +SourceMgr, PCMCache, HeaderInfo, ModLoader, +/*IILookup =*/nullptr, +/*OwnsHeaderSearch =*/false); +return InclusionDirectiveCallback(PP)->FileType; + } + + InclusionDirectiveCallbacks *InclusionDirectiveCallback(Preprocessor &PP) { PP.Initialize(*Target); InclusionDirectiveCallbacks* Callbacks = new InclusionDirectiveCallbacks; PP.addPPCallbacks(std::unique_ptr(Callbacks)); @@ -168,7 +195,7 @@ } // Callbacks have been executed at this point -- return filename range. -return Callbacks->FilenameRange; +return Callbacks; } PragmaOpenCLExtensionCallbacks::CallbackParameters @@ -222,6 +249,15 @@ } }; +TEST_F(PPCallbacksTest, UserFileCharacteristics) { + const char *Source = "#include \"quoted.h\"\n"; + + SrcMgr::CharacteristicKind Kind = + InclusionDirectiveCharacteristicKind(Source, "/quoted.h", false); + + ASSERT_EQ(SrcMgr::CharacteristicKind::C_User, Kind); +} + TEST_F(PPCallbacksTest, QuotedFilename) { const char* Source = "#include \"quoted.h\"\n"; Index: tools/libclang/Indexing.cpp === --- tools/libclang/Indexing.cpp +++ tools/libclang/Indexing.cpp @@ -249,7 +249,8 @@ StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported) override { + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override { bool isImport = (IncludeTok.is(tok::identifier) && IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import); DataConsumer.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled, Index: lib/Lex/PreprocessingRecord.cpp === --- lib/Lex
[PATCH] D46614: [clang] Adding CharacteristicKind to PPCallbacks::InclusionDirective
aaron.ballman accepted this revision. aaron.ballman added a comment. LGTM! https://reviews.llvm.org/D46614 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r332018 - Allow dllimport non-type template arguments in C++17
Author: rnk Date: Thu May 10 11:57:35 2018 New Revision: 332018 URL: http://llvm.org/viewvc/llvm-project?rev=332018&view=rev Log: Allow dllimport non-type template arguments in C++17 Summary: Fixes PR35772. Reviewers: rsmith Differential Revision: https://reviews.llvm.org/D43320 Added: cfe/trunk/test/SemaCXX/dllimport-constexpr.cpp Modified: cfe/trunk/include/clang/AST/Expr.h cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/test/SemaCXX/dllimport-memptr.cpp Modified: cfe/trunk/include/clang/AST/Expr.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=332018&r1=332017&r2=332018&view=diff == --- cfe/trunk/include/clang/AST/Expr.h (original) +++ cfe/trunk/include/clang/AST/Expr.h Thu May 10 11:57:35 2018 @@ -658,6 +658,13 @@ public: ArrayRef Args, const Expr *This = nullptr) const; + /// Indicates how the constant expression will be used. + enum ConstExprUsage { EvaluateForCodeGen, EvaluateForMangling }; + + /// Evaluate an expression that is required to be a constant expression. + bool EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage, + const ASTContext &Ctx) const; + /// If the current Expr is a pointer, this will try to statically /// determine the number of bytes available where the pointer is pointing. /// Returns true if all of the above holds and we were able to figure out the Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=332018&r1=332017&r2=332018&view=diff == --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Thu May 10 11:57:35 2018 @@ -1720,7 +1720,8 @@ static void NoteLValueLocation(EvalInfo /// value for an address or reference constant expression. Return true if we /// can fold this expression, whether or not it's a constant expression. static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, - QualType Type, const LValue &LVal) { + QualType Type, const LValue &LVal, + Expr::ConstExprUsage Usage) { bool IsReferenceType = Type->isReferenceType(); APValue::LValueBase Base = LVal.getLValueBase(); @@ -1753,7 +1754,7 @@ static bool CheckLValueConstantExpressio return false; // A dllimport variable never acts like a constant. - if (Var->hasAttr()) + if (Usage == Expr::EvaluateForCodeGen && Var->hasAttr()) return false; } if (const auto *FD = dyn_cast(VD)) { @@ -1767,7 +1768,8 @@ static bool CheckLValueConstantExpressio // The C language has no notion of ODR; furthermore, it has no notion of // dynamic initialization. This means that we are permitted to // perform initialization with the address of the thunk. - if (Info.getLangOpts().CPlusPlus && FD->hasAttr()) + if (Info.getLangOpts().CPlusPlus && Usage == Expr::EvaluateForCodeGen && + FD->hasAttr()) return false; } } @@ -1800,12 +1802,14 @@ static bool CheckLValueConstantExpressio static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, - const APValue &Value) { + const APValue &Value, + Expr::ConstExprUsage Usage) { const ValueDecl *Member = Value.getMemberPointerDecl(); const auto *FD = dyn_cast_or_null(Member); if (!FD) return true; - return FD->isVirtual() || !FD->hasAttr(); + return Usage == Expr::EvaluateForMangling || FD->isVirtual() || + !FD->hasAttr(); } /// Check that this core constant expression is of literal type, and if not, @@ -1843,8 +1847,10 @@ static bool CheckLiteralType(EvalInfo &I /// Check that this core constant expression value is a valid value for a /// constant expression. If not, report an appropriate diagnostic. Does not /// check that the expression is of literal type. -static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, -QualType Type, const APValue &Value) { +static bool +CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, +const APValue &Value, +Expr::ConstExprUsage Usage = Expr::EvaluateForCodeGen) { if (Value.isUninit()) { Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized) << true << Type; @@ -1863,28 +1869,28 @@ static
[PATCH] D43320: Allow dllimport non-type template arguments in C++17
This revision was automatically updated to reflect the committed changes. Closed by commit rC332018: Allow dllimport non-type template arguments in C++17 (authored by rnk, committed by ). Changed prior to commit: https://reviews.llvm.org/D43320?vs=146039&id=146178#toc Repository: rC Clang https://reviews.llvm.org/D43320 Files: include/clang/AST/Expr.h lib/AST/ExprConstant.cpp lib/Sema/SemaOverload.cpp test/SemaCXX/dllimport-constexpr.cpp test/SemaCXX/dllimport-memptr.cpp Index: lib/AST/ExprConstant.cpp === --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -1720,7 +1720,8 @@ /// value for an address or reference constant expression. Return true if we /// can fold this expression, whether or not it's a constant expression. static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, - QualType Type, const LValue &LVal) { + QualType Type, const LValue &LVal, + Expr::ConstExprUsage Usage) { bool IsReferenceType = Type->isReferenceType(); APValue::LValueBase Base = LVal.getLValueBase(); @@ -1753,7 +1754,7 @@ return false; // A dllimport variable never acts like a constant. - if (Var->hasAttr()) + if (Usage == Expr::EvaluateForCodeGen && Var->hasAttr()) return false; } if (const auto *FD = dyn_cast(VD)) { @@ -1767,7 +1768,8 @@ // The C language has no notion of ODR; furthermore, it has no notion of // dynamic initialization. This means that we are permitted to // perform initialization with the address of the thunk. - if (Info.getLangOpts().CPlusPlus && FD->hasAttr()) + if (Info.getLangOpts().CPlusPlus && Usage == Expr::EvaluateForCodeGen && + FD->hasAttr()) return false; } } @@ -1800,12 +1802,14 @@ static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, - const APValue &Value) { + const APValue &Value, + Expr::ConstExprUsage Usage) { const ValueDecl *Member = Value.getMemberPointerDecl(); const auto *FD = dyn_cast_or_null(Member); if (!FD) return true; - return FD->isVirtual() || !FD->hasAttr(); + return Usage == Expr::EvaluateForMangling || FD->isVirtual() || + !FD->hasAttr(); } /// Check that this core constant expression is of literal type, and if not, @@ -1843,8 +1847,10 @@ /// Check that this core constant expression value is a valid value for a /// constant expression. If not, report an appropriate diagnostic. Does not /// check that the expression is of literal type. -static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, -QualType Type, const APValue &Value) { +static bool +CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, +const APValue &Value, +Expr::ConstExprUsage Usage = Expr::EvaluateForCodeGen) { if (Value.isUninit()) { Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized) << true << Type; @@ -1863,48 +1869,49 @@ QualType EltTy = Type->castAsArrayTypeUnsafe()->getElementType(); for (unsigned I = 0, N = Value.getArrayInitializedElts(); I != N; ++I) { if (!CheckConstantExpression(Info, DiagLoc, EltTy, - Value.getArrayInitializedElt(I))) + Value.getArrayInitializedElt(I), Usage)) return false; } if (!Value.hasArrayFiller()) return true; -return CheckConstantExpression(Info, DiagLoc, EltTy, - Value.getArrayFiller()); +return CheckConstantExpression(Info, DiagLoc, EltTy, Value.getArrayFiller(), + Usage); } if (Value.isUnion() && Value.getUnionField()) { return CheckConstantExpression(Info, DiagLoc, Value.getUnionField()->getType(), - Value.getUnionValue()); + Value.getUnionValue(), Usage); } if (Value.isStruct()) { RecordDecl *RD = Type->castAs()->getDecl(); if (const CXXRecordDecl *CD = dyn_cast(RD)) { unsigned BaseIndex = 0; - for (CXXRecordDecl::base_class_const_iterator I = CD->bases_begin(), - End = CD->bases_end(); I != End; ++I, ++BaseIndex) { -if (!CheckConstantExpression(Info, DiagLoc, I->getType(), - Value.getStructBase(BaseIndex))) + for (const CXXBaseSpecifier &BS : CD->bases()) { +if (!Check
[PATCH] D46683: [X86] Assume alignment of movdir64b dst argument
GBuella added a comment. In https://reviews.llvm.org/D46683#1094662, @craig.topper wrote: > What effect does this have? Nothing important really, I just guessed it doesn't cost. One contrived example I could come up with in 2 minutes: #include void x(char *restrict a __attribute__((align_value(64))), char *restrict b, const char *c) { _movdir64b(b, c); for (int i = 0; i < 32; ++i) a[i] = b[i]; } The silly memcpy loop above becomes 2 `movaps` instructions, instead of two `movups` instructions. Repository: rC Clang https://reviews.llvm.org/D46683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r332021 - Reland '[clang] Adding CharacteristicKind to PPCallbacks::InclusionDirective'
Author: juliehockett Date: Thu May 10 12:05:36 2018 New Revision: 332021 URL: http://llvm.org/viewvc/llvm-project?rev=332021&view=rev Log: Reland '[clang] Adding CharacteristicKind to PPCallbacks::InclusionDirective' This commit relands r331904. Adding a SrcMgr::CharacteristicKind parameter to the InclusionDirective in PPCallbacks, and updating calls to that function. This will be useful in https://reviews.llvm.org/D43778 to determine which includes are system headers. Differential Revision: https://reviews.llvm.org/D46614 Modified: cfe/trunk/include/clang/Lex/PPCallbacks.h cfe/trunk/include/clang/Lex/PreprocessingRecord.h cfe/trunk/lib/CodeGen/MacroPPCallbacks.cpp cfe/trunk/lib/CodeGen/MacroPPCallbacks.h cfe/trunk/lib/Frontend/DependencyFile.cpp cfe/trunk/lib/Frontend/DependencyGraph.cpp cfe/trunk/lib/Frontend/ModuleDependencyCollector.cpp cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp cfe/trunk/lib/Frontend/Rewrite/InclusionRewriter.cpp cfe/trunk/lib/Lex/PPDirectives.cpp cfe/trunk/lib/Lex/PreprocessingRecord.cpp cfe/trunk/tools/libclang/Indexing.cpp cfe/trunk/unittests/Lex/PPCallbacksTest.cpp Modified: cfe/trunk/include/clang/Lex/PPCallbacks.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PPCallbacks.h?rev=332021&r1=332020&r2=332021&view=diff == --- cfe/trunk/include/clang/Lex/PPCallbacks.h (original) +++ cfe/trunk/include/clang/Lex/PPCallbacks.h Thu May 10 12:05:36 2018 @@ -117,6 +117,10 @@ public: /// \param Imported The module, whenever an inclusion directive was /// automatically turned into a module import or null otherwise. /// + /// \param FileType The characteristic kind, indicates whether a file or + /// directory holds normal user code, system code, or system code which is + /// implicitly 'extern "C"' in C++ mode. + /// virtual void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, @@ -125,7 +129,8 @@ public: const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported) { + const Module *Imported, + SrcMgr::CharacteristicKind FileType) { } /// Callback invoked whenever there was an explicit module-import @@ -367,13 +372,14 @@ public: StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported) override { + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override { First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, FilenameRange, File, SearchPath, RelativePath, - Imported); + Imported, FileType); Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, FilenameRange, File, SearchPath, RelativePath, - Imported); + Imported, FileType); } void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, Modified: cfe/trunk/include/clang/Lex/PreprocessingRecord.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PreprocessingRecord.h?rev=332021&r1=332020&r2=332021&view=diff == --- cfe/trunk/include/clang/Lex/PreprocessingRecord.h (original) +++ cfe/trunk/include/clang/Lex/PreprocessingRecord.h Thu May 10 12:05:36 2018 @@ -532,8 +532,8 @@ class Token; StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, -StringRef RelativePath, -const Module *Imported) override; +StringRef RelativePath, const Module *Imported, +SrcMgr::CharacteristicKind FileType) override; void Ifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD) override; void Ifndef(SourceLocation Loc, const Token &MacroNameTok, Modified: cfe/trunk/lib/CodeGen/MacroPPCallbacks.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MacroPPCallbacks.cpp?rev=332021&r1=332020&r2=332021&view=diff == --- cfe/trunk/lib/CodeGen/MacroPPCallbacks.cpp (original) ++
[PATCH] D46614: [clang] Adding CharacteristicKind to PPCallbacks::InclusionDirective
This revision was automatically updated to reflect the committed changes. Closed by commit rC332021: Reland '[clang] Adding CharacteristicKind to PPCallbacks::InclusionDirective' (authored by juliehockett, committed by ). Repository: rC Clang https://reviews.llvm.org/D46614 Files: include/clang/Lex/PPCallbacks.h include/clang/Lex/PreprocessingRecord.h lib/CodeGen/MacroPPCallbacks.cpp lib/CodeGen/MacroPPCallbacks.h lib/Frontend/DependencyFile.cpp lib/Frontend/DependencyGraph.cpp lib/Frontend/ModuleDependencyCollector.cpp lib/Frontend/PrintPreprocessedOutput.cpp lib/Frontend/Rewrite/InclusionRewriter.cpp lib/Lex/PPDirectives.cpp lib/Lex/PreprocessingRecord.cpp tools/libclang/Indexing.cpp unittests/Lex/PPCallbacksTest.cpp Index: include/clang/Lex/PreprocessingRecord.h === --- include/clang/Lex/PreprocessingRecord.h +++ include/clang/Lex/PreprocessingRecord.h @@ -532,8 +532,8 @@ StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, -StringRef RelativePath, -const Module *Imported) override; +StringRef RelativePath, const Module *Imported, +SrcMgr::CharacteristicKind FileType) override; void Ifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD) override; void Ifndef(SourceLocation Loc, const Token &MacroNameTok, Index: include/clang/Lex/PPCallbacks.h === --- include/clang/Lex/PPCallbacks.h +++ include/clang/Lex/PPCallbacks.h @@ -117,15 +117,20 @@ /// \param Imported The module, whenever an inclusion directive was /// automatically turned into a module import or null otherwise. /// + /// \param FileType The characteristic kind, indicates whether a file or + /// directory holds normal user code, system code, or system code which is + /// implicitly 'extern "C"' in C++ mode. + /// virtual void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported) { + const Module *Imported, + SrcMgr::CharacteristicKind FileType) { } /// Callback invoked whenever there was an explicit module-import @@ -367,13 +372,14 @@ StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported) override { + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override { First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, FilenameRange, File, SearchPath, RelativePath, - Imported); + Imported, FileType); Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, FilenameRange, File, SearchPath, RelativePath, - Imported); + Imported, FileType); } void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, Index: lib/CodeGen/MacroPPCallbacks.h === --- lib/CodeGen/MacroPPCallbacks.h +++ lib/CodeGen/MacroPPCallbacks.h @@ -101,7 +101,8 @@ StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported) override; + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override; /// Hook called whenever a macro definition is seen. void MacroDefined(const Token &MacroNameTok, Index: lib/CodeGen/MacroPPCallbacks.cpp === --- lib/CodeGen/MacroPPCallbacks.cpp +++ lib/CodeGen/MacroPPCallbacks.cpp @@ -178,7 +178,8 @@ void MacroPPCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry
[clang-tools-extra] r332023 - Reland "[tools] Updating PPCallbacks::InclusionDirective calls"
Author: juliehockett Date: Thu May 10 12:13:14 2018 New Revision: 332023 URL: http://llvm.org/viewvc/llvm-project?rev=332023&view=rev Log: Reland "[tools] Updating PPCallbacks::InclusionDirective calls" This commit relands r331905. r331904 added SrcMgr::CharacteristicKind to the InclusionDirective callback, this revision updates instances of it in clang-tools-extra. Modified: clang-tools-extra/trunk/clang-move/ClangMove.cpp clang-tools-extra/trunk/clang-tidy/llvm/IncludeOrderCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/DeprecatedHeadersCheck.cpp clang-tools-extra/trunk/clang-tidy/utils/IncludeInserter.cpp clang-tools-extra/trunk/clangd/ClangdUnit.cpp clang-tools-extra/trunk/clangd/Headers.cpp clang-tools-extra/trunk/modularize/CoverageChecker.cpp clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.cpp clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.h Modified: clang-tools-extra/trunk/clang-move/ClangMove.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-move/ClangMove.cpp?rev=332023&r1=332022&r2=332023&view=diff == --- clang-tools-extra/trunk/clang-move/ClangMove.cpp (original) +++ clang-tools-extra/trunk/clang-move/ClangMove.cpp Thu May 10 12:13:14 2018 @@ -131,7 +131,8 @@ public: clang::CharSourceRange FilenameRange, const clang::FileEntry * /*File*/, StringRef SearchPath, StringRef /*RelativePath*/, - const clang::Module * /*Imported*/) override { + const clang::Module * /*Imported*/, + SrcMgr::CharacteristicKind /*FileType*/) override { if (const auto *FileEntry = SM.getFileEntryForID(SM.getFileID(HashLoc))) MoveTool->addIncludes(FileName, IsAngled, SearchPath, FileEntry->getName(), FilenameRange, SM); Modified: clang-tools-extra/trunk/clang-tidy/llvm/IncludeOrderCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/llvm/IncludeOrderCheck.cpp?rev=332023&r1=332022&r2=332023&view=diff == --- clang-tools-extra/trunk/clang-tidy/llvm/IncludeOrderCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/llvm/IncludeOrderCheck.cpp Thu May 10 12:13:14 2018 @@ -28,7 +28,8 @@ public: StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported) override; + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override; void EndOfMainFile() override; private: @@ -76,7 +77,8 @@ static int getPriority(StringRef Filenam void IncludeOrderPPCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, -StringRef SearchPath, StringRef RelativePath, const Module *Imported) { +StringRef SearchPath, StringRef RelativePath, const Module *Imported, +SrcMgr::CharacteristicKind FileType) { // We recognize the first include as a special main module header and want // to leave it in the top position. IncludeDirective ID = {HashLoc, FilenameRange, FileName, IsAngled, false}; Modified: clang-tools-extra/trunk/clang-tidy/modernize/DeprecatedHeadersCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/DeprecatedHeadersCheck.cpp?rev=332023&r1=332022&r2=332023&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/DeprecatedHeadersCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/DeprecatedHeadersCheck.cpp Thu May 10 12:13:14 2018 @@ -30,7 +30,8 @@ public: StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported) override; + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override; private: ClangTidyCheck &Check; @@ -94,7 +95,8 @@ IncludeModernizePPCallbacks::IncludeMode void IncludeModernizePPCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, -StringRef SearchPath, StringRef RelativePath, const Module *Imported) { +StringRef SearchPath, StringRef RelativeP
r332028 - [Itanium] Emit type info names with external linkage.
Author: ericwf Date: Thu May 10 12:51:56 2018 New Revision: 332028 URL: http://llvm.org/viewvc/llvm-project?rev=332028&view=rev Log: [Itanium] Emit type info names with external linkage. Summary: The Itanium ABI requires that the type info for pointer-to-incomplete types to have internal linkage, so that it doesn't interfere with the type info once completed. Currently it also marks the type info name as internal as well. However, this causes a bug with the STL implementations, which use the type info name pointer to perform ordering and hashing of type infos. For example: ``` // header.h struct T; extern std::type_info const& Info; // tu_one.cpp #include "header.h" std::type_info const& Info = typeid(T*); // tu_two.cpp #include "header.h" struct T {}; int main() { auto &TI1 = Info; auto &TI2 = typeid(T*); assert(TI1 == TI2); // Fails assert(TI1.hash_code() == TI2.hash_code()); // Fails } ``` This patch fixes the STL bug by emitting the type info name as linkonce_odr when the type-info is for a pointer-to-incomplete type. Note that libc++ could fix this without a compiler change, but the quality of fix would be poor. The library would either have to: (A) Always perform strcmp/string hashes. (B) Determine if we have a pointer-to-incomplete type, and only do strcmp then. This would require an ABI break for libc++. Reviewers: rsmith, rjmccall, majnemer, vsapsai Reviewed By: rjmccall Subscribers: smeenai, cfe-commits Differential Revision: https://reviews.llvm.org/D46665 Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=332028&r1=332027&r2=332028&view=diff == --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Thu May 10 12:51:56 2018 @@ -3008,8 +3008,46 @@ void ItaniumRTTIBuilder::BuildVTablePoin /// Return the linkage that the type info and type info name constants /// should have for the given type. -static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, - QualType Ty) { +static std::pair +getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) { + llvm::GlobalValue::LinkageTypes TypeLinkage = [&]() { +switch (Ty->getLinkage()) { +case NoLinkage: +case InternalLinkage: +case UniqueExternalLinkage: + return llvm::GlobalValue::InternalLinkage; + +case VisibleNoLinkage: +case ModuleInternalLinkage: +case ModuleLinkage: +case ExternalLinkage: + // RTTI is not enabled, which means that this type info struct is going + // to be used for exception handling. Give it linkonce_odr linkage. + if (!CGM.getLangOpts().RTTI) +return llvm::GlobalValue::LinkOnceODRLinkage; + + if (const RecordType *Record = dyn_cast(Ty)) { +const CXXRecordDecl *RD = cast(Record->getDecl()); +if (RD->hasAttr()) + return llvm::GlobalValue::WeakODRLinkage; +if (CGM.getTriple().isWindowsItaniumEnvironment()) + if (RD->hasAttr() && + ShouldUseExternalRTTIDescriptor(CGM, Ty)) +return llvm::GlobalValue::ExternalLinkage; +// MinGW always uses LinkOnceODRLinkage for type info. +if (RD->isCompleteDefinition() && RD->isDynamicClass() && +!CGM.getContext() + .getTargetInfo() + .getTriple() + .isWindowsGNUEnvironment()) + return CGM.getVTableLinkage(RD); + } + + return llvm::GlobalValue::LinkOnceODRLinkage; +} +llvm_unreachable("Invalid linkage!"); + }(); // Itanium C++ ABI 2.9.5p7: // In addition, it and all of the intermediate abi::__pointer_type_info // structs in the chain down to the abi::__class_type_info for the @@ -3020,44 +3058,8 @@ static llvm::GlobalVariable::LinkageType // complete class RTTI (because the latter need not exist), possibly by // making it a local static object. if (ContainsIncompleteClassType(Ty)) -return llvm::GlobalValue::InternalLinkage; - - switch (Ty->getLinkage()) { - case NoLinkage: - case InternalLinkage: - case UniqueExternalLinkage: -return llvm::GlobalValue::InternalLinkage; - - case VisibleNoLinkage: - case ModuleInternalLinkage: - case ModuleLinkage: - case ExternalLinkage: -// RTTI is not enabled, which means that this type info struct is going -// to be used for exception handling. Give it linkonce_odr linkage. -if (!CGM.getLangOpts().RTTI) - return llvm::GlobalValue::LinkOnceODRLinkage; - -if (const RecordType *Record = dyn_cast(Ty)) { - const CXXRecordDecl *RD = cast(Record->getDecl()); - if (RD->hasAttr()) -return llvm::GlobalValue::WeakODRLinkage; - if (CGM.getTriple().is
[PATCH] D46665: [Itanium] Emit type info names with external linkage.
This revision was automatically updated to reflect the committed changes. Closed by commit rC332028: [Itanium] Emit type info names with external linkage. (authored by EricWF, committed by ). Repository: rC Clang https://reviews.llvm.org/D46665 Files: lib/CodeGen/ItaniumCXXABI.cpp test/CodeGenCXX/rtti-linkage.cpp Index: lib/CodeGen/ItaniumCXXABI.cpp === --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -3008,8 +3008,46 @@ /// Return the linkage that the type info and type info name constants /// should have for the given type. -static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, - QualType Ty) { +static std::pair +getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) { + llvm::GlobalValue::LinkageTypes TypeLinkage = [&]() { +switch (Ty->getLinkage()) { +case NoLinkage: +case InternalLinkage: +case UniqueExternalLinkage: + return llvm::GlobalValue::InternalLinkage; + +case VisibleNoLinkage: +case ModuleInternalLinkage: +case ModuleLinkage: +case ExternalLinkage: + // RTTI is not enabled, which means that this type info struct is going + // to be used for exception handling. Give it linkonce_odr linkage. + if (!CGM.getLangOpts().RTTI) +return llvm::GlobalValue::LinkOnceODRLinkage; + + if (const RecordType *Record = dyn_cast(Ty)) { +const CXXRecordDecl *RD = cast(Record->getDecl()); +if (RD->hasAttr()) + return llvm::GlobalValue::WeakODRLinkage; +if (CGM.getTriple().isWindowsItaniumEnvironment()) + if (RD->hasAttr() && + ShouldUseExternalRTTIDescriptor(CGM, Ty)) +return llvm::GlobalValue::ExternalLinkage; +// MinGW always uses LinkOnceODRLinkage for type info. +if (RD->isCompleteDefinition() && RD->isDynamicClass() && +!CGM.getContext() + .getTargetInfo() + .getTriple() + .isWindowsGNUEnvironment()) + return CGM.getVTableLinkage(RD); + } + + return llvm::GlobalValue::LinkOnceODRLinkage; +} +llvm_unreachable("Invalid linkage!"); + }(); // Itanium C++ ABI 2.9.5p7: // In addition, it and all of the intermediate abi::__pointer_type_info // structs in the chain down to the abi::__class_type_info for the @@ -3020,44 +3058,8 @@ // complete class RTTI (because the latter need not exist), possibly by // making it a local static object. if (ContainsIncompleteClassType(Ty)) -return llvm::GlobalValue::InternalLinkage; - - switch (Ty->getLinkage()) { - case NoLinkage: - case InternalLinkage: - case UniqueExternalLinkage: -return llvm::GlobalValue::InternalLinkage; - - case VisibleNoLinkage: - case ModuleInternalLinkage: - case ModuleLinkage: - case ExternalLinkage: -// RTTI is not enabled, which means that this type info struct is going -// to be used for exception handling. Give it linkonce_odr linkage. -if (!CGM.getLangOpts().RTTI) - return llvm::GlobalValue::LinkOnceODRLinkage; - -if (const RecordType *Record = dyn_cast(Ty)) { - const CXXRecordDecl *RD = cast(Record->getDecl()); - if (RD->hasAttr()) -return llvm::GlobalValue::WeakODRLinkage; - if (CGM.getTriple().isWindowsItaniumEnvironment()) -if (RD->hasAttr() && -ShouldUseExternalRTTIDescriptor(CGM, Ty)) - return llvm::GlobalValue::ExternalLinkage; - // MinGW always uses LinkOnceODRLinkage for type info. - if (RD->isDynamicClass() && - !CGM.getContext() - .getTargetInfo() - .getTriple() - .isWindowsGNUEnvironment()) -return CGM.getVTableLinkage(RD); -} - -return llvm::GlobalValue::LinkOnceODRLinkage; - } - - llvm_unreachable("Invalid linkage!"); +return {llvm::GlobalValue::InternalLinkage, TypeLinkage}; + return {TypeLinkage, TypeLinkage}; } llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force, @@ -3084,23 +3086,25 @@ return GetAddrOfExternalRTTIDescriptor(Ty); // Emit the standard library with external linkage. - llvm::GlobalVariable::LinkageTypes Linkage; + llvm::GlobalVariable::LinkageTypes InfoLinkage, NameLinkage; if (IsStdLib) -Linkage = llvm::GlobalValue::ExternalLinkage; - else -Linkage = getTypeInfoLinkage(CGM, Ty); - +InfoLinkage = NameLinkage = llvm::GlobalValue::ExternalLinkage; + else { +auto LinkagePair = getTypeInfoLinkage(CGM, Ty); +InfoLinkage = LinkagePair.first; +NameLinkage = LinkagePair.second; + } // Add the vtable pointer. BuildVTablePointer(cast(Ty)); // And the name. - llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage); + llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, NameLinkage); llvm::Constant *TypeNameField; // If we're
[PATCH] D46520: [Driver] Use -fuse-line-directives by default in MSVC mode
rnk added a comment. In https://reviews.llvm.org/D46520#1092681, @mstorsjo wrote: > Reverted in SVN r331858. Thanks! When one attempts to generate pre-processed source with clang and compile it with MSVC, you usually have to remove clang's internal intrinsic headers from the include search path, otherwise you'll end up with references to builtins that don't exist in MSVC. Adding an extra -fuse-line-directives flag is just one more thing that you have to remember for that corner-case usage. Repository: rL LLVM https://reviews.llvm.org/D46520 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43320: Allow dllimport non-type template arguments in C++17
rnk added a comment. Thanks for the guidance! Comment at: clang/lib/AST/ExprConstant.cpp:1871-1902 if (!CheckConstantExpression(Info, DiagLoc, EltTy, Value.getArrayInitializedElt(I))) return false; } if (!Value.hasArrayFiller()) return true; return CheckConstantExpression(Info, DiagLoc, EltTy, rsmith wrote: > `Usage` should be passed into these recursive calls to > `CheckConstantExpression`, although that's NFC for now, until/unless we start > allowing class types as template parameters. Makes sense, done. Repository: rC Clang https://reviews.llvm.org/D43320 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30035: Add const to function parameters
hiraditya abandoned this revision. hiraditya added a comment. Merged with https://reviews.llvm.org/D30268 https://reviews.llvm.org/D30035 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r332040 - Fix PR37407 - callable traits don't correctly check complete types.
Author: ericwf Date: Thu May 10 13:59:35 2018 New Revision: 332040 URL: http://llvm.org/viewvc/llvm-project?rev=332040&view=rev Log: Fix PR37407 - callable traits don't correctly check complete types. Checking for complete types is really rather tricky when you consider the amount of specializations required to check a function type. This specifically caused PR37407 where we incorrectly diagnosed noexcept function types as incomplete (but there were plenty of other cases that would cause this). This patch removes the complete type checking for now. I'm going to look into adding a clang builtin to correctly do this for us. Modified: libcxx/trunk/include/type_traits libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp Modified: libcxx/trunk/include/type_traits URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=332040&r1=332039&r2=332040&view=diff == --- libcxx/trunk/include/type_traits (original) +++ libcxx/trunk/include/type_traits Thu May 10 13:59:35 2018 @@ -4168,147 +4168,6 @@ template struct __is_referen #ifndef _LIBCPP_CXX03_LANG -// Check for complete types - -template struct __check_complete; - -template <> -struct __check_complete<> -{ -}; - -template -struct __check_complete<_Hp, _T0, _Tp...> -: private __check_complete<_Hp>, - private __check_complete<_T0, _Tp...> -{ -}; - -template -struct __check_complete<_Hp, _Hp> -: private __check_complete<_Hp> -{ -}; - -template -struct __check_complete<_Tp> -{ -static_assert(sizeof(_Tp) > 0, "Type must be complete."); -}; - -template -struct __check_complete<_Tp&> -: private __check_complete<_Tp> -{ -}; - -template -struct __check_complete<_Tp&&> -: private __check_complete<_Tp> -{ -}; - -template -struct __check_complete<_Rp (*)(_Param...)> -: private __check_complete<_Rp> -{ -}; - -template -struct __check_complete -{ -}; - -template -struct __check_complete<_Rp (_Param...)> -: private __check_complete<_Rp> -{ -}; - -template -struct __check_complete -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...)> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) volatile> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const volatile> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) &> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const&> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) volatile&> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) &&> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const&&> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) volatile&&> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&&> -: private __check_complete<_Class> -{ -}; - -template -struct __check_complete<_Rp _Class::*> -: private __check_complete<_Class> -{ -}; - - template ::type, class _DecayA0 = typename decay<_A0>::type, @@ -4491,8 +4350,9 @@ _LIBCPP_INVOKE_RETURN(_VSTD::forward<_Fp template struct __invokable_r -: private __check_complete<_Fp> { +// FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void, +// or incomplete array types as required by the standard. using _Result = decltype( _VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)); Modified: libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp?rev=332040&r1=332039&r2=332040&view=diff == --- libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp Thu May 10 13:59:35 2018 @@ -104,36 +104,43 @@ int main() test_result_of (); } { // pointer to function -typedef bool (&RF0)(); +typedef bool(&RF0)(); typedef
r332045 - implementing Cursor.get_included_file in python bindings
Author: jbcoe Date: Thu May 10 14:39:29 2018 New Revision: 332045 URL: http://llvm.org/viewvc/llvm-project?rev=332045&view=rev Log: implementing Cursor.get_included_file in python bindings Summary: adding function: `Cursor.get_included_file` , so the C API's `clang_getIncludedFile` function is available on the python binding interface also adding test to unittests related ticket: https://bugs.llvm.org/show_bug.cgi?id=15223 Reviewers: mgorny, arphaman, jbcoe Reviewed By: jbcoe Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D46383 Patch by jlaz (József Láz) Modified: cfe/trunk/bindings/python/clang/cindex.py cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py Modified: cfe/trunk/bindings/python/clang/cindex.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/bindings/python/clang/cindex.py?rev=332045&r1=332044&r2=332045&view=diff == --- cfe/trunk/bindings/python/clang/cindex.py (original) +++ cfe/trunk/bindings/python/clang/cindex.py Thu May 10 14:39:29 2018 @@ -1511,6 +1511,12 @@ class Cursor(Structure): another translation unit.""" return conf.lib.clang_getCursorUSR(self) +def get_included_file(self): +"""Returns the File that is included by the current inclusion cursor.""" +assert self.kind == CursorKind.INCLUSION_DIRECTIVE + +return conf.lib.clang_getIncludedFile(self) + @property def kind(self): """Return the kind of this cursor.""" @@ -3085,8 +3091,9 @@ class File(ClangObject): return "" % (self.name) @staticmethod -def from_cursor_result(res, fn, args): -assert isinstance(res, File) +def from_result(res, fn, args): +assert isinstance(res, c_object_p) +res = File(res) # Copy a reference to the TranslationUnit to prevent premature GC. res._tu = args[0]._tu @@ -3701,8 +3708,8 @@ functionList = [ ("clang_getIncludedFile", [Cursor], - File, - File.from_cursor_result), + c_object_p, + File.from_result), ("clang_getInclusions", [TranslationUnit, callbacks['translation_unit_includes'], py_object]), Modified: cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py?rev=332045&r1=332044&r2=332045&view=diff == --- cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py (original) +++ cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py Thu May 10 14:39:29 2018 @@ -108,6 +108,18 @@ int SOME_DEFINE; for i in zip(inc, tu.get_includes()): eq(i[0], i[1]) +def test_inclusion_directive(self): +src = os.path.join(kInputsDir, 'include.cpp') +h1 = os.path.join(kInputsDir, "header1.h") +h2 = os.path.join(kInputsDir, "header2.h") +h3 = os.path.join(kInputsDir, "header3.h") +inc = [h1, h3, h2, h3, h1] + +tu = TranslationUnit.from_source(src, options=TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD) +inclusion_directive_files = [c.get_included_file().name for c in tu.cursor.get_children() if c.kind == CursorKind.INCLUSION_DIRECTIVE] +for i in zip(inc, inclusion_directive_files): +self.assert_normpaths_equal(i[0], i[1]) + def test_save(self): """Ensure TranslationUnit.save() works.""" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46383: implementing Cursor.get_included_file in python bindings
This revision was automatically updated to reflect the committed changes. Closed by commit rL332045: implementing Cursor.get_included_file in python bindings (authored by jbcoe, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D46383?vs=144992&id=146230#toc Repository: rL LLVM https://reviews.llvm.org/D46383 Files: cfe/trunk/bindings/python/clang/cindex.py cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py Index: cfe/trunk/bindings/python/clang/cindex.py === --- cfe/trunk/bindings/python/clang/cindex.py +++ cfe/trunk/bindings/python/clang/cindex.py @@ -1511,6 +1511,12 @@ another translation unit.""" return conf.lib.clang_getCursorUSR(self) +def get_included_file(self): +"""Returns the File that is included by the current inclusion cursor.""" +assert self.kind == CursorKind.INCLUSION_DIRECTIVE + +return conf.lib.clang_getIncludedFile(self) + @property def kind(self): """Return the kind of this cursor.""" @@ -3085,8 +3091,9 @@ return "" % (self.name) @staticmethod -def from_cursor_result(res, fn, args): -assert isinstance(res, File) +def from_result(res, fn, args): +assert isinstance(res, c_object_p) +res = File(res) # Copy a reference to the TranslationUnit to prevent premature GC. res._tu = args[0]._tu @@ -3701,8 +3708,8 @@ ("clang_getIncludedFile", [Cursor], - File, - File.from_cursor_result), + c_object_p, + File.from_result), ("clang_getInclusions", [TranslationUnit, callbacks['translation_unit_includes'], py_object]), Index: cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py === --- cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py +++ cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py @@ -108,6 +108,18 @@ for i in zip(inc, tu.get_includes()): eq(i[0], i[1]) +def test_inclusion_directive(self): +src = os.path.join(kInputsDir, 'include.cpp') +h1 = os.path.join(kInputsDir, "header1.h") +h2 = os.path.join(kInputsDir, "header2.h") +h3 = os.path.join(kInputsDir, "header3.h") +inc = [h1, h3, h2, h3, h1] + +tu = TranslationUnit.from_source(src, options=TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD) +inclusion_directive_files = [c.get_included_file().name for c in tu.cursor.get_children() if c.kind == CursorKind.INCLUSION_DIRECTIVE] +for i in zip(inc, inclusion_directive_files): +self.assert_normpaths_equal(i[0], i[1]) + def test_save(self): """Ensure TranslationUnit.save() works.""" Index: cfe/trunk/bindings/python/clang/cindex.py === --- cfe/trunk/bindings/python/clang/cindex.py +++ cfe/trunk/bindings/python/clang/cindex.py @@ -1511,6 +1511,12 @@ another translation unit.""" return conf.lib.clang_getCursorUSR(self) +def get_included_file(self): +"""Returns the File that is included by the current inclusion cursor.""" +assert self.kind == CursorKind.INCLUSION_DIRECTIVE + +return conf.lib.clang_getIncludedFile(self) + @property def kind(self): """Return the kind of this cursor.""" @@ -3085,8 +3091,9 @@ return "" % (self.name) @staticmethod -def from_cursor_result(res, fn, args): -assert isinstance(res, File) +def from_result(res, fn, args): +assert isinstance(res, c_object_p) +res = File(res) # Copy a reference to the TranslationUnit to prevent premature GC. res._tu = args[0]._tu @@ -3701,8 +3708,8 @@ ("clang_getIncludedFile", [Cursor], - File, - File.from_cursor_result), + c_object_p, + File.from_result), ("clang_getInclusions", [TranslationUnit, callbacks['translation_unit_includes'], py_object]), Index: cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py === --- cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py +++ cfe/trunk/bindings/python/tests/cindex/test_translation_unit.py @@ -108,6 +108,18 @@ for i in zip(inc, tu.get_includes()): eq(i[0], i[1]) +def test_inclusion_directive(self): +src = os.path.join(kInputsDir, 'include.cpp') +h1 = os.path.join(kInputsDir, "header1.h") +h2 = os.path.join(kInputsDir, "header2.h") +h3 = os.path.join(kInputsDir, "header3.h") +inc = [h1, h3, h2, h3, h1] + +tu = TranslationUnit.from_source(src, options=TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD) +inclusion_directive_files = [c.get_included_file().name for c in tu.cursor.get_children() if c.ki
[PATCH] D46656: [Builtins] Improve the IR emitted for MSVC compatible rotr/rotl builtins to match what the middle and backends understand
rnk added a comment. Thanks! Repository: rL LLVM https://reviews.llvm.org/D46656 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46241: [CodeGen] Recognize more cases of zero initialization
rsmith added inline comments. Comment at: lib/CodeGen/CGExprConstant.cpp:1414-1415 +Expr::EvalResult Result; +if (Init->EvaluateAsRValue(Result, CE.CGM.getContext()) && +!Result.hasUnacceptableSideEffect(Expr::SE_NoSideEffects)) + return (Result.Val.isInt() && Result.Val.getInt().isNullValue()) || Please call `D.evaluateValue()` here rather than inventing your own evaluation scheme. That way, we'll cache the evaluated initializer on the variable for other uses or reuse the value if we've already evaluated it, and you don't need to worry about the corner cases involved in getting the evaluation right. (As it happens, you're getting some minor details wrong because evaluating an initializer is not quite the same as evaluating an rvalue, but in practice it's not a big deal here.) Repository: rC Clang https://reviews.llvm.org/D46241 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r332053 - [clang-cl] Make -f[no-]coverage-mapping available
Author: rnk Date: Thu May 10 15:24:00 2018 New Revision: 332053 URL: http://llvm.org/viewvc/llvm-project?rev=332053&view=rev Log: [clang-cl] Make -f[no-]coverage-mapping available Modified: cfe/trunk/include/clang/Driver/Options.td Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=332053&r1=332052&r2=332053&view=diff == --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Thu May 10 15:24:00 2018 @@ -718,10 +718,10 @@ def fprofile_instr_use_EQ : Joined<["-"] Group, Flags<[CoreOption]>, HelpText<"Use instrumentation data for profile-guided optimization">; def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">, -Group, Flags<[CC1Option]>, +Group, Flags<[CC1Option, CoreOption]>, HelpText<"Generate coverage mapping to enable code coverage analysis">; def fno_coverage_mapping : Flag<["-"], "fno-coverage-mapping">, -Group, Flags<[DriverOption]>, +Group, Flags<[DriverOption, CoreOption]>, HelpText<"Disable code coverage analysis">; def fprofile_generate : Flag<["-"], "fprofile-generate">, Group, Flags<[DriverOption]>, ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45680: [C++2a] Implement operator<=> Part 2: Operator Rewritting and Overload Resolution.
rsmith added inline comments. Comment at: include/clang/AST/ExprCXX.h:4218-4226 + struct ComparisonBits { +/// Whether this rewritten comparison expression has reverse-order +/// parameters. +unsigned IsSynthesized : 1; + }; + + union ExtraRewrittenBits { I don't think you need this. Comment at: include/clang/AST/ExprCXX.h:4294-4296 + Expr *getLHS() const { return getLHSExpr(getRewrittenExpr()); } + Expr *getRHS() const { return getRHSExpr(getRewrittenExpr()); } + Opcode getOpcode() const { return getOpcodeFromExpr(getRewrittenExpr()); } rsmith wrote: > I find the interface exposed by this class a little confusing. On the one > hand, it provides the original expression as an `Expr*`, and on the other > hand it hard-codes knowledge about the form of that expression and exposes > accessors into that original form. The upshot is that we pay the cost of a > general mechanism (that can cope with any form of original expression) but > don't get any benefit from that (because the class hard-codes non-generality). > > This also generates a distinctly non-tree-shaped AST; clients naively walking > recursively over expressions and their subexpressions will see the > same`Expr*` multiple times and potentially end up performing an > exponential-time tree walk. > > I think there are (at least) two reasonable approaches here: > > 1) Use `OpaqueValueExpr`s to handle the repeated AST nodes, and track an > original expression, a rewritten expression, and probably an original LHS > expr and an original RHS expr; the original and rewrite would use OVEs to > refer indirectly to the LHS and RHS. Remove all hardcoded knowledge of the > original and rewrite from this expression node and make it generic for > rewritten expression forms. > > 2) Make this node explicitly be specific to spaceship rewrites. Remove the > original expression pointer and rename it to something more specific. Keep > the accessors that make hardcoded assumptions about the form of the rewritten > expression. > > Option 2 looks closer to what this patch is currently doing (you're not using > the original expression much). As noted, if you want this to be a general-purpose "rewritten expression" node, you should use `OpaqueValueExpr`s to track the repeated AST nodes between the original and rewritten expression forms rather than forming a non-tree-shaped AST. However, if you want to take that path, you don't need to add a new `Expr` node for that; that's what `PseudoObjectExpr` is for. Comment at: include/clang/AST/Stmt.h:254 + +unsigned Kind : 1; + }; I don't think you need this either. Comment at: include/clang/Sema/Overload.h:938 +/// exited. +struct RewrittenCandidateContextGuard { + RewrittenCandidateContextGuard(OverloadCandidateSet &CS) EricWF wrote: > This is unneeded. As long as the rewritten candidates are added last, > restoring the `Functions` member is unneeded. Please instead extend the `Functions` set to be a set of `PointerIntPair`. Comment at: include/clang/Sema/Overload.h:81-83 +ROC_Rewritten, +/// Both rewritten and synthesized. +ROC_Synthesized These names are not very good. The standard describes both these cases as "rewritten", so `ROC_Rewritten` is ambiguous, and it says "a synthesized candidate with reversed order of parameters", not merely "synthesized" (which would fail to communicate what's going on). How about `ROC_AsThreeWayComparison` and `ROC_AsReversedThreeWayComparison` or similar? Comment at: include/clang/Serialization/ASTBitCodes.h:1814 + EXPR_CXX_FOLD, // CXXFoldExpr + EXPR_CXX_REWRITTEN_OPERATOR,// CXXRewrittenExpr Drop the `_OPERATOR` here. Comment at: lib/Sema/SemaOverload.cpp:12542 + // FIXME(EricWF): This doesn't actually really represent the expression as + // written, because it may not result in a to a builtin operator. + Expr *Original = new (S.Context) > in a *call* to a Comment at: lib/Sema/SemaOverload.cpp:12543-12547 + Expr *Original = new (S.Context) + BinaryOperator(OpaqueValueExpr::Create(S.Context, Args[0]), + OpaqueValueExpr::Create(S.Context, Args[1]), Opc, + Rewritten->getType(), Rewritten->getValueKind(), + Rewritten->getObjectKind(), OpLoc, S.FPFeatures); If you want to model this as a generic (syntactic form, semantic form) pair, the syntactic form needs to preserve enough information that `TreeTransform` on it can recreate the semantic form. That means you need to store a `CXXOperatorCallExpr` to an `UnresolvedLookupExpr` to hold `Fns` if `Fns` is not empty (see the code at the start of `CreateOverloadedBinOp` that d
[libcxx] r332066 - Fix failing test due to incorrect use of noexcept
Author: ericwf Date: Thu May 10 17:33:20 2018 New Revision: 332066 URL: http://llvm.org/viewvc/llvm-project?rev=332066&view=rev Log: Fix failing test due to incorrect use of noexcept Modified: libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp Modified: libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp?rev=332066&r1=332065&r2=332066&view=diff == --- libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp Thu May 10 17:33:20 2018 @@ -58,20 +58,6 @@ void test_result_of_imp() int main() { -{ // Function types with noexcept -typedef bool (&RF0)(int) noexcept; -typedef bool (&RF1)(int, ...) noexcept; -typedef bool (*PF0)(int) noexcept; -typedef bool (*PF1)(int, ...) noexcept; -typedef bool (*&PRF0)(int) noexcept; -typedef bool (*&PRF1)(int, ...) noexcept; -test_result_of_imp(); -test_result_of_imp(); -test_result_of_imp(); -test_result_of_imp(); -test_result_of_imp(); -test_result_of_imp(); -} { typedef char F::*PMD; test_result_of_imp(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r332070 - Permit -fxray-instrument for NetBSD/amd64
Author: kamil Date: Thu May 10 17:58:55 2018 New Revision: 332070 URL: http://llvm.org/viewvc/llvm-project?rev=332070&view=rev Log: Permit -fxray-instrument for NetBSD/amd64 Summary: Use the same branch as FreeBSD and OpenBSD. Sponsored by Reviewers: joerg, dberris, vitalybuka Reviewed By: vitalybuka Subscribers: emaste, llvm-commits Differential Revision: https://reviews.llvm.org/D46737 Modified: cfe/trunk/lib/Driver/XRayArgs.cpp Modified: cfe/trunk/lib/Driver/XRayArgs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/XRayArgs.cpp?rev=332070&r1=332069&r2=332070&view=diff == --- cfe/trunk/lib/Driver/XRayArgs.cpp (original) +++ cfe/trunk/lib/Driver/XRayArgs.cpp Thu May 10 17:58:55 2018 @@ -51,7 +51,8 @@ XRayArgs::XRayArgs(const ToolChain &TC, << (std::string(XRayInstrumentOption) + " on " + Triple.str()); } } else if (Triple.getOS() == llvm::Triple::FreeBSD || - Triple.getOS() == llvm::Triple::OpenBSD) { + Triple.getOS() == llvm::Triple::OpenBSD || + Triple.getOS() == llvm::Triple::NetBSD) { if (Triple.getArch() != llvm::Triple::x86_64) { D.Diag(diag::err_drv_clang_unsupported) << (std::string(XRayInstrumentOption) + " on " + Triple.str()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46737: Permit -fxray-instrument for NetBSD/amd64
This revision was automatically updated to reflect the committed changes. Closed by commit rC332070: Permit -fxray-instrument for NetBSD/amd64 (authored by kamil, committed by ). Herald added a subscriber: cfe-commits. Repository: rC Clang https://reviews.llvm.org/D46737 Files: lib/Driver/XRayArgs.cpp Index: lib/Driver/XRayArgs.cpp === --- lib/Driver/XRayArgs.cpp +++ lib/Driver/XRayArgs.cpp @@ -51,7 +51,8 @@ << (std::string(XRayInstrumentOption) + " on " + Triple.str()); } } else if (Triple.getOS() == llvm::Triple::FreeBSD || - Triple.getOS() == llvm::Triple::OpenBSD) { + Triple.getOS() == llvm::Triple::OpenBSD || + Triple.getOS() == llvm::Triple::NetBSD) { if (Triple.getArch() != llvm::Triple::x86_64) { D.Diag(diag::err_drv_clang_unsupported) << (std::string(XRayInstrumentOption) + " on " + Triple.str()); Index: lib/Driver/XRayArgs.cpp === --- lib/Driver/XRayArgs.cpp +++ lib/Driver/XRayArgs.cpp @@ -51,7 +51,8 @@ << (std::string(XRayInstrumentOption) + " on " + Triple.str()); } } else if (Triple.getOS() == llvm::Triple::FreeBSD || - Triple.getOS() == llvm::Triple::OpenBSD) { + Triple.getOS() == llvm::Triple::OpenBSD || + Triple.getOS() == llvm::Triple::NetBSD) { if (Triple.getArch() != llvm::Triple::x86_64) { D.Diag(diag::err_drv_clang_unsupported) << (std::string(XRayInstrumentOption) + " on " + Triple.str()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46721: Support XRay in the NetBSD driver
This revision was automatically updated to reflect the committed changes. Closed by commit rC332071: Support XRay in the NetBSD driver (authored by kamil, committed by ). Herald added a subscriber: cfe-commits. Repository: rC Clang https://reviews.llvm.org/D46721 Files: lib/Driver/ToolChains/NetBSD.cpp Index: lib/Driver/ToolChains/NetBSD.cpp === --- lib/Driver/ToolChains/NetBSD.cpp +++ lib/Driver/ToolChains/NetBSD.cpp @@ -112,7 +112,9 @@ const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { - const Driver &D = getToolChain().getDriver(); + const toolchains::NetBSD &ToolChain = +static_cast(getToolChain()); + const Driver &D = ToolChain.getDriver(); ArgStringList CmdArgs; if (!D.SysRoot.empty()) @@ -135,15 +137,15 @@ // Many NetBSD architectures support more than one ABI. // Determine the correct emulation for ld. - switch (getToolChain().getArch()) { + switch (ToolChain.getArch()) { case llvm::Triple::x86: CmdArgs.push_back("-m"); CmdArgs.push_back("elf_i386"); break; case llvm::Triple::arm: case llvm::Triple::thumb: CmdArgs.push_back("-m"); -switch (getToolChain().getTriple().getEnvironment()) { +switch (ToolChain.getTriple().getEnvironment()) { case llvm::Triple::EABI: case llvm::Triple::GNUEABI: CmdArgs.push_back("armelf_nbsd_eabi"); @@ -159,9 +161,9 @@ break; case llvm::Triple::armeb: case llvm::Triple::thumbeb: -arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getEffectiveTriple()); +arm::appendEBLinkFlags(Args, CmdArgs, ToolChain.getEffectiveTriple()); CmdArgs.push_back("-m"); -switch (getToolChain().getTriple().getEnvironment()) { +switch (ToolChain.getTriple().getEnvironment()) { case llvm::Triple::EABI: case llvm::Triple::GNUEABI: CmdArgs.push_back("armelfb_nbsd_eabi"); @@ -179,13 +181,13 @@ case llvm::Triple::mips64el: if (mips::hasMipsAbiArg(Args, "32")) { CmdArgs.push_back("-m"); - if (getToolChain().getArch() == llvm::Triple::mips64) + if (ToolChain.getArch() == llvm::Triple::mips64) CmdArgs.push_back("elf32btsmip"); else CmdArgs.push_back("elf32ltsmip"); } else if (mips::hasMipsAbiArg(Args, "64")) { CmdArgs.push_back("-m"); - if (getToolChain().getArch() == llvm::Triple::mips64) + if (ToolChain.getArch() == llvm::Triple::mips64) CmdArgs.push_back("elf64btsmip"); else CmdArgs.push_back("elf64ltsmip"); @@ -226,16 +228,16 @@ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { if (!Args.hasArg(options::OPT_shared)) { CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crt0.o"))); + Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); } CmdArgs.push_back( -Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); +Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) { CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o"))); + Args.MakeArgString(ToolChain.GetFilePath("crtbeginS.o"))); } else { CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); + Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); } } @@ -248,13 +250,14 @@ Args.AddAllArgs(CmdArgs, options::OPT_r); bool NeedsSanitizerDeps = addSanitizerRuntimes(getToolChain(), Args, CmdArgs); + bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); unsigned Major, Minor, Micro; - getToolChain().getTriple().getOSVersion(Major, Minor, Micro); + ToolChain.getTriple().getOSVersion(Major, Minor, Micro); bool useLibgcc = true; if (Major >= 7 || Major == 0) { -switch (getToolChain().getArch()) { +switch (ToolChain.getArch()) { case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: case llvm::Triple::arm: @@ -278,12 +281,14 @@ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { addOpenMPRuntime(CmdArgs, getToolChain(), Args); if (D.CCCIsCXX()) { - if (getToolChain().ShouldLinkCXXStdlib(Args)) -getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); + if (ToolChain.ShouldLinkCXXStdlib(Args)) +ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); CmdArgs.push_back("-lm"); } if (NeedsSanitizerDeps) linkSanitizerRuntimeDeps(getToolChain(), CmdArgs); +if (NeedsXRayDeps) + linkXRayRuntimeDeps(ToolChain, CmdArgs); if (Args.hasArg(options::OPT_pthread)) CmdArgs.push_back("-lpthread"); CmdArgs.push_back("-lc"); @@ -308,16 +313,1
r332071 - Support XRay in the NetBSD driver
Author: kamil Date: Thu May 10 18:00:38 2018 New Revision: 332071 URL: http://llvm.org/viewvc/llvm-project?rev=332071&view=rev Log: Support XRay in the NetBSD driver Summary: While there, perform a small cleanup, reducing delta with drivers for other OSes. Sponsored by Reviewers: joerg, vitalybuka, dberris Reviewed By: dberris Subscribers: llvm-commits, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D46721 Modified: cfe/trunk/lib/Driver/ToolChains/NetBSD.cpp Modified: cfe/trunk/lib/Driver/ToolChains/NetBSD.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/NetBSD.cpp?rev=332071&r1=332070&r2=332071&view=diff == --- cfe/trunk/lib/Driver/ToolChains/NetBSD.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/NetBSD.cpp Thu May 10 18:00:38 2018 @@ -112,7 +112,9 @@ void netbsd::Linker::ConstructJob(Compil const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { - const Driver &D = getToolChain().getDriver(); + const toolchains::NetBSD &ToolChain = +static_cast(getToolChain()); + const Driver &D = ToolChain.getDriver(); ArgStringList CmdArgs; if (!D.SysRoot.empty()) @@ -135,7 +137,7 @@ void netbsd::Linker::ConstructJob(Compil // Many NetBSD architectures support more than one ABI. // Determine the correct emulation for ld. - switch (getToolChain().getArch()) { + switch (ToolChain.getArch()) { case llvm::Triple::x86: CmdArgs.push_back("-m"); CmdArgs.push_back("elf_i386"); @@ -143,7 +145,7 @@ void netbsd::Linker::ConstructJob(Compil case llvm::Triple::arm: case llvm::Triple::thumb: CmdArgs.push_back("-m"); -switch (getToolChain().getTriple().getEnvironment()) { +switch (ToolChain.getTriple().getEnvironment()) { case llvm::Triple::EABI: case llvm::Triple::GNUEABI: CmdArgs.push_back("armelf_nbsd_eabi"); @@ -159,9 +161,9 @@ void netbsd::Linker::ConstructJob(Compil break; case llvm::Triple::armeb: case llvm::Triple::thumbeb: -arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getEffectiveTriple()); +arm::appendEBLinkFlags(Args, CmdArgs, ToolChain.getEffectiveTriple()); CmdArgs.push_back("-m"); -switch (getToolChain().getTriple().getEnvironment()) { +switch (ToolChain.getTriple().getEnvironment()) { case llvm::Triple::EABI: case llvm::Triple::GNUEABI: CmdArgs.push_back("armelfb_nbsd_eabi"); @@ -179,13 +181,13 @@ void netbsd::Linker::ConstructJob(Compil case llvm::Triple::mips64el: if (mips::hasMipsAbiArg(Args, "32")) { CmdArgs.push_back("-m"); - if (getToolChain().getArch() == llvm::Triple::mips64) + if (ToolChain.getArch() == llvm::Triple::mips64) CmdArgs.push_back("elf32btsmip"); else CmdArgs.push_back("elf32ltsmip"); } else if (mips::hasMipsAbiArg(Args, "64")) { CmdArgs.push_back("-m"); - if (getToolChain().getArch() == llvm::Triple::mips64) + if (ToolChain.getArch() == llvm::Triple::mips64) CmdArgs.push_back("elf64btsmip"); else CmdArgs.push_back("elf64ltsmip"); @@ -226,16 +228,16 @@ void netbsd::Linker::ConstructJob(Compil if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { if (!Args.hasArg(options::OPT_shared)) { CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crt0.o"))); + Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); } CmdArgs.push_back( -Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); +Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) { CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o"))); + Args.MakeArgString(ToolChain.GetFilePath("crtbeginS.o"))); } else { CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); + Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); } } @@ -248,13 +250,14 @@ void netbsd::Linker::ConstructJob(Compil Args.AddAllArgs(CmdArgs, options::OPT_r); bool NeedsSanitizerDeps = addSanitizerRuntimes(getToolChain(), Args, CmdArgs); + bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); unsigned Major, Minor, Micro; - getToolChain().getTriple().getOSVersion(Major, Minor, Micro); + ToolChain.getTriple().getOSVersion(Major, Minor, Micro); bool useLibgcc = true; if (Major >= 7 || Major == 0) { -switch (getToolChain().getArch()) { +switch (ToolChain.getArch()) { case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: case llvm::Triple::arm: @@ -278,12 +281,14 @@ voi
r332074 - Don't propagate dllimport to base class template static data members
Author: rnk Date: Thu May 10 18:26:11 2018 New Revision: 332074 URL: http://llvm.org/viewvc/llvm-project?rev=332074&view=rev Log: Don't propagate dllimport to base class template static data members MSVC doesn't, so we shouldn't. Fixes PR37232. Added: cfe/trunk/test/CodeGenCXX/dllimport-template-sdm.cpp Modified: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/lib/Sema/SemaDeclCXX.cpp Modified: cfe/trunk/include/clang/Basic/Attr.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=332074&r1=332073&r2=332074&view=diff == --- cfe/trunk/include/clang/Basic/Attr.td (original) +++ cfe/trunk/include/clang/Basic/Attr.td Thu May 10 18:26:11 2018 @@ -2566,6 +2566,16 @@ def DLLImport : InheritableAttr, TargetS let Spellings = [Declspec<"dllimport">, GCC<"dllimport">]; let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>; let Documentation = [DLLImportDocs]; + + + let AdditionalMembers = [{ +private: + bool PropagatedToBaseTemplate = false; + +public: + void setPropagatedToBaseTemplate() { PropagatedToBaseTemplate = true; } + bool wasPropagatedToBaseTemplate() { return PropagatedToBaseTemplate; } + }]; } def SelectAny : InheritableAttr { Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=332074&r1=332073&r2=332074&view=diff == --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu May 10 18:26:11 2018 @@ -5626,6 +5626,13 @@ void Sema::checkClassLevelDLLAttribute(C // The class is either imported or exported. const bool ClassExported = ClassAttr->getKind() == attr::DLLExport; + // Check if this was a dllimport attribute propagated from a derived class to + // a base class template specialization. We don't apply these attributes to + // static data members. + const bool PropagatedImport = + !ClassExported && + cast(ClassAttr)->wasPropagatedToBaseTemplate(); + TemplateSpecializationKind TSK = Class->getTemplateSpecializationKind(); // Ignore explicit dllexport on explicit class template instantiation declarations. @@ -5677,6 +5684,11 @@ void Sema::checkClassLevelDLLAttribute(C } } +// Don't apply dllimport attributes to static data members of class template +// instantiations when the attribute is propagated from a derived class. +if (VD && PropagatedImport) + continue; + if (!cast(Member)->isExternallyVisible()) continue; @@ -5729,6 +5741,11 @@ void Sema::propagateDLLAttrToBaseClassTe NewAttr->setInherited(true); BaseTemplateSpec->addAttr(NewAttr); +// If this was an import, mark that we propagated it from a derived class to +// a base class template specialization. +if (auto *ImportAttr = dyn_cast(NewAttr)) + ImportAttr->setPropagatedToBaseTemplate(); + // If the template is already instantiated, checkDLLAttributeRedeclaration() // needs to be run again to work see the new attribute. Otherwise this will // get run whenever the template is instantiated. Added: cfe/trunk/test/CodeGenCXX/dllimport-template-sdm.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport-template-sdm.cpp?rev=332074&view=auto == --- cfe/trunk/test/CodeGenCXX/dllimport-template-sdm.cpp (added) +++ cfe/trunk/test/CodeGenCXX/dllimport-template-sdm.cpp Thu May 10 18:26:11 2018 @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++14 -fms-extensions -o - %s | FileCheck %s --check-prefix=IMPORT +// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++14 -fms-extensions -o - %s -DTEST_EXPORT | FileCheck %s --check-prefix=EXPORT + +#ifndef TEST_EXPORT +#define DLLATTR __declspec(dllimport) +#else +#define DLLATTR __declspec(dllexport) +#endif + +// PR37232: When a dllimport attribute is propagated from a derived class to a +// base class that happens to be a template specialization, it is only applied +// to template *methods*, and not static data members. If a dllexport attribute +// is propagated, it still applies to static data members. + +// IMPORT-DAG: @"?sdm@Exporter@@2HB" = available_externally dllimport constant i32 2, align 4 +// IMPORT-DAG: @"?csdm@?$A@H@@2HB" = linkonce_odr dso_local constant i32 2, comdat, align 4 +// IMPORT-DAG: @"?sdm@?$A@H@@2HA" = linkonce_odr dso_local global i32 1, comdat, align 4 +// IMPORT-DAG: @"?sdm@?$B@H@@2HB" = available_externally dllimport constant i32 2, align 4 +// IMPORT-DAG: @"?sdm@?$C@H@@2HB" = available_externally dllimport constant i32 2, align 4 + +// EXPORT-DAG: @"?sdm@Exporter@@2HB" = weak_odr dso_local dllexport constant i32 2, comdat, align 4 +// EXPORT-DAG: @"?csdm@?$A@H@@2HB" = weak_
[PATCH] D45463: [AST] Print correct tag decl for tag specifier
rsmith added inline comments. Comment at: include/clang/AST/Type.h:4852-4855 +/// \brief Represents a type occurrence that either (1) refers to the type +/// using an elaborated type keyword, e.g., struct S, (2) refers to the type +/// via a qualified name, e.g., N::M::type, (3) owns a (re)declaration of that +/// type, or (4) some combination of those. I think it's better to keep this as-is: the "owns a (re)declaration" case is a special case of using an elaborated type keyword. Comment at: include/clang/AST/Type.h:4905 + /// + /// FIXME: This is set for tag types but not necessarily other types. + /// FIXME: The TypeDecl returned is not always exactly faithful to the Are there other types for which it would be meaningful? (If not, we could store and expose this as a `TagDecl` instead.) Comment at: include/clang/AST/Type.h:4906-4916 + /// FIXME: The TypeDecl returned is not always exactly faithful to the + /// original source because, when building the AST, the parser (1) adds + /// all attributes declared on a tag to all later redeclarations of that + /// tag (that is, tag occurrences declaring an attribute or member list), + /// and (2) drops attributes declared on a tag after an occurrence of that + /// tag declaring a member list. When printing the AST, the first change + /// should not affect semantics or diagnostics because it merely reveals You can use `isInherited()` on the attribute to find out whether it was written on that declaration or inherited. https://reviews.llvm.org/D45463 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r332076 - Improve diagnostics and error recovery for template name lookup.
Author: rsmith Date: Thu May 10 19:43:08 2018 New Revision: 332076 URL: http://llvm.org/viewvc/llvm-project?rev=332076&view=rev Log: Improve diagnostics and error recovery for template name lookup. For 'x::template y', consistently give a "no member named 'y' in 'x'" diagnostic if there is no such member, and give a 'template keyword not followed by a template' name error if there is such a member but it's not a template. In the latter case, add a note pointing at the non-template. Don't suggest inserting a 'template' keyword in 'X::Y<' if X is dependent if the lookup of X::Y was actually not a dependent lookup and found only non-templates. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Parse/ParseExprCXX.cpp cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaExprMember.cpp cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/lib/Sema/TreeTransform.h cfe/trunk/test/CXX/drs/dr1xx.cpp cfe/trunk/test/CXX/drs/dr3xx.cpp cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp cfe/trunk/test/SemaCXX/invalid-template-specifier.cpp cfe/trunk/test/SemaObjCXX/parameterized_classes_subst.mm cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp cfe/trunk/test/SemaTemplate/metafun-apply.cpp cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp cfe/trunk/test/SemaTemplate/template-id-expr.cpp cfe/trunk/test/SemaTemplate/typo-dependent-name.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=332076&r1=332075&r2=332076&view=diff == --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 10 19:43:08 2018 @@ -4505,6 +4505,8 @@ def note_using_value_decl_missing_typena def err_template_kw_refers_to_non_template : Error< "%0 following the 'template' keyword does not refer to a template">; +def note_template_kw_refers_to_non_template : Note< + "declared as a non-template here">; def err_template_kw_refers_to_class_template : Error< "'%0%1' instantiated to a class template, not a function template">; def note_referenced_class_template : Note< Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=332076&r1=332075&r2=332076&view=diff == --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Thu May 10 19:43:08 2018 @@ -6090,9 +6090,10 @@ public: bool hasAnyAcceptableTemplateNames(LookupResult &R, bool AllowFunctionTemplates = true); - void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS, + bool LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS, QualType ObjectType, bool EnteringContext, - bool &MemberOfUnknownSpecialization); + bool &MemberOfUnknownSpecialization, + SourceLocation TemplateKWLoc = SourceLocation()); TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=332076&r1=332075&r2=332076&view=diff == --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu May 10 19:43:08 2018 @@ -515,7 +515,7 @@ bool Parser::ParseOptionalCXXScopeSpecif << FixItHint::CreateInsertion(Tok.getLocation(), "template "); if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName( -getCurScope(), SS, SourceLocation(), TemplateName, ObjectType, +getCurScope(), SS, Tok.getLocation(), TemplateName, ObjectType, EnteringContext, Template, /*AllowInjectedClassName*/ true)) { // Consume the identifier. ConsumeToken(); Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=332076&r1=332075&r2=332076&view=diff == --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu May 10 19:43:08 2018 @@ -2087,8 +2087,9 @@ Sema::ActOnIdExpression(Scope *S, CXXSco // this becomes a performance hit, we can work harder to preserve those // results until we get here but it's likely not worth it. bool MemberOfUnknownSpecialization; -LookupTemplateName(R, S, SS, QualType(), /*EnteringContext=*/false, - MemberOfU
[PATCH] D45680: [C++2a] Implement operator<=> Part 2: Operator Rewritting and Overload Resolution.
EricWF added inline comments. Comment at: include/clang/AST/ExprCXX.h:4218-4226 + struct ComparisonBits { +/// Whether this rewritten comparison expression has reverse-order +/// parameters. +unsigned IsSynthesized : 1; + }; + + union ExtraRewrittenBits { rsmith wrote: > I don't think you need this. I guess it's just future proofing, or an attempt to demonstrate how the class may be generalized. I'll remove it for now. Comment at: include/clang/Sema/Overload.h:938 +/// exited. +struct RewrittenCandidateContextGuard { + RewrittenCandidateContextGuard(OverloadCandidateSet &CS) rsmith wrote: > EricWF wrote: > > This is unneeded. As long as the rewritten candidates are added last, > > restoring the `Functions` member is unneeded. > Please instead extend the `Functions` set to be a set of > `PointerIntPair`. Sure. I'll get that done. There are two options here: (A) Keep the guard object. Store the RewrittenOverloadCandidateKind which we're currently adding candidates for, and have `addCandidate` and `isNewCandidate` handle the ROC. (B) Change all of the `AddFooCandidates` interfaces in Sema to take yet another default parameter, and pass it around everywhere. Which would you prefer @rsmith? Comment at: include/clang/Sema/Overload.h:81-83 +ROC_Rewritten, +/// Both rewritten and synthesized. +ROC_Synthesized rsmith wrote: > These names are not very good. The standard describes both these cases as > "rewritten", so `ROC_Rewritten` is ambiguous, and it says "a synthesized > candidate with reversed order of parameters", not merely "synthesized" (which > would fail to communicate what's going on). > > How about `ROC_AsThreeWayComparison` and `ROC_AsReversedThreeWayComparison` > or similar? Sounds good to me. Comment at: lib/Sema/SemaOverload.cpp:12543-12547 + Expr *Original = new (S.Context) + BinaryOperator(OpaqueValueExpr::Create(S.Context, Args[0]), + OpaqueValueExpr::Create(S.Context, Args[1]), Opc, + Rewritten->getType(), Rewritten->getValueKind(), + Rewritten->getObjectKind(), OpLoc, S.FPFeatures); rsmith wrote: > If you want to model this as a generic (syntactic form, semantic form) pair, > the syntactic form needs to preserve enough information that `TreeTransform` > on it can recreate the semantic form. That means you need to store a > `CXXOperatorCallExpr` to an `UnresolvedLookupExpr` to hold `Fns` if `Fns` is > not empty (see the code at the start of `CreateOverloadedBinOp` that deals > with the type-dependent case for an example of what you would need to do). > > Though perhaps this is as good a reason as any to give up the idea of a > generic rewrite expression and add something specific to a three-way > comparison rewrite; the representation needed to fit this into a generic > rewrite mechanism is very unwieldy. (If we add any more forms of rewritten > operator later, we can consider whether a generalization is worthwhile.) I think the FIXME comment may be incorrect. Shouldn't this be sufficient since we never actually build the rewritten expression until the input expressions are no longer type dependent? Additionally, with this representation `TreeTransform` can transform the semantic form, since (if I'm correct), a rebuild should never re-perform overload resolution to choose how to rewrite the initial expression. (Does that make sense, and is it correct?) I'll go ahead and start converting to a less-general representation of the rewritten expression. https://reviews.llvm.org/D45680 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45680: [C++2a] Implement operator<=> Part 2: Operator Rewritting and Overload Resolution.
EricWF updated this revision to Diff 146274. EricWF marked 13 inline comments as done. EricWF added a comment. - Change `CXXRewrittenExpr` to be a non-general wrapper only for rewritten comparison operators. - Start fixing and improving overload resolution diagnostics. https://reviews.llvm.org/D45680 Files: include/clang/AST/ComparisonCategories.h include/clang/AST/Expr.h include/clang/AST/ExprCXX.h include/clang/AST/RecursiveASTVisitor.h include/clang/AST/Stmt.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/StmtNodes.td include/clang/Sema/Overload.h include/clang/Sema/Sema.h include/clang/Serialization/ASTBitCodes.h lib/AST/ComparisonCategories.cpp lib/AST/Expr.cpp lib/AST/ExprCXX.cpp lib/AST/ExprClassification.cpp lib/AST/ExprConstant.cpp lib/AST/ItaniumMangle.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtProfile.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaExceptionSpec.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp test/CodeGenCXX/cxx2a-compare.cpp test/SemaCXX/compare-cxx2a.cpp Index: test/SemaCXX/compare-cxx2a.cpp === --- test/SemaCXX/compare-cxx2a.cpp +++ test/SemaCXX/compare-cxx2a.cpp @@ -292,20 +292,21 @@ template struct Tag {}; -// expected-note@+1 {{candidate}} -Tag<0> operator<=>(EnumA, EnumA) { - return {}; +std::strong_ordering operator<=>(EnumA, EnumA) { + return std::strong_ordering::equal; } -Tag<1> operator<=>(EnumA, EnumB) { - return {}; +// expected-note@+1 {{candidate function}}, +std::strong_ordering operator<=>(EnumA a, EnumB b) { + return ((int)a <=> (int)b); } void test_enum_ovl_provided() { auto r1 = (EnumA::A <=> EnumA::A); - ASSERT_EXPR_TYPE(r1, Tag<0>); + ASSERT_EXPR_TYPE(r1, std::strong_ordering); auto r2 = (EnumA::A <=> EnumB::B); - ASSERT_EXPR_TYPE(r2, Tag<1>); - (void)(EnumB::B <=> EnumA::A); // expected-error {{invalid operands to binary expression ('EnumCompareTests::EnumB' and 'EnumCompareTests::EnumA')}} + ASSERT_EXPR_TYPE(r2, std::strong_ordering); + (void)(EnumB::B <=> EnumA::A); // OK, chooses reverse order synthesized candidate. + (void)(EnumB::B <=> EnumC::C); // expected-error {{invalid operands to binary expression ('EnumCompareTests::EnumB' and 'EnumCompareTests::EnumC')}} } void enum_float_test() { @@ -421,3 +422,114 @@ } } // namespace ComplexTest + +namespace TestRewritting { + +struct T { + int x; + // expected-note@+1 {{candidate}} + constexpr std::strong_ordering operator<=>(T y) const { +return (x <=> y.x); + } +}; + +struct U { + int x; + // FIXME: This diagnostic is wrong-ish. + // expected-note@+1 {{candidate function not viable: requires single argument 'y', but 2 arguments were provided}} + constexpr std::strong_equality operator<=>(T y) const { +if (x == y.x) + return std::strong_equality::equal; +return std::strong_equality::nonequal; + } +}; + +struct X { int x; }; +struct Y { int x; }; +template +struct Tag {}; + +Tag<0> operator<=>(X, Y) { + return {}; +} + +constexpr auto operator<=>(Y y, X x) { + return y.x <=> x.x; +} + +void foo() { + T t{42}; + T t2{0}; + U u{101}; + auto r1 = (t <=> u); + ASSERT_EXPR_TYPE(r1, std::strong_equality); + auto r2 = (t <=> t2); + ASSERT_EXPR_TYPE(r2, std::strong_ordering); + + auto r3 = t == u; + ASSERT_EXPR_TYPE(r3, bool); + + (void)(t < u); // expected-error {{invalid operands to binary expression ('TestRewritting::T' and 'TestRewritting::U')}} + + constexpr X x{1}; + constexpr Y y{2}; + constexpr auto r4 = (y < x); + static_assert(r4 == false); + constexpr auto r5 = (x < y); + static_assert(r5 == true); +} + +} // namespace TestRewritting + +// The implicit object parameter is not considered when performing partial +// ordering. That makes the reverse synthesized candidates ambiguous with the +// rewritten candidates if any of them resolve to a member function. +namespace TestOvlMatchingIgnoresImplicitObject { +struct U; +struct T { + std::strong_ordering operator<=>(U const &RHS) const; +}; +struct U { + std::strong_ordering operator<=>(T const &RHS) const = delete; +}; + +struct V { + int x; +}; +auto operator<=>(V const &LHS, V &&RHS) { // expected-note 4 {{candidate}} + return LHS.x <=> RHS.x; +} +auto operator<(V const &, V &&) { // expected-note {{candidate}} + return std::strong_equality::equal; +} + +void test() { + // OK. selects T::operator<=>(U) + (void)(T{} < U{}); + // expected-error@+1 {{use of overloaded operator '<' is ambiguous}} + (void)(V{} < V{}); + // expected-error@+1 {{use of overloaded operator '<=>' is ambiguous}} + (void)(V{} <=> V{}); +} + +} // namespace TestOvlMatchingIgnoresImplicitObject + +namespace TestRewrittenTemplate { + +template +auto test(T const &LHS, T const &RHS) { + // expected-error@+1 {{invalid opera
[PATCH] D45680: [C++2a] Implement operator<=> Part 2: Operator Rewritting and Overload Resolution.
EricWF marked 2 inline comments as done. EricWF added inline comments. Comment at: lib/Sema/SemaOverload.cpp:12543-12547 + Expr *Original = new (S.Context) + BinaryOperator(OpaqueValueExpr::Create(S.Context, Args[0]), + OpaqueValueExpr::Create(S.Context, Args[1]), Opc, + Rewritten->getType(), Rewritten->getValueKind(), + Rewritten->getObjectKind(), OpLoc, S.FPFeatures); EricWF wrote: > rsmith wrote: > > If you want to model this as a generic (syntactic form, semantic form) > > pair, the syntactic form needs to preserve enough information that > > `TreeTransform` on it can recreate the semantic form. That means you need > > to store a `CXXOperatorCallExpr` to an `UnresolvedLookupExpr` to hold `Fns` > > if `Fns` is not empty (see the code at the start of `CreateOverloadedBinOp` > > that deals with the type-dependent case for an example of what you would > > need to do). > > > > Though perhaps this is as good a reason as any to give up the idea of a > > generic rewrite expression and add something specific to a three-way > > comparison rewrite; the representation needed to fit this into a generic > > rewrite mechanism is very unwieldy. (If we add any more forms of rewritten > > operator later, we can consider whether a generalization is worthwhile.) > I think the FIXME comment may be incorrect. > > Shouldn't this be sufficient since we never actually build the rewritten > expression until the input expressions are no longer type dependent? > Additionally, with this representation `TreeTransform` can transform the > semantic form, since (if I'm correct), a rebuild should never re-perform > overload resolution to choose how to rewrite the initial expression. (Does > that make sense, and is it correct?) > > > > I'll go ahead and start converting to a less-general representation of the > rewritten expression. Nevermind. This was answered offline. https://reviews.llvm.org/D45680 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45680: [C++2a] Implement operator<=> Part 2: Operator Rewritting and Overload Resolution.
EricWF marked 11 inline comments as done. EricWF added inline comments. Comment at: include/clang/AST/Stmt.h:254 + +unsigned Kind : 1; + }; rsmith wrote: > I don't think you need this either. Does keeping it help save bits in `CXXRewrittenOperatorExpr`? https://reviews.llvm.org/D45680 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46740: [Clang Tablegen][RFC] Allow Early Textual Substitutions in `Diagnostic` messages.
EricWF created this revision. EricWF added reviewers: rsmith, rjmccall, aaron.ballman. Herald added a reviewer: a.sidorin. There are cases where the same string or select is repeated verbatim in a lot of diagnostics. This can be a pain to maintain and update. However, Tablegen provides no way stash the common text somewhere and reuse it in the diagnostics, until now! This patch allows diagnostic texts to contain `%sub{}`, where `` names a Tablegen record of type `TextSubstitution`. These substitutions are done early, before the diagnostic string is otherwise processed. All `%sub` modifiers will be replaced before the diagnostic definitions are emitted. Thoughts? I'll add tests once there is consensus that this change should proceed. Repository: rC Clang https://reviews.llvm.org/D46740 Files: include/clang/Basic/Diagnostic.td include/clang/Basic/DiagnosticSemaKinds.td utils/TableGen/ClangDiagnosticsEmitter.cpp Index: utils/TableGen/ClangDiagnosticsEmitter.cpp === --- utils/TableGen/ClangDiagnosticsEmitter.cpp +++ utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -14,12 +14,13 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/Regex.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringToOffsetTable.h" @@ -455,6 +456,39 @@ return ClsName == "CLASS_REMARK"; } +static void substituteDiagText(Record *Diag, StringMap SubsMap) { + llvm::Regex RE("%sub{[^}]*}"); + std::string Error; + ((void)Error); + assert(RE.isValid(Error) && RE.getNumMatches() == 0); + + RecordVal *RV = Diag->getValue("Text"); + std::string Text = RV->getValue()->getAsString(); + + unsigned Count = 0; + SmallVector Matches; + while (RE.match(Text, &Matches)) { +++Count; +assert(Matches.size() == 1); +StringRef M = Matches[0]; +std::pair Range(M.data() - Text.data(), M.size()); + +assert(Text.size() > Range.first + Range.second); +StringRef Found(Text); + +Found = Found.substr(Range.first, Range.second); +StringRef FoundName = Found.substr(5, Found.size() - 6); +Record *S = SubsMap.lookup(FoundName); +if (!S) { + PrintFatalError(Diag->getLoc(), "Diag " + Diag->getName() + + " has no substitution for: " + Found); +} +Text.replace(Range.first, Range.second, + S->getValueAsString("Substitution")); + } + RV->setValue(StringInit::get(Text)); +} + /// ClangDiagsDefsEmitter - The top-level class emits .def files containing /// declarations of Clang diagnostics. namespace clang { @@ -470,8 +504,14 @@ OS << "#endif\n\n"; } - const std::vector &Diags = -Records.getAllDerivedDefinitions("Diagnostic"); + std::vector Substitutions = + Records.getAllDerivedDefinitions("TextSubstitution"); + StringMap SubsMap; + for (auto *R : Substitutions) +SubsMap.try_emplace(R->getName(), R); + + std::vector Diags = Records.getAllDerivedDefinitions("Diagnostic"); + llvm::for_each(Diags, [&](Record *R) { substituteDiagText(R, SubsMap); }); std::vector DiagGroups = Records.getAllDerivedDefinitions("DiagGroup"); @@ -953,6 +993,9 @@ StringRef Modifier = Text.slice(0, ModLength); Text = Text.slice(ModLength, StringRef::npos); +assert(Modifier != "sub" && + "substitutions should have already taken place!"); + // FIXME: Handle %ordinal here. if (Modifier == "select" || Modifier == "plural") { DiagText::SelectPiece Select; @@ -1208,9 +1251,16 @@ } OS << Documentation->getValueAsString("Intro") << "\n"; + std::vector Substitutions = + Records.getAllDerivedDefinitions("TextSubstitution"); + StringMap SubsMap; + for (Record *R : Substitutions) +SubsMap.try_emplace(R->getName(), R); std::vector Diags = Records.getAllDerivedDefinitions("Diagnostic"); + llvm::for_each(Diags, [&](Record *R) { substituteDiagText(R, SubsMap); }); + std::vector DiagGroups = Records.getAllDerivedDefinitions("DiagGroup"); llvm::sort(DiagGroups.begin(), DiagGroups.end(), diagGroupBeforeByName); @@ -1300,6 +1350,7 @@ Severity[0] = tolower(Severity[0]); if (Severity == "ignored") Severity = IsRemarkGroup ? "remark" : "warning"; + writeDiagnosticText(Severity, D->getValueAsString("Text"), OS); } } Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -3613,41 +3613,39 @@ def note_ovl_candidate_non_deduced_mismatch_qua
[PATCH] D46740: [Clang Tablegen][RFC] Allow Early Textual Substitutions in `Diagnostic` messages.
EricWF updated this revision to Diff 146279. EricWF added a comment. Fix copy paste error. https://reviews.llvm.org/D46740 Files: include/clang/Basic/Diagnostic.td include/clang/Basic/DiagnosticSemaKinds.td utils/TableGen/ClangDiagnosticsEmitter.cpp Index: utils/TableGen/ClangDiagnosticsEmitter.cpp === --- utils/TableGen/ClangDiagnosticsEmitter.cpp +++ utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -14,12 +14,13 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/Regex.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringToOffsetTable.h" @@ -455,6 +456,39 @@ return ClsName == "CLASS_REMARK"; } +static void substituteDiagText(Record *Diag, StringMap SubsMap) { + llvm::Regex RE("%sub{[^}]*}"); + std::string Error; + ((void)Error); + assert(RE.isValid(Error) && RE.getNumMatches() == 0); + + RecordVal *RV = Diag->getValue("Text"); + std::string Text = RV->getValue()->getAsString(); + + unsigned Count = 0; + SmallVector Matches; + while (RE.match(Text, &Matches)) { +++Count; +assert(Matches.size() == 1); +StringRef M = Matches[0]; +std::pair Range(M.data() - Text.data(), M.size()); + +assert(Text.size() > Range.first + Range.second); +StringRef Found(Text); + +Found = Found.substr(Range.first, Range.second); +StringRef FoundName = Found.substr(5, Found.size() - 6); +Record *S = SubsMap.lookup(FoundName); +if (!S) { + PrintFatalError(Diag->getLoc(), "Diag " + Diag->getName() + + " has no substitution for: " + Found); +} +Text.replace(Range.first, Range.second, + S->getValueAsString("Substitution")); + } + RV->setValue(StringInit::get(Text)); +} + /// ClangDiagsDefsEmitter - The top-level class emits .def files containing /// declarations of Clang diagnostics. namespace clang { @@ -470,8 +504,14 @@ OS << "#endif\n\n"; } - const std::vector &Diags = -Records.getAllDerivedDefinitions("Diagnostic"); + std::vector Substitutions = + Records.getAllDerivedDefinitions("TextSubstitution"); + StringMap SubsMap; + for (auto *R : Substitutions) +SubsMap.try_emplace(R->getName(), R); + + std::vector Diags = Records.getAllDerivedDefinitions("Diagnostic"); + llvm::for_each(Diags, [&](Record *R) { substituteDiagText(R, SubsMap); }); std::vector DiagGroups = Records.getAllDerivedDefinitions("DiagGroup"); @@ -953,6 +993,9 @@ StringRef Modifier = Text.slice(0, ModLength); Text = Text.slice(ModLength, StringRef::npos); +assert(Modifier != "sub" && + "substitutions should have already taken place!"); + // FIXME: Handle %ordinal here. if (Modifier == "select" || Modifier == "plural") { DiagText::SelectPiece Select; @@ -1208,9 +1251,16 @@ } OS << Documentation->getValueAsString("Intro") << "\n"; + std::vector Substitutions = + Records.getAllDerivedDefinitions("TextSubstitution"); + StringMap SubsMap; + for (Record *R : Substitutions) +SubsMap.try_emplace(R->getName(), R); std::vector Diags = Records.getAllDerivedDefinitions("Diagnostic"); + llvm::for_each(Diags, [&](Record *R) { substituteDiagText(R, SubsMap); }); + std::vector DiagGroups = Records.getAllDerivedDefinitions("DiagGroup"); llvm::sort(DiagGroups.begin(), DiagGroups.end(), diagGroupBeforeByName); @@ -1300,6 +1350,7 @@ Severity[0] = tolower(Severity[0]); if (Severity == "ignored") Severity = IsRemarkGroup ? "remark" : "warning"; + writeDiagnosticText(Severity, D->getValueAsString("Text"), OS); } } Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -3613,41 +3613,39 @@ def note_ovl_candidate_non_deduced_mismatch_qualified : Note< "candidate template ignored: could not match %q0 against %q1">; -// Note that we don't treat templates differently for this diagnostic. -def note_ovl_candidate_arity : Note<"candidate " +def select_ovl_candidate_kind : TextSubstitution< "%select{function|function|constructor|function|function|constructor|" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" "inherited constructor|" -"inherited constructor}0 %select{|template
[PATCH] D45680: [C++2a] Implement operator<=> Part 2: Operator Rewritting and Overload Resolution.
EricWF updated this revision to Diff 146280. EricWF added a comment. Do better english in diagnostics. https://reviews.llvm.org/D45680 Files: include/clang/AST/ComparisonCategories.h include/clang/AST/Expr.h include/clang/AST/ExprCXX.h include/clang/AST/RecursiveASTVisitor.h include/clang/AST/Stmt.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/StmtNodes.td include/clang/Sema/Overload.h include/clang/Sema/Sema.h include/clang/Serialization/ASTBitCodes.h lib/AST/ComparisonCategories.cpp lib/AST/Expr.cpp lib/AST/ExprCXX.cpp lib/AST/ExprClassification.cpp lib/AST/ExprConstant.cpp lib/AST/ItaniumMangle.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtProfile.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaExceptionSpec.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp test/CodeGenCXX/cxx2a-compare.cpp test/SemaCXX/compare-cxx2a.cpp Index: test/SemaCXX/compare-cxx2a.cpp === --- test/SemaCXX/compare-cxx2a.cpp +++ test/SemaCXX/compare-cxx2a.cpp @@ -292,20 +292,21 @@ template struct Tag {}; -// expected-note@+1 {{candidate}} -Tag<0> operator<=>(EnumA, EnumA) { - return {}; +std::strong_ordering operator<=>(EnumA, EnumA) { + return std::strong_ordering::equal; } -Tag<1> operator<=>(EnumA, EnumB) { - return {}; +// expected-note@+1 {{candidate function}}, +std::strong_ordering operator<=>(EnumA a, EnumB b) { + return ((int)a <=> (int)b); } void test_enum_ovl_provided() { auto r1 = (EnumA::A <=> EnumA::A); - ASSERT_EXPR_TYPE(r1, Tag<0>); + ASSERT_EXPR_TYPE(r1, std::strong_ordering); auto r2 = (EnumA::A <=> EnumB::B); - ASSERT_EXPR_TYPE(r2, Tag<1>); - (void)(EnumB::B <=> EnumA::A); // expected-error {{invalid operands to binary expression ('EnumCompareTests::EnumB' and 'EnumCompareTests::EnumA')}} + ASSERT_EXPR_TYPE(r2, std::strong_ordering); + (void)(EnumB::B <=> EnumA::A); // OK, chooses reverse order synthesized candidate. + (void)(EnumB::B <=> EnumC::C); // expected-error {{invalid operands to binary expression ('EnumCompareTests::EnumB' and 'EnumCompareTests::EnumC')}} } void enum_float_test() { @@ -421,3 +422,114 @@ } } // namespace ComplexTest + +namespace TestRewritting { + +struct T { + int x; + // expected-note@+1 {{candidate}} + constexpr std::strong_ordering operator<=>(T y) const { +return (x <=> y.x); + } +}; + +struct U { + int x; + // FIXME: This diagnostic is wrong-ish. + // expected-note@+1 {{candidate function not viable: requires single argument 'y', but 2 arguments were provided}} + constexpr std::strong_equality operator<=>(T y) const { +if (x == y.x) + return std::strong_equality::equal; +return std::strong_equality::nonequal; + } +}; + +struct X { int x; }; +struct Y { int x; }; +template +struct Tag {}; + +Tag<0> operator<=>(X, Y) { + return {}; +} + +constexpr auto operator<=>(Y y, X x) { + return y.x <=> x.x; +} + +void foo() { + T t{42}; + T t2{0}; + U u{101}; + auto r1 = (t <=> u); + ASSERT_EXPR_TYPE(r1, std::strong_equality); + auto r2 = (t <=> t2); + ASSERT_EXPR_TYPE(r2, std::strong_ordering); + + auto r3 = t == u; + ASSERT_EXPR_TYPE(r3, bool); + + (void)(t < u); // expected-error {{invalid operands to binary expression ('TestRewritting::T' and 'TestRewritting::U')}} + + constexpr X x{1}; + constexpr Y y{2}; + constexpr auto r4 = (y < x); + static_assert(r4 == false); + constexpr auto r5 = (x < y); + static_assert(r5 == true); +} + +} // namespace TestRewritting + +// The implicit object parameter is not considered when performing partial +// ordering. That makes the reverse synthesized candidates ambiguous with the +// rewritten candidates if any of them resolve to a member function. +namespace TestOvlMatchingIgnoresImplicitObject { +struct U; +struct T { + std::strong_ordering operator<=>(U const &RHS) const; +}; +struct U { + std::strong_ordering operator<=>(T const &RHS) const = delete; +}; + +struct V { + int x; +}; +auto operator<=>(V const &LHS, V &&RHS) { // expected-note 4 {{candidate}} + return LHS.x <=> RHS.x; +} +auto operator<(V const &, V &&) { // expected-note {{candidate}} + return std::strong_equality::equal; +} + +void test() { + // OK. selects T::operator<=>(U) + (void)(T{} < U{}); + // expected-error@+1 {{use of overloaded operator '<' is ambiguous}} + (void)(V{} < V{}); + // expected-error@+1 {{use of overloaded operator '<=>' is ambiguous}} + (void)(V{} <=> V{}); +} + +} // namespace TestOvlMatchingIgnoresImplicitObject + +namespace TestRewrittenTemplate { + +template +auto test(T const &LHS, T const &RHS) { + // expected-error@+1 {{invalid operands to binary expression ('const TestRewrittenTemplate::None'}} + return LHS < RHS; +} +struct None {}; +template auto test(None const &, None const &); // expected-no
[PATCH] D46241: [CodeGen] Recognize more cases of zero initialization
sepavloff added inline comments. Comment at: lib/CodeGen/CGExprConstant.cpp:1414-1415 +Expr::EvalResult Result; +if (Init->EvaluateAsRValue(Result, CE.CGM.getContext()) && +!Result.hasUnacceptableSideEffect(Expr::SE_NoSideEffects)) + return (Result.Val.isInt() && Result.Val.getInt().isNullValue()) || rsmith wrote: > Please call `D.evaluateValue()` here rather than inventing your own > evaluation scheme. That way, we'll cache the evaluated initializer on the > variable for other uses or reuse the value if we've already evaluated it, and > you don't need to worry about the corner cases involved in getting the > evaluation right. (As it happens, you're getting some minor details wrong > because evaluating an initializer is not quite the same as evaluating an > rvalue, but in practice it's not a big deal here.) Call of `D.evaluateValue()` may result in substantial memory and time consumption if the variable value is huge, like in: ``` int char data_1[2147483648u] = { 0 }; ``` The idea of this patch is to recognize some cases of zero initialization prior to the evaluation of variable initializer. In the example above, value would be evaluated only for part of the initializer, namely `0`, which does not have an associated variable, so call of `D.evaluateValue()` is not possible. Repository: rC Clang https://reviews.llvm.org/D46241 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45680: [C++2a] Implement operator<=> Part 2: Operator Rewritting and Overload Resolution.
EricWF updated this revision to Diff 146281. EricWF added a comment. Fix fetching the correct source location information in `CXXRewrittenOperatorExpr`. https://reviews.llvm.org/D45680 Files: include/clang/AST/ComparisonCategories.h include/clang/AST/Expr.h include/clang/AST/ExprCXX.h include/clang/AST/RecursiveASTVisitor.h include/clang/AST/Stmt.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/StmtNodes.td include/clang/Sema/Overload.h include/clang/Sema/Sema.h include/clang/Serialization/ASTBitCodes.h lib/AST/ComparisonCategories.cpp lib/AST/Expr.cpp lib/AST/ExprCXX.cpp lib/AST/ExprClassification.cpp lib/AST/ExprConstant.cpp lib/AST/ItaniumMangle.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtProfile.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaExceptionSpec.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp test/CodeGenCXX/cxx2a-compare.cpp test/SemaCXX/compare-cxx2a.cpp Index: test/SemaCXX/compare-cxx2a.cpp === --- test/SemaCXX/compare-cxx2a.cpp +++ test/SemaCXX/compare-cxx2a.cpp @@ -292,20 +292,21 @@ template struct Tag {}; -// expected-note@+1 {{candidate}} -Tag<0> operator<=>(EnumA, EnumA) { - return {}; +std::strong_ordering operator<=>(EnumA, EnumA) { + return std::strong_ordering::equal; } -Tag<1> operator<=>(EnumA, EnumB) { - return {}; +// expected-note@+1 {{candidate function}}, +std::strong_ordering operator<=>(EnumA a, EnumB b) { + return ((int)a <=> (int)b); } void test_enum_ovl_provided() { auto r1 = (EnumA::A <=> EnumA::A); - ASSERT_EXPR_TYPE(r1, Tag<0>); + ASSERT_EXPR_TYPE(r1, std::strong_ordering); auto r2 = (EnumA::A <=> EnumB::B); - ASSERT_EXPR_TYPE(r2, Tag<1>); - (void)(EnumB::B <=> EnumA::A); // expected-error {{invalid operands to binary expression ('EnumCompareTests::EnumB' and 'EnumCompareTests::EnumA')}} + ASSERT_EXPR_TYPE(r2, std::strong_ordering); + (void)(EnumB::B <=> EnumA::A); // OK, chooses reverse order synthesized candidate. + (void)(EnumB::B <=> EnumC::C); // expected-error {{invalid operands to binary expression ('EnumCompareTests::EnumB' and 'EnumCompareTests::EnumC')}} } void enum_float_test() { @@ -421,3 +422,113 @@ } } // namespace ComplexTest + +namespace TestRewritting { + +struct T { + int x; + // expected-note@+1 {{candidate}} + constexpr std::strong_ordering operator<=>(T y) const { +return (x <=> y.x); + } +}; + +struct U { + int x; + // FIXME(EricWF2 + constexpr std::strong_equality operator<=>(T y) const { +if (x == y.x) + return std::strong_equality::equal; +return std::strong_equality::nonequal; + } +}; + +struct X { int x; }; +struct Y { int x; }; +template +struct Tag {}; + +Tag<0> operator<=>(X, Y) { + return {}; +} + +constexpr auto operator<=>(Y y, X x) { + return y.x <=> x.x; +} + +void foo() { + T t{42}; + T t2{0}; + U u{101}; + auto r1 = (t <=> u); + ASSERT_EXPR_TYPE(r1, std::strong_equality); + auto r2 = (t <=> t2); + ASSERT_EXPR_TYPE(r2, std::strong_ordering); + + auto r3 = t == u; + ASSERT_EXPR_TYPE(r3, bool); + + (void)(t < u); // expected-error {{invalid operands to binary expression ('TestRewritting::T' and 'TestRewritting::U')}} + + constexpr X x{1}; + constexpr Y y{2}; + constexpr auto r4 = (y < x); + static_assert(r4 == false); + constexpr auto r5 = (x < y); + static_assert(r5 == true); +} + +} // namespace TestRewritting + +// The implicit object parameter is not considered when performing partial +// ordering. That makes the reverse synthesized candidates ambiguous with the +// rewritten candidates if any of them resolve to a member function. +namespace TestOvlMatchingIgnoresImplicitObject { +struct U; +struct T { + std::strong_ordering operator<=>(U const &RHS) const; +}; +struct U { + std::strong_ordering operator<=>(T const &RHS) const = delete; +}; + +struct V { + int x; +}; +auto operator<=>(V const &LHS, V &&RHS) { // expected-note 4 {{candidate}} + return LHS.x <=> RHS.x; +} +auto operator<(V const &, V &&) { // expected-note {{candidate}} + return std::strong_equality::equal; +} + +void test() { + // OK. selects T::operator<=>(U) + (void)(T{} < U{}); + // expected-error@+1 {{use of overloaded operator '<' is ambiguous}} + (void)(V{} < V{}); + // expected-error@+1 {{use of overloaded operator '<=>' is ambiguous}} + (void)(V{} <=> V{}); +} + +} // namespace TestOvlMatchingIgnoresImplicitObject + +namespace TestRewrittenTemplate { + +template +auto test(T const &LHS, T const &RHS) { + // expected-error@+1 {{invalid operands to binary expression ('const TestRewrittenTemplate::None'}} + return LHS < RHS; +} +struct None {}; +template auto test(None const &, None const &); // expected-note {{requested here}} + +struct Relational {}; +bool operator<(Relational, Relational); +t
[PATCH] D46683: [X86] Assume alignment of movdir64b dst argument
craig.topper accepted this revision. craig.topper added a comment. This revision is now accepted and ready to land. LGTM Repository: rC Clang https://reviews.llvm.org/D46683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45680: [C++2a] Implement operator<=> Part 2: Operator Rewritting and Overload Resolution.
EricWF updated this revision to Diff 146285. EricWF added a comment. - Update tests and improve diagnostics. Still more work to be done here though. https://reviews.llvm.org/D45680 Files: include/clang/AST/ComparisonCategories.h include/clang/AST/Expr.h include/clang/AST/ExprCXX.h include/clang/AST/RecursiveASTVisitor.h include/clang/AST/Stmt.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/StmtNodes.td include/clang/Sema/Overload.h include/clang/Sema/Sema.h include/clang/Serialization/ASTBitCodes.h lib/AST/ComparisonCategories.cpp lib/AST/Expr.cpp lib/AST/ExprCXX.cpp lib/AST/ExprClassification.cpp lib/AST/ExprConstant.cpp lib/AST/ItaniumMangle.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtProfile.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaExceptionSpec.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp test/CodeGenCXX/cxx2a-compare.cpp test/SemaCXX/compare-cxx2a.cpp Index: test/SemaCXX/compare-cxx2a.cpp === --- test/SemaCXX/compare-cxx2a.cpp +++ test/SemaCXX/compare-cxx2a.cpp @@ -292,20 +292,21 @@ template struct Tag {}; -// expected-note@+1 {{candidate}} -Tag<0> operator<=>(EnumA, EnumA) { - return {}; +std::strong_ordering operator<=>(EnumA, EnumA) { + return std::strong_ordering::equal; } -Tag<1> operator<=>(EnumA, EnumB) { - return {}; +// expected-note@+1 {{candidate function}}, +std::strong_ordering operator<=>(EnumA a, EnumB b) { + return ((int)a <=> (int)b); } void test_enum_ovl_provided() { auto r1 = (EnumA::A <=> EnumA::A); - ASSERT_EXPR_TYPE(r1, Tag<0>); + ASSERT_EXPR_TYPE(r1, std::strong_ordering); auto r2 = (EnumA::A <=> EnumB::B); - ASSERT_EXPR_TYPE(r2, Tag<1>); - (void)(EnumB::B <=> EnumA::A); // expected-error {{invalid operands to binary expression ('EnumCompareTests::EnumB' and 'EnumCompareTests::EnumA')}} + ASSERT_EXPR_TYPE(r2, std::strong_ordering); + (void)(EnumB::B <=> EnumA::A); // OK, chooses reverse order synthesized candidate. + (void)(EnumB::B <=> EnumC::C); // expected-error {{invalid operands to binary expression ('EnumCompareTests::EnumB' and 'EnumCompareTests::EnumC')}} } void enum_float_test() { @@ -421,3 +422,132 @@ } } // namespace ComplexTest + +namespace TestRewritting { + +struct T { + int x; + // expected-note@+1 {{candidate}} + constexpr std::strong_ordering operator<=>(T y) const { +return (x <=> y.x); + } +}; + +struct U { + int x; + // FIXME(EricWF) + // expected-note@+1 {{return type cannot be used as an operand to the reversed rewritten comparison operator}} + constexpr std::strong_equality operator<=>(T y) const { +if (x == y.x) + return std::strong_equality::equal; +return std::strong_equality::nonequal; + } +}; + +struct X { int x; }; +struct Y { int x; }; +template +struct Tag {}; + +// expected-note@+2 {{candidate function (rewritten operator) not viable: no known conversion from 'TestRewritting::T' to 'TestRewritting::X' for 1st argument}} +// expected-note@+1 {{candidate function (reversed rewritten operator) not viable: no known conversion from 'TestRewritting::U' to 'TestRewritting::X' for 1st argument}} +Tag<0> operator<=>(X, Y) { + return {}; +} + +// expected-note@+2 {{candidate function (rewritten operator) not viable: no known conversion from 'TestRewritting::T' to 'TestRewritting::Y' for 1st argument}} +// expected-note@+1 {{candidate function (reversed rewritten operator) not viable: no known conversion from 'TestRewritting::U' to 'TestRewritting::Y' for 1st argument}} +constexpr auto operator<=>(Y y, X x) { + return y.x <=> x.x; +} + +void foo() { + T t{42}; + T t2{0}; + U u{101}; + auto r1 = (t <=> u); + ASSERT_EXPR_TYPE(r1, std::strong_equality); + auto r2 = (t <=> t2); + ASSERT_EXPR_TYPE(r2, std::strong_ordering); + + auto r3 = t == u; + ASSERT_EXPR_TYPE(r3, bool); + + (void)(t < u); // expected-error {{invalid operands to binary expression ('TestRewritting::T' and 'TestRewritting::U')}} + + constexpr X x{1}; + constexpr Y y{2}; + constexpr auto r4 = (y < x); + static_assert(r4 == false); + constexpr auto r5 = (x < y); + static_assert(r5 == true); +} + +} // namespace TestRewritting + +// The implicit object parameter is not considered when performing partial +// ordering. That makes the reverse synthesized candidates ambiguous with the +// rewritten candidates if any of them resolve to a member function. +namespace TestOvlMatchingIgnoresImplicitObject { +struct U; +struct T { + std::strong_ordering operator<=>(U const &RHS) const; +}; +struct U { + std::strong_ordering operator<=>(T const &RHS) const = delete; +}; + +struct V { + int x; +}; +auto operator<=>(V const &LHS, V &&RHS) { // expected-note 4 {{candidate}} + return LHS.x <=> RHS.x; +} +auto operator<(V const &, V &&) { // expected
[PATCH] D46742: [X86] Use __builtin_convertvector to replace some of the avx512 truncate builtins.
craig.topper created this revision. craig.topper added reviewers: RKSimon, GBuella, tkrupa. As long as the destination type is a 256 or 128 bit vector we can use __builtin_convertvector to directly generate trunc IR instruction which will be handled natively by the backend. Repository: rC Clang https://reviews.llvm.org/D46742 Files: include/clang/Basic/BuiltinsX86.def lib/Headers/avx512bwintrin.h lib/Headers/avx512fintrin.h lib/Headers/avx512vlbwintrin.h lib/Headers/avx512vlintrin.h test/CodeGen/avx512bw-builtins.c test/CodeGen/avx512f-builtins.c test/CodeGen/avx512vl-builtins.c test/CodeGen/avx512vlbw-builtins.c Index: test/CodeGen/avx512vlbw-builtins.c === --- test/CodeGen/avx512vlbw-builtins.c +++ test/CodeGen/avx512vlbw-builtins.c @@ -1804,19 +1804,21 @@ __m128i test_mm256_cvtepi16_epi8(__m256i __A) { // CHECK-LABEL: @test_mm256_cvtepi16_epi8 - // CHECK: @llvm.x86.avx512.mask.pmov.wb.256 + // CHECK: trunc <16 x i16> %{{.*}} to <16 x i8> return _mm256_cvtepi16_epi8(__A); } __m128i test_mm256_mask_cvtepi16_epi8(__m128i __O, __mmask16 __M, __m256i __A) { // CHECK-LABEL: @test_mm256_mask_cvtepi16_epi8 - // CHECK: @llvm.x86.avx512.mask.pmov.wb.256 + // CHECK: trunc <16 x i16> %{{.*}} to <16 x i8> + // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm256_mask_cvtepi16_epi8(__O, __M, __A); } __m128i test_mm256_maskz_cvtepi16_epi8(__mmask16 __M, __m256i __A) { // CHECK-LABEL: @test_mm256_maskz_cvtepi16_epi8 - // CHECK: @llvm.x86.avx512.mask.pmov.wb.256 + // CHECK: trunc <16 x i16> %{{.*}} to <16 x i8> + // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm256_maskz_cvtepi16_epi8(__M, __A); } Index: test/CodeGen/avx512vl-builtins.c === --- test/CodeGen/avx512vl-builtins.c +++ test/CodeGen/avx512vl-builtins.c @@ -6577,19 +6577,21 @@ __m128i test_mm256_cvtepi32_epi16(__m256i __A) { // CHECK-LABEL: @test_mm256_cvtepi32_epi16 - // CHECK: @llvm.x86.avx512.mask.pmov.dw.256 + // CHECK: trunc <8 x i32> %{{.*}} to <8 x i16> return _mm256_cvtepi32_epi16(__A); } __m128i test_mm256_mask_cvtepi32_epi16(__m128i __O, __mmask8 __M, __m256i __A) { // CHECK-LABEL: @test_mm256_mask_cvtepi32_epi16 - // CHECK: @llvm.x86.avx512.mask.pmov.dw.256 + // CHECK: trunc <8 x i32> %{{.*}} to <8 x i16> + // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm256_mask_cvtepi32_epi16(__O, __M, __A); } __m128i test_mm256_maskz_cvtepi32_epi16(__mmask8 __M, __m256i __A) { // CHECK-LABEL: @test_mm256_maskz_cvtepi32_epi16 - // CHECK: @llvm.x86.avx512.mask.pmov.dw.256 + // CHECK: trunc <8 x i32> %{{.*}} to <8 x i16> + // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm256_maskz_cvtepi32_epi16(__M, __A); } @@ -6673,19 +6675,21 @@ __m128i test_mm256_cvtepi64_epi32(__m256i __A) { // CHECK-LABEL: @test_mm256_cvtepi64_epi32 - // CHECK: @llvm.x86.avx512.mask.pmov.qd.256 + // CHECK: trunc <4 x i64> %{{.*}} to <4 x i32> return _mm256_cvtepi64_epi32(__A); } __m128i test_mm256_mask_cvtepi64_epi32(__m128i __O, __mmask8 __M, __m256i __A) { // CHECK-LABEL: @test_mm256_mask_cvtepi64_epi32 - // CHECK: @llvm.x86.avx512.mask.pmov.qd.256 + // CHECK: trunc <4 x i64> %{{.*}} to <4 x i32> + // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}} return _mm256_mask_cvtepi64_epi32(__O, __M, __A); } __m128i test_mm256_maskz_cvtepi64_epi32(__mmask8 __M, __m256i __A) { // CHECK-LABEL: @test_mm256_maskz_cvtepi64_epi32 - // CHECK: @llvm.x86.avx512.mask.pmov.qd.256 + // CHECK: trunc <4 x i64> %{{.*}} to <4 x i32> + // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}} return _mm256_maskz_cvtepi64_epi32(__M, __A); } Index: test/CodeGen/avx512f-builtins.c === --- test/CodeGen/avx512f-builtins.c +++ test/CodeGen/avx512f-builtins.c @@ -5102,19 +5102,21 @@ __m128i test_mm512_cvtepi32_epi8(__m512i __A) { // CHECK-LABEL: @test_mm512_cvtepi32_epi8 - // CHECK: @llvm.x86.avx512.mask.pmov.db.512 + // CHECK: trunc <16 x i32> %{{.*}} to <16 x i8> return _mm512_cvtepi32_epi8(__A); } __m128i test_mm512_mask_cvtepi32_epi8(__m128i __O, __mmask16 __M, __m512i __A) { // CHECK-LABEL: @test_mm512_mask_cvtepi32_epi8 - // CHECK: @llvm.x86.avx512.mask.pmov.db.512 + // CHECK: trunc <16 x i32> %{{.*}} to <16 x i8> + // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm512_mask_cvtepi32_epi8(__O, __M, __A); } __m128i test_mm512_maskz_cvtepi32_epi8(__mmask16 __M, __m512i __A) { // CHECK-LABEL: @test_mm512_maskz_cvtepi32_epi8 - // CHECK: @llvm.x86.avx512.mask.pmov.db.512 + // CHECK: trunc <16 x i32> %{{.*}} to <16 x i8> + // CHECK: select <16 x i1> %