From 6252156da5066bd47f63f8bd40404d1f89909d32 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Dec 24 2017 01:00:23 +0000 Subject: Vendor import of clang trunk r321414: https://llvm.org/svn/llvm-project/cfe/trunk@321414 --- diff --git a/cmake/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake index 52512e9..7ad2d9c 100644 --- a/cmake/caches/Fuchsia-stage2.cmake +++ b/cmake/caches/Fuchsia-stage2.cmake @@ -23,6 +23,7 @@ if(APPLE) set(LLDB_CODESIGN_IDENTITY "" CACHE STRING "") endif() +set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "") diff --git a/cmake/caches/Fuchsia.cmake b/cmake/caches/Fuchsia.cmake index 05a28d6..0d81592 100644 --- a/cmake/caches/Fuchsia.cmake +++ b/cmake/caches/Fuchsia.cmake @@ -13,6 +13,7 @@ set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "") set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") +set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") set(CMAKE_BUILD_TYPE Release CACHE STRING "") set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "") diff --git a/docs/HardwareAssistedAddressSanitizerDesign.rst b/docs/HardwareAssistedAddressSanitizerDesign.rst index 00777ce..5904cce 100644 --- a/docs/HardwareAssistedAddressSanitizerDesign.rst +++ b/docs/HardwareAssistedAddressSanitizerDesign.rst @@ -21,7 +21,7 @@ The redzones, the quarantine, and, to a less extent, the shadow, are the sources of AddressSanitizer's memory overhead. See the `AddressSanitizer paper`_ for details. -AArch64 has the `Address Tagging`_, a hardware feature that allows +AArch64 has the `Address Tagging`_ (or top-byte-ignore, TBI), a hardware feature that allows software to use 8 most significant bits of a 64-bit pointer as a tag. HWASAN uses `Address Tagging`_ to implement a memory safety tool, similar to :doc:`AddressSanitizer`, @@ -31,7 +31,7 @@ accuracy guarantees. Algorithm ========= * Every heap/stack/global memory object is forcibly aligned by `N` bytes - (`N` is e.g. 16 or 64) + (`N` is e.g. 16 or 64). We call `N` the **granularity** of tagging. * For every such object a random `K`-bit tag `T` is chosen (`K` is e.g. 4 or 8) * The pointer to the object is tagged with `T`. * The memory for the object is also tagged with `T` @@ -44,19 +44,35 @@ Instrumentation Memory Accesses --------------- -All memory accesses are prefixed with a call to a run-time function. -The function encodes the type and the size of access in its name; -it receives the address as a parameter, e.g. `__hwasan_load4(void *ptr)`; -it loads the memory tag, compares it with the -pointer tag, and executes `__builtin_trap` (or calls `__hwasan_error_load4(void *ptr)`) on mismatch. +All memory accesses are prefixed with an inline instruction sequence that +verifies the tags. Currently, the following sequence is used: -It's possible to inline this callback too. + +.. code-block:: asm + + // int foo(int *a) { return *a; } + // clang -O2 --target=aarch64-linux -fsanitize=hwaddress -c load.c + foo: + 0: 08 dc 44 d3 ubfx x8, x0, #4, #52 // shadow address + 4: 08 01 40 39 ldrb w8, [x8] // load shadow + 8: 09 fc 78 d3 lsr x9, x0, #56 // address tag + c: 3f 01 08 6b cmp w9, w8 // compare tags + 10: 61 00 00 54 b.ne #12 // jump on mismatch + 14: 00 00 40 b9 ldr w0, [x0] // original load + 18: c0 03 5f d6 ret + 1c: 40 20 40 d4 hlt #0x102 // halt + 20: 00 00 40 b9 ldr w0, [x0] // original load + 24: c0 03 5f d6 ret + + +Alternatively, memory accesses are prefixed with a function call. Heap ---- Tagging the heap memory/pointers is done by `malloc`. This can be based on any malloc that forces all objects to be N-aligned. +`free` tags the memory with a different tag. Stack ----- @@ -75,7 +91,7 @@ TODO: details. Error reporting --------------- -Errors are generated by `__builtin_trap` and are handled by a signal handler. +Errors are generated by the `HLT` instruction and are handled by a signal handler. Attribute --------- diff --git a/docs/Modules.rst b/docs/Modules.rst index 757be61..2fa38be 100644 --- a/docs/Modules.rst +++ b/docs/Modules.rst @@ -859,10 +859,12 @@ express this with a single module map file in the library: module Foo { header "Foo.h" - - explicit module Private { - header "Foo_Private.h" - } + ... + } + + module Foo_Private { + header "Foo_Private.h" + ... } @@ -873,7 +875,7 @@ build machinery. Private module map files, which are named ``module.private.modulemap`` (or, for backward compatibility, ``module_private.map``), allow one to -augment the primary module map file with an additional submodule. For +augment the primary module map file with an additional modules. For example, we would split the module map file above into two module map files: @@ -883,9 +885,9 @@ files: module Foo { header "Foo.h" } - + /* module.private.modulemap */ - explicit module Foo.Private { + module Foo_Private { header "Foo_Private.h" } @@ -899,13 +901,12 @@ boundaries. When writing a private module as part of a *framework*, it's recommended that: -* Headers for this module are present in the ``PrivateHeaders`` - framework subdirectory. -* The private module is defined as a *submodule* of the public framework (if - there's one), similar to how ``Foo.Private`` is defined in the example above. -* The ``explicit`` keyword should be used to guarantee that its content will - only be available when the submodule itself is explicitly named (through a - ``@import`` for example). +* Headers for this module are present in the ``PrivateHeaders`` framework + subdirectory. +* The private module is defined as a *top level module* with the name of the + public framework prefixed, like ``Foo_Private`` above. Clang has extra logic + to work with this naming, using ``FooPrivate`` or ``Foo.Private`` (submodule) + trigger warnings and might not work as expected. Modularizing a Platform ======================= diff --git a/docs/UndefinedBehaviorSanitizer.rst b/docs/UndefinedBehaviorSanitizer.rst index 0a08a41..e9f85c2 100644 --- a/docs/UndefinedBehaviorSanitizer.rst +++ b/docs/UndefinedBehaviorSanitizer.rst @@ -124,8 +124,8 @@ Available checks are: - ``-fsanitize=signed-integer-overflow``: Signed integer overflow, including all the checks added by ``-ftrapv``, and checking for overflow in signed division (``INT_MIN / -1``). - - ``-fsanitize=unreachable``: If control flow reaches - ``__builtin_unreachable``. + - ``-fsanitize=unreachable``: If control flow reaches an unreachable + program point. - ``-fsanitize=unsigned-integer-overflow``: Unsigned integer overflows. Note that unlike signed integer overflow, unsigned integer is not undefined behavior. However, while it has well-defined semantics, diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 4db0b1e..04a832e 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1759,6 +1759,11 @@ protected: unsigned IsCopyDeductionCandidate : 1; private: + + /// Store the ODRHash after first calculation. + unsigned HasODRHash : 1; + unsigned ODRHash; + /// \brief End part of this FunctionDecl's source range. /// /// We could compute the full range in getSourceRange(). However, when we're @@ -1841,8 +1846,9 @@ protected: IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified), InstantiationIsPending(false), UsesSEHTry(false), HasSkippedBody(false), - WillHaveBody(false), IsCopyDeductionCandidate(false), - EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {} + WillHaveBody(false), IsCopyDeductionCandidate(false), HasODRHash(false), + ODRHash(0), EndRangeLoc(NameInfo.getEndLoc()), + DNLoc(NameInfo.getInfo()) {} using redeclarable_base = Redeclarable; @@ -2439,6 +2445,10 @@ public: /// returns 0. unsigned getMemoryFunctionKind() const; + /// \brief Returns ODRHash of the function. This value is calculated and + /// stored on first call, then the stored value returned on the other calls. + unsigned getODRHash(); + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { diff --git a/include/clang/AST/ODRHash.h b/include/clang/AST/ODRHash.h index e4cc12d..ed648bb 100644 --- a/include/clang/AST/ODRHash.h +++ b/include/clang/AST/ODRHash.h @@ -53,6 +53,10 @@ public: // more information than the AddDecl class. void AddCXXRecordDecl(const CXXRecordDecl *Record); + // Use this for ODR checking functions between modules. This method compares + // more information than the AddDecl class. + void AddFunctionDecl(const FunctionDecl *Function); + // Process SubDecls of the main Decl. This method calls the DeclVisitor // while AddDecl does not. void AddSubDecl(const Decl *D); diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 7247838..882878b 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -976,16 +976,14 @@ public: return LHS.Value != RHS.Value; } - std::string getAsString() const { - return getAsString(split()); + static std::string getAsString(SplitQualType split, + const PrintingPolicy &Policy) { + return getAsString(split.Ty, split.Quals, Policy); } + static std::string getAsString(const Type *ty, Qualifiers qs, + const PrintingPolicy &Policy); - static std::string getAsString(SplitQualType split) { - return getAsString(split.Ty, split.Quals); - } - - static std::string getAsString(const Type *ty, Qualifiers qs); - + std::string getAsString() const; std::string getAsString(const PrintingPolicy &Policy) const; void print(raw_ostream &OS, const PrintingPolicy &Policy, diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index d926fdd..8b84c4b 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -267,13 +267,24 @@ def RenderScript : LangOpt<"RenderScript">; def ObjC : LangOpt<"ObjC1">; def BlocksSupported : LangOpt<"Blocks">; -// Defines targets for target-specific attributes. The list of strings should -// specify architectures for which the target applies, based off the ArchType -// enumeration in Triple.h. -class TargetArch arches> { - list Arches = arches; +// Defines targets for target-specific attributes. Empty lists are unchecked. +class TargetSpec { + // Specifies Architectures for which the target applies, based off the + // ArchType enumeration in Triple.h. + list Arches = []; + // Specifies Operating Systems for which the target applies, based off the + // OSType enumeration in Triple.h list OSes; + // Specifies the C++ ABIs for which the target applies, based off the + // TargetCXXABI::Kind in TargetCXXABI.h. list CXXABIs; + // Specifies Object Formats for which the target applies, based off the + // ObjectFormatType enumeration in Triple.h + list ObjectFormats; +} + +class TargetArch arches> : TargetSpec { + let Arches = arches; } def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>; def TargetAVR : TargetArch<["avr"]>; @@ -288,6 +299,9 @@ def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> { def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> { let CXXABIs = ["Microsoft"]; } +def TargetELF : TargetSpec { + let ObjectFormats = ["ELF"]; +} // Attribute subject match rules that are used for #pragma clang attribute. // @@ -465,8 +479,8 @@ class InheritableAttr : Attr; /// A target-specific attribute. This class is meant to be used as a mixin /// with InheritableAttr or Attr depending on the attribute's needs. -class TargetSpecificAttr { - TargetArch Target = target; +class TargetSpecificAttr { + TargetSpec Target = target; // Attributes are generally required to have unique spellings for their names // so that the parser can determine what kind of attribute it has parsed. // However, target-specific attributes are special in that the attribute only @@ -1121,7 +1135,7 @@ def IBOutletCollection : InheritableAttr { let Documentation = [Undocumented]; } -def IFunc : Attr { +def IFunc : Attr, TargetSpecificAttr { let Spellings = [GCC<"ifunc">]; let Args = [StringArgument<"Resolver">]; let Subjects = SubjectList<[Function]>; diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 392a340..b25181f 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -198,6 +198,11 @@ def err_missing_module : Error< def err_no_submodule : Error<"no submodule named %0 in module '%1'">; def err_no_submodule_suggest : Error< "no submodule named %0 in module '%1'; did you mean '%2'?">; +def warn_no_priv_submodule_use_toplevel : Warning< + "no submodule named %0 in module '%1'; using top level '%2'">, + InGroup; +def note_private_top_level_defined : Note< + "module defined here">; def warn_missing_submodule : Warning<"missing submodule '%0'">, InGroup; def note_module_import_here : Note<"module imported here">; diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h index 43183a1..b4ea85b 100644 --- a/include/clang/Basic/DiagnosticIDs.h +++ b/include/clang/Basic/DiagnosticIDs.h @@ -297,7 +297,7 @@ public: /// \brief Get the set of all diagnostic IDs. static void getAllDiagnostics(diag::Flavor Flavor, - SmallVectorImpl &Diags); + std::vector &Diags); /// \brief Get the diagnostic option with the closest edit distance to the /// given group name. diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index c664281..c391470 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -691,11 +691,15 @@ def err_mmap_expected_feature : Error<"expected a feature name">; def err_mmap_expected_attribute : Error<"expected an attribute name">; def warn_mmap_unknown_attribute : Warning<"unknown attribute '%0'">, InGroup; -def warn_mmap_mismatched_top_level_private : Warning< - "top-level module '%0' in private module map, expected a submodule of '%1'">, +def warn_mmap_mismatched_private_submodule : Warning< + "private submodule '%0' in private module map, expected top-level module">, InGroup; -def note_mmap_rename_top_level_private_as_submodule : Note< - "make '%0' a submodule of '%1' to ensure it can be found by name">; +def warn_mmap_mismatched_private_module_name : Warning< + "expected canonical name for private module '%0'">, + InGroup; +def note_mmap_rename_top_level_private_module : Note< + "rename '%0' to ensure it can be found by name">; + def err_mmap_duplicate_header_attribute : Error< "header attribute '%0' specified multiple times">; def err_mmap_invalid_header_attribute_value : Error< diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 29236ea..01e8199 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -3911,6 +3911,9 @@ def err_template_param_different_kind : Error< "%select{|template parameter }0redeclaration">; def note_template_param_different_kind : Note< "template parameter has a different kind in template argument">; + +def err_invalid_decl_specifier_in_nontype_parm : Error< + "invalid declaration specifier in template non-type parameter">; def err_template_nontype_parm_different_type : Error< "template non-type parameter has a different type %0 in template " diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td index 3949bc2..250b49f 100644 --- a/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/include/clang/Basic/DiagnosticSerializationKinds.td @@ -270,6 +270,29 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found " "friend function %2|" "}1">; +def err_module_odr_violation_function : Error< + "%q0 has different definitions in different modules; " + "%select{definition in module '%2'|defined here}1 " + "first difference is " + "%select{" + "return type is %4|" + "%ordinal4 parameter with name %5|" + "%ordinal4 parameter with type %5%select{| decayed from %7}6|" + "%ordinal4 parameter with%select{out|}5 a default argument|" + "%ordinal4 parameter with a default argument|" + "function body" + "}3">; + +def note_module_odr_violation_function : Note<"but in '%0' found " + "%select{" + "different return type %2|" + "%ordinal2 parameter with name %3|" + "%ordinal2 parameter with type %3%select{| decayed from %5}4|" + "%ordinal2 parameter with%select{out|}3 a default argument|" + "%ordinal2 parameter with a different default argument|" + "a different body" + "}1">; + def err_module_odr_violation_mismatch_decl_unknown : Error< "%q0 %select{with definition in module '%2'|defined here}1 has different " "definitions in different modules; first difference is this " diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td index ad8d679..d5c16a9 100644 --- a/include/clang/Basic/arm_neon.td +++ b/include/clang/Basic/arm_neon.td @@ -227,6 +227,7 @@ def OP_UNAVAILABLE : Operation { // u: unsigned integer (int/float args) // f: float (int args) // F: double (int args) +// H: half (int args) // d: default // g: default, ignore 'Q' size modifier. // j: default, force 'Q' size modifier. @@ -345,6 +346,7 @@ def OP_MLSLHi : Op<(call "vmlsl", $p0, (call "vget_high", $p1), (call "vget_high", $p2))>; def OP_MLSLHi_N : Op<(call "vmlsl_n", $p0, (call "vget_high", $p1), $p2)>; def OP_MUL_N : Op<(op "*", $p0, (dup $p1))>; +def OP_MULX_N : Op<(call "vmulx", $p0, (dup $p1))>; def OP_MLA_N : Op<(op "+", $p0, (op "*", $p1, (dup $p2)))>; def OP_MLS_N : Op<(op "-", $p0, (op "*", $p1, (dup $p2)))>; def OP_FMLA_N : Op<(call "vfma", $p0, $p1, (dup $p2))>; @@ -1661,3 +1663,186 @@ def SCALAR_SQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "sssji", "SsSi", OP_SCALAR def SCALAR_VDUP_LANE : IInst<"vdup_lane", "sdi", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">; def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "sji", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">; } + +// ARMv8.2-A FP16 intrinsics. +let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarch64__)" in { + + // ARMv8.2-A FP16 one-operand vector intrinsics. + + // Comparison + def CMEQH : SInst<"vceqz", "ud", "hQh">; + def CMGEH : SInst<"vcgez", "ud", "hQh">; + def CMGTH : SInst<"vcgtz", "ud", "hQh">; + def CMLEH : SInst<"vclez", "ud", "hQh">; + def CMLTH : SInst<"vcltz", "ud", "hQh">; + + // Vector conversion + def VCVT_F16 : SInst<"vcvt_f16", "Hd", "sUsQsQUs">; + def VCVT_S16 : SInst<"vcvt_s16", "xd", "hQh">; + def VCVT_U16 : SInst<"vcvt_u16", "ud", "hQh">; + def VCVTA_S16 : SInst<"vcvta_s16", "xd", "hQh">; + def VCVTA_U16 : SInst<"vcvta_u16", "ud", "hQh">; + def VCVTM_S16 : SInst<"vcvtm_s16", "xd", "hQh">; + def VCVTM_U16 : SInst<"vcvtm_u16", "ud", "hQh">; + def VCVTN_S16 : SInst<"vcvtn_s16", "xd", "hQh">; + def VCVTN_U16 : SInst<"vcvtn_u16", "ud", "hQh">; + def VCVTP_S16 : SInst<"vcvtp_s16", "xd", "hQh">; + def VCVTP_U16 : SInst<"vcvtp_u16", "ud", "hQh">; + + // Vector rounding + def FRINTZH : SInst<"vrnd", "dd", "hQh">; + def FRINTNH : SInst<"vrndn", "dd", "hQh">; + def FRINTAH : SInst<"vrnda", "dd", "hQh">; + def FRINTPH : SInst<"vrndp", "dd", "hQh">; + def FRINTMH : SInst<"vrndm", "dd", "hQh">; + def FRINTXH : SInst<"vrndx", "dd", "hQh">; + def FRINTIH : SInst<"vrndi", "dd", "hQh">; + + // Misc. + def VABSH : SInst<"vabs", "dd", "hQh">; + def VNEGH : SOpInst<"vneg", "dd", "hQh", OP_NEG>; + def VRECPEH : SInst<"vrecpe", "dd", "hQh">; + def FRSQRTEH : SInst<"vrsqrte", "dd", "hQh">; + def FSQRTH : SInst<"vsqrt", "dd", "hQh">; + + // ARMv8.2-A FP16 two-operands vector intrinsics. + + // Misc. + def VADDH : SOpInst<"vadd", "ddd", "hQh", OP_ADD>; + def VABDH : SInst<"vabd", "ddd", "hQh">; + def VSUBH : SOpInst<"vsub", "ddd", "hQh", OP_SUB>; + + // Comparison + let InstName = "vacge" in { + def VCAGEH : SInst<"vcage", "udd", "hQh">; + def VCALEH : SInst<"vcale", "udd", "hQh">; + } + let InstName = "vacgt" in { + def VCAGTH : SInst<"vcagt", "udd", "hQh">; + def VCALTH : SInst<"vcalt", "udd", "hQh">; + } + def VCEQH : SOpInst<"vceq", "udd", "hQh", OP_EQ>; + def VCGEH : SOpInst<"vcge", "udd", "hQh", OP_GE>; + def VCGTH : SOpInst<"vcgt", "udd", "hQh", OP_GT>; + let InstName = "vcge" in + def VCLEH : SOpInst<"vcle", "udd", "hQh", OP_LE>; + let InstName = "vcgt" in + def VCLTH : SOpInst<"vclt", "udd", "hQh", OP_LT>; + + // Vector conversion + let isVCVT_N = 1 in { + def VCVT_N_F16 : SInst<"vcvt_n_f16", "Hdi", "sUsQsQUs">; + def VCVT_N_S16 : SInst<"vcvt_n_s16", "xdi", "hQh">; + def VCVT_N_U16 : SInst<"vcvt_n_u16", "udi", "hQh">; + } + + // Max/Min + def VMAXH : SInst<"vmax", "ddd", "hQh">; + def VMINH : SInst<"vmin", "ddd", "hQh">; + def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">; + def FMINNMH : SInst<"vminnm", "ddd", "hQh">; + + // Multiplication/Division + def VMULH : SOpInst<"vmul", "ddd", "hQh", OP_MUL>; + def MULXH : SInst<"vmulx", "ddd", "hQh">; + def FDIVH : IOpInst<"vdiv", "ddd", "hQh", OP_DIV>; + + // Pairwise addition + def VPADDH : SInst<"vpadd", "ddd", "hQh">; + + // Pairwise Max/Min + def VPMAXH : SInst<"vpmax", "ddd", "hQh">; + def VPMINH : SInst<"vpmin", "ddd", "hQh">; + // Pairwise MaxNum/MinNum + def FMAXNMPH : SInst<"vpmaxnm", "ddd", "hQh">; + def FMINNMPH : SInst<"vpminnm", "ddd", "hQh">; + + // Reciprocal/Sqrt + def VRECPSH : SInst<"vrecps", "ddd", "hQh">; + def VRSQRTSH : SInst<"vrsqrts", "ddd", "hQh">; + + // ARMv8.2-A FP16 three-operands vector intrinsics. + + // Vector fused multiply-add operations + def VFMAH : SInst<"vfma", "dddd", "hQh">; + def VFMSH : SOpInst<"vfms", "dddd", "hQh", OP_FMLS>; + + // ARMv8.2-A FP16 lane vector intrinsics. + + // FMA lane + def VFMA_LANEH : IInst<"vfma_lane", "dddgi", "hQh">; + def VFMA_LANEQH : IInst<"vfma_laneq", "dddji", "hQh">; + + // FMA lane with scalar argument + def FMLA_NH : SOpInst<"vfma_n", "ddds", "hQh", OP_FMLA_N>; + // Scalar floating point fused multiply-add (scalar, by element) + def SCALAR_FMLA_LANEH : IInst<"vfma_lane", "sssdi", "Sh">; + def SCALAR_FMLA_LANEQH : IInst<"vfma_laneq", "sssji", "Sh">; + + // FMS lane + def VFMS_LANEH : IOpInst<"vfms_lane", "dddgi", "hQh", OP_FMS_LN>; + def VFMS_LANEQH : IOpInst<"vfms_laneq", "dddji", "hQh", OP_FMS_LNQ>; + // FMS lane with scalar argument + def FMLS_NH : SOpInst<"vfms_n", "ddds", "hQh", OP_FMLS_N>; + // Scalar floating foint fused multiply-subtract (scalar, by element) + def SCALAR_FMLS_LANEH : IOpInst<"vfms_lane", "sssdi", "Sh", OP_FMS_LN>; + def SCALAR_FMLS_LANEQH : IOpInst<"vfms_laneq", "sssji", "Sh", OP_FMS_LNQ>; + + // Mul lane + def VMUL_LANEH : IOpInst<"vmul_lane", "ddgi", "hQh", OP_MUL_LN>; + def VMUL_LANEQH : IOpInst<"vmul_laneq", "ddji", "hQh", OP_MUL_LN>; + def VMUL_NH : IOpInst<"vmul_n", "dds", "hQh", OP_MUL_N>; + // Scalar floating point multiply (scalar, by element) + def SCALAR_FMUL_LANEH : IOpInst<"vmul_lane", "ssdi", "Sh", OP_SCALAR_MUL_LN>; + def SCALAR_FMUL_LANEQH : IOpInst<"vmul_laneq", "ssji", "Sh", OP_SCALAR_MUL_LN>; + + // Mulx lane + def VMULX_LANEH : IOpInst<"vmulx_lane", "ddgi", "hQh", OP_MULX_LN>; + def VMULX_LANEQH : IOpInst<"vmulx_laneq", "ddji", "hQh", OP_MULX_LN>; + def VMULX_NH : IOpInst<"vmulx_n", "dds", "hQh", OP_MULX_N>; + // TODO: Scalar floating point multiply extended (scalar, by element) + // Below ones are commented out because they need vmulx_f16(float16_t, float16_t) + // which will be implemented later with fp16 scalar intrinsic (arm_fp16.h) + //def SCALAR_FMULX_LANEH : IOpInst<"vmulx_lane", "ssdi", "Sh", OP_SCALAR_MUL_LN>; + //def SCALAR_FMULX_LANEQH : IOpInst<"vmulx_laneq", "ssji", "Sh", OP_SCALAR_MUL_LN>; + + // ARMv8.2-A FP16 reduction vector intrinsics. + def VMAXVH : SInst<"vmaxv", "sd", "hQh">; + def VMINVH : SInst<"vminv", "sd", "hQh">; + def FMAXNMVH : SInst<"vmaxnmv", "sd", "hQh">; + def FMINNMVH : SInst<"vminnmv", "sd", "hQh">; + + // Data processing intrinsics - section 5 + + // Logical operations + let isHiddenLInst = 1 in + def VBSLH : SInst<"vbsl", "dudd", "hQh">; + + // Transposition operations + def VZIPH : WInst<"vzip", "2dd", "hQh">; + def VUZPH : WInst<"vuzp", "2dd", "hQh">; + def VTRNH : WInst<"vtrn", "2dd", "hQh">; + + // Set all lanes to same value. + /* Already implemented prior to ARMv8.2-A. + def VMOV_NH : WOpInst<"vmov_n", "ds", "hQh", OP_DUP>; + def VDUP_NH : WOpInst<"vdup_n", "ds", "hQh", OP_DUP>; + def VDUP_LANE1H : WOpInst<"vdup_lane", "dgi", "hQh", OP_DUP_LN>;*/ + + // Vector Extract + def VEXTH : WInst<"vext", "dddi", "hQh">; + + // Reverse vector elements + def VREV64H : WOpInst<"vrev64", "dd", "hQh", OP_REV64>; + + // Permutation + def VTRN1H : SOpInst<"vtrn1", "ddd", "hQh", OP_TRN1>; + def VZIP1H : SOpInst<"vzip1", "ddd", "hQh", OP_ZIP1>; + def VUZP1H : SOpInst<"vuzp1", "ddd", "hQh", OP_UZP1>; + def VTRN2H : SOpInst<"vtrn2", "ddd", "hQh", OP_TRN2>; + def VZIP2H : SOpInst<"vzip2", "ddd", "hQh", OP_ZIP2>; + def VUZP2H : SOpInst<"vuzp2", "ddd", "hQh", OP_UZP2>; + + def SCALAR_VDUP_LANEH : IInst<"vdup_lane", "sdi", "Sh">; + def SCALAR_VDUP_LANEQH : IInst<"vdup_laneq", "sji", "Sh">; +} diff --git a/include/clang/Frontend/PrecompiledPreamble.h b/include/clang/Frontend/PrecompiledPreamble.h index 64342b1..130fe60 100644 --- a/include/clang/Frontend/PrecompiledPreamble.h +++ b/include/clang/Frontend/PrecompiledPreamble.h @@ -19,6 +19,7 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/MD5.h" +#include #include #include #include @@ -89,6 +90,11 @@ public: /// PreambleBounds used to build the preamble. PreambleBounds getBounds() const; + /// Returns the size, in bytes, that preamble takes on disk or in memory. + /// For on-disk preambles returns 0 if filesystem operations fail. Intended to + /// be used for logging and debugging purposes only. + std::size_t getSize() const; + /// Check whether PrecompiledPreamble can be reused for the new contents(\p /// MainFileBuffer) of the main file. bool CanReuse(const CompilerInvocation &Invocation, @@ -244,6 +250,11 @@ class PreambleCallbacks { public: virtual ~PreambleCallbacks() = default; + /// Called before FrontendAction::BeginSourceFile. + /// Can be used to store references to various CompilerInstance fields + /// (e.g. SourceManager) that may be interesting to the consumers of other + /// callbacks. + virtual void BeforeExecute(CompilerInstance &CI); /// Called after FrontendAction::Execute(), but before /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of /// various CompilerInstance fields before they are destroyed. diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h index ae59136..08f2839 100644 --- a/include/clang/Index/IndexSymbol.h +++ b/include/clang/Index/IndexSymbol.h @@ -56,7 +56,7 @@ enum class SymbolKind : uint8_t { Using, }; -enum class SymbolLanguage { +enum class SymbolLanguage : uint8_t { C, ObjC, CXX, @@ -64,7 +64,7 @@ enum class SymbolLanguage { }; /// Language specific sub-kinds. -enum class SymbolSubKind { +enum class SymbolSubKind : uint8_t { None, CXXCopyConstructor, CXXMoveConstructor, @@ -74,8 +74,9 @@ enum class SymbolSubKind { UsingValue, }; +typedef uint8_t SymbolPropertySet; /// Set of properties that provide additional info about a symbol. -enum class SymbolProperty : uint8_t { +enum class SymbolProperty : SymbolPropertySet { Generic = 1 << 0, TemplatePartialSpecialization = 1 << 1, TemplateSpecialization = 1 << 2, @@ -86,7 +87,6 @@ enum class SymbolProperty : uint8_t { Local = 1 << 7, }; static const unsigned SymbolPropertyBitNum = 8; -typedef unsigned SymbolPropertySet; /// Set of roles that are attributed to symbol occurrences. enum class SymbolRole : uint32_t { @@ -127,8 +127,8 @@ struct SymbolRelation { struct SymbolInfo { SymbolKind Kind; SymbolSubKind SubKind; - SymbolPropertySet Properties; SymbolLanguage Lang; + SymbolPropertySet Properties; }; SymbolInfo getSymbolInfo(const Decl *D); diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 396b5a9..8f5b20c 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -2748,10 +2748,10 @@ private: bool ParseTemplateParameterList(unsigned Depth, SmallVectorImpl &TemplateParams); bool isStartOfTemplateTypeParameter(); - Decl *ParseTemplateParameter(unsigned Depth, unsigned Position); - Decl *ParseTypeParameter(unsigned Depth, unsigned Position); - Decl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position); - Decl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position); + NamedDecl *ParseTemplateParameter(unsigned Depth, unsigned Position); + NamedDecl *ParseTypeParameter(unsigned Depth, unsigned Position); + NamedDecl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position); + NamedDecl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position); void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc, SourceLocation CorrectLoc, bool AlreadyHasEllipsis, diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 47cea30..9cbe8e5 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -6064,7 +6064,7 @@ public: void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl); TemplateDecl *AdjustDeclIfTemplate(Decl *&Decl); - Decl *ActOnTypeParameter(Scope *S, bool Typename, + NamedDecl *ActOnTypeParameter(Scope *S, bool Typename, SourceLocation EllipsisLoc, SourceLocation KeyLoc, IdentifierInfo *ParamName, @@ -6077,12 +6077,12 @@ public: SourceLocation Loc); QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc); - Decl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, + NamedDecl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, unsigned Depth, unsigned Position, SourceLocation EqualLoc, Expr *DefaultArg); - Decl *ActOnTemplateTemplateParameter(Scope *S, + NamedDecl *ActOnTemplateTemplateParameter(Scope *S, SourceLocation TmpLoc, TemplateParameterList *Params, SourceLocation EllipsisLoc, diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 7b71fee..37920fc 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1092,6 +1092,10 @@ private: llvm::SmallDenseMap, 2> PendingOdrMergeFailures; + /// \brief Function definitions in which we found an ODR violation. + llvm::SmallDenseMap, 2> + PendingFunctionOdrMergeFailures; + /// \brief DeclContexts in which we have diagnosed an ODR violation. llvm::SmallPtrSet DiagnosedOdrMergeFailures; diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index a07cd88..f31ab2c 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -334,7 +334,7 @@ public: // Path "pieces" for path-sensitive diagnostics. //===----------------------------------------------------------------------===// -class PathDiagnosticPiece { +class PathDiagnosticPiece: public llvm::FoldingSetNode { public: enum Kind { ControlFlow, Event, Macro, Call, Note }; enum DisplayHint { Above, Below }; diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 157b29f..92be6d9 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -99,6 +99,9 @@ namespace { const CommandTraits *Traits; const SourceManager *SM; + /// The policy to use for printing; can be defaulted. + PrintingPolicy PrintPolicy; + /// Pending[i] is an action to dump an entity at level i. llvm::SmallVector, 32> Pending; @@ -207,12 +210,17 @@ namespace { public: ASTDumper(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM) - : OS(OS), Traits(Traits), SM(SM), - ShowColors(SM && SM->getDiagnostics().getShowColors()) { } + : ASTDumper(OS, Traits, SM, + SM && SM->getDiagnostics().getShowColors()) {} ASTDumper(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM, bool ShowColors) - : OS(OS), Traits(Traits), SM(SM), ShowColors(ShowColors) {} + : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {} + ASTDumper(raw_ostream &OS, const CommandTraits *Traits, + const SourceManager *SM, bool ShowColors, + const PrintingPolicy &PrintPolicy) + : OS(OS), Traits(Traits), SM(SM), PrintPolicy(PrintPolicy), + ShowColors(ShowColors) {} void setDeserialize(bool D) { Deserialize = D; } @@ -646,13 +654,13 @@ void ASTDumper::dumpBareType(QualType T, bool Desugar) { ColorScope Color(*this, TypeColor); SplitQualType T_split = T.split(); - OS << "'" << QualType::getAsString(T_split) << "'"; + OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'"; if (Desugar && !T.isNull()) { // If the type is sugared, also dump a (shallow) desugared type. SplitQualType D_split = T.getSplitDesugaredType(); if (T_split != D_split) - OS << ":'" << QualType::getAsString(D_split) << "'"; + OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'"; } } @@ -1187,12 +1195,12 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { if (const CXXMethodDecl *MD = dyn_cast(D)) { if (MD->size_overridden_methods() != 0) { - auto dumpOverride = - [=](const CXXMethodDecl *D) { - SplitQualType T_split = D->getType().split(); - OS << D << " " << D->getParent()->getName() << "::" - << D->getNameAsString() << " '" << QualType::getAsString(T_split) << "'"; - }; + auto dumpOverride = [=](const CXXMethodDecl *D) { + SplitQualType T_split = D->getType().split(); + OS << D << " " << D->getParent()->getName() + << "::" << D->getNameAsString() << " '" + << QualType::getAsString(T_split, PrintPolicy) << "'"; + }; dumpChild([=] { auto Overrides = MD->overridden_methods(); @@ -1537,7 +1545,7 @@ void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D, case TSK_ExplicitInstantiationDefinition: if (!DumpExplicitInst) break; - // Fall through. + LLVM_FALLTHROUGH; case TSK_Undeclared: case TSK_ImplicitInstantiation: if (DumpRefOnly) @@ -2682,15 +2690,19 @@ LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const { LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); } LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize) const { - ASTDumper P(OS, &getASTContext().getCommentCommandTraits(), - &getASTContext().getSourceManager()); + const ASTContext &Ctx = getASTContext(); + const SourceManager &SM = Ctx.getSourceManager(); + ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM, + SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy()); P.setDeserialize(Deserialize); P.dumpDecl(this); } LLVM_DUMP_METHOD void Decl::dumpColor() const { - ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(), - &getASTContext().getSourceManager(), /*ShowColors*/true); + const ASTContext &Ctx = getASTContext(); + ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(), + &Ctx.getSourceManager(), /*ShowColors*/ true, + Ctx.getPrintingPolicy()); P.dumpDecl(this); } @@ -2705,7 +2717,9 @@ LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS, while (!DC->isTranslationUnit()) DC = DC->getParent(); ASTContext &Ctx = cast(DC)->getASTContext(); - ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager()); + const SourceManager &SM = Ctx.getSourceManager(); + ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(), + SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy()); P.setDeserialize(Deserialize); P.dumpLookups(this, DumpDecls); } diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 84b0d7e..0e627f9 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -134,17 +134,12 @@ namespace clang { bool ImportTemplateArguments(const TemplateArgument *FromArgs, unsigned NumFromArgs, SmallVectorImpl &ToArgs); - template - bool ImportTemplateArgumentListInfo(const InContainerTy &Container, - TemplateArgumentListInfo &ToTAInfo); bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain = true); bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, bool Complain = true); bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord); bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC); - bool IsStructuralMatch(FunctionTemplateDecl *From, - FunctionTemplateDecl *To); bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); Decl *VisitDecl(Decl *D); @@ -200,7 +195,6 @@ namespace clang { ClassTemplateSpecializationDecl *D); Decl *VisitVarTemplateDecl(VarTemplateDecl *D); Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D); - Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); // Importing statements DeclGroupRef ImportDeclGroup(DeclGroupRef DG); @@ -286,7 +280,6 @@ namespace clang { Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E); Expr *VisitCXXConstructExpr(CXXConstructExpr *E); Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); - Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); Expr *VisitCXXThisExpr(CXXThisExpr *E); Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); @@ -1254,18 +1247,6 @@ bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs, return false; } -template -bool ASTNodeImporter::ImportTemplateArgumentListInfo( - const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) { - for (const auto &FromLoc : Container) { - if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc)) - ToTAInfo.addArgument(*ToLoc); - else - return true; - } - return false; -} - bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain) { // Eliminate a potential failure point where we attempt to re-import @@ -1299,14 +1280,6 @@ bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) { return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum); } -bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From, - FunctionTemplateDecl *To) { - StructuralEquivalenceContext Ctx( - Importer.getFromContext(), Importer.getToContext(), - Importer.getNonEquivalentDecls(), false, false); - return Ctx.IsStructurallyEquivalent(From, To); -} - bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC) { @@ -4224,64 +4197,6 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl( return D2; } -Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { - DeclContext *DC, *LexicalDC; - DeclarationName Name; - SourceLocation Loc; - NamedDecl *ToD; - - if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) - return nullptr; - - if (ToD) - return ToD; - - // Try to find a function in our own ("to") context with the same name, same - // type, and in the same context as the function we're importing. - if (!LexicalDC->isFunctionOrMethod()) { - unsigned IDNS = Decl::IDNS_Ordinary; - SmallVector FoundDecls; - DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); - for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { - if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) - continue; - - if (FunctionTemplateDecl *FoundFunction = - dyn_cast(FoundDecls[I])) { - if (FoundFunction->hasExternalFormalLinkage() && - D->hasExternalFormalLinkage()) { - if (IsStructuralMatch(D, FoundFunction)) { - Importer.Imported(D, FoundFunction); - // FIXME: Actually try to merge the body and other attributes. - return FoundFunction; - } - } - } - } - } - - TemplateParameterList *Params = - ImportTemplateParameterList(D->getTemplateParameters()); - if (!Params) - return nullptr; - - FunctionDecl *TemplatedFD = - cast_or_null(Importer.Import(D->getTemplatedDecl())); - if (!TemplatedFD) - return nullptr; - - FunctionTemplateDecl *ToFunc = FunctionTemplateDecl::Create( - Importer.getToContext(), DC, Loc, Name, Params, TemplatedFD); - - TemplatedFD->setDescribedFunctionTemplate(ToFunc); - ToFunc->setAccess(D->getAccess()); - ToFunc->setLexicalDeclContext(LexicalDC); - Importer.Imported(D, ToFunc); - - LexicalDC->addDeclInternal(ToFunc); - return ToFunc; -} - //---------------------------------------------------------------------------- // Import Statements //---------------------------------------------------------------------------- @@ -5844,47 +5759,6 @@ Expr *ASTNodeImporter::VisitCXXPseudoDestructorExpr( Importer.Import(E->getTildeLoc()), Storage); } -Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr( - CXXDependentScopeMemberExpr *E) { - Expr *Base = nullptr; - if (!E->isImplicitAccess()) { - Base = Importer.Import(E->getBase()); - if (!Base) - return nullptr; - } - - QualType BaseType = Importer.Import(E->getBaseType()); - if (BaseType.isNull()) - return nullptr; - - TemplateArgumentListInfo ToTAInfo(Importer.Import(E->getLAngleLoc()), - Importer.Import(E->getRAngleLoc())); - TemplateArgumentListInfo *ResInfo = nullptr; - if (E->hasExplicitTemplateArgs()) { - if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo)) - return nullptr; - ResInfo = &ToTAInfo; - } - - DeclarationName Name = Importer.Import(E->getMember()); - if (!E->getMember().isEmpty() && Name.isEmpty()) - return nullptr; - - DeclarationNameInfo MemberNameInfo(Name, Importer.Import(E->getMemberLoc())); - // Import additional name location/type info. - ImportDeclarationNameLoc(E->getMemberNameInfo(), MemberNameInfo); - auto ToFQ = Importer.Import(E->getFirstQualifierFoundInScope()); - if (!ToFQ && E->getFirstQualifierFoundInScope()) - return nullptr; - - return CXXDependentScopeMemberExpr::Create( - Importer.getToContext(), Base, BaseType, E->isArrow(), - Importer.Import(E->getOperatorLoc()), - Importer.Import(E->getQualifierLoc()), - Importer.Import(E->getTemplateKeywordLoc()), - cast_or_null(ToFQ), MemberNameInfo, ResInfo); -} - Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 2f51ec3..629037b 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -26,6 +26,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/ODRHash.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/Redeclarable.h" #include "clang/AST/Stmt.h" @@ -1548,7 +1549,10 @@ void NamedDecl::printQualifiedName(raw_ostream &OS, // enumerator is declared in the scope that immediately contains // the enum-specifier. Each scoped enumerator is declared in the // scope of the enumeration. - if (ED->isScoped() || ED->getIdentifier()) + // For the case of unscoped enumerator, do not include in the qualified + // name any information about its enum enclosing scope, as is visibility + // is global. + if (ED->isScoped()) OS << *ED; else continue; @@ -3601,6 +3605,25 @@ unsigned FunctionDecl::getMemoryFunctionKind() const { return 0; } +unsigned FunctionDecl::getODRHash() { + if (HasODRHash) + return ODRHash; + + if (FunctionDecl *Definition = getDefinition()) { + if (Definition != this) { + HasODRHash = true; + ODRHash = Definition->getODRHash(); + return ODRHash; + } + } + + class ODRHash Hash; + Hash.AddFunctionDecl(this); + HasODRHash = true; + ODRHash = Hash.CalculateHash(); + return ODRHash; +} + //===----------------------------------------------------------------------===// // FieldDecl Implementation //===----------------------------------------------------------------------===// diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 55061aa..7ddab93 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -3116,7 +3116,8 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, if (DCE->getTypeAsWritten()->isReferenceType() && DCE->getCastKind() == CK_Dynamic) return true; - } // Fall through. + } + LLVM_FALLTHROUGH; case ImplicitCastExprClass: case CStyleCastExprClass: case CXXStaticCastExprClass: diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 262a1e3..a0d6113 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -857,7 +857,7 @@ LambdaCapture::LambdaCapture(SourceLocation Loc, bool Implicit, switch (Kind) { case LCK_StarThis: Bits |= Capture_ByCopy; - // Fall through + LLVM_FALLTHROUGH; case LCK_This: assert(!Var && "'this' capture cannot have a variable!"); Bits |= Capture_This; @@ -865,7 +865,7 @@ LambdaCapture::LambdaCapture(SourceLocation Loc, bool Implicit, case LCK_ByCopy: Bits |= Capture_ByCopy; - // Fall through + LLVM_FALLTHROUGH; case LCK_ByRef: assert(Var && "capture must have a variable!"); break; diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 9c9eeb7..8d9b3c3 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -5913,7 +5913,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'"); else Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr); - // Fall through. + LLVM_FALLTHROUGH; case Builtin::BI__builtin_strchr: case Builtin::BI__builtin_wcschr: case Builtin::BI__builtin_memchr: @@ -5952,7 +5952,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, Desired)) return ZeroInitialization(E); StopAtNull = true; - // Fall through. + LLVM_FALLTHROUGH; case Builtin::BImemchr: case Builtin::BI__builtin_memchr: case Builtin::BI__builtin_char_memchr: @@ -5965,7 +5965,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, case Builtin::BIwcschr: case Builtin::BI__builtin_wcschr: StopAtNull = true; - // Fall through. + LLVM_FALLTHROUGH; case Builtin::BIwmemchr: case Builtin::BI__builtin_wmemchr: // wcschr and wmemchr are given a wchar_t to look for. Just use it. @@ -7209,6 +7209,7 @@ static int EvaluateBuiltinClassifyType(const CallExpr *E, case BuiltinType::Dependent: llvm_unreachable("CallExpr::isBuiltinClassifyType(): unimplemented type"); }; + break; case Type::Enum: return LangOpts.CPlusPlus ? enumeral_type_class : integer_type_class; @@ -7419,7 +7420,10 @@ static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) { // If we don't know the array bound, conservatively assume we're looking at // the final array element. ++I; - BaseType = BaseType->castAs()->getPointeeType(); + if (BaseType->isIncompleteArrayType()) + BaseType = Ctx.getAsArrayType(BaseType)->getElementType(); + else + BaseType = BaseType->castAs()->getPointeeType(); } for (unsigned E = LVal.Designator.Entries.size(); I != E; ++I) { @@ -7821,7 +7825,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'"); else Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr); - // Fall through. + LLVM_FALLTHROUGH; case Builtin::BI__builtin_strlen: case Builtin::BI__builtin_wcslen: { // As an extension, we support __builtin_strlen() as a constant expression, @@ -7881,7 +7885,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'"); else Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr); - // Fall through. + LLVM_FALLTHROUGH; case Builtin::BI__builtin_strcmp: case Builtin::BI__builtin_wcscmp: case Builtin::BI__builtin_strncmp: diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index f95dc84..3c7e26d 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -1468,7 +1468,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, if (!MD->isStatic()) Arity++; } - // FALLTHROUGH + LLVM_FALLTHROUGH; case DeclarationName::CXXConversionFunctionName: case DeclarationName::CXXLiteralOperatorName: mangleOperatorName(Name, Arity); diff --git a/lib/AST/ODRHash.cpp b/lib/AST/ODRHash.cpp index 17c95f2..088d8be 100644 --- a/lib/AST/ODRHash.cpp +++ b/lib/AST/ODRHash.cpp @@ -466,8 +466,42 @@ void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) { } } +void ODRHash::AddFunctionDecl(const FunctionDecl *Function) { + assert(Function && "Expecting non-null pointer."); + + // Skip hashing these kinds of function. + if (Function->isImplicit()) return; + if (Function->isDefaulted()) return; + if (Function->isDeleted()) return; + if (!Function->hasBody()) return; + if (!Function->getBody()) return; + + // TODO: Fix hashing for class methods. + if (isa(Function)) return; + + // Skip functions that are specializations or in specialization context. + const DeclContext *DC = Function; + while (DC) { + if (isa(DC)) return; + if (auto *F = dyn_cast(DC)) + if (F->isFunctionTemplateSpecialization()) return; + DC = DC->getParent(); + } + + AddDecl(Function); + + AddQualType(Function->getReturnType()); + + ID.AddInteger(Function->param_size()); + for (auto Param : Function->parameters()) + AddSubDecl(Param); + + AddStmt(Function->getBody()); +} + void ODRHash::AddDecl(const Decl *D) { assert(D && "Expecting non-null pointer."); + D = D->getCanonicalDecl(); auto Result = DeclMap.insert(std::make_pair(D, DeclMap.size())); ID.AddInteger(Result.first->second); // On first encounter of a Decl pointer, process it. Every time afterwards, diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index b05c5fc..0ac50b3 100644 --- a/lib/AST/TypeLoc.cpp +++ b/lib/AST/TypeLoc.cpp @@ -201,7 +201,7 @@ SourceLocation TypeLoc::getBeginLoc() const { LeftMost = Cur; break; } - /* Fall through */ + LLVM_FALLTHROUGH; case FunctionNoProto: case ConstantArray: case DependentSizedArray: diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index 35e0b75..c28ada7 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -213,7 +213,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T, case Type::VariableArray: case Type::DependentSizedArray: NeedARCStrongQualifier = true; - // Fall through + LLVM_FALLTHROUGH; case Type::Adjusted: case Type::Decayed: @@ -1712,16 +1712,20 @@ void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy, OS << ' '; } +std::string QualType::getAsString() const { + return getAsString(split(), LangOptions()); +} + std::string QualType::getAsString(const PrintingPolicy &Policy) const { std::string S; getAsStringInternal(S, Policy); return S; } -std::string QualType::getAsString(const Type *ty, Qualifiers qs) { +std::string QualType::getAsString(const Type *ty, Qualifiers qs, + const PrintingPolicy &Policy) { std::string buffer; - LangOptions options; - getAsStringInternal(ty, qs, buffer, PrintingPolicy(options)); + getAsStringInternal(ty, qs, buffer, Policy); return buffer; } diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index 640b42c..26baa83 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -363,7 +363,7 @@ void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor, diag::Severity Map, SourceLocation Loc) { // Get all the diagnostics. - SmallVector AllDiags; + std::vector AllDiags; DiagnosticIDs::getAllDiagnostics(Flavor, AllDiags); // Set the mapping. diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp index 5c53f35..c4c425d 100644 --- a/lib/Basic/DiagnosticIDs.cpp +++ b/lib/Basic/DiagnosticIDs.cpp @@ -583,7 +583,7 @@ DiagnosticIDs::getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group, } void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor, - SmallVectorImpl &Diags) { + std::vector &Diags) { for (unsigned i = 0; i != StaticDiagInfoSize; ++i) if (StaticDiagInfo[i].getFlavor() == Flavor) Diags.push_back(StaticDiagInfo[i].DiagID); diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index e664879..0a51985 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -125,11 +125,12 @@ llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag, // possible. if (!BufferOrError) { StringRef FillStr("<<>>\n"); - Buffer.setPointer(MemoryBuffer::getNewUninitMemBuffer( - ContentsEntry->getSize(), "").release()); - char *Ptr = const_cast(Buffer.getPointer()->getBufferStart()); + auto BackupBuffer = llvm::WritableMemoryBuffer::getNewUninitMemBuffer( + ContentsEntry->getSize(), ""); + char *Ptr = BackupBuffer->getBufferStart(); for (unsigned i = 0, e = ContentsEntry->getSize(); i != e; ++i) Ptr[i] = FillStr[i % FillStr.size()]; + Buffer.setPointer(BackupBuffer.release()); if (Diag.isDiagnosticInFlight()) Diag.SetDelayedDiagnostic(diag::err_cannot_open_file, diff --git a/lib/Basic/Targets/AArch64.cpp b/lib/Basic/Targets/AArch64.cpp index 62990dc..6080cef 100644 --- a/lib/Basic/Targets/AArch64.cpp +++ b/lib/Basic/Targets/AArch64.cpp @@ -181,6 +181,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (Unaligned) Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); + if ((FPU & NeonMode) && HasFullFP16) + Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); + switch (ArchKind) { default: break; diff --git a/lib/Basic/Targets/X86.cpp b/lib/Basic/Targets/X86.cpp index 7fd9fd0..bdf5cdb 100644 --- a/lib/Basic/Targets/X86.cpp +++ b/lib/Basic/Targets/X86.cpp @@ -159,6 +159,7 @@ bool X86TargetInfo::initFeatureMap( case CK_Broadwell: setFeatureEnabledImpl(Features, "rdseed", true); setFeatureEnabledImpl(Features, "adx", true); + setFeatureEnabledImpl(Features, "prfchw", true); LLVM_FALLTHROUGH; case CK_Haswell: setFeatureEnabledImpl(Features, "avx2", true); @@ -224,6 +225,7 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "aes", true); setFeatureEnabledImpl(Features, "pclmul", true); setFeatureEnabledImpl(Features, "sse4.2", true); + setFeatureEnabledImpl(Features, "prfchw", true); LLVM_FALLTHROUGH; case CK_Bonnell: setFeatureEnabledImpl(Features, "movbe", true); @@ -241,6 +243,7 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "avx512cd", true); setFeatureEnabledImpl(Features, "avx512er", true); setFeatureEnabledImpl(Features, "avx512pf", true); + setFeatureEnabledImpl(Features, "prfchw", true); setFeatureEnabledImpl(Features, "prefetchwt1", true); setFeatureEnabledImpl(Features, "fxsr", true); setFeatureEnabledImpl(Features, "rdseed", true); @@ -1131,6 +1134,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { return llvm::StringSwitch(Name) .Case("3dnow", true) .Case("3dnowa", true) + .Case("adx", true) .Case("aes", true) .Case("avx", true) .Case("avx2", true) @@ -1160,6 +1164,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("mmx", true) .Case("movbe", true) .Case("mpx", true) + .Case("mwaitx", true) .Case("pclmul", true) .Case("pku", true) .Case("popcnt", true) @@ -1170,6 +1175,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("rtm", true) .Case("sgx", true) .Case("sha", true) + .Case("shstk", true) .Case("sse", true) .Case("sse2", true) .Case("sse3", true) @@ -1190,6 +1196,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { bool X86TargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch(Feature) + .Case("adx", HasADX) .Case("aes", HasAES) .Case("avx", SSELevel >= AVX) .Case("avx2", SSELevel >= AVX2) @@ -1214,6 +1221,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("fma4", XOPLevel >= FMA4) .Case("fsgsbase", HasFSGSBASE) .Case("fxsr", HasFXSR) + .Case("ibt", HasIBT) .Case("lwp", HasLWP) .Case("lzcnt", HasLZCNT) .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow) @@ -1221,8 +1229,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("mmx", MMX3DNowLevel >= MMX) .Case("movbe", HasMOVBE) .Case("mpx", HasMPX) - .Case("shstk", HasSHSTK) - .Case("ibt", HasIBT) + .Case("mwaitx", HasMWAITX) .Case("pclmul", HasPCLMUL) .Case("pku", HasPKU) .Case("popcnt", HasPOPCNT) @@ -1233,6 +1240,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("rtm", HasRTM) .Case("sgx", HasSGX) .Case("sha", HasSHA) + .Case("shstk", HasSHSTK) .Case("sse", SSELevel >= SSE1) .Case("sse2", SSELevel >= SSE2) .Case("sse3", SSELevel >= SSE3) diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index 2c033e0..e2349da 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -239,7 +239,11 @@ static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, static void addHWAddressSanitizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createHWAddressSanitizerPass()); + const PassManagerBuilderWrapper &BuilderWrapper = + static_cast(Builder); + const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); + bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::HWAddress); + PM.add(createHWAddressSanitizerPass(Recover)); } static void addMemorySanitizerPass(const PassManagerBuilder &Builder, diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp index d90c3a5..6862fd8 100644 --- a/lib/CodeGen/CGAtomic.cpp +++ b/lib/CodeGen/CGAtomic.cpp @@ -573,7 +573,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, case AtomicExpr::AO__atomic_add_fetch: PostOp = llvm::Instruction::Add; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_add: case AtomicExpr::AO__opencl_atomic_fetch_add: case AtomicExpr::AO__atomic_fetch_add: @@ -582,7 +582,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, case AtomicExpr::AO__atomic_sub_fetch: PostOp = llvm::Instruction::Sub; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_sub: case AtomicExpr::AO__opencl_atomic_fetch_sub: case AtomicExpr::AO__atomic_fetch_sub: @@ -601,7 +601,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, case AtomicExpr::AO__atomic_and_fetch: PostOp = llvm::Instruction::And; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_and: case AtomicExpr::AO__opencl_atomic_fetch_and: case AtomicExpr::AO__atomic_fetch_and: @@ -610,7 +610,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, case AtomicExpr::AO__atomic_or_fetch: PostOp = llvm::Instruction::Or; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_or: case AtomicExpr::AO__opencl_atomic_fetch_or: case AtomicExpr::AO__atomic_fetch_or: @@ -619,7 +619,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, case AtomicExpr::AO__atomic_xor_fetch: PostOp = llvm::Instruction::Xor; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_xor: case AtomicExpr::AO__opencl_atomic_fetch_xor: case AtomicExpr::AO__atomic_fetch_xor: @@ -628,7 +628,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, case AtomicExpr::AO__atomic_nand_fetch: PostOp = llvm::Instruction::And; // the NOT is special cased below - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__atomic_fetch_nand: Op = llvm::AtomicRMWInst::Nand; break; @@ -828,7 +828,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { EmitStoreOfScalar(Val1Scalar, MakeAddrLValue(Temp, Val1Ty)); break; } - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__atomic_fetch_add: case AtomicExpr::AO__atomic_fetch_sub: case AtomicExpr::AO__atomic_add_fetch: @@ -1035,7 +1035,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { // T __atomic_fetch_add_N(T *mem, T val, int order) case AtomicExpr::AO__atomic_add_fetch: PostOp = llvm::Instruction::Add; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_add: case AtomicExpr::AO__opencl_atomic_fetch_add: case AtomicExpr::AO__atomic_fetch_add: @@ -1047,7 +1047,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { // T __atomic_fetch_and_N(T *mem, T val, int order) case AtomicExpr::AO__atomic_and_fetch: PostOp = llvm::Instruction::And; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_and: case AtomicExpr::AO__opencl_atomic_fetch_and: case AtomicExpr::AO__atomic_fetch_and: @@ -1059,7 +1059,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { // T __atomic_fetch_or_N(T *mem, T val, int order) case AtomicExpr::AO__atomic_or_fetch: PostOp = llvm::Instruction::Or; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_or: case AtomicExpr::AO__opencl_atomic_fetch_or: case AtomicExpr::AO__atomic_fetch_or: @@ -1071,7 +1071,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { // T __atomic_fetch_sub_N(T *mem, T val, int order) case AtomicExpr::AO__atomic_sub_fetch: PostOp = llvm::Instruction::Sub; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_sub: case AtomicExpr::AO__opencl_atomic_fetch_sub: case AtomicExpr::AO__atomic_fetch_sub: @@ -1083,7 +1083,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { // T __atomic_fetch_xor_N(T *mem, T val, int order) case AtomicExpr::AO__atomic_xor_fetch: PostOp = llvm::Instruction::Xor; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_xor: case AtomicExpr::AO__opencl_atomic_fetch_xor: case AtomicExpr::AO__atomic_fetch_xor: @@ -1109,7 +1109,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { // T __atomic_fetch_nand_N(T *mem, T val, int order) case AtomicExpr::AO__atomic_nand_fetch: PostOp = llvm::Instruction::And; // the NOT is special cased below - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__atomic_fetch_nand: LibCallName = "__atomic_fetch_nand"; AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 3ecd1c6..609987c 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -1432,14 +1432,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, case Builtin::BI__debugbreak: return RValue::get(EmitTrapCall(Intrinsic::debugtrap)); case Builtin::BI__builtin_unreachable: { - if (SanOpts.has(SanitizerKind::Unreachable)) { - SanitizerScope SanScope(this); - EmitCheck(std::make_pair(static_cast(Builder.getFalse()), - SanitizerKind::Unreachable), - SanitizerHandler::BuiltinUnreachable, - EmitCheckSourceLocation(E->getExprLoc()), None); - } else - Builder.CreateUnreachable(); + EmitUnreachable(E->getExprLoc()); // We do need to preserve an insertion point. EmitBlock(createBasicBlock("unreachable.cont")); @@ -3341,10 +3334,10 @@ static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF, case llvm::Triple::armeb: case llvm::Triple::thumb: case llvm::Triple::thumbeb: - return CGF->EmitARMBuiltinExpr(BuiltinID, E); + return CGF->EmitARMBuiltinExpr(BuiltinID, E, Arch); case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: - return CGF->EmitAArch64BuiltinExpr(BuiltinID, E); + return CGF->EmitAArch64BuiltinExpr(BuiltinID, E, Arch); case llvm::Triple::x86: case llvm::Triple::x86_64: return CGF->EmitX86BuiltinExpr(BuiltinID, E); @@ -3385,6 +3378,7 @@ Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, static llvm::VectorType *GetNeonType(CodeGenFunction *CGF, NeonTypeFlags TypeFlags, + llvm::Triple::ArchType Arch, bool V1Ty=false) { int IsQuad = TypeFlags.isQuad(); switch (TypeFlags.getEltType()) { @@ -3393,8 +3387,14 @@ static llvm::VectorType *GetNeonType(CodeGenFunction *CGF, return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad)); case NeonTypeFlags::Int16: case NeonTypeFlags::Poly16: - case NeonTypeFlags::Float16: return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad)); + case NeonTypeFlags::Float16: + // FIXME: Only AArch64 backend can so far properly handle half types. + // Remove else part once ARM backend support for half is complete. + if (Arch == llvm::Triple::aarch64) + return llvm::VectorType::get(CGF->HalfTy, V1Ty ? 1 : (4 << IsQuad)); + else + return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad)); case NeonTypeFlags::Int32: return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad)); case NeonTypeFlags::Int64: @@ -3417,6 +3417,8 @@ static llvm::VectorType *GetFloatNeonType(CodeGenFunction *CGF, NeonTypeFlags IntTypeFlags) { int IsQuad = IntTypeFlags.isQuad(); switch (IntTypeFlags.getEltType()) { + case NeonTypeFlags::Int16: + return llvm::VectorType::get(CGF->HalfTy, (4 << IsQuad)); case NeonTypeFlags::Int32: return llvm::VectorType::get(CGF->FloatTy, (2 << IsQuad)); case NeonTypeFlags::Int64: @@ -3564,55 +3566,80 @@ static const NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = { NEONMAP1(vcvt_f16_f32, arm_neon_vcvtfp2hf, 0), NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0), NEONMAP0(vcvt_f32_v), + NEONMAP2(vcvt_n_f16_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), + NEONMAP1(vcvt_n_s16_v, arm_neon_vcvtfp2fxs, 0), NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0), NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0), + NEONMAP1(vcvt_n_u16_v, arm_neon_vcvtfp2fxu, 0), NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0), NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0), + NEONMAP0(vcvt_s16_v), NEONMAP0(vcvt_s32_v), NEONMAP0(vcvt_s64_v), + NEONMAP0(vcvt_u16_v), NEONMAP0(vcvt_u32_v), NEONMAP0(vcvt_u64_v), + NEONMAP1(vcvta_s16_v, arm_neon_vcvtas, 0), NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0), NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0), NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0), NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0), + NEONMAP1(vcvtaq_s16_v, arm_neon_vcvtas, 0), NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0), NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0), + NEONMAP1(vcvtaq_u16_v, arm_neon_vcvtau, 0), NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0), NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0), + NEONMAP1(vcvtm_s16_v, arm_neon_vcvtms, 0), NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0), NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0), + NEONMAP1(vcvtm_u16_v, arm_neon_vcvtmu, 0), NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0), NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0), + NEONMAP1(vcvtmq_s16_v, arm_neon_vcvtms, 0), NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0), NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0), + NEONMAP1(vcvtmq_u16_v, arm_neon_vcvtmu, 0), NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0), NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0), + NEONMAP1(vcvtn_s16_v, arm_neon_vcvtns, 0), NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0), NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0), + NEONMAP1(vcvtn_u16_v, arm_neon_vcvtnu, 0), NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0), NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0), + NEONMAP1(vcvtnq_s16_v, arm_neon_vcvtns, 0), NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0), NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0), + NEONMAP1(vcvtnq_u16_v, arm_neon_vcvtnu, 0), NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0), NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0), + NEONMAP1(vcvtp_s16_v, arm_neon_vcvtps, 0), NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0), NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0), + NEONMAP1(vcvtp_u16_v, arm_neon_vcvtpu, 0), NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0), NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0), + NEONMAP1(vcvtpq_s16_v, arm_neon_vcvtps, 0), NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0), NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0), + NEONMAP1(vcvtpq_u16_v, arm_neon_vcvtpu, 0), NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0), NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0), NEONMAP0(vcvtq_f32_v), + NEONMAP2(vcvtq_n_f16_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), + NEONMAP1(vcvtq_n_s16_v, arm_neon_vcvtfp2fxs, 0), NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0), NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0), + NEONMAP1(vcvtq_n_u16_v, arm_neon_vcvtfp2fxu, 0), NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0), NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0), + NEONMAP0(vcvtq_s16_v), NEONMAP0(vcvtq_s32_v), NEONMAP0(vcvtq_s64_v), + NEONMAP0(vcvtq_u16_v), NEONMAP0(vcvtq_u32_v), NEONMAP0(vcvtq_u64_v), NEONMAP0(vext_v), @@ -3775,19 +3802,27 @@ static const NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = { NEONMAP1(vcnt_v, ctpop, Add1ArgType), NEONMAP1(vcntq_v, ctpop, Add1ArgType), NEONMAP1(vcvt_f16_f32, aarch64_neon_vcvtfp2hf, 0), + NEONMAP0(vcvt_f16_v), NEONMAP1(vcvt_f32_f16, aarch64_neon_vcvthf2fp, 0), NEONMAP0(vcvt_f32_v), + NEONMAP2(vcvt_n_f16_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), NEONMAP2(vcvt_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), NEONMAP2(vcvt_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), + NEONMAP1(vcvt_n_s16_v, aarch64_neon_vcvtfp2fxs, 0), NEONMAP1(vcvt_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), NEONMAP1(vcvt_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), + NEONMAP1(vcvt_n_u16_v, aarch64_neon_vcvtfp2fxu, 0), NEONMAP1(vcvt_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), + NEONMAP0(vcvtq_f16_v), NEONMAP0(vcvtq_f32_v), + NEONMAP2(vcvtq_n_f16_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), + NEONMAP1(vcvtq_n_s16_v, aarch64_neon_vcvtfp2fxs, 0), NEONMAP1(vcvtq_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), NEONMAP1(vcvtq_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), + NEONMAP1(vcvtq_n_u16_v, aarch64_neon_vcvtfp2fxu, 0), NEONMAP1(vcvtq_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), NEONMAP1(vcvtq_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), NEONMAP1(vcvtx_f32_v, aarch64_neon_fcvtxn, AddRetType | Add1ArgType), @@ -4197,7 +4232,8 @@ static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF, Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic, const char *NameHint, unsigned Modifier, const CallExpr *E, - SmallVectorImpl &Ops, Address PtrOp0, Address PtrOp1) { + SmallVectorImpl &Ops, Address PtrOp0, Address PtrOp1, + llvm::Triple::ArchType Arch) { // Get the last argument, which specifies the vector type. llvm::APSInt NeonTypeConst; const Expr *Arg = E->getArg(E->getNumArgs() - 1); @@ -4209,7 +4245,7 @@ Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( bool Usgn = Type.isUnsigned(); bool Quad = Type.isQuad(); - llvm::VectorType *VTy = GetNeonType(this, Type); + llvm::VectorType *VTy = GetNeonType(this, Type, Arch); llvm::Type *Ty = VTy; if (!Ty) return nullptr; @@ -4256,9 +4292,20 @@ Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( case NEON::BI__builtin_neon_vcageq_v: case NEON::BI__builtin_neon_vcagt_v: case NEON::BI__builtin_neon_vcagtq_v: { - llvm::Type *VecFlt = llvm::VectorType::get( - VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy, - VTy->getNumElements()); + llvm::Type *Ty; + switch (VTy->getScalarSizeInBits()) { + default: llvm_unreachable("unexpected type"); + case 32: + Ty = FloatTy; + break; + case 64: + Ty = DoubleTy; + break; + case 16: + Ty = HalfTy; + break; + } + llvm::Type *VecFlt = llvm::VectorType::get(Ty, VTy->getNumElements()); llvm::Type *Tys[] = { VTy, VecFlt }; Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); return EmitNeonCall(F, Ops, NameHint); @@ -4272,11 +4319,19 @@ Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( case NEON::BI__builtin_neon_vcvt_f32_v: case NEON::BI__builtin_neon_vcvtq_f32_v: Ops[0] = Builder.CreateBitCast(Ops[0], Ty); - Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad)); + Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad), Arch); + return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") + : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); + case NEON::BI__builtin_neon_vcvt_f16_v: + case NEON::BI__builtin_neon_vcvtq_f16_v: + Ops[0] = Builder.CreateBitCast(Ops[0], Ty); + Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float16, false, Quad), Arch); return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); + case NEON::BI__builtin_neon_vcvt_n_f16_v: case NEON::BI__builtin_neon_vcvt_n_f32_v: case NEON::BI__builtin_neon_vcvt_n_f64_v: + case NEON::BI__builtin_neon_vcvtq_n_f16_v: case NEON::BI__builtin_neon_vcvtq_n_f32_v: case NEON::BI__builtin_neon_vcvtq_n_f64_v: { llvm::Type *Tys[2] = { GetFloatNeonType(this, Type), Ty }; @@ -4284,11 +4339,15 @@ Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( Function *F = CGM.getIntrinsic(Int, Tys); return EmitNeonCall(F, Ops, "vcvt_n"); } + case NEON::BI__builtin_neon_vcvt_n_s16_v: case NEON::BI__builtin_neon_vcvt_n_s32_v: + case NEON::BI__builtin_neon_vcvt_n_u16_v: case NEON::BI__builtin_neon_vcvt_n_u32_v: case NEON::BI__builtin_neon_vcvt_n_s64_v: case NEON::BI__builtin_neon_vcvt_n_u64_v: + case NEON::BI__builtin_neon_vcvtq_n_s16_v: case NEON::BI__builtin_neon_vcvtq_n_s32_v: + case NEON::BI__builtin_neon_vcvtq_n_u16_v: case NEON::BI__builtin_neon_vcvtq_n_u32_v: case NEON::BI__builtin_neon_vcvtq_n_s64_v: case NEON::BI__builtin_neon_vcvtq_n_u64_v: { @@ -4300,44 +4359,63 @@ Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( case NEON::BI__builtin_neon_vcvt_u32_v: case NEON::BI__builtin_neon_vcvt_s64_v: case NEON::BI__builtin_neon_vcvt_u64_v: + case NEON::BI__builtin_neon_vcvt_s16_v: + case NEON::BI__builtin_neon_vcvt_u16_v: case NEON::BI__builtin_neon_vcvtq_s32_v: case NEON::BI__builtin_neon_vcvtq_u32_v: case NEON::BI__builtin_neon_vcvtq_s64_v: - case NEON::BI__builtin_neon_vcvtq_u64_v: { + case NEON::BI__builtin_neon_vcvtq_u64_v: + case NEON::BI__builtin_neon_vcvtq_s16_v: + case NEON::BI__builtin_neon_vcvtq_u16_v: { Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); } + case NEON::BI__builtin_neon_vcvta_s16_v: case NEON::BI__builtin_neon_vcvta_s32_v: case NEON::BI__builtin_neon_vcvta_s64_v: case NEON::BI__builtin_neon_vcvta_u32_v: case NEON::BI__builtin_neon_vcvta_u64_v: + case NEON::BI__builtin_neon_vcvtaq_s16_v: case NEON::BI__builtin_neon_vcvtaq_s32_v: case NEON::BI__builtin_neon_vcvtaq_s64_v: + case NEON::BI__builtin_neon_vcvtaq_u16_v: case NEON::BI__builtin_neon_vcvtaq_u32_v: case NEON::BI__builtin_neon_vcvtaq_u64_v: + case NEON::BI__builtin_neon_vcvtn_s16_v: case NEON::BI__builtin_neon_vcvtn_s32_v: case NEON::BI__builtin_neon_vcvtn_s64_v: + case NEON::BI__builtin_neon_vcvtn_u16_v: case NEON::BI__builtin_neon_vcvtn_u32_v: case NEON::BI__builtin_neon_vcvtn_u64_v: + case NEON::BI__builtin_neon_vcvtnq_s16_v: case NEON::BI__builtin_neon_vcvtnq_s32_v: case NEON::BI__builtin_neon_vcvtnq_s64_v: + case NEON::BI__builtin_neon_vcvtnq_u16_v: case NEON::BI__builtin_neon_vcvtnq_u32_v: case NEON::BI__builtin_neon_vcvtnq_u64_v: + case NEON::BI__builtin_neon_vcvtp_s16_v: case NEON::BI__builtin_neon_vcvtp_s32_v: case NEON::BI__builtin_neon_vcvtp_s64_v: + case NEON::BI__builtin_neon_vcvtp_u16_v: case NEON::BI__builtin_neon_vcvtp_u32_v: case NEON::BI__builtin_neon_vcvtp_u64_v: + case NEON::BI__builtin_neon_vcvtpq_s16_v: case NEON::BI__builtin_neon_vcvtpq_s32_v: case NEON::BI__builtin_neon_vcvtpq_s64_v: + case NEON::BI__builtin_neon_vcvtpq_u16_v: case NEON::BI__builtin_neon_vcvtpq_u32_v: case NEON::BI__builtin_neon_vcvtpq_u64_v: + case NEON::BI__builtin_neon_vcvtm_s16_v: case NEON::BI__builtin_neon_vcvtm_s32_v: case NEON::BI__builtin_neon_vcvtm_s64_v: + case NEON::BI__builtin_neon_vcvtm_u16_v: case NEON::BI__builtin_neon_vcvtm_u32_v: case NEON::BI__builtin_neon_vcvtm_u64_v: + case NEON::BI__builtin_neon_vcvtmq_s16_v: case NEON::BI__builtin_neon_vcvtmq_s32_v: case NEON::BI__builtin_neon_vcvtmq_s64_v: + case NEON::BI__builtin_neon_vcvtmq_u16_v: case NEON::BI__builtin_neon_vcvtmq_u32_v: case NEON::BI__builtin_neon_vcvtmq_u64_v: { llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; @@ -4816,7 +4894,8 @@ static bool HasExtraNeonArgument(unsigned BuiltinID) { } Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, - const CallExpr *E) { + const CallExpr *E, + llvm::Triple::ArchType Arch) { if (auto Hint = GetValueForARMHint(BuiltinID)) return Hint; @@ -5355,7 +5434,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, bool usgn = Type.isUnsigned(); bool rightShift = false; - llvm::VectorType *VTy = GetNeonType(this, Type); + llvm::VectorType *VTy = GetNeonType(this, Type, Arch); llvm::Type *Ty = VTy; if (!Ty) return nullptr; @@ -5368,7 +5447,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, if (Builtin) return EmitCommonNeonBuiltinExpr( Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, - Builtin->NameHint, Builtin->TypeModifier, E, Ops, PtrOp0, PtrOp1); + Builtin->NameHint, Builtin->TypeModifier, E, Ops, PtrOp0, PtrOp1, Arch); unsigned Int; switch (BuiltinID) { @@ -5393,7 +5472,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, SV = llvm::ConstantDataVector::get(getLLVMContext(), Indices); return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); } - // fall through + LLVM_FALLTHROUGH; case NEON::BI__builtin_neon_vld1_lane_v: { Ops[1] = Builder.CreateBitCast(Ops[1], Ty); PtrOp0 = Builder.CreateElementBitCast(PtrOp0, VTy->getElementType()); @@ -5518,7 +5597,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, Tys), Ops); } - // fall through + LLVM_FALLTHROUGH; case NEON::BI__builtin_neon_vst1_lane_v: { Ops[1] = Builder.CreateBitCast(Ops[1], Ty); Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); @@ -5555,7 +5634,8 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID, const CallExpr *E, - SmallVectorImpl &Ops) { + SmallVectorImpl &Ops, + llvm::Triple::ArchType Arch) { unsigned int Int = 0; const char *s = nullptr; @@ -5600,7 +5680,7 @@ static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID // Determine the type of this overloaded NEON intrinsic. NeonTypeFlags Type(Result.getZExtValue()); - llvm::VectorType *Ty = GetNeonType(&CGF, Type); + llvm::VectorType *Ty = GetNeonType(&CGF, Type, Arch); if (!Ty) return nullptr; @@ -5710,7 +5790,8 @@ Value *CodeGenFunction::vectorWrapScalar16(Value *Op) { } Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, - const CallExpr *E) { + const CallExpr *E, + llvm::Triple::ArchType Arch) { unsigned HintID = static_cast(-1); switch (BuiltinID) { default: break; @@ -6011,7 +6092,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, case NEON::BI__builtin_neon_vcvts_u32_f32: case NEON::BI__builtin_neon_vcvtd_u64_f64: usgn = true; - // FALL THROUGH + LLVM_FALLTHROUGH; case NEON::BI__builtin_neon_vcvts_s32_f32: case NEON::BI__builtin_neon_vcvtd_s64_f64: { Ops.push_back(EmitScalarExpr(E->getArg(0))); @@ -6026,7 +6107,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, case NEON::BI__builtin_neon_vcvts_f32_u32: case NEON::BI__builtin_neon_vcvtd_f64_u64: usgn = true; - // FALL THROUGH + LLVM_FALLTHROUGH; case NEON::BI__builtin_neon_vcvts_f32_s32: case NEON::BI__builtin_neon_vcvtd_f64_s64: { Ops.push_back(EmitScalarExpr(E->getArg(0))); @@ -6453,7 +6534,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, } } - llvm::VectorType *VTy = GetNeonType(this, Type); + llvm::VectorType *VTy = GetNeonType(this, Type, Arch); llvm::Type *Ty = VTy; if (!Ty) return nullptr; @@ -6467,9 +6548,9 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, return EmitCommonNeonBuiltinExpr( Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, Builtin->NameHint, Builtin->TypeModifier, E, Ops, - /*never use addresses*/ Address::invalid(), Address::invalid()); + /*never use addresses*/ Address::invalid(), Address::invalid(), Arch); - if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops)) + if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops, Arch)) return V; unsigned Int; @@ -6518,7 +6599,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); llvm::Type *VTy = GetNeonType(this, - NeonTypeFlags(NeonTypeFlags::Float64, false, true)); + NeonTypeFlags(NeonTypeFlags::Float64, false, true), Arch); Ops[2] = Builder.CreateBitCast(Ops[2], VTy); Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); @@ -6547,7 +6628,9 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, Ops[2] = EmitNeonSplat(Ops[2], cast(Ops[3])); return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]}); } + case NEON::BI__builtin_neon_vfmah_lane_f16: case NEON::BI__builtin_neon_vfmas_lane_f32: + case NEON::BI__builtin_neon_vfmah_laneq_f16: case NEON::BI__builtin_neon_vfmas_laneq_f32: case NEON::BI__builtin_neon_vfmad_lane_f64: case NEON::BI__builtin_neon_vfmad_laneq_f64: { @@ -6699,14 +6782,14 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, case NEON::BI__builtin_neon_vcvt_f64_v: case NEON::BI__builtin_neon_vcvtq_f64_v: Ops[0] = Builder.CreateBitCast(Ops[0], Ty); - Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); + Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad), Arch); return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); case NEON::BI__builtin_neon_vcvt_f64_f32: { assert(Type.getEltType() == NeonTypeFlags::Float64 && quad && "unexpected vcvt_f64_f32 builtin"); NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float32, false, false); - Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); + Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag, Arch)); return Builder.CreateFPExt(Ops[0], Ty, "vcvt"); } @@ -6714,7 +6797,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, assert(Type.getEltType() == NeonTypeFlags::Float32 && "unexpected vcvt_f32_f64 builtin"); NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true); - Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); + Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag, Arch)); return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt"); } @@ -6722,18 +6805,25 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, case NEON::BI__builtin_neon_vcvt_u32_v: case NEON::BI__builtin_neon_vcvt_s64_v: case NEON::BI__builtin_neon_vcvt_u64_v: + case NEON::BI__builtin_neon_vcvt_s16_v: + case NEON::BI__builtin_neon_vcvt_u16_v: case NEON::BI__builtin_neon_vcvtq_s32_v: case NEON::BI__builtin_neon_vcvtq_u32_v: case NEON::BI__builtin_neon_vcvtq_s64_v: - case NEON::BI__builtin_neon_vcvtq_u64_v: { + case NEON::BI__builtin_neon_vcvtq_u64_v: + case NEON::BI__builtin_neon_vcvtq_s16_v: + case NEON::BI__builtin_neon_vcvtq_u16_v: { Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); if (usgn) return Builder.CreateFPToUI(Ops[0], Ty); return Builder.CreateFPToSI(Ops[0], Ty); } + case NEON::BI__builtin_neon_vcvta_s16_v: case NEON::BI__builtin_neon_vcvta_s32_v: + case NEON::BI__builtin_neon_vcvtaq_s16_v: case NEON::BI__builtin_neon_vcvtaq_s32_v: case NEON::BI__builtin_neon_vcvta_u32_v: + case NEON::BI__builtin_neon_vcvtaq_u16_v: case NEON::BI__builtin_neon_vcvtaq_u32_v: case NEON::BI__builtin_neon_vcvta_s64_v: case NEON::BI__builtin_neon_vcvtaq_s64_v: @@ -6743,9 +6833,13 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvta"); } + case NEON::BI__builtin_neon_vcvtm_s16_v: case NEON::BI__builtin_neon_vcvtm_s32_v: + case NEON::BI__builtin_neon_vcvtmq_s16_v: case NEON::BI__builtin_neon_vcvtmq_s32_v: + case NEON::BI__builtin_neon_vcvtm_u16_v: case NEON::BI__builtin_neon_vcvtm_u32_v: + case NEON::BI__builtin_neon_vcvtmq_u16_v: case NEON::BI__builtin_neon_vcvtmq_u32_v: case NEON::BI__builtin_neon_vcvtm_s64_v: case NEON::BI__builtin_neon_vcvtmq_s64_v: @@ -6755,9 +6849,13 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtm"); } + case NEON::BI__builtin_neon_vcvtn_s16_v: case NEON::BI__builtin_neon_vcvtn_s32_v: + case NEON::BI__builtin_neon_vcvtnq_s16_v: case NEON::BI__builtin_neon_vcvtnq_s32_v: + case NEON::BI__builtin_neon_vcvtn_u16_v: case NEON::BI__builtin_neon_vcvtn_u32_v: + case NEON::BI__builtin_neon_vcvtnq_u16_v: case NEON::BI__builtin_neon_vcvtnq_u32_v: case NEON::BI__builtin_neon_vcvtn_s64_v: case NEON::BI__builtin_neon_vcvtnq_s64_v: @@ -6767,9 +6865,13 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtn"); } + case NEON::BI__builtin_neon_vcvtp_s16_v: case NEON::BI__builtin_neon_vcvtp_s32_v: + case NEON::BI__builtin_neon_vcvtpq_s16_v: case NEON::BI__builtin_neon_vcvtpq_s32_v: + case NEON::BI__builtin_neon_vcvtp_u16_v: case NEON::BI__builtin_neon_vcvtp_u32_v: + case NEON::BI__builtin_neon_vcvtpq_u16_v: case NEON::BI__builtin_neon_vcvtpq_u32_v: case NEON::BI__builtin_neon_vcvtp_s64_v: case NEON::BI__builtin_neon_vcvtpq_s64_v: @@ -6792,7 +6894,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, Quad = true; Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); llvm::Type *VTy = GetNeonType(this, - NeonTypeFlags(NeonTypeFlags::Float64, false, Quad)); + NeonTypeFlags(NeonTypeFlags::Float64, false, Quad), Arch); Ops[1] = Builder.CreateBitCast(Ops[1], VTy); Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract"); Value *Result = Builder.CreateFMul(Ops[0], Ops[1]); @@ -6824,7 +6926,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, case NEON::BI__builtin_neon_vaddv_u8: // FIXME: These are handled by the AArch64 scalar code. usgn = true; - // FALLTHROUGH + LLVM_FALLTHROUGH; case NEON::BI__builtin_neon_vaddv_s8: { Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; Ty = Int32Ty; @@ -6836,7 +6938,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, } case NEON::BI__builtin_neon_vaddv_u16: usgn = true; - // FALLTHROUGH + LLVM_FALLTHROUGH; case NEON::BI__builtin_neon_vaddv_s16: { Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; Ty = Int32Ty; @@ -6848,7 +6950,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, } case NEON::BI__builtin_neon_vaddvq_u8: usgn = true; - // FALLTHROUGH + LLVM_FALLTHROUGH; case NEON::BI__builtin_neon_vaddvq_s8: { Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; Ty = Int32Ty; @@ -6860,7 +6962,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, } case NEON::BI__builtin_neon_vaddvq_u16: usgn = true; - // FALLTHROUGH + LLVM_FALLTHROUGH; case NEON::BI__builtin_neon_vaddvq_s16: { Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; Ty = Int32Ty; @@ -6942,6 +7044,24 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); return Builder.CreateTrunc(Ops[0], Int16Ty); } + case NEON::BI__builtin_neon_vmaxv_f16: { + Int = Intrinsic::aarch64_neon_fmaxv; + Ty = HalfTy; + VTy = llvm::VectorType::get(HalfTy, 4); + llvm::Type *Tys[2] = { Ty, VTy }; + Ops.push_back(EmitScalarExpr(E->getArg(0))); + Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); + return Builder.CreateTrunc(Ops[0], HalfTy); + } + case NEON::BI__builtin_neon_vmaxvq_f16: { + Int = Intrinsic::aarch64_neon_fmaxv; + Ty = HalfTy; + VTy = llvm::VectorType::get(HalfTy, 8); + llvm::Type *Tys[2] = { Ty, VTy }; + Ops.push_back(EmitScalarExpr(E->getArg(0))); + Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); + return Builder.CreateTrunc(Ops[0], HalfTy); + } case NEON::BI__builtin_neon_vminv_u8: { Int = Intrinsic::aarch64_neon_uminv; Ty = Int32Ty; @@ -7014,6 +7134,60 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); return Builder.CreateTrunc(Ops[0], Int16Ty); } + case NEON::BI__builtin_neon_vminv_f16: { + Int = Intrinsic::aarch64_neon_fminv; + Ty = HalfTy; + VTy = llvm::VectorType::get(HalfTy, 4); + llvm::Type *Tys[2] = { Ty, VTy }; + Ops.push_back(EmitScalarExpr(E->getArg(0))); + Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); + return Builder.CreateTrunc(Ops[0], HalfTy); + } + case NEON::BI__builtin_neon_vminvq_f16: { + Int = Intrinsic::aarch64_neon_fminv; + Ty = HalfTy; + VTy = llvm::VectorType::get(HalfTy, 8); + llvm::Type *Tys[2] = { Ty, VTy }; + Ops.push_back(EmitScalarExpr(E->getArg(0))); + Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); + return Builder.CreateTrunc(Ops[0], HalfTy); + } + case NEON::BI__builtin_neon_vmaxnmv_f16: { + Int = Intrinsic::aarch64_neon_fmaxnmv; + Ty = HalfTy; + VTy = llvm::VectorType::get(HalfTy, 4); + llvm::Type *Tys[2] = { Ty, VTy }; + Ops.push_back(EmitScalarExpr(E->getArg(0))); + Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxnmv"); + return Builder.CreateTrunc(Ops[0], HalfTy); + } + case NEON::BI__builtin_neon_vmaxnmvq_f16: { + Int = Intrinsic::aarch64_neon_fmaxnmv; + Ty = HalfTy; + VTy = llvm::VectorType::get(HalfTy, 8); + llvm::Type *Tys[2] = { Ty, VTy }; + Ops.push_back(EmitScalarExpr(E->getArg(0))); + Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxnmv"); + return Builder.CreateTrunc(Ops[0], HalfTy); + } + case NEON::BI__builtin_neon_vminnmv_f16: { + Int = Intrinsic::aarch64_neon_fminnmv; + Ty = HalfTy; + VTy = llvm::VectorType::get(HalfTy, 4); + llvm::Type *Tys[2] = { Ty, VTy }; + Ops.push_back(EmitScalarExpr(E->getArg(0))); + Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminnmv"); + return Builder.CreateTrunc(Ops[0], HalfTy); + } + case NEON::BI__builtin_neon_vminnmvq_f16: { + Int = Intrinsic::aarch64_neon_fminnmv; + Ty = HalfTy; + VTy = llvm::VectorType::get(HalfTy, 8); + llvm::Type *Tys[2] = { Ty, VTy }; + Ops.push_back(EmitScalarExpr(E->getArg(0))); + Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminnmv"); + return Builder.CreateTrunc(Ops[0], HalfTy); + } case NEON::BI__builtin_neon_vmul_n_f64: { Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); Value *RHS = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), DoubleTy); @@ -7848,8 +8022,9 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, default: return nullptr; case X86::BI_mm_prefetch: { Value *Address = Ops[0]; - Value *RW = ConstantInt::get(Int32Ty, 0); - Value *Locality = Ops[1]; + ConstantInt *C = cast(Ops[1]); + Value *RW = ConstantInt::get(Int32Ty, (C->getZExtValue() >> 2) & 0x1); + Value *Locality = ConstantInt::get(Int32Ty, C->getZExtValue() & 0x3); Value *Data = ConstantInt::get(Int32Ty, 1); Value *F = CGM.getIntrinsic(Intrinsic::prefetch); return Builder.CreateCall(F, {Address, RW, Locality, Data}); diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index c3709bf..38d7344 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1929,7 +1929,7 @@ void CodeGenModule::ConstructAttributeList( RetAttrs.addAttribute(llvm::Attribute::SExt); else if (RetTy->hasUnsignedIntegerRepresentation()) RetAttrs.addAttribute(llvm::Attribute::ZExt); - // FALL THROUGH + LLVM_FALLTHROUGH; case ABIArgInfo::Direct: if (RetAI.getInReg()) RetAttrs.addAttribute(llvm::Attribute::InReg); @@ -2014,7 +2014,7 @@ void CodeGenModule::ConstructAttributeList( else Attrs.addAttribute(llvm::Attribute::ZExt); } - // FALL THROUGH + LLVM_FALLTHROUGH; case ABIArgInfo::Direct: if (ArgNo == 0 && FI.isChainCall()) Attrs.addAttribute(llvm::Attribute::Nest); @@ -2758,6 +2758,12 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc, SourceLocation EndLoc) { + if (FI.isNoReturn()) { + // Noreturn functions don't return. + EmitUnreachable(EndLoc); + return; + } + if (CurCodeDecl && CurCodeDecl->hasAttr()) { // Naked functions don't have epilogues. Builder.CreateUnreachable(); @@ -3718,7 +3724,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &CallArgs, - llvm::Instruction **callOrInvoke) { + llvm::Instruction **callOrInvoke, + SourceLocation Loc) { // FIXME: We no longer need the types from CallArgs; lift up and simplify. assert(Callee.isOrdinary()); @@ -4241,7 +4248,15 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, EmitLifetimeEnd(llvm::ConstantInt::get(Int64Ty, UnusedReturnSize), SRetPtr.getPointer()); - Builder.CreateUnreachable(); + // Strip away the noreturn attribute to better diagnose unreachable UB. + if (SanOpts.has(SanitizerKind::Unreachable)) { + if (auto *F = CS.getCalledFunction()) + F->removeFnAttr(llvm::Attribute::NoReturn); + CS.removeAttribute(llvm::AttributeList::FunctionIndex, + llvm::Attribute::NoReturn); + } + + EmitUnreachable(Loc); Builder.ClearInsertionPoint(); // FIXME: For now, emit a dummy basic block because expr emitters in diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index caea41e..aeed4d6 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -2653,7 +2653,6 @@ llvm::DIModule *CGDebugInfo::getParentModuleOrNull(const Decl *D) { // file where the type's definition is located, so it might be // best to make this behavior a command line or debugger tuning // option. - FullSourceLoc Loc(D->getLocation(), CGM.getContext().getSourceManager()); if (Module *M = D->getOwningModule()) { // This is a (sub-)module. auto Info = ExternalASTSource::ASTSourceDescriptor(*M); diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 6c9d9f1..1ec084f 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -133,7 +133,7 @@ static const EHPersonality &getObjCPersonality(const llvm::Triple &T, case ObjCRuntime::GNUstep: if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7)) return EHPersonality::GNUstep_ObjC; - // fallthrough + LLVM_FALLTHROUGH; case ObjCRuntime::GCC: case ObjCRuntime::ObjFW: if (L.SjLjExceptions) diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 98740e8..90eeddf 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -3076,6 +3076,17 @@ void CodeGenFunction::EmitCfiCheckFail() { CGM.addUsedGlobal(F); } +void CodeGenFunction::EmitUnreachable(SourceLocation Loc) { + if (SanOpts.has(SanitizerKind::Unreachable)) { + SanitizerScope SanScope(this); + EmitCheck(std::make_pair(static_cast(Builder.getFalse()), + SanitizerKind::Unreachable), + SanitizerHandler::BuiltinUnreachable, + EmitCheckSourceLocation(Loc), None); + } + Builder.CreateUnreachable(); +} + void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked) { llvm::BasicBlock *Cont = createBasicBlock("cont"); @@ -3790,8 +3801,10 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, FieldTBAAInfo.Offset += Layout.getFieldOffset(field->getFieldIndex()) / CharWidth; - // Update the final access type. + // Update the final access type and size. FieldTBAAInfo.AccessType = CGM.getTBAATypeInfo(FieldType); + FieldTBAAInfo.Size = + getContext().getTypeSizeInChars(FieldType).getQuantity(); } Address addr = base.getAddress(); @@ -4616,7 +4629,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee Callee.setFunctionPointer(CalleePtr); } - return EmitCall(FnInfo, Callee, ReturnValue, Args); + return EmitCall(FnInfo, Callee, ReturnValue, Args, nullptr, E->getExprLoc()); } LValue CodeGenFunction:: diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 1ab8433..0f05cab 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -692,7 +692,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { return Visit(E->getSubExpr()); } - // fallthrough + LLVM_FALLTHROUGH; case CK_NoOp: case CK_UserDefinedConversion: diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 41bb199..0749b0a 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -89,7 +89,8 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorCall( *this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args, RtlArgs); auto &FnInfo = CGM.getTypes().arrangeCXXMethodCall( Args, FPT, CallInfo.ReqArgs, CallInfo.PrefixSize); - return EmitCall(FnInfo, Callee, ReturnValue, Args); + return EmitCall(FnInfo, Callee, ReturnValue, Args, nullptr, + CE ? CE->getExprLoc() : SourceLocation()); } RValue CodeGenFunction::EmitCXXDestructorCall( @@ -446,7 +447,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, EmitCallArgs(Args, FPT, E->arguments()); return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required, /*PrefixSize=*/0), - Callee, ReturnValue, Args); + Callee, ReturnValue, Args, nullptr, E->getExprLoc()); } RValue @@ -613,7 +614,7 @@ CodeGenFunction::EmitCXXConstructExpr(const CXXConstructExpr *E, case CXXConstructExpr::CK_VirtualBase: ForVirtualBase = true; - // fall-through + LLVM_FALLTHROUGH; case CXXConstructExpr::CK_NonVirtualBase: Type = Ctor_Base; diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index e860b30..9094d3f 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -761,15 +761,16 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second; llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second; - llvm::Value *DSTr, *DSTi; if (LHSr->getType()->isFloatingPointTy()) { - // If we have a complex operand on the RHS, we delegate to a libcall to - // handle all of the complexities and minimize underflow/overflow cases. + // If we have a complex operand on the RHS and FastMath is not allowed, we + // delegate to a libcall to handle all of the complexities and minimize + // underflow/overflow cases. When FastMath is allowed we construct the + // divide inline using the same algorithm as for integer operands. // // FIXME: We would be able to avoid the libcall in many places if we // supported imaginary types in addition to complex types. - if (RHSi) { + if (RHSi && !CGF.getLangOpts().FastMath) { BinOpInfo LibCallOp = Op; // If LHS was a real, supply a null imaginary part. if (!LHSi) @@ -791,11 +792,31 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { case llvm::Type::FP128TyID: return EmitComplexBinOpLibCall("__divtc3", LibCallOp); } - } - assert(LHSi && "Can have at most one non-complex operand!"); + } else if (RHSi) { + if (!LHSi) + LHSi = llvm::Constant::getNullValue(RHSi->getType()); + + // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) + llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c + llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d + llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd + + llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c + llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d + llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd - DSTr = Builder.CreateFDiv(LHSr, RHSr); - DSTi = Builder.CreateFDiv(LHSi, RHSr); + llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c + llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d + llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad + + DSTr = Builder.CreateFDiv(ACpBD, CCpDD); + DSTi = Builder.CreateFDiv(BCmAD, CCpDD); + } else { + assert(LHSi && "Can have at most one non-complex operand!"); + + DSTr = Builder.CreateFDiv(LHSr, RHSr); + DSTi = Builder.CreateFDiv(LHSi, RHSr); + } } else { assert(Op.LHS.second && Op.RHS.second && "Both operands of integer complex operators must be complex!"); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index ab5bbc0..cd62d00 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -3288,11 +3288,15 @@ public: /// LLVM arguments and the types they were derived from. RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, - llvm::Instruction **callOrInvoke = nullptr); - + llvm::Instruction **callOrInvoke, SourceLocation Loc); + RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, + ReturnValueSlot ReturnValue, const CallArgList &Args, + llvm::Instruction **callOrInvoke = nullptr) { + return EmitCall(CallInfo, Callee, ReturnValue, Args, callOrInvoke, + SourceLocation()); + } RValue EmitCall(QualType FnType, const CGCallee &Callee, const CallExpr *E, - ReturnValueSlot ReturnValue, - llvm::Value *Chain = nullptr); + ReturnValueSlot ReturnValue, llvm::Value *Chain = nullptr); RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue = ReturnValueSlot()); RValue EmitSimpleCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue); @@ -3391,7 +3395,8 @@ public: const llvm::CmpInst::Predicate Fp, const llvm::CmpInst::Predicate Ip, const llvm::Twine &Name = ""); - llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E); + llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E, + llvm::Triple::ArchType Arch); llvm::Value *EmitCommonNeonBuiltinExpr(unsigned BuiltinID, unsigned LLVMIntrinsic, @@ -3400,7 +3405,8 @@ public: unsigned Modifier, const CallExpr *E, SmallVectorImpl &Ops, - Address PtrOp0, Address PtrOp1); + Address PtrOp0, Address PtrOp1, + llvm::Triple::ArchType Arch); llvm::Function *LookupNeonLLVMIntrinsic(unsigned IntrinsicID, unsigned Modifier, llvm::Type *ArgTy, const CallExpr *E); @@ -3414,7 +3420,8 @@ public: llvm::Value *EmitNeonRShiftImm(llvm::Value *Vec, llvm::Value *Amt, llvm::Type *Ty, bool usgn, const char *name); llvm::Value *vectorWrapScalar16(llvm::Value *Op); - llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E); + llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, + llvm::Triple::ArchType Arch); llvm::Value *BuildVector(ArrayRef Ops); llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E); @@ -3747,6 +3754,10 @@ public: llvm::ConstantInt *TypeId, llvm::Value *Ptr, ArrayRef StaticArgs); + /// Emit a reached-unreachable diagnostic if \p Loc is valid and runtime + /// checking is enabled. Otherwise, just emit an unreachable instruction. + void EmitUnreachable(SourceLocation Loc); + /// \brief Create a basic block that will call the trap intrinsic, and emit a /// conditional branch to it, for the -ftrapv checks. void EmitTrapCheck(llvm::Value *Checked); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index c59dc71..5bdf81a 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -103,6 +103,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO, Int16Ty = llvm::Type::getInt16Ty(LLVMContext); Int32Ty = llvm::Type::getInt32Ty(LLVMContext); Int64Ty = llvm::Type::getInt64Ty(LLVMContext); + HalfTy = llvm::Type::getHalfTy(LLVMContext); FloatTy = llvm::Type::getFloatTy(LLVMContext); DoubleTy = llvm::Type::getDoubleTy(LLVMContext); PointerWidthInBits = C.getTargetInfo().getPointerWidth(0); @@ -4289,7 +4290,11 @@ void CodeGenModule::ClearUnusedCoverageMapping(const Decl *D) { } void CodeGenModule::EmitDeferredUnusedCoverageMappings() { - for (const auto &Entry : DeferredEmptyCoverageMappingDecls) { + // We call takeVector() here to avoid use-after-free. + // FIXME: DeferredEmptyCoverageMappingDecls is getting mutated because + // we deserialize function bodies to emit coverage info for them, and that + // deserializes more declarations. How should we handle that case? + for (const auto &Entry : DeferredEmptyCoverageMappingDecls.takeVector()) { if (!Entry.second) continue; const Decl *D = Entry.first; diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp index f394ea2..ad47303 100644 --- a/lib/CodeGen/CodeGenTBAA.cpp +++ b/lib/CodeGen/CodeGenTBAA.cpp @@ -59,7 +59,10 @@ llvm::MDNode *CodeGenTBAA::getRoot() { llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name, llvm::MDNode *Parent, uint64_t Size) { - (void)Size; // TODO: Support generation of size-aware type nodes. + if (CodeGenOpts.NewStructPathTBAA) { + llvm::Metadata *Id = MDHelper.createString(Name); + return MDHelper.createTBAATypeNode(Parent, Size, Id); + } return MDHelper.createTBAAScalarTypeNode(Name, Parent); } @@ -158,6 +161,10 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { if (Ty->isPointerType() || Ty->isReferenceType()) return createScalarTypeNode("any pointer", getChar(), Size); + // Accesses to arrays are accesses to objects of their element types. + if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType()) + return getTypeInfo(cast(Ty)->getElementType()); + // Enum types are distinct types. In C++ they have "underlying types", // however they aren't related for TBAA. if (const EnumType *ETy = dyn_cast(Ty)) { @@ -300,8 +307,12 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) { OutName = RD->getName(); } - // TODO: Support size-aware type nodes and create one here for the - // given aggregate type. + if (CodeGenOpts.NewStructPathTBAA) { + llvm::MDNode *Parent = getChar(); + uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity(); + llvm::Metadata *Id = MDHelper.createString(OutName); + return MDHelper.createTBAATypeNode(Parent, Size, Id, Fields); + } // Create the struct type node with a vector of pairs (offset, type). SmallVector, 4> OffsetsAndTypes; @@ -348,6 +359,10 @@ llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) { Info.BaseType = Info.AccessType; assert(!Info.Offset && "Nonzero offset for an access with no base type!"); } + if (CodeGenOpts.NewStructPathTBAA) { + return N = MDHelper.createTBAAAccessTag(Info.BaseType, Info.AccessType, + Info.Offset, Info.Size); + } return N = MDHelper.createTBAAStructTagNode(Info.BaseType, Info.AccessType, Info.Offset); } diff --git a/lib/CodeGen/CodeGenTypeCache.h b/lib/CodeGen/CodeGenTypeCache.h index 2af7b30..fb096ac 100644 --- a/lib/CodeGen/CodeGenTypeCache.h +++ b/lib/CodeGen/CodeGenTypeCache.h @@ -37,7 +37,7 @@ struct CodeGenTypeCache { /// i8, i16, i32, and i64 llvm::IntegerType *Int8Ty, *Int16Ty, *Int32Ty, *Int64Ty; /// float, double - llvm::Type *FloatTy, *DoubleTy; + llvm::Type *HalfTy, *FloatTy, *DoubleTy; /// int llvm::IntegerType *IntTy; diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp index f617d8b..6ba8892 100644 --- a/lib/Driver/SanitizerArgs.cpp +++ b/lib/Driver/SanitizerArgs.cpp @@ -440,6 +440,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, RecoverableKinds &= ~Unrecoverable; TrappingKinds &= Kinds; + RecoverableKinds &= ~TrappingKinds; // Setup blacklist files. // Add default blacklist from resource directory. @@ -683,6 +684,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, Sanitizers.Mask |= Kinds; RecoverableSanitizers.Mask |= RecoverableKinds; TrapSanitizers.Mask |= TrappingKinds; + assert(!(RecoverableKinds & TrappingKinds) && + "Overlap between recoverable and trapping sanitizers"); } static std::string toString(const clang::SanitizerSet &Sanitizers) { diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 0a89ff9..7b3f4bc 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -4389,6 +4389,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fapple-pragma-pack"); if (Args.hasFlag(options::OPT_fsave_optimization_record, + options::OPT_foptimization_record_file_EQ, options::OPT_fno_save_optimization_record, false)) { CmdArgs.push_back("-opt-record-file"); diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp index ab51a8c..60f96d0 100644 --- a/lib/Driver/ToolChains/CommonArgs.cpp +++ b/lib/Driver/ToolChains/CommonArgs.cpp @@ -549,6 +549,12 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, TC.getTriple().getOS() != llvm::Triple::NetBSD && TC.getTriple().getOS() != llvm::Triple::RTEMS) CmdArgs.push_back("-ldl"); + // Required for forkpty on some OSes + if (TC.getTriple().getOS() == llvm::Triple::NetBSD) + CmdArgs.push_back("-lutil"); + // Required for backtrace on some OSes + if (TC.getTriple().getOS() == llvm::Triple::NetBSD) + CmdArgs.push_back("-lexecinfo"); } static void diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp index 28efa86..289f4ed 100644 --- a/lib/Driver/ToolChains/Darwin.cpp +++ b/lib/Driver/ToolChains/Darwin.cpp @@ -1181,9 +1181,12 @@ struct DarwinPlatform { }; using DarwinPlatformKind = Darwin::DarwinPlatformKind; + using DarwinEnvironmentKind = Darwin::DarwinEnvironmentKind; DarwinPlatformKind getPlatform() const { return Platform; } + DarwinEnvironmentKind getEnvironment() const { return Environment; } + StringRef getOSVersion() const { if (Kind == OSVersionArg) return Argument->getValue(); @@ -1233,6 +1236,19 @@ struct DarwinPlatform { llvm_unreachable("Unsupported Darwin Source Kind"); } + static DarwinPlatform createFromTarget(llvm::Triple::OSType OS, + StringRef OSVersion, Arg *A, + llvm::Triple::EnvironmentType Env) { + DarwinPlatform Result(TargetArg, getPlatformFromOS(OS), OSVersion, A); + switch (Env) { + case llvm::Triple::Simulator: + Result.Environment = DarwinEnvironmentKind::Simulator; + break; + default: + break; + } + return Result; + } static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform, Arg *A) { return DarwinPlatform(OSVersionArg, Platform, A); @@ -1250,35 +1266,35 @@ struct DarwinPlatform { } static DarwinPlatform createFromArch(llvm::Triple::OSType OS, StringRef Value) { - DarwinPlatformKind Platform; + return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Value); + } + +private: + DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument) + : Kind(Kind), Platform(Platform), Argument(Argument) {} + DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, StringRef Value, + Arg *Argument = nullptr) + : Kind(Kind), Platform(Platform), OSVersion(Value), Argument(Argument) {} + + static DarwinPlatformKind getPlatformFromOS(llvm::Triple::OSType OS) { switch (OS) { case llvm::Triple::Darwin: case llvm::Triple::MacOSX: - Platform = DarwinPlatformKind::MacOS; - break; + return DarwinPlatformKind::MacOS; case llvm::Triple::IOS: - Platform = DarwinPlatformKind::IPhoneOS; - break; + return DarwinPlatformKind::IPhoneOS; case llvm::Triple::TvOS: - Platform = DarwinPlatformKind::TvOS; - break; + return DarwinPlatformKind::TvOS; case llvm::Triple::WatchOS: - Platform = DarwinPlatformKind::WatchOS; - break; + return DarwinPlatformKind::WatchOS; default: llvm_unreachable("Unable to infer Darwin variant"); } - return DarwinPlatform(InferredFromArch, Platform, Value); } -private: - DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument) - : Kind(Kind), Platform(Platform), Argument(Argument) {} - DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, StringRef Value) - : Kind(Kind), Platform(Platform), OSVersion(Value), Argument(nullptr) {} - SourceKind Kind; DarwinPlatformKind Platform; + DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment; std::string OSVersion; Arg *Argument; StringRef EnvVarName; @@ -1449,20 +1465,15 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain, const Driver &TheDriver) { llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS; - // Set the OSTy based on -target if -arch isn't present. - if (Args.hasArg(options::OPT_target) && !Args.hasArg(options::OPT_arch)) { - OSTy = Triple.getOS(); - } else { - StringRef MachOArchName = Toolchain.getMachOArchName(Args); - if (MachOArchName == "armv7" || MachOArchName == "armv7s" || - MachOArchName == "arm64") - OSTy = llvm::Triple::IOS; - else if (MachOArchName == "armv7k") - OSTy = llvm::Triple::WatchOS; - else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" && - MachOArchName != "armv7em") - OSTy = llvm::Triple::MacOSX; - } + StringRef MachOArchName = Toolchain.getMachOArchName(Args); + if (MachOArchName == "armv7" || MachOArchName == "armv7s" || + MachOArchName == "arm64") + OSTy = llvm::Triple::IOS; + else if (MachOArchName == "armv7k") + OSTy = llvm::Triple::WatchOS; + else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" && + MachOArchName != "armv7em") + OSTy = llvm::Triple::MacOSX; if (OSTy == llvm::Triple::UnknownOS) return None; @@ -1470,6 +1481,20 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain, getOSVersion(OSTy, Triple, TheDriver)); } +/// Returns the deployment target that's specified using the -target option. +Optional getDeploymentTargetFromTargetArg( + DerivedArgList &Args, const llvm::Triple &Triple, const Driver &TheDriver) { + if (!Args.hasArg(options::OPT_target)) + return None; + if (Triple.getOS() == llvm::Triple::Darwin || + Triple.getOS() == llvm::Triple::UnknownOS) + return None; + std::string OSVersion = getOSVersion(Triple.getOS(), Triple, TheDriver); + return DarwinPlatform::createFromTarget(Triple.getOS(), OSVersion, + Args.getLastArg(options::OPT_target), + Triple.getEnvironment()); +} + } // namespace void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { @@ -1494,24 +1519,52 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { } } - // The OS target can be specified using the -mversion-min argument. + // The OS and the version can be specified using the -target argument. Optional OSTarget = - getDeploymentTargetFromOSVersionArg(Args, getDriver()); - // If no deployment target was specified on the command line, check for - // environment defines. - if (!OSTarget) - OSTarget = - getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple()); - // If there is no command-line argument to specify the Target version and - // no environment variable defined, see if we can set the default based - // on -isysroot. - if (!OSTarget) - OSTarget = inferDeploymentTargetFromSDK(Args); - // If no OS targets have been specified, try to guess platform from -target - // or arch name and compute the version from the triple. - if (!OSTarget) - OSTarget = - inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver()); + getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver()); + if (OSTarget) { + Optional OSVersionArgTarget = + getDeploymentTargetFromOSVersionArg(Args, getDriver()); + if (OSVersionArgTarget) { + unsigned TargetMajor, TargetMinor, TargetMicro; + bool TargetExtra; + unsigned ArgMajor, ArgMinor, ArgMicro; + bool ArgExtra; + if (OSTarget->getPlatform() != OSVersionArgTarget->getPlatform() || + (Driver::GetReleaseVersion(OSTarget->getOSVersion(), TargetMajor, + TargetMinor, TargetMicro, TargetExtra) && + Driver::GetReleaseVersion(OSVersionArgTarget->getOSVersion(), + ArgMajor, ArgMinor, ArgMicro, ArgExtra) && + (VersionTuple(TargetMajor, TargetMinor, TargetMicro) != + VersionTuple(ArgMajor, ArgMinor, ArgMicro) || + TargetExtra != ArgExtra))) { + // Warn about -m-version-min that doesn't match the OS version + // that's specified in the target. + std::string OSVersionArg = OSVersionArgTarget->getAsString(Args, Opts); + std::string TargetArg = OSTarget->getAsString(Args, Opts); + getDriver().Diag(clang::diag::warn_drv_overriding_flag_option) + << OSVersionArg << TargetArg; + } + } + } else { + // The OS target can be specified using the -mversion-min argument. + OSTarget = getDeploymentTargetFromOSVersionArg(Args, getDriver()); + // If no deployment target was specified on the command line, check for + // environment defines. + if (!OSTarget) + OSTarget = + getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple()); + // If there is no command-line argument to specify the Target version and + // no environment variable defined, see if we can set the default based + // on -isysroot. + if (!OSTarget) + OSTarget = inferDeploymentTargetFromSDK(Args); + // If no OS targets have been specified, try to guess platform from -target + // or arch name and compute the version from the triple. + if (!OSTarget) + OSTarget = + inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver()); + } assert(OSTarget && "Unable to infer Darwin variant"); OSTarget->addOSVersionMinArgument(Args, Opts); @@ -1562,10 +1615,11 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { } else llvm_unreachable("unknown kind of Darwin platform"); - DarwinEnvironmentKind Environment = NativeEnvironment; + DarwinEnvironmentKind Environment = OSTarget->getEnvironment(); // Recognize iOS targets with an x86 architecture as the iOS simulator. - if (Platform != MacOS && (getTriple().getArch() == llvm::Triple::x86 || - getTriple().getArch() == llvm::Triple::x86_64)) + if (Environment == NativeEnvironment && Platform != MacOS && + (getTriple().getArch() == llvm::Triple::x86 || + getTriple().getArch() == llvm::Triple::x86_64)) Environment = Simulator; setTarget(Platform, Environment, Major, Minor, Micro); diff --git a/lib/Driver/ToolChains/Fuchsia.cpp b/lib/Driver/ToolChains/Fuchsia.cpp index 10ee7b7..269d34d 100644 --- a/lib/Driver/ToolChains/Fuchsia.cpp +++ b/lib/Driver/ToolChains/Fuchsia.cpp @@ -280,5 +280,6 @@ SanitizerMask Fuchsia::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::SafeStack; Res |= SanitizerKind::Address; + Res |= SanitizerKind::Scudo; return Res; } diff --git a/lib/Driver/ToolChains/Myriad.cpp b/lib/Driver/ToolChains/Myriad.cpp index 6fdb5a2..06079b1 100644 --- a/lib/Driver/ToolChains/Myriad.cpp +++ b/lib/Driver/ToolChains/Myriad.cpp @@ -199,7 +199,7 @@ void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA, } std::string Exec = - Args.MakeArgString(TC.GetProgramPath("sparc-myriad-elf-ld")); + Args.MakeArgString(TC.GetProgramPath("sparc-myriad-rtems-ld")); C.addCommand(llvm::make_unique(JA, *this, Args.MakeArgString(Exec), CmdArgs, Inputs)); } @@ -218,10 +218,11 @@ MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple, D.Diag(clang::diag::err_target_unsupported_arch) << Triple.getArchName() << "myriad"; LLVM_FALLTHROUGH; + case llvm::Triple::shave: + return; case llvm::Triple::sparc: case llvm::Triple::sparcel: - case llvm::Triple::shave: - GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"}); + GCCInstallation.init(Triple, Args, {"sparc-myriad-rtems"}); } if (GCCInstallation.isValid()) { @@ -231,7 +232,7 @@ MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple, addPathIfExists(D, CompilerSupportDir, getFilePaths()); } // libstd++ and libc++ must both be found in this one place. - addPathIfExists(D, D.Dir + "/../sparc-myriad-elf/lib", getFilePaths()); + addPathIfExists(D, D.Dir + "/../sparc-myriad-rtems/lib", getFilePaths()); } MyriadToolChain::~MyriadToolChain() {} diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 32f1232..7208177 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -1854,6 +1854,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, // Verify that the rest of the module path actually corresponds to // a submodule. + bool MapPrivateSubModToTopLevel = false; if (!getLangOpts().ModulesTS && Path.size() > 1) { for (unsigned I = 1, N = Path.size(); I != N; ++I) { StringRef Name = Path[I].first->getName(); @@ -1892,7 +1893,40 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, Sub = Module->findSubmodule(Best[0]); } } - + + // If the user is requesting Foo.Private and it doesn't exist, try to + // match Foo_Private and emit a warning asking for the user to write + // @import Foo_Private instead. FIXME: remove this when existing clients + // migrate off of Foo.Private syntax. + if (!Sub && PP->getLangOpts().ImplicitModules && Name == "Private" && + Module == Module->getTopLevelModule()) { + SmallString<128> PrivateModule(Module->Name); + PrivateModule.append("_Private"); + + SmallVector, 2> PrivPath; + auto &II = PP->getIdentifierTable().get( + PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID()); + PrivPath.push_back(std::make_pair(&II, Path[0].second)); + + if (PP->getHeaderSearchInfo().lookupModule(PrivateModule)) + Sub = + loadModule(ImportLoc, PrivPath, Visibility, IsInclusionDirective); + if (Sub) { + MapPrivateSubModToTopLevel = true; + if (!getDiagnostics().isIgnored( + diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) { + getDiagnostics().Report(Path[I].second, + diag::warn_no_priv_submodule_use_toplevel) + << Path[I].first << Module->getFullModuleName() << PrivateModule + << SourceRange(Path[0].second, Path[I].second) + << FixItHint::CreateReplacement(SourceRange(Path[0].second), + PrivateModule); + getDiagnostics().Report(Sub->DefinitionLoc, + diag::note_private_top_level_defined); + } + } + } + if (!Sub) { // No submodule by this name. Complain, and don't look for further // submodules. @@ -1909,7 +1943,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, // Make the named module visible, if it's not already part of the module // we are parsing. if (ModuleName != getLangOpts().CurrentModule) { - if (!Module->IsFromModuleFile) { + if (!Module->IsFromModuleFile && !MapPrivateSubModToTopLevel) { // We have an umbrella header or directory that doesn't actually include // all of the headers within the directory it covers. Complain about // this missing submodule and recover by forgetting that we ever saw diff --git a/lib/Frontend/PrecompiledPreamble.cpp b/lib/Frontend/PrecompiledPreamble.cpp index f6964d0..7e1323f 100644 --- a/lib/Frontend/PrecompiledPreamble.cpp +++ b/lib/Frontend/PrecompiledPreamble.cpp @@ -30,7 +30,7 @@ #include "llvm/Support/Mutex.h" #include "llvm/Support/MutexGuard.h" #include "llvm/Support/Process.h" - +#include #include using namespace clang; @@ -333,6 +333,7 @@ llvm::ErrorOr PrecompiledPreamble::Build( std::unique_ptr Act; Act.reset(new PrecompilePreambleAction( StoreInMemory ? &Storage.asMemory().Data : nullptr, Callbacks)); + Callbacks.BeforeExecute(*Clang); if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) return BuildPreambleError::BeginSourceFileFailed; @@ -380,6 +381,27 @@ PreambleBounds PrecompiledPreamble::getBounds() const { return PreambleBounds(PreambleBytes.size(), PreambleEndsAtStartOfLine); } +std::size_t PrecompiledPreamble::getSize() const { + switch (Storage.getKind()) { + case PCHStorage::Kind::Empty: + assert(false && "Calling getSize() on invalid PrecompiledPreamble. " + "Was it std::moved?"); + return 0; + case PCHStorage::Kind::InMemory: + return Storage.asMemory().Data.size(); + case PCHStorage::Kind::TempFile: { + uint64_t Result; + if (llvm::sys::fs::file_size(Storage.asFile().getFilePath(), Result)) + return 0; + + assert(Result <= std::numeric_limits::max() && + "file size did not fit into size_t"); + return Result; + } + } + llvm_unreachable("Unhandled storage kind"); +} + bool PrecompiledPreamble::CanReuse(const CompilerInvocation &Invocation, const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds, @@ -505,8 +527,8 @@ PrecompiledPreamble::TempPCHFile::createInSystemTempDir(const Twine &Prefix, StringRef Suffix) { llvm::SmallString<64> File; // Using a version of createTemporaryFile with a file descriptor guarantees - // that we would never get a race condition in a multi-threaded setting (i.e., - // multiple threads getting the same temporary path). + // that we would never get a race condition in a multi-threaded setting + // (i.e., multiple threads getting the same temporary path). int FD; auto EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, FD, File); if (EC) @@ -694,6 +716,7 @@ void PrecompiledPreamble::setupPreambleStorage( } } +void PreambleCallbacks::BeforeExecute(CompilerInstance &CI) {} void PreambleCallbacks::AfterExecute(CompilerInstance &CI) {} void PreambleCallbacks::AfterPCHEmitted(ASTWriter &Writer) {} void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {} diff --git a/lib/Headers/__clang_cuda_intrinsics.h b/lib/Headers/__clang_cuda_intrinsics.h index 02d68a2..1794eb3 100644 --- a/lib/Headers/__clang_cuda_intrinsics.h +++ b/lib/Headers/__clang_cuda_intrinsics.h @@ -34,23 +34,24 @@ #if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 300 #pragma push_macro("__MAKE_SHUFFLES") -#define __MAKE_SHUFFLES(__FnName, __IntIntrinsic, __FloatIntrinsic, __Mask) \ - inline __device__ int __FnName(int __val, int __offset, \ +#define __MAKE_SHUFFLES(__FnName, __IntIntrinsic, __FloatIntrinsic, __Mask, \ + __Type) \ + inline __device__ int __FnName(int __val, __Type __offset, \ int __width = warpSize) { \ return __IntIntrinsic(__val, __offset, \ ((warpSize - __width) << 8) | (__Mask)); \ } \ - inline __device__ float __FnName(float __val, int __offset, \ + inline __device__ float __FnName(float __val, __Type __offset, \ int __width = warpSize) { \ return __FloatIntrinsic(__val, __offset, \ ((warpSize - __width) << 8) | (__Mask)); \ } \ - inline __device__ unsigned int __FnName(unsigned int __val, int __offset, \ + inline __device__ unsigned int __FnName(unsigned int __val, __Type __offset, \ int __width = warpSize) { \ return static_cast( \ ::__FnName(static_cast(__val), __offset, __width)); \ } \ - inline __device__ long long __FnName(long long __val, int __offset, \ + inline __device__ long long __FnName(long long __val, __Type __offset, \ int __width = warpSize) { \ struct __Bits { \ int __a, __b; \ @@ -65,12 +66,29 @@ memcpy(&__ret, &__tmp, sizeof(__tmp)); \ return __ret; \ } \ + inline __device__ long __FnName(long __val, __Type __offset, \ + int __width = warpSize) { \ + _Static_assert(sizeof(long) == sizeof(long long) || \ + sizeof(long) == sizeof(int)); \ + if (sizeof(long) == sizeof(long long)) { \ + return static_cast( \ + ::__FnName(static_cast(__val), __offset, __width)); \ + } else if (sizeof(long) == sizeof(int)) { \ + return static_cast( \ + ::__FnName(static_cast(__val), __offset, __width)); \ + } \ + } \ + inline __device__ unsigned long __FnName( \ + unsigned long __val, __Type __offset, int __width = warpSize) { \ + return static_cast( \ + ::__FnName(static_cast(__val), __offset, __width)); \ + } \ inline __device__ unsigned long long __FnName( \ - unsigned long long __val, int __offset, int __width = warpSize) { \ + unsigned long long __val, __Type __offset, int __width = warpSize) { \ return static_cast(::__FnName( \ static_cast(__val), __offset, __width)); \ } \ - inline __device__ double __FnName(double __val, int __offset, \ + inline __device__ double __FnName(double __val, __Type __offset, \ int __width = warpSize) { \ long long __tmp; \ _Static_assert(sizeof(__tmp) == sizeof(__val)); \ @@ -81,13 +99,15 @@ return __ret; \ } -__MAKE_SHUFFLES(__shfl, __nvvm_shfl_idx_i32, __nvvm_shfl_idx_f32, 0x1f); +__MAKE_SHUFFLES(__shfl, __nvvm_shfl_idx_i32, __nvvm_shfl_idx_f32, 0x1f, int); // We use 0 rather than 31 as our mask, because shfl.up applies to lanes >= // maxLane. -__MAKE_SHUFFLES(__shfl_up, __nvvm_shfl_up_i32, __nvvm_shfl_up_f32, 0); -__MAKE_SHUFFLES(__shfl_down, __nvvm_shfl_down_i32, __nvvm_shfl_down_f32, 0x1f); -__MAKE_SHUFFLES(__shfl_xor, __nvvm_shfl_bfly_i32, __nvvm_shfl_bfly_f32, 0x1f); - +__MAKE_SHUFFLES(__shfl_up, __nvvm_shfl_up_i32, __nvvm_shfl_up_f32, 0, + unsigned int); +__MAKE_SHUFFLES(__shfl_down, __nvvm_shfl_down_i32, __nvvm_shfl_down_f32, 0x1f, + unsigned int); +__MAKE_SHUFFLES(__shfl_xor, __nvvm_shfl_bfly_i32, __nvvm_shfl_bfly_f32, 0x1f, + int); #pragma pop_macro("__MAKE_SHUFFLES") #endif // !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 300 @@ -97,25 +117,26 @@ __MAKE_SHUFFLES(__shfl_xor, __nvvm_shfl_bfly_i32, __nvvm_shfl_bfly_f32, 0x1f); // __shfl_sync_* variants available in CUDA-9 #pragma push_macro("__MAKE_SYNC_SHUFFLES") #define __MAKE_SYNC_SHUFFLES(__FnName, __IntIntrinsic, __FloatIntrinsic, \ - __Mask) \ - inline __device__ int __FnName(unsigned int __mask, int __val, int __offset, \ - int __width = warpSize) { \ + __Mask, __Type) \ + inline __device__ int __FnName(unsigned int __mask, int __val, \ + __Type __offset, int __width = warpSize) { \ return __IntIntrinsic(__mask, __val, __offset, \ ((warpSize - __width) << 8) | (__Mask)); \ } \ inline __device__ float __FnName(unsigned int __mask, float __val, \ - int __offset, int __width = warpSize) { \ + __Type __offset, int __width = warpSize) { \ return __FloatIntrinsic(__mask, __val, __offset, \ ((warpSize - __width) << 8) | (__Mask)); \ } \ inline __device__ unsigned int __FnName(unsigned int __mask, \ - unsigned int __val, int __offset, \ + unsigned int __val, __Type __offset, \ int __width = warpSize) { \ return static_cast( \ ::__FnName(__mask, static_cast(__val), __offset, __width)); \ } \ inline __device__ long long __FnName(unsigned int __mask, long long __val, \ - int __offset, int __width = warpSize) { \ + __Type __offset, \ + int __width = warpSize) { \ struct __Bits { \ int __a, __b; \ }; \ @@ -130,13 +151,13 @@ __MAKE_SHUFFLES(__shfl_xor, __nvvm_shfl_bfly_i32, __nvvm_shfl_bfly_f32, 0x1f); return __ret; \ } \ inline __device__ unsigned long long __FnName( \ - unsigned int __mask, unsigned long long __val, int __offset, \ + unsigned int __mask, unsigned long long __val, __Type __offset, \ int __width = warpSize) { \ return static_cast(::__FnName( \ __mask, static_cast(__val), __offset, __width)); \ } \ inline __device__ long __FnName(unsigned int __mask, long __val, \ - int __offset, int __width = warpSize) { \ + __Type __offset, int __width = warpSize) { \ _Static_assert(sizeof(long) == sizeof(long long) || \ sizeof(long) == sizeof(int)); \ if (sizeof(long) == sizeof(long long)) { \ @@ -147,14 +168,14 @@ __MAKE_SHUFFLES(__shfl_xor, __nvvm_shfl_bfly_i32, __nvvm_shfl_bfly_f32, 0x1f); ::__FnName(__mask, static_cast(__val), __offset, __width)); \ } \ } \ - inline __device__ unsigned long __FnName(unsigned int __mask, \ - unsigned long __val, int __offset, \ - int __width = warpSize) { \ + inline __device__ unsigned long __FnName( \ + unsigned int __mask, unsigned long __val, __Type __offset, \ + int __width = warpSize) { \ return static_cast( \ ::__FnName(__mask, static_cast(__val), __offset, __width)); \ } \ inline __device__ double __FnName(unsigned int __mask, double __val, \ - int __offset, int __width = warpSize) { \ + __Type __offset, int __width = warpSize) { \ long long __tmp; \ _Static_assert(sizeof(__tmp) == sizeof(__val)); \ memcpy(&__tmp, &__val, sizeof(__val)); \ @@ -164,15 +185,15 @@ __MAKE_SHUFFLES(__shfl_xor, __nvvm_shfl_bfly_i32, __nvvm_shfl_bfly_f32, 0x1f); return __ret; \ } __MAKE_SYNC_SHUFFLES(__shfl_sync, __nvvm_shfl_sync_idx_i32, - __nvvm_shfl_sync_idx_f32, 0x1f); + __nvvm_shfl_sync_idx_f32, 0x1f, int); // We use 0 rather than 31 as our mask, because shfl.up applies to lanes >= // maxLane. __MAKE_SYNC_SHUFFLES(__shfl_up_sync, __nvvm_shfl_sync_up_i32, - __nvvm_shfl_sync_up_f32, 0); + __nvvm_shfl_sync_up_f32, 0, unsigned int); __MAKE_SYNC_SHUFFLES(__shfl_down_sync, __nvvm_shfl_sync_down_i32, - __nvvm_shfl_sync_down_f32, 0x1f); + __nvvm_shfl_sync_down_f32, 0x1f, unsigned int); __MAKE_SYNC_SHUFFLES(__shfl_xor_sync, __nvvm_shfl_sync_bfly_i32, - __nvvm_shfl_sync_bfly_f32, 0x1f); + __nvvm_shfl_sync_bfly_f32, 0x1f, int); #pragma pop_macro("__MAKE_SYNC_SHUFFLES") inline __device__ void __syncwarp(unsigned int mask = 0xffffffff) { diff --git a/lib/Headers/cpuid.h b/lib/Headers/cpuid.h index 2dd0add..3ae90de 100644 --- a/lib/Headers/cpuid.h +++ b/lib/Headers/cpuid.h @@ -173,16 +173,24 @@ #define bit_AVX512VL 0x80000000 /* Features in %ecx for leaf 7 sub-leaf 0 */ -#define bit_PREFTCHWT1 0x00000001 -#define bit_AVX512VBMI 0x00000002 -#define bit_PKU 0x00000004 -#define bit_OSPKE 0x00000010 +#define bit_PREFTCHWT1 0x00000001 +#define bit_AVX512VBMI 0x00000002 +#define bit_PKU 0x00000004 +#define bit_OSPKE 0x00000010 +#define bit_AVX512VBMI2 0x00000040 +#define bit_SHSTK 0x00000080 +#define bit_GFNI 0x00000100 +#define bit_VAES 0x00000200 +#define bit_VPCLMULQDQ 0x00000400 +#define bit_AVX512VNNI 0x00000800 +#define bit_AVX512BITALG 0x00001000 #define bit_AVX512VPOPCNTDQ 0x00004000 -#define bit_RDPID 0x00400000 +#define bit_RDPID 0x00400000 /* Features in %edx for leaf 7 sub-leaf 0 */ #define bit_AVX5124VNNIW 0x00000004 #define bit_AVX5124FMAPS 0x00000008 +#define bit_IBT 0x00100000 /* Features in %eax for leaf 13 sub-leaf 1 */ #define bit_XSAVEOPT 0x00000001 @@ -192,6 +200,7 @@ /* Features in %ecx for leaf 0x80000001 */ #define bit_LAHF_LM 0x00000001 #define bit_ABM 0x00000020 +#define bit_LZCNT bit_ABM /* for gcc compat */ #define bit_SSE4a 0x00000040 #define bit_PRFCHW 0x00000100 #define bit_XOP 0x00000800 diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h index bbc2117..279c027 100644 --- a/lib/Headers/xmmintrin.h +++ b/lib/Headers/xmmintrin.h @@ -2035,9 +2035,11 @@ _mm_storer_ps(float *__p, __m128 __a) _mm_store_ps(__p, __a); } -#define _MM_HINT_T0 3 -#define _MM_HINT_T1 2 -#define _MM_HINT_T2 1 +#define _MM_HINT_ET0 7 +#define _MM_HINT_ET1 6 +#define _MM_HINT_T0 3 +#define _MM_HINT_T1 2 +#define _MM_HINT_T2 1 #define _MM_HINT_NTA 0 #ifndef _MSC_VER @@ -2068,7 +2070,8 @@ _mm_storer_ps(float *__p, __m128 __a) /// be generated. \n /// _MM_HINT_T2: Move data using the T2 hint. The PREFETCHT2 instruction will /// be generated. -#define _mm_prefetch(a, sel) (__builtin_prefetch((void *)(a), 0, (sel))) +#define _mm_prefetch(a, sel) (__builtin_prefetch((void *)(a), \ + ((sel) >> 2) & 1, (sel) & 0x3)) #endif /// \brief Stores a 64-bit integer in the specified aligned memory location. To diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp index 03db0cd..733d4db 100644 --- a/lib/Index/IndexSymbol.cpp +++ b/lib/Index/IndexSymbol.cpp @@ -42,10 +42,10 @@ static bool isUnitTest(const ObjCMethodDecl *D) { static void checkForIBOutlets(const Decl *D, SymbolPropertySet &PropSet) { if (D->hasAttr()) { - PropSet |= (unsigned)SymbolProperty::IBAnnotated; + PropSet |= (SymbolPropertySet)SymbolProperty::IBAnnotated; } else if (D->hasAttr()) { - PropSet |= (unsigned)SymbolProperty::IBAnnotated; - PropSet |= (unsigned)SymbolProperty::IBOutletCollection; + PropSet |= (SymbolPropertySet)SymbolProperty::IBAnnotated; + PropSet |= (SymbolPropertySet)SymbolProperty::IBOutletCollection; } } @@ -93,7 +93,7 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { Info.Lang = SymbolLanguage::C; if (isFunctionLocalSymbol(D)) { - Info.Properties |= (unsigned)SymbolProperty::Local; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Local; } if (const TagDecl *TD = dyn_cast(D)) { @@ -118,17 +118,19 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { if (!CXXRec->isCLike()) { Info.Lang = SymbolLanguage::CXX; if (CXXRec->getDescribedClassTemplate()) { - Info.Properties |= (unsigned)SymbolProperty::Generic; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; } } } if (isa(D)) { - Info.Properties |= (unsigned)SymbolProperty::Generic; - Info.Properties |= (unsigned)SymbolProperty::TemplatePartialSpecialization; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; + Info.Properties |= + (SymbolPropertySet)SymbolProperty::TemplatePartialSpecialization; } else if (isa(D)) { - Info.Properties |= (unsigned)SymbolProperty::Generic; - Info.Properties |= (unsigned)SymbolProperty::TemplateSpecialization; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; + Info.Properties |= + (SymbolPropertySet)SymbolProperty::TemplateSpecialization; } } else if (auto *VD = dyn_cast(D)) { @@ -142,15 +144,17 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { if (isa(D)) { Info.Lang = SymbolLanguage::CXX; - Info.Properties |= (unsigned)SymbolProperty::Generic; - Info.Properties |= (unsigned)SymbolProperty::TemplatePartialSpecialization; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; + Info.Properties |= + (SymbolPropertySet)SymbolProperty::TemplatePartialSpecialization; } else if (isa(D)) { Info.Lang = SymbolLanguage::CXX; - Info.Properties |= (unsigned)SymbolProperty::Generic; - Info.Properties |= (unsigned)SymbolProperty::TemplateSpecialization; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; + Info.Properties |= + (SymbolPropertySet)SymbolProperty::TemplateSpecialization; } else if (VD->getDescribedVarTemplate()) { Info.Lang = SymbolLanguage::CXX; - Info.Properties |= (unsigned)SymbolProperty::Generic; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; } } else { @@ -181,7 +185,7 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { if (!ClsD) ClsD = cast(D)->getClassInterface(); if (isUnitTestCase(ClsD)) - Info.Properties |= (unsigned)SymbolProperty::UnitTest; + Info.Properties |= (SymbolPropertySet)SymbolProperty::UnitTest; break; } case Decl::ObjCProtocol: @@ -198,7 +202,7 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { else ClsD = cast(D)->getClassInterface(); if (isUnitTestCase(ClsD)) - Info.Properties |= (unsigned)SymbolProperty::UnitTest; + Info.Properties |= (SymbolPropertySet)SymbolProperty::UnitTest; break; } case Decl::ObjCMethod: { @@ -212,9 +216,9 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { } Info.Lang = SymbolLanguage::ObjC; if (isUnitTest(MD)) - Info.Properties |= (unsigned)SymbolProperty::UnitTest; + Info.Properties |= (SymbolPropertySet)SymbolProperty::UnitTest; if (D->hasAttr()) - Info.Properties |= (unsigned)SymbolProperty::IBAnnotated; + Info.Properties |= (SymbolPropertySet)SymbolProperty::IBAnnotated; break; } case Decl::ObjCProperty: @@ -223,7 +227,7 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { checkForIBOutlets(D, Info.Properties); if (auto *Annot = D->getAttr()) { if (Annot->getAnnotation() == "gk_inspectable") - Info.Properties |= (unsigned)SymbolProperty::GKInspectable; + Info.Properties |= (SymbolPropertySet)SymbolProperty::GKInspectable; } break; case Decl::ObjCIvar: @@ -268,12 +272,12 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { } case Decl::ClassTemplate: Info.Kind = SymbolKind::Class; - Info.Properties |= (unsigned)SymbolProperty::Generic; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; Info.Lang = SymbolLanguage::CXX; break; case Decl::FunctionTemplate: Info.Kind = SymbolKind::Function; - Info.Properties |= (unsigned)SymbolProperty::Generic; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; Info.Lang = SymbolLanguage::CXX; if (const CXXMethodDecl *MD = dyn_cast_or_null( cast(D)->getTemplatedDecl())) { @@ -294,7 +298,7 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { case Decl::TypeAliasTemplate: Info.Kind = SymbolKind::TypeAlias; Info.Lang = SymbolLanguage::CXX; - Info.Properties |= (unsigned)SymbolProperty::Generic; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; break; case Decl::TypeAlias: Info.Kind = SymbolKind::TypeAlias; @@ -304,13 +308,13 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { Info.Kind = SymbolKind::Using; Info.SubKind = SymbolSubKind::UsingTypename; Info.Lang = SymbolLanguage::CXX; - Info.Properties |= (unsigned)SymbolProperty::Generic; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; break; case Decl::UnresolvedUsingValue: Info.Kind = SymbolKind::Using; Info.SubKind = SymbolSubKind::UsingValue; Info.Lang = SymbolLanguage::CXX; - Info.Properties |= (unsigned)SymbolProperty::Generic; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; break; case Decl::Binding: Info.Kind = SymbolKind::Variable; @@ -327,12 +331,13 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { if (const FunctionDecl *FD = dyn_cast(D)) { if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplateSpecialization) { - Info.Properties |= (unsigned)SymbolProperty::Generic; - Info.Properties |= (unsigned)SymbolProperty::TemplateSpecialization; + Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic; + Info.Properties |= + (SymbolPropertySet)SymbolProperty::TemplateSpecialization; } } - if (Info.Properties & (unsigned)SymbolProperty::Generic) + if (Info.Properties & (SymbolPropertySet)SymbolProperty::Generic) Info.Lang = SymbolLanguage::CXX; if (auto *attr = D->getExternalSourceSymbolAttr()) { @@ -490,9 +495,9 @@ StringRef index::getSymbolLanguageString(SymbolLanguage K) { void index::applyForEachSymbolProperty(SymbolPropertySet Props, llvm::function_ref Fn) { -#define APPLY_FOR_PROPERTY(K) \ - if (Props & (unsigned)SymbolProperty::K) \ - Fn(SymbolProperty::K) +#define APPLY_FOR_PROPERTY(K) \ + if (Props & (SymbolPropertySet)SymbolProperty::K) \ + Fn(SymbolProperty::K) APPLY_FOR_PROPERTY(Generic); APPLY_FOR_PROPERTY(TemplatePartialSpecialization); diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index aa25886..6976294 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -209,11 +209,14 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { // The facility for "private modules" -- adjacent, optional module maps named // module.private.modulemap that are supposed to define private submodules -- - // is sometimes misused by frameworks that name their associated private - // module FooPrivate, rather than as a submodule named Foo.Private as - // intended. Here we compensate for such cases by looking in directories named - // Foo.framework, when we previously looked and failed to find a - // FooPrivate.framework. + // may have different flavors of names: FooPrivate, Foo_Private and Foo.Private. + // + // Foo.Private is now depracated in favor of Foo_Private. Users of FooPrivate + // should also rename to Foo_Private. Representing private as submodules + // could force building unwanted dependencies into the parent module and cause + // dependency cycles. + if (!Module && SearchName.consume_back("_Private")) + Module = lookupModule(ModuleName, SearchName); if (!Module && SearchName.consume_back("Private")) Module = lookupModule(ModuleName, SearchName); return Module; diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp index fbbae7a..b3ac10c 100644 --- a/lib/Lex/ModuleMap.cpp +++ b/lib/Lex/ModuleMap.cpp @@ -1608,6 +1608,54 @@ namespace { } // namespace +/// Private modules are canonicalized as Foo_Private. Clang provides extra +/// module map search logic to find the appropriate private module when PCH +/// is used with implicit module maps. Warn when private modules are written +/// in other ways (FooPrivate and Foo.Private), providing notes and fixits. +static void diagnosePrivateModules(const ModuleMap &Map, + DiagnosticsEngine &Diags, + const Module *ActiveModule) { + + auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical, + const Module *M) { + auto D = Diags.Report(ActiveModule->DefinitionLoc, + diag::note_mmap_rename_top_level_private_module); + D << BadName << M->Name; + D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc, Canonical); + }; + + for (auto E = Map.module_begin(); E != Map.module_end(); ++E) { + auto const *M = E->getValue(); + if (M->Directory != ActiveModule->Directory) + continue; + + SmallString<128> FullName(ActiveModule->getFullModuleName()); + if (!FullName.startswith(M->Name) && !FullName.endswith("Private")) + continue; + SmallString<128> Canonical(M->Name); + Canonical.append("_Private"); + + // Foo.Private -> Foo_Private + if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent && + M->Name == ActiveModule->Parent->Name) { + Diags.Report(ActiveModule->DefinitionLoc, + diag::warn_mmap_mismatched_private_submodule) + << FullName; + GenNoteAndFixIt(FullName, Canonical, M); + continue; + } + + // FooPrivate and whatnots -> Foo_Private + if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name && + ActiveModule->Name != Canonical) { + Diags.Report(ActiveModule->DefinitionLoc, + diag::warn_mmap_mismatched_private_module_name) + << ActiveModule->Name; + GenNoteAndFixIt(ActiveModule->Name, Canonical, M); + } + } +} + /// \brief Parse a module declaration. /// /// module-declaration: @@ -1791,41 +1839,21 @@ void ModuleMapParser::parseModuleDecl() { ActiveModule->NoUndeclaredIncludes = true; ActiveModule->Directory = Directory; - if (!ActiveModule->Parent) { - StringRef MapFileName(ModuleMapFile->getName()); - if (MapFileName.endswith("module.private.modulemap") || - MapFileName.endswith("module_private.map")) { - // Adding a top-level module from a private modulemap is likely a - // user error; we check to see if there's another top-level module - // defined in the non-private map in the same dir, and if so emit a - // warning. - for (auto E = Map.module_begin(); E != Map.module_end(); ++E) { - auto const *M = E->getValue(); - if (!M->Parent && - M->Directory == ActiveModule->Directory && - M->Name != ActiveModule->Name) { - Diags.Report(ActiveModule->DefinitionLoc, - diag::warn_mmap_mismatched_top_level_private) - << ActiveModule->Name << M->Name; - // The pattern we're defending against here is typically due to - // a module named FooPrivate which is supposed to be a submodule - // called Foo.Private. Emit a fixit in that case. - auto D = - Diags.Report(ActiveModule->DefinitionLoc, - diag::note_mmap_rename_top_level_private_as_submodule); - D << ActiveModule->Name << M->Name; - StringRef Bad(ActiveModule->Name); - if (Bad.consume_back("Private")) { - SmallString<128> Fixed = Bad; - Fixed.append(".Private"); - D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc, - Fixed); - } - break; - } - } - } - } + + // Private modules named as FooPrivate, Foo.Private or similar are likely a + // user error; provide warnings, notes and fixits to direct users to use + // Foo_Private instead. + SourceLocation StartLoc = + SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); + StringRef MapFileName(ModuleMapFile->getName()); + if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps && + !Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule, + StartLoc) && + !Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name, + StartLoc) && + (MapFileName.endswith("module.private.modulemap") || + MapFileName.endswith("module_private.map"))) + diagnosePrivateModules(Map, Diags, ActiveModule); bool Done = false; do { diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index c291a4b..7d789e7 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -420,10 +420,9 @@ bool Preprocessor::SetCodeCompletionPoint(const FileEntry *File, CodeCompletionFile = File; CodeCompletionOffset = Position - Buffer->getBufferStart(); - std::unique_ptr NewBuffer = - MemoryBuffer::getNewUninitMemBuffer(Buffer->getBufferSize() + 1, - Buffer->getBufferIdentifier()); - char *NewBuf = const_cast(NewBuffer->getBufferStart()); + auto NewBuffer = llvm::WritableMemoryBuffer::getNewUninitMemBuffer( + Buffer->getBufferSize() + 1, Buffer->getBufferIdentifier()); + char *NewBuf = NewBuffer->getBufferStart(); char *NewPos = std::copy(Buffer->getBufferStart(), Position, NewBuf); *NewPos = '\0'; std::copy(Position, Buffer->getBufferEnd(), NewPos+1); diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 6df9df8..56a16b9 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -372,10 +372,10 @@ bool Parser::ParseTemplateParameterList(unsigned Depth, SmallVectorImpl &TemplateParams) { while (1) { - // FIXME: ParseTemplateParameter should probably just return a NamedDecl. - if (Decl *TmpParam + + if (NamedDecl *TmpParam = ParseTemplateParameter(Depth, TemplateParams.size())) { - TemplateParams.push_back(dyn_cast(TmpParam)); + TemplateParams.push_back(TmpParam); } else { // If we failed to parse a template parameter, skip until we find // a comma or closing brace. @@ -480,7 +480,7 @@ bool Parser::isStartOfTemplateTypeParameter() { /// 'class' ...[opt] identifier[opt] /// 'template' '<' template-parameter-list '>' 'class' identifier[opt] /// = id-expression -Decl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { +NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { if (isStartOfTemplateTypeParameter()) return ParseTypeParameter(Depth, Position); @@ -502,7 +502,7 @@ Decl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { /// 'class' identifier[opt] '=' type-id /// 'typename' ...[opt][C++0x] identifier[opt] /// 'typename' identifier[opt] '=' type-id -Decl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) { +NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) { assert(Tok.isOneOf(tok::kw_class, tok::kw_typename) && "A type-parameter starts with 'class' or 'typename'"); @@ -564,7 +564,7 @@ Decl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) { /// type-parameter-key: /// 'class' /// 'typename' [C++1z] -Decl * +NamedDecl * Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { assert(Tok.is(tok::kw_template) && "Expected 'template' keyword"); @@ -669,7 +669,7 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { /// template-parameter: /// ... /// parameter-declaration -Decl * +NamedDecl * Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { // Parse the declaration-specifiers (i.e., the type). // FIXME: The type should probably be restricted in some way... Not all diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp index 23d1895..618c017 100644 --- a/lib/Rewrite/HTMLRewrite.cpp +++ b/lib/Rewrite/HTMLRewrite.cpp @@ -342,6 +342,7 @@ void html::AddHeaderFooterInternalBuiltinCSS(Rewriter &R, FileID FID, " .CodeInsertionHint { font-weight: bold; background-color: #10dd10 }\n" " .CodeRemovalHint { background-color:#de1010 }\n" " .CodeRemovalHint { border-bottom:1px solid #6F9DBE }\n" + " .selected{ background-color:orange !important; }\n" " table.simpletable {\n" " padding: 5px;\n" " font-size:12pt;\n" diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp index 542b653..3431ddc 100644 --- a/lib/Sema/CodeCompleteConsumer.cpp +++ b/lib/Sema/CodeCompleteConsumer.cpp @@ -562,7 +562,7 @@ void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) { // Do nothing: Patterns can come with cursor kinds! break; } - // Fall through + LLVM_FALLTHROUGH; case RK_Declaration: { // Set the availability based on attributes. diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp index 865aea9..64fa2c3 100644 --- a/lib/Sema/JumpDiagnostics.cpp +++ b/lib/Sema/JumpDiagnostics.cpp @@ -323,7 +323,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, BuildScopeInformation(Var, ParentScope); ++StmtsToSkip; } - // Fall through + LLVM_FALLTHROUGH; case Stmt::GotoStmtClass: // Remember both what scope a goto is in as well as the fact that we have diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 94070bb..803f87b 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -2278,7 +2278,7 @@ bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { default: return false; case X86::BI_mm_prefetch: - i = 1; l = 0; u = 3; + i = 1; l = 0; u = 7; break; case X86::BI__builtin_ia32_sha1rnds4: case X86::BI__builtin_ia32_shuf_f32x4_256_mask: @@ -3020,7 +3020,7 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, case AtomicExpr::AO__atomic_add_fetch: case AtomicExpr::AO__atomic_sub_fetch: IsAddSub = true; - // Fall through. + LLVM_FALLTHROUGH; case AtomicExpr::AO__c11_atomic_fetch_and: case AtomicExpr::AO__c11_atomic_fetch_or: case AtomicExpr::AO__c11_atomic_fetch_xor: @@ -8487,7 +8487,7 @@ static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth) { return IntRange(R.Width, /*NonNegative*/ true); } } - // fallthrough + LLVM_FALLTHROUGH; case BO_ShlAssign: return IntRange::forValueOfType(C, GetExprType(E)); diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 834e149..9aed178 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -1420,7 +1420,7 @@ static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC, Results.AddResult(Result("mutable")); Results.AddResult(Result("virtual")); } - // Fall through + LLVM_FALLTHROUGH; case Sema::PCC_ObjCInterface: case Sema::PCC_ObjCImplementation: @@ -1638,7 +1638,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, AddObjCTopLevelResults(Results, true); AddTypedefResult(Results); - // Fall through + LLVM_FALLTHROUGH; case Sema::PCC_Class: if (SemaRef.getLangOpts().CPlusPlus) { @@ -1688,7 +1688,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Results.AddResult(Result(Builder.TakeString())); } } - // Fall through + LLVM_FALLTHROUGH; case Sema::PCC_Template: case Sema::PCC_MemberTemplate: diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ec5ca69..a1fc725 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -10671,7 +10671,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { // that has an in-class initializer, so we type-check this like // a declaration. // - // Fall through + LLVM_FALLTHROUGH; case VarDecl::DeclarationOnly: // It's only a declaration. @@ -12179,9 +12179,11 @@ bool Sema::canSkipFunctionBody(Decl *D) { } Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) { - if (FunctionDecl *FD = dyn_cast_or_null(Decl)) + if (!Decl) + return nullptr; + if (FunctionDecl *FD = Decl->getAsFunction()) FD->setHasSkippedBody(); - else if (ObjCMethodDecl *MD = dyn_cast_or_null(Decl)) + else if (ObjCMethodDecl *MD = dyn_cast(Decl)) MD->setHasSkippedBody(); return Decl; } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 676d003..21fe46a 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1844,12 +1844,6 @@ static void handleIFuncAttr(Sema &S, Decl *D, const AttributeList &Attr) { S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << FD << 1; return; } - // FIXME: it should be handled as a target specific attribute. - if (S.Context.getTargetInfo().getTriple().getObjectFormat() != - llvm::Triple::ELF) { - S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); - return; - } D->addAttr(::new (S.Context) IFuncAttr(Attr.getRange(), S.Context, Str, Attr.getAttributeSpellingListIndex())); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 96472a0..f2fb95c 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -8157,7 +8157,7 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R, PastFunctionChunk = true; break; } - // Fall through. + LLVM_FALLTHROUGH; case DeclaratorChunk::Array: NeedsTypedef = true; extendRight(After, Chunk.getSourceRange()); @@ -12352,7 +12352,7 @@ static bool hasOneRealArgument(MultiExprArg Args) { if (!Args[1]->isDefaultArgument()) return false; - // fall through + LLVM_FALLTHROUGH; case 1: return !Args[0]->isDefaultArgument(); } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 929806a..4746355 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -817,7 +817,7 @@ void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) { E->getLocStart(), nullptr, PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg) << Ty << CT); - // Fall through. + LLVM_FALLTHROUGH; case VAK_Valid: if (Ty->isRecordType()) { // This is unlikely to be what the user intended. If the class has a @@ -2881,7 +2881,7 @@ ExprResult Sema::BuildDeclarationNameExpr( valueKind = VK_RValue; break; } - // fallthrough + LLVM_FALLTHROUGH; case Decl::ImplicitParam: case Decl::ParmVar: { @@ -2978,7 +2978,7 @@ ExprResult Sema::BuildDeclarationNameExpr( valueKind = VK_LValue; break; } - // fallthrough + LLVM_FALLTHROUGH; case Decl::CXXConversion: case Decl::CXXDestructor: diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 03ddcc0..dd516ea 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -251,7 +251,7 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, case IMA_Field_Uneval_Context: Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use) << R.getLookupNameInfo().getName(); - // Fall through. + LLVM_FALLTHROUGH; case IMA_Static: case IMA_Abstract: case IMA_Mixed_StaticContext: diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 6ed5047..cd0c2c4 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -2981,6 +2981,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, case OMF_init: if (Method) checkInitMethod(Method, ReceiverType); + break; case OMF_None: case OMF_alloc: diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index e4789cd..011051d 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -6212,7 +6212,7 @@ static const InitializedEntity *getEntityForTemporaryLifetimeExtension( if (Entity->getParent()) return getEntityForTemporaryLifetimeExtension(Entity->getParent(), Entity); - // Fall through. + LLVM_FALLTHROUGH; case InitializedEntity::EK_Delegating: // We can reach this case for aggregate initialization in a constructor: // struct A { int &&r; }; @@ -7656,7 +7656,7 @@ bool InitializationSequence::Diagnose(Sema &S, << Args[0]->getSourceRange(); break; } - // Intentional fallthrough + LLVM_FALLTHROUGH; case FK_NonConstLValueReferenceBindingToUnrelated: S.Diag(Kind.getLocation(), diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index b34bb33..0880b2d 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -1290,9 +1290,14 @@ bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) { } if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { - IsByRef = !DSAStack->hasExplicitDSA( - D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, - Level, /*NotLastprivate=*/true); + IsByRef = + !DSAStack->hasExplicitDSA( + D, + [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, + Level, /*NotLastprivate=*/true) && + // If the variable is artificial and must be captured by value - try to + // capture by value. + !(isa(D) && D->hasAttr()); } // When passing data by copy, we need to make sure it fits the uintptr size @@ -2321,10 +2326,11 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, ASTContext &C = S.getASTContext(); Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); QualType Ty = Init->getType(); + Attr *OMPCaptureKind = nullptr; if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { - if (S.getLangOpts().CPlusPlus) + if (S.getLangOpts().CPlusPlus) { Ty = C.getLValueReferenceType(Ty); - else { + } else { Ty = C.getPointerType(Ty); ExprResult Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); @@ -2333,11 +2339,16 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, Init = Res.get(); } WithInit = true; + } else if (AsExpression) { + // This variable must be captured by value. + OMPCaptureKind = OMPCaptureKindAttr::CreateImplicit(C, OMPC_unknown); } auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, CaptureExpr->getLocStart()); if (!WithInit) CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); + if (OMPCaptureKind) + CED->addAttr(OMPCaptureKind); S.CurContext->addHiddenDecl(CED); S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); return CED; @@ -2346,31 +2357,34 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit) { OMPCapturedExprDecl *CD; - if (auto *VD = S.IsOpenMPCapturedDecl(D)) + if (auto *VD = S.IsOpenMPCapturedDecl(D)) { CD = cast(VD); - else + } else { CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, /*AsExpression=*/false); + } return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), CaptureExpr->getExprLoc()); } static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { + CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); if (!Ref) { - auto *CD = - buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), - CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); + OMPCapturedExprDecl *CD = buildCaptureDecl( + S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, + /*WithInit=*/true, /*AsExpression=*/true); Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), CaptureExpr->getExprLoc()); } ExprResult Res = Ref; if (!S.getLangOpts().CPlusPlus && CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && - Ref->getType()->isPointerType()) + Ref->getType()->isPointerType()) { Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); - if (!Res.isUsable()) - return ExprError(); - return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); + if (!Res.isUsable()) + return ExprError(); + } + return S.DefaultLvalueConversion(Res.get()); } namespace { @@ -8117,12 +8131,13 @@ OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, if (Val.isInvalid()) return nullptr; - ValExpr = MakeFullExpr(Val.get()).get(); + ValExpr = Val.get(); OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -8239,6 +8254,7 @@ OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -8666,6 +8682,7 @@ OMPClause *Sema::ActOnOpenMPScheduleClause( DSAStack->getCurrentDirective(), OMPC_schedule) != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -11355,6 +11372,7 @@ OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_device); if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -12378,6 +12396,7 @@ OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -12404,6 +12423,7 @@ OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); @@ -12514,6 +12534,7 @@ OMPClause *Sema::ActOnOpenMPDistScheduleClause( DSAStack->getCurrentDirective(), OMPC_dist_schedule) != OMPD_unknown && !CurContext->isDependentContext()) { + ValExpr = MakeFullExpr(ValExpr).get(); llvm::MapVector Captures; ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); HelperValStmt = buildPreInits(Context, Captures); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 268be94..2144845 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -5790,7 +5790,7 @@ ExprResult Sema::PerformContextualImplicitConversion( HadMultipleCandidates, ExplicitConversions)) return ExprError(); - // fall through 'OR_Deleted' case. + LLVM_FALLTHROUGH; case OR_Deleted: // We'll complain below about a non-integral condition type. break; @@ -8651,7 +8651,7 @@ void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, case OO_Plus: // '+' is either unary or binary if (Args.size() == 1) OpBuilder.addUnaryPlusPointerOverloads(); - // Fall through. + LLVM_FALLTHROUGH; case OO_Minus: // '-' is either unary or binary if (Args.size() == 1) { @@ -8682,7 +8682,7 @@ void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, case OO_EqualEqual: case OO_ExclaimEqual: OpBuilder.addEqualEqualOrNotEqualMemberPointerOrNullptrOverloads(); - // Fall through. + LLVM_FALLTHROUGH; case OO_Less: case OO_Greater: @@ -8719,12 +8719,12 @@ void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, case OO_Equal: OpBuilder.addAssignmentMemberPointerOrEnumeralOverloads(); - // Fall through. + LLVM_FALLTHROUGH; case OO_PlusEqual: case OO_MinusEqual: OpBuilder.addAssignmentPointerOverloads(Op == OO_Equal); - // Fall through. + LLVM_FALLTHROUGH; case OO_StarEqual: case OO_SlashEqual: diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index c70a8ba..d94cb0d 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -792,7 +792,7 @@ static void maybeDiagnoseTemplateParameterShadow(Sema &SemaRef, Scope *S, /// ParamNameLoc is the location of the parameter name (if any). /// If the type parameter has a default argument, it will be added /// later via ActOnTypeParameterDefault. -Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, +NamedDecl *Sema::ActOnTypeParameter(Scope *S, bool Typename, SourceLocation EllipsisLoc, SourceLocation KeyLoc, IdentifierInfo *ParamName, @@ -922,13 +922,67 @@ QualType Sema::CheckNonTypeTemplateParameterType(QualType T, return QualType(); } -Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, +NamedDecl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, unsigned Depth, unsigned Position, SourceLocation EqualLoc, Expr *Default) { TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); + // Check that we have valid decl-specifiers specified. + auto CheckValidDeclSpecifiers = [this, &D] { + // C++ [temp.param] + // p1 + // template-parameter: + // ... + // parameter-declaration + // p2 + // ... A storage class shall not be specified in a template-parameter + // declaration. + // [dcl.typedef]p1: + // The typedef specifier [...] shall not be used in the decl-specifier-seq + // of a parameter-declaration + const DeclSpec &DS = D.getDeclSpec(); + auto EmitDiag = [this](SourceLocation Loc) { + Diag(Loc, diag::err_invalid_decl_specifier_in_nontype_parm) + << FixItHint::CreateRemoval(Loc); + }; + if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) + EmitDiag(DS.getStorageClassSpecLoc()); + + if (DS.getThreadStorageClassSpec() != TSCS_unspecified) + EmitDiag(DS.getThreadStorageClassSpecLoc()); + + // [dcl.inline]p1: + // The inline specifier can be applied only to the declaration or + // definition of a variable or function. + + if (DS.isInlineSpecified()) + EmitDiag(DS.getInlineSpecLoc()); + + // [dcl.constexpr]p1: + // The constexpr specifier shall be applied only to the definition of a + // variable or variable template or the declaration of a function or + // function template. + + if (DS.isConstexprSpecified()) + EmitDiag(DS.getConstexprSpecLoc()); + + // [dcl.fct.spec]p1: + // Function-specifiers can be used only in function declarations. + + if (DS.isVirtualSpecified()) + EmitDiag(DS.getVirtualSpecLoc()); + + if (DS.isExplicitSpecified()) + EmitDiag(DS.getExplicitSpecLoc()); + + if (DS.isNoreturnSpecified()) + EmitDiag(DS.getNoreturnSpecLoc()); + }; + + CheckValidDeclSpecifiers(); + if (TInfo->getType()->isUndeducedType()) { Diag(D.getIdentifierLoc(), diag::warn_cxx14_compat_template_nontype_parm_auto_type) @@ -999,7 +1053,7 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, /// ActOnTemplateTemplateParameter - Called when a C++ template template /// parameter (e.g. T in template