6 changes: 4 additions & 2 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,10 @@ def warn_drv_amdgpu_cov6: Warning<
"code object v6 is still in development and not ready for production use yet;"
" use at your own risk">;
def err_drv_undetermined_gpu_arch : Error<
"cannot determine %0 architecture: %1; consider passing it via "
"'%2'">;
"cannot determine %0 architecture: %1; consider passing it via '%2'; "
"environment variable CLANG_TOOLCHAIN_PROGRAM_TIMEOUT specifies the tool "
"timeout (integer secs, <=0 is infinite)">;

def warn_drv_multi_gpu_arch : Warning<
"multiple %0 architectures are detected: %1; only the first one is used for "
"'%2'">, InGroup<MultiGPU>;
Expand Down
9 changes: 8 additions & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -985,11 +985,14 @@ def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 "
def warn_main_returns_bool_literal : Warning<"bool literal returned from "
"'main'">, InGroup<Main>;
def err_main_global_variable :
Error<"main cannot be declared as global variable">;
Error<"main cannot be declared as a variable %select{in the global scope|with C language linkage}0">;
def warn_main_redefined : Warning<"variable named 'main' with external linkage "
"has undefined behavior">, InGroup<Main>;
def ext_main_used : Extension<
"referring to 'main' within an expression is a Clang extension">, InGroup<Main>;
def ext_main_invalid_linkage_specification : ExtWarn<
"'main' should not be "
"'extern \"%select{C|C++}0\"'">, InGroup<Main>;

/// parser diagnostics
def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
Expand Down Expand Up @@ -11639,6 +11642,8 @@ def warn_omp_unterminated_declare_target : Warning<
InGroup<SourceUsesOpenMP>;
def err_ompx_bare_no_grid : Error<
"'ompx_bare' clauses requires explicit grid size via 'num_teams' and 'thread_limit' clauses">;
def err_omp_multi_expr_not_allowed: Error<"only one expression allowed in '%0' clause">;
def err_ompx_more_than_three_expr_not_allowed: Error<"at most three expressions are allowed in '%0' clause in 'target teams ompx_bare' construct">;
} // end of OpenMP category

let CategoryName = "Related Result Type Issue" in {
Expand Down Expand Up @@ -11688,6 +11693,8 @@ def err_module_not_defined : Error<
def err_module_redeclaration : Error<
"translation unit contains multiple module declarations">;
def note_prev_module_declaration : Note<"previous module declaration is here">;
def err_module_declaration_missing : Error<
"missing 'export module' declaration in module interface unit">;
def err_module_declaration_missing_after_global_module_introducer : Error<
"missing 'module' declaration at end of global module fragment "
"introduced here">;
Expand Down
46 changes: 23 additions & 23 deletions clang/include/clang/Basic/DiagnosticSerializationKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@ def note_pch_rebuild_required : Note<"please rebuild precompiled header '%0'">;
def note_module_cache_path : Note<
"after modifying system headers, please delete the module cache at '%0'">;

def err_pch_targetopt_mismatch : Error<
"PCH file was compiled for the %0 '%1' but the current translation "
"unit is being compiled for target '%2'">;
def err_pch_targetopt_feature_mismatch : Error<
"%select{AST file was|current translation unit is}0 compiled with the target "
"feature '%1' but the %select{current translation unit is|AST file was}0 "
def err_ast_file_targetopt_mismatch : Error<
"AST file '%0' was compiled for the %1 '%2' but the current translation "
"unit is being compiled for target '%3'">;
def err_ast_file_targetopt_feature_mismatch : Error<
"%select{AST file '%1' was|current translation unit is}0 compiled with the target "
"feature '%2' but the %select{current translation unit is|AST file '%1' was}0 "
"not">;
def err_pch_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in "
"PCH file but is currently %select{disabled|enabled}2">;
def err_pch_langopt_value_mismatch : Error<
"%0 differs in PCH file vs. current file">;
def err_pch_diagopt_mismatch : Error<"%0 is currently enabled, but was not in "
"the PCH file">;
def err_pch_modulecache_mismatch : Error<"PCH was compiled with module cache "
def err_ast_file_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in "
"AST file '%3' but is currently %select{disabled|enabled}2">;
def err_ast_file_langopt_value_mismatch : Error<
"%0 differs in AST file '%1' vs. current file">;
def err_ast_file_diagopt_mismatch : Error<"%0 is currently enabled, but was not in "
"the AST file '%1'">;
def err_ast_file_modulecache_mismatch : Error<"AST file '%2' was compiled with module cache "
"path '%0', but the path is currently '%1'">;
def warn_pch_vfsoverlay_mismatch : Warning<
"PCH was compiled with different VFS overlay files than are currently in use">,
Expand Down Expand Up @@ -99,19 +99,19 @@ def err_module_different_modmap : Error<
"module '%0' %select{uses|does not use}1 additional module map '%2'"
"%select{| not}1 used when the module was built">;

def err_pch_macro_def_undef : Error<
"macro '%0' was %select{defined|undef'd}1 in the precompiled header but "
def err_ast_file_macro_def_undef : Error<
"macro '%0' was %select{defined|undef'd}1 in the AST file '%2' but "
"%select{undef'd|defined}1 on the command line">;
def err_pch_macro_def_conflict : Error<
"definition of macro '%0' differs between the precompiled header ('%1') "
def err_ast_file_macro_def_conflict : Error<
"definition of macro '%0' differs between the AST file '%3' ('%1') "
"and the command line ('%2')">;
def err_pch_undef : Error<
"%select{command line contains|precompiled header was built with}0 "
"'-undef' but %select{precompiled header was not built with it|"
def err_ast_file_undef : Error<
"%select{command line contains|AST file '%1' was built with}0 "
"'-undef' but %select{AST file '%1' was not built with it|"
"it is not present on the command line}0">;
def err_pch_pp_detailed_record : Error<
"%select{command line contains|precompiled header was built with}0 "
"'-detailed-preprocessing-record' but %select{precompiled header was not "
def err_ast_file_pp_detailed_record : Error<
"%select{command line contains|AST file '%1' was built with}0 "
"'-detailed-preprocessing-record' but %select{AST file '%1' was not "
"built with it|it is not present on the command line}0">;

def err_module_odr_violation_missing_decl : Error<
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,10 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtr
FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination)
FEATURE(ptrauth_type_info_vtable_pointer_discrimination, LangOpts.PointerAuthTypeInfoVTPtrDiscrimination)
FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls)
FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
FEATURE(ptrauth_function_pointer_type_discrimination, LangOpts.PointerAuthFunctionTypeDiscrimination)
FEATURE(ptrauth_indirect_gotos, LangOpts.PointerAuthIndirectGotos)
FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
FEATURE(ptrauth_init_fini_address_discrimination, LangOpts.PointerAuthInitFiniAddressDiscrimination)
EXTENSION(swiftcc,
PP.getTargetInfo().checkCallingConvention(CC_Swift) ==
clang::TargetInfo::CCCR_OK)
Expand Down
33 changes: 33 additions & 0 deletions clang/include/clang/Basic/HLSLIntangibleTypes.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//===-- HLSLIntangibleTypes.def - HLSL standard intangible types ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===--------------------------------------------------------------------------===//
//
// This file defines HLSL standard intangible types. These are implementation-
// defined types such as handle types that have no defined object
// representation or value representation and their size is unknown at compile
// time.
//
// The macro is:
//
// HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)
//
// where:
//
// - Name is the name of the builtin type.
//
// - BuiltinType::Id is the enumerator defining the type.
//
// - Context.SingletonId is the global singleton of this type.
//
// To include this file, define HLSL_INTANGIBLE_TYPE.
// The macro will be undefined after inclusion.
//
//===----------------------------------------------------------------------===//

HLSL_INTANGIBLE_TYPE(__hlsl_resource_t, HLSLResource, HLSLResourceTy)

#undef HLSL_INTANGIBLE_TYPE
6 changes: 5 additions & 1 deletion clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ LANGOPT(C2y , 1, 0, "C2y")
LANGOPT(MSVCCompat , 1, 0, "Microsoft Visual C++ full compatibility mode")
LANGOPT(Kernel , 1, 0, "Kernel mode")
LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions")
LANGOPT(ZOSExt , 1, 0, "z/OS extensions")
LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks")
LANGOPT(Borland , 1, 0, "Borland extensions")
LANGOPT(CPlusPlus , 1, 0, "C++")
Expand Down Expand Up @@ -170,9 +171,12 @@ LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps")
LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers")
LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers")
LANGOPT(PointerAuthTypeInfoVTPtrDiscrimination, 1, 0, "incorporate type and address discrimination in authenticated vtable pointers for std::type_info")
LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays")
BENIGN_LANGOPT(PointerAuthFunctionTypeDiscrimination, 1, 0,
"Use type discrimination when signing function pointers")
LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays")
LANGOPT(PointerAuthInitFiniAddressDiscrimination, 1, 0,
"incorporate address discrimination in authenticated function pointers in init/fini arrays")
LANGOPT(PointerAuthELFGOT, 1, 0, "authenticate pointers from GOT")

LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
LANGOPT(ExperimentalLateParseAttributes, 1, 0, "experimental late parsing of attributes")
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/OpenMPKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,11 @@ bool checkFailClauseParameter(OpenMPClauseKind FailClauseParameter);
/// otherwise - false.
bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind);

/// Checks if the specified directive is considered as "informational".
/// \param DKind Specified directive.
/// \return true if it is an informational directive, false otherwise.
bool isOpenMPInformationalDirective(OpenMPDirectiveKind DKind);

/// Checks if the specified directive can capture variables.
/// \param DKind Specified directive.
/// \return true - if the above condition is met for this directive
Expand Down
13 changes: 13 additions & 0 deletions clang/include/clang/Basic/PointerAuthOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@

namespace clang {

/// Constant discriminator to be used with function pointers in .init_array and
/// .fini_array. The value is ptrauth_string_discriminator("init_fini")
constexpr uint16_t InitFiniPointerConstantDiscriminator = 0xD9D4;

constexpr unsigned PointerAuthKeyNone = -1;

/// Constant discriminator for std::type_info vtable pointers: 0xB1EA/45546
Expand Down Expand Up @@ -159,6 +163,12 @@ class PointerAuthSchema {
};

struct PointerAuthOptions {
/// Should return addresses be authenticated?
bool ReturnAddresses = false;

/// Do authentication failures cause a trap?
bool AuthTraps = false;

/// Do indirect goto label addresses need to be authenticated?
bool IndirectGotos = false;

Expand Down Expand Up @@ -186,6 +196,9 @@ struct PointerAuthOptions {

/// The ABI for C++ member function pointers.
PointerAuthSchema CXXMemberFunctionPointers;

/// The ABI for function addresses in .init_array and .fini_array
PointerAuthSchema InitFiniPointers;
};

} // end namespace clang
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/Specifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ namespace clang {
#define GENERIC_IMAGE_TYPE(ImgType, Id) \
TST_##ImgType##_t, // OpenCL image types
#include "clang/Basic/OpenCLImageTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
TST_##Name, // HLSL Intangible Types
#include "clang/Basic/HLSLIntangibleTypes.def"
TST_error // erroneous type
};

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/StmtNodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ def OMPTeamsGenericLoopDirective : StmtNode<OMPLoopDirective>;
def OMPTargetTeamsGenericLoopDirective : StmtNode<OMPLoopDirective>;
def OMPParallelGenericLoopDirective : StmtNode<OMPLoopDirective>;
def OMPTargetParallelGenericLoopDirective : StmtNode<OMPLoopDirective>;
def OMPAssumeDirective : StmtNode<OMPExecutableDirective>;
def OMPErrorDirective : StmtNode<OMPExecutableDirective>;

// OpenACC Constructs.
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ PUNCTUATOR(caretcaret, "^^")
// CHAR8SUPPORT - This is a keyword if 'char8_t' is a built-in type
// KEYFIXEDPOINT - This is a keyword according to the N1169 fixed point
// extension.
// KEYZOS - This is a keyword in C/C++ on z/OS
//
KEYWORD(auto , KEYALL)
KEYWORD(break , KEYALL)
Expand Down Expand Up @@ -654,6 +655,9 @@ KEYWORD(groupshared , KEYHLSL)
KEYWORD(in , KEYHLSL)
KEYWORD(inout , KEYHLSL)
KEYWORD(out , KEYHLSL)
// HLSL Intangible Types
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) KEYWORD(Name, KEYHLSL)
#include "clang/Basic/HLSLIntangibleTypes.def"

// OpenMP Type Traits
UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL)
Expand Down Expand Up @@ -722,7 +726,7 @@ KEYWORD(__funcref , KEYALL)

// Microsoft extensions which should be disabled in strict conformance mode
KEYWORD(__ptr64 , KEYMS)
KEYWORD(__ptr32 , KEYMS)
KEYWORD(__ptr32 , KEYMS | KEYZOS)
KEYWORD(__sptr , KEYMS)
KEYWORD(__uptr , KEYMS)
KEYWORD(__w64 , KEYMS)
Expand Down
34 changes: 25 additions & 9 deletions clang/include/clang/Basic/arm_sve.td
Original file line number Diff line number Diff line change
Expand Up @@ -2092,7 +2092,7 @@ let SVETargetGuard = "sve2p1", SMETargetGuard = "sme2" in {
def SVCNTP_COUNT : SInst<"svcntp_{d}", "n}i", "QcQsQiQl", MergeNone, "aarch64_sve_cntp_{d}", [IsOverloadNone, VerifyRuntimeMode], [ImmCheck<1, ImmCheck2_4_Mul2>]>;
}

let SVETargetGuard = "sve2,b16b16", SMETargetGuard = "sme2,b16b16" in {
let SVETargetGuard = "sve2,sve-b16b16", SMETargetGuard = "sme2,sve-b16b16" in {
defm SVMUL_BF : SInstZPZZ<"svmul", "b", "aarch64_sve_fmul", "aarch64_sve_fmul_u", [VerifyRuntimeMode]>;
defm SVADD_BF : SInstZPZZ<"svadd", "b", "aarch64_sve_fadd", "aarch64_sve_fadd_u", [VerifyRuntimeMode]>;
defm SVSUB_BF : SInstZPZZ<"svsub", "b", "aarch64_sve_fsub", "aarch64_sve_fsub_u", [VerifyRuntimeMode]>;
Expand All @@ -2116,7 +2116,7 @@ def SVFCLAMP_BF : SInst<"svclamp[_{d}]", "dddd", "b", MergeNone, "aarch64_sve_
multiclass MinMaxIntr<string i, string zm, string mul, string t> {
def SVS # NAME : SInst<"sv" # i # "[" # zm # "_{d}_" # mul # "]", t, "csil", MergeNone, "aarch64_sve_s" # i # zm # "_" # mul, [IsStreaming], []>;
def SVU # NAME : SInst<"sv" # i # "[" # zm # "_{d}_" # mul # "]", t, "UcUsUiUl", MergeNone, "aarch64_sve_u" # i # zm # "_" # mul, [IsStreaming], []>;
def SVF # NAME : SInst<"sv" # i # "[" # zm # "_{d}_" # mul # "]", t, "bhfd", MergeNone, "aarch64_sve_f" # i # zm # "_" # mul, [IsStreaming], []>;
def SVF # NAME : SInst<"sv" # i # "[" # zm # "_{d}_" # mul # "]", t, "hfd", MergeNone, "aarch64_sve_f" # i # zm # "_" # mul, [IsStreaming], []>;
}

let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in {
Expand All @@ -2134,11 +2134,11 @@ let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in {
}

multiclass SInstMinMaxByVector<string name> {
def NAME # _SINGLE_X2 : SInst<"sv" # name # "nm[_single_{d}_x2]", "22d", "bhfd", MergeNone, "aarch64_sve_f" # name # "nm_single_x2", [IsStreaming], []>;
def NAME # _SINGLE_X4 : SInst<"sv" # name # "nm[_single_{d}_x4]", "44d", "bhfd", MergeNone, "aarch64_sve_f" # name # "nm_single_x4", [IsStreaming], []>;
def NAME # _SINGLE_X2 : SInst<"sv" # name # "nm[_single_{d}_x2]", "22d", "hfd", MergeNone, "aarch64_sve_f" # name # "nm_single_x2", [IsStreaming], []>;
def NAME # _SINGLE_X4 : SInst<"sv" # name # "nm[_single_{d}_x4]", "44d", "hfd", MergeNone, "aarch64_sve_f" # name # "nm_single_x4", [IsStreaming], []>;

def NAME # _X2 : SInst<"sv" # name # "nm[_{d}_x2]", "222", "bhfd", MergeNone, "aarch64_sve_f" # name # "nm_x2", [IsStreaming], []>;
def NAME # _X4 : SInst<"sv" # name # "nm[_{d}_x4]", "444", "bhfd", MergeNone, "aarch64_sve_f" # name # "nm_x4", [IsStreaming], []>;
def NAME # _X2 : SInst<"sv" # name # "nm[_{d}_x2]", "222", "hfd", MergeNone, "aarch64_sve_f" # name # "nm_x2", [IsStreaming], []>;
def NAME # _X4 : SInst<"sv" # name # "nm[_{d}_x4]", "444", "hfd", MergeNone, "aarch64_sve_f" # name # "nm_x4", [IsStreaming], []>;
}

let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in {
Expand Down Expand Up @@ -2172,9 +2172,25 @@ let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in {
def SVFCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]", "44dd", "hfd", MergeNone, "aarch64_sve_fclamp_single_x4", [IsStreaming], []>;
}

let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2,b16b16"in {
def SVBFCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]", "22dd", "b", MergeNone, "aarch64_sve_bfclamp_single_x2", [IsStreaming], []>;
def SVBFCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]", "44dd", "b", MergeNone, "aarch64_sve_bfclamp_single_x4", [IsStreaming], []>;
multiclass BfSingleMultiVector<string name> {
def NAME # _SINGLE_X2 : SInst<"sv" # name # "[_single_{d}_x2]", "22d", "b", MergeNone, "aarch64_sve_f" # name # "_single_x2", [IsStreaming], []>;
def NAME # _SINGLE_X4 : SInst<"sv" # name # "[_single_{d}_x4]", "44d", "b", MergeNone, "aarch64_sve_f" # name # "_single_x4", [IsStreaming], []>;

def NAME # _X2 : SInst<"sv" # name # "[_{d}_x2]", "222", "b", MergeNone, "aarch64_sve_f" # name # "_x2", [IsStreaming], []>;
def NAME # _X4 : SInst<"sv" # name # "[_{d}_x4]", "444", "b", MergeNone, "aarch64_sve_f" # name # "_x4", [IsStreaming], []>;
}

let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2,sve-b16b16"in {
def SVBFCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]", "22dd", "b", MergeNone, "aarch64_sve_bfclamp_single_x2", [IsStreaming], []>;
def SVBFCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]", "44dd", "b", MergeNone, "aarch64_sve_bfclamp_single_x4", [IsStreaming], []>;

// bfmin, bfmax (single, multi)
defm SVBFMIN : BfSingleMultiVector<"min">;
defm SVBFMAX : BfSingleMultiVector<"max">;

// bfminnm, bfmaxnm (single, multi)
defm SVBFMINNM : BfSingleMultiVector<"minnm">;
defm SVBFMAXNM : BfSingleMultiVector<"maxnm">;
}

let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in {
Expand Down
88 changes: 76 additions & 12 deletions clang/include/clang/Basic/riscv_vector.td
Original file line number Diff line number Diff line change
Expand Up @@ -1378,6 +1378,9 @@ let HasMasked = false,
let RequiredFeatures = ["Zvfhmin"] in
defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "x",
[["v", "v", "vv"]]>;
let RequiredFeatures = ["Zvfbfmin"] in
defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "y",
[["v", "v", "vv"]]>;
let SupportOverloading = false in
defm vmv_v : RVVOutBuiltinSet<"vmv_v_x", "csil",
[["x", "v", "ve"],
Expand Down Expand Up @@ -1890,6 +1893,9 @@ let HasMasked = false,
let RequiredFeatures = ["Zvfhmin"] in
defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "x",
[["vvm", "v", "vvvm"]]>;
let RequiredFeatures = ["Zvfbfmin"] in
defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "y",
[["vvm", "v", "vvvm"]]>;
defm vfmerge : RVVOutOp1BuiltinSet<"vfmerge", "xfd",
[["vfm", "v", "vvem"]]>;
}
Expand All @@ -1912,8 +1918,18 @@ def vfcvt_rtz_x_f_v : RVVConvToSignedBuiltin<"vfcvt_rtz_x">;
let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
def vfwcvt_rtz_xu_f_v : RVVConvToWidenUnsignedBuiltin<"vfwcvt_rtz_xu">;
def vfwcvt_rtz_x_f_v : RVVConvToWidenSignedBuiltin<"vfwcvt_rtz_x">;
def vfwcvt_f_xu_v : RVVConvBuiltin<"Fw", "FwUv", "csi", "vfwcvt_f">;
def vfwcvt_f_x_v : RVVConvBuiltin<"Fw", "Fwv", "csi", "vfwcvt_f">;
def vfwcvt_f_xu_v : RVVConvBuiltin<"Fw", "FwUv", "si", "vfwcvt_f">;
def vfwcvt_f_x_v : RVVConvBuiltin<"Fw", "Fwv", "si", "vfwcvt_f">;
let RequiredFeatures = ["Zvfh"] in {
let Name = "vfwcvt_f_xu_v",
IRName = "vfwcvt_f_xu_v",
MaskedIRName = "vfwcvt_f_xu_v_mask" in
def : RVVConvBuiltin<"Fw", "FwUv", "c", "vfwcvt_f">;
let Name = "vfwcvt_f_x_v",
IRName = "vfwcvt_f_x_v",
MaskedIRName = "vfwcvt_f_x_v_mask" in
def : RVVConvBuiltin<"Fw", "Fwv", "c", "vfwcvt_f">;
}
def vfwcvt_f_f_v : RVVConvBuiltin<"w", "wv", "f", "vfwcvt_f">;
let RequiredFeatures = ["Zvfhmin"] in
def vfwcvt_f_f_v_fp16 : RVVConvBuiltin<"w", "wv", "x", "vfwcvt_f"> {
Expand All @@ -1927,6 +1943,16 @@ let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
def vfncvt_rtz_xu_f_w : RVVConvToNarrowingUnsignedBuiltin<"vfncvt_rtz_xu">;
def vfncvt_rtz_x_f_w : RVVConvToNarrowingSignedBuiltin<"vfncvt_rtz_x">;
let RequiredFeatures = ["Zvfh"] in {
let Name = "vfncvt_rtz_xu_f_w",
IRName = "vfncvt_rtz_xu_f_w",
MaskedIRName = "vfncvt_rtz_xu_f_w_mask" in
def : RVVConvBuiltin<"Uv", "UvFw", "c", "vfncvt_rtz_xu">;
let Name = "vfncvt_rtz_x_f_w",
IRName = "vfncvt_rtz_x_f_w",
MaskedIRName = "vfncvt_rtz_x_f_w_mask" in
def : RVVConvBuiltin<"Iv", "IvFw", "c", "vfncvt_rtz_x">;
}
def vfncvt_rod_f_f_w : RVVConvBuiltin<"v", "vw", "xf", "vfncvt_rod_f">;
}

Expand Down Expand Up @@ -2005,10 +2031,18 @@ let ManualCodegen = [{
let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
let OverloadedName = "vfncvt_x" in
defm :
RVVConvBuiltinSet<"vfncvt_x_f_w", "csi", [["Iv", "IvFwu"]]>;
RVVConvBuiltinSet<"vfncvt_x_f_w", "si", [["Iv", "IvFwu"]]>;
let OverloadedName = "vfncvt_xu" in
defm :
RVVConvBuiltinSet<"vfncvt_xu_f_w", "csi", [["Uv", "UvFwu"]]>;
RVVConvBuiltinSet<"vfncvt_xu_f_w", "si", [["Uv", "UvFwu"]]>;
let RequiredFeatures = ["Zvfh"] in {
let OverloadedName = "vfncvt_x" in
defm :
RVVConvBuiltinSet<"vfncvt_x_f_w", "c", [["Iv", "IvFwu"]]>;
let OverloadedName = "vfncvt_xu" in
defm :
RVVConvBuiltinSet<"vfncvt_xu_f_w", "c", [["Uv", "UvFwu"]]>;
}
let OverloadedName = "vfncvt_f" in {
defm :
RVVConvBuiltinSet<"vfncvt_f_x_w", "xf", [["v", "vIwu"]]>;
Expand Down Expand Up @@ -2055,10 +2089,18 @@ let ManualCodegen = [{
let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
let OverloadedName = "vfncvt_x" in
defm :
RVVConvBuiltinSet<"vfncvt_x_f_w", "csi", [["Iv", "IvFw"]]>;
RVVConvBuiltinSet<"vfncvt_x_f_w", "si", [["Iv", "IvFw"]]>;
let OverloadedName = "vfncvt_xu" in
defm :
RVVConvBuiltinSet<"vfncvt_xu_f_w", "csi", [["Uv", "UvFw"]]>;
RVVConvBuiltinSet<"vfncvt_xu_f_w", "si", [["Uv", "UvFw"]]>;
let RequiredFeatures = ["Zvfh"] in {
let OverloadedName = "vfncvt_x" in
defm :
RVVConvBuiltinSet<"vfncvt_x_f_w", "c", [["Iv", "IvFw"]]>;
let OverloadedName = "vfncvt_xu" in
defm :
RVVConvBuiltinSet<"vfncvt_xu_f_w", "c", [["Uv", "UvFw"]]>;
}
let OverloadedName = "vfncvt_f" in {
defm :
RVVConvBuiltinSet<"vfncvt_f_x_w", "xf", [["v", "vIw"]]>;
Expand Down Expand Up @@ -2256,10 +2298,22 @@ defm vfslide1down : RVVFloatingBinVFBuiltinSet;

// 16.4. Vector Register Gather Instructions
// signed and floating type
defm vrgather : RVVOutBuiltinSet<"vrgather_vv", "csilxfd",
defm vrgather : RVVOutBuiltinSet<"vrgather_vv", "csilfd",
[["vv", "v", "vvUv"]]>;
defm vrgather : RVVOutBuiltinSet<"vrgather_vx", "csilxfd",
defm vrgather : RVVOutBuiltinSet<"vrgather_vx", "csilfd",
[["vx", "v", "vvz"]]>;
let RequiredFeatures = ["Zvfhmin"] in {
defm vrgather : RVVOutBuiltinSet<"vrgather_vv", "x",
[["vv", "v", "vvUv"]]>;
defm vrgather : RVVOutBuiltinSet<"vrgather_vx", "x",
[["vx", "v", "vvz"]]>;
}
let RequiredFeatures = ["Zvfbfmin"] in {
defm vrgather : RVVOutBuiltinSet<"vrgather_vv", "y",
[["vv", "v", "vvUv"]]>;
defm vrgather : RVVOutBuiltinSet<"vrgather_vx", "y",
[["vx", "v", "vvz"]]>;
}
defm vrgatherei16 : RVVOutBuiltinSet<"vrgatherei16_vv", "csilxfd",
[["vv", "v", "vv(Log2EEW:4)Uv"]]>;
// unsigned type
Expand All @@ -2282,8 +2336,14 @@ let HasMasked = false,
IntrinsicTypes = {ResultType, Ops.back()->getType()};
}] in {
// signed and floating type
defm vcompress : RVVOutBuiltinSet<"vcompress", "csilxfd",
defm vcompress : RVVOutBuiltinSet<"vcompress", "csilfd",
[["vm", "v", "vvm"]]>;
let RequiredFeatures = ["Zvfhmin"] in
defm vcompress : RVVOutBuiltinSet<"vcompress", "x",
[["vm", "v", "vvm"]]>;
let RequiredFeatures = ["Zvfbfmin"] in
defm vcompress : RVVOutBuiltinSet<"vcompress", "y",
[["vm", "v", "vvm"]]>;
// unsigned type
defm vcompress : RVVOutBuiltinSet<"vcompress", "csil",
[["vm", "Uv", "UvUvm"]]>;
Expand Down Expand Up @@ -2487,12 +2547,16 @@ let HasMasked = false, HasVL = false, IRName = "" in {
}
}] in {
foreach dst_lmul = ["(SFixedLog2LMUL:0)", "(SFixedLog2LMUL:1)", "(SFixedLog2LMUL:2)"] in {
def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vvKz", "csilxfdy", dst_lmul # "v">;
def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vvKz", "csilxfd", dst_lmul # "v">;
let RequiredFeatures = ["Zvfbfmin"] in
def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vvKz", "y", dst_lmul # "v">;
def : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "UvUvKz", "csil", dst_lmul # "Uv">;
}
foreach nf = NFList in {
defvar T = "(Tuple:" # nf # ")";
def : RVVBuiltin<T # "vv", "v" # T # "vKz", "csilxfdy", "v">;
def : RVVBuiltin<T # "vv", "v" # T # "vKz", "csilxfd", "v">;
let RequiredFeatures = ["Zvfbfmin"] in
def : RVVBuiltin<T # "vv", "v" # T # "vKz", "y", "v">;
def : RVVBuiltin<T # "UvUv", "Uv" # T # "UvKz", "csil", "Uv">;
}
}
Expand Down Expand Up @@ -2573,7 +2637,7 @@ let HasMasked = false, HasVL = false, IRName = "" in {
defvar T = "(Tuple:" # nf # ")";
defvar V = VString<nf, /*signed=*/true>.S;
defvar UV = VString<nf, /*signed=*/false>.S;
def : RVVBuiltin<T # "v", T # "v" # V, "csilxfdy">;
def : RVVBuiltin<T # "v", T # "v" # V, "csilxfd">;
let RequiredFeatures = ["Zvfbfmin"] in
def : RVVBuiltin<T # "v", T # "v" # V, "y">;
def : RVVBuiltin<T # "Uv", T # "Uv" # UV, "csil">;
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/riscv_vector_common.td
Original file line number Diff line number Diff line change
Expand Up @@ -604,10 +604,10 @@ class RVVConvToWidenUnsignedBuiltin<string overloaded_name>
: RVVConvBuiltin<"Uw", "Uwv", "xf", overloaded_name>;

class RVVConvToNarrowingSignedBuiltin<string overloaded_name>
: RVVConvBuiltin<"Iv", "IvFw", "csi", overloaded_name>;
: RVVConvBuiltin<"Iv", "IvFw", "si", overloaded_name>;

class RVVConvToNarrowingUnsignedBuiltin<string overloaded_name>
: RVVConvBuiltin<"Uv", "UvFw", "csi", overloaded_name>;
: RVVConvBuiltin<"Uv", "UvFw", "si", overloaded_name>;

let HasMaskedOffOperand = true in {
multiclass RVVSignedReductionBuiltin {
Expand Down
14 changes: 8 additions & 6 deletions clang/include/clang/Driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -715,14 +715,16 @@ class Driver {
ModuleHeaderMode getModuleHeaderMode() const { return CXX20HeaderType; }

/// Returns true if we are performing any kind of LTO.
bool isUsingLTO(bool IsOffload = false) const {
return getLTOMode(IsOffload) != LTOK_None;
}
bool isUsingLTO() const { return getLTOMode() != LTOK_None; }

/// Get the specific kind of LTO being performed.
LTOKind getLTOMode(bool IsOffload = false) const {
return IsOffload ? OffloadLTOMode : LTOMode;
}
LTOKind getLTOMode() const { return LTOMode; }

/// Returns true if we are performing any kind of offload LTO.
bool isUsingOffloadLTO() const { return getOffloadLTOMode() != LTOK_None; }

/// Get the specific kind of offload LTO being performed.
LTOKind getOffloadLTOMode() const { return OffloadLTOMode; }

private:

Expand Down
30 changes: 21 additions & 9 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -932,8 +932,9 @@ def O_flag : Flag<["-"], "O">, Visibility<[ClangOption, CC1Option, FC1Option]>,
Alias<O>, AliasArgs<["1"]>;
def Ofast : Joined<["-"], "Ofast">, Group<O_Group>,
Visibility<[ClangOption, CC1Option, FlangOption]>,
HelpText<"Deprecated; use '-O3 -ffast-math' for the same behavior,"
" or '-O3' to enable only conforming optimizations">;
HelpTextForVariants<[ClangOption, CC1Option],
"Deprecated; use '-O3 -ffast-math' for the same behavior,"
" or '-O3' to enable only conforming optimizations">;
def P : Flag<["-"], "P">,
Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
Group<Preprocessor_Group>,
Expand Down Expand Up @@ -3065,6 +3066,10 @@ dll version.}]>;
def fms_omit_default_lib : Joined<["-"], "fms-omit-default-lib">,
Group<f_Group>, Flags<[]>,
Visibility<[ClangOption, CLOption]>;
def fzos_extensions : Flag<["-"], "fzos-extensions">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Accept some non-standard constructs supported by the z/OS compiler">;
def fno_zos_extensions : Flag<["-"], "fno-zos-extensions">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Do not accept non-standard constructs supported by the z/OS compiler">;
defm delayed_template_parsing : BoolFOption<"delayed-template-parsing",
LangOpts<"DelayedTemplateParsing">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
Expand Down Expand Up @@ -3104,7 +3109,7 @@ def fmodules_user_build_path : Separate<["-"], "fmodules-user-build-path">, Grou
HelpText<"Specify the module user build path">,
MarshallingInfoString<HeaderSearchOpts<"ModuleUserBuildPath">>;
def fprebuilt_module_path : Joined<["-"], "fprebuilt-module-path=">, Group<i_Group>,
Flags<[]>, Visibility<[ClangOption, CC1Option]>,
Flags<[]>, Visibility<[ClangOption, CLOption, CC1Option]>,
MetaVarName<"<directory>">,
HelpText<"Specify the prebuilt module path">;
defm prebuilt_implicit_modules : BoolFOption<"prebuilt-implicit-modules",
Expand All @@ -3113,11 +3118,11 @@ defm prebuilt_implicit_modules : BoolFOption<"prebuilt-implicit-modules",
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;

def fmodule_output_EQ : Joined<["-"], "fmodule-output=">,
Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option]>,
Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, CC1Option]>,
MarshallingInfoString<FrontendOpts<"ModuleOutputPath">>,
HelpText<"Save intermediate module file results when compiling a standard C++ module unit.">;
def fmodule_output : Flag<["-"], "fmodule-output">, Flags<[NoXarchOption]>,
Visibility<[ClangOption, CC1Option]>,
Visibility<[ClangOption, CLOption, CC1Option]>,
HelpText<"Save intermediate module file results when compiling a standard C++ module unit.">;

defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf",
Expand Down Expand Up @@ -3301,8 +3306,10 @@ def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-sy
Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<LangOpts<"RetainCommentsFromSystemHeaders">>;
def fmodule_header : Flag <["-"], "fmodule-header">, Group<f_Group>,
Visibility<[ClangOption, CLOption]>,
HelpText<"Build a C++20 Header Unit from a header">;
def fmodule_header_EQ : Joined<["-"], "fmodule-header=">, Group<f_Group>,
Visibility<[ClangOption, CLOption]>,
MetaVarName<"<kind>">,
HelpText<"Build a C++20 Header Unit from a header that should be found in the user (fmodule-header=user) or system (fmodule-header=system) search path.">;

Expand Down Expand Up @@ -4253,11 +4260,13 @@ defm ptrauth_vtable_pointer_type_discrimination :
OptInCC1FFlag<"ptrauth-vtable-pointer-type-discrimination", "Enable type discrimination of vtable pointers">;
defm ptrauth_type_info_vtable_pointer_discrimination :
OptInCC1FFlag<"ptrauth-type-info-vtable-pointer-discrimination", "Enable type and address discrimination of vtable pointer of std::type_info">;
defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of function pointers in init/fini arrays">;
defm ptrauth_function_pointer_type_discrimination : OptInCC1FFlag<"ptrauth-function-pointer-type-discrimination",
"Enable type discrimination on C function pointers">;
defm ptrauth_indirect_gotos : OptInCC1FFlag<"ptrauth-indirect-gotos",
"Enable signing and authentication of indirect goto targets">;
defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of function pointers in init/fini arrays">;
defm ptrauth_init_fini_address_discrimination : OptInCC1FFlag<"ptrauth-init-fini-address-discrimination",
"Enable address discrimination of function pointers in init/fini arrays">;
}

def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
Expand Down Expand Up @@ -5502,7 +5511,7 @@ def no__dead__strip__inits__and__terms : Flag<["-"], "no_dead_strip_inits_and_te
def nobuiltininc : Flag<["-"], "nobuiltininc">,
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
Group<IncludePath_Group>,
HelpText<"Disable builtin #include directories">,
HelpText<"Disable builtin #include directories only">,
MarshallingInfoNegativeFlag<HeaderSearchOpts<"UseBuiltinIncludes">>;
def nogpuinc : Flag<["-"], "nogpuinc">, Group<IncludePath_Group>,
HelpText<"Do not add include paths for CUDA/HIP and"
Expand All @@ -5529,8 +5538,10 @@ def noprofilelib : Flag<["-"], "noprofilelib">;
def noseglinkedit : Flag<["-"], "noseglinkedit">;
def nostartfiles : Flag<["-"], "nostartfiles">, Group<Link_Group>;
def nostdinc : Flag<["-"], "nostdinc">,
Visibility<[ClangOption, CLOption, DXCOption]>, Group<IncludePath_Group>;
def nostdlibinc : Flag<["-"], "nostdlibinc">, Group<IncludePath_Group>;
Visibility<[ClangOption, CLOption, DXCOption]>, Group<IncludePath_Group>,
HelpText<"Disable both standard system #include directories and builtin #include directores">;
def nostdlibinc : Flag<["-"], "nostdlibinc">, Group<IncludePath_Group>,
HelpText<"Disable standard system #include directories only">;
def nostdincxx : Flag<["-"], "nostdinc++">, Visibility<[ClangOption, CC1Option]>,
Group<IncludePath_Group>,
HelpText<"Disable standard #include directories for the C++ standard library">,
Expand Down Expand Up @@ -5952,6 +5963,7 @@ def _output : Separate<["--"], "output">, Alias<o>;
def _param : Separate<["--"], "param">, Group<CompileOnly_Group>;
def _param_EQ : Joined<["--"], "param=">, Alias<_param>;
def _precompile : Flag<["--"], "precompile">, Flags<[NoXarchOption]>,
Visibility<[ClangOption, CLOption]>,
Group<Action_Group>, HelpText<"Only precompile the input">;
def _prefix_EQ : Joined<["--"], "prefix=">, Alias<B>;
def _prefix : Separate<["--"], "prefix">, Alias<B>;
Expand Down
3 changes: 1 addition & 2 deletions clang/include/clang/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,7 @@ class ToolChain {

/// Executes the given \p Executable and returns the stdout.
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
executeToolChainProgram(StringRef Executable,
unsigned SecondsToWait = 0) const;
executeToolChainProgram(StringRef Executable) const;

void setTripleEnvironment(llvm::Triple::EnvironmentType Env);

Expand Down
38 changes: 37 additions & 1 deletion clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ struct FormatStyle {
OAS_Align,
/// Horizontally align operands of binary and ternary expressions.
///
/// This is similar to ``AO_Align``, except when
/// This is similar to ``OAS_Align``, except when
/// ``BreakBeforeBinaryOperators`` is set, the operator is un-indented so
/// that the wrapped operand is aligned with the operand on the first line.
/// \code
Expand Down Expand Up @@ -2231,6 +2231,41 @@ struct FormatStyle {
/// \version 3.7
bool BreakBeforeTernaryOperators;

/// Different ways to break binary operations.
enum BreakBinaryOperationsStyle : int8_t {
/// Don't break binary operations
/// \code
/// aaa + bbbb * ccccc - ddddd +
/// eeeeeeeeeeeeeeee;
/// \endcode
BBO_Never,

/// Binary operations will either be all on the same line, or each operation
/// will have one line each.
/// \code
/// aaa +
/// bbbb *
/// ccccc -
/// ddddd +
/// eeeeeeeeeeeeeeee;
/// \endcode
BBO_OnePerLine,

/// Binary operations of a particular precedence that exceed the column
/// limit will have one line each.
/// \code
/// aaa +
/// bbbb * ccccc -
/// ddddd +
/// eeeeeeeeeeeeeeee;
/// \endcode
BBO_RespectPrecedence
};

/// The break constructor initializers style to use.
/// \version 20
BreakBinaryOperationsStyle BreakBinaryOperations;

/// Different ways to break initializers.
enum BreakConstructorInitializersStyle : int8_t {
/// Break constructor initializers before the colon and after the commas.
Expand Down Expand Up @@ -5037,6 +5072,7 @@ struct FormatStyle {
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations &&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakBinaryOperations == R.BreakBinaryOperations &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
BreakFunctionDefinitionParameters ==
R.BreakFunctionDefinitionParameters &&
Expand Down
3 changes: 1 addition & 2 deletions clang/include/clang/Index/DeclOccurrence.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ struct DeclOccurrence {

DeclOccurrence(SymbolRoleSet R, unsigned Offset, const Decl *D,
ArrayRef<SymbolRelation> Relations)
: Roles(R), Offset(Offset), DeclOrMacro(D),
Relations(Relations.begin(), Relations.end()) {}
: Roles(R), Offset(Offset), DeclOrMacro(D), Relations(Relations) {}
DeclOccurrence(SymbolRoleSet R, unsigned Offset, const IdentifierInfo *Name,
const MacroInfo *MI)
: Roles(R), Offset(Offset), DeclOrMacro(MI), MacroName(Name) {}
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Lex/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2139,8 +2139,8 @@ class Preprocessor {
}

/// Given a Token \p Tok that is a numeric constant with length 1,
/// return the character.
char
/// return the value of constant as an unsigned 8-bit integer.
uint8_t
getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
bool *Invalid = nullptr) const {
assert((Tok.is(tok::numeric_constant) || Tok.is(tok::binary_data)) &&
Expand Down
11 changes: 11 additions & 0 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3532,6 +3532,17 @@ class Parser : public CodeCompletionHandler {
OpenMPDirectiveKind DKind, SourceLocation Loc,
bool ReadDirectiveWithinMetadirective);

/// Parses informational directive.
///
/// \param StmtCtx The context in which we're parsing the directive.
/// \param DKind The kind of the informational directive.
/// \param Loc Source location of the beginning of the directive.
/// \param ReadDirectiveWithinMetadirective true if directive is within a
/// metadirective and therefore ends on the closing paren.
StmtResult ParseOpenMPInformationalDirective(
ParsedStmtContext StmtCtx, OpenMPDirectiveKind DKind, SourceLocation Loc,
bool ReadDirectiveWithinMetadirective);

/// Parses clause of kind \a CKind for directive of a kind \a Kind.
///
/// \param DKind Kind of current directive.
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Sema/DeclSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,9 @@ class DeclSpec {
#define GENERIC_IMAGE_TYPE(ImgType, Id) \
static const TST TST_##ImgType##_t = clang::TST_##ImgType##_t;
#include "clang/Basic/OpenCLImageTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
static const TST TST_##Name = clang::TST_##Name;
#include "clang/Basic/HLSLIntangibleTypes.def"
static const TST TST_error = clang::TST_error;

// type-qualifiers
Expand Down
13 changes: 6 additions & 7 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -14186,6 +14186,10 @@ class Sema final : public SemaBase {
std::optional<unsigned> getNumArgumentsInExpansion(
QualType T, const MultiLevelTemplateArgumentList &TemplateArgs);

std::optional<unsigned> getNumArgumentsInExpansionFromUnexpanded(
llvm::ArrayRef<UnexpandedParameterPack> Unexpanded,
const MultiLevelTemplateArgumentList &TemplateArgs);

/// Determine whether the given declarator contains any unexpanded
/// parameter packs.
///
Expand Down Expand Up @@ -15071,9 +15075,6 @@ class Sema final : public SemaBase {
///
/// \param FD The FieldDecl to apply the attribute to
/// \param E The count expression on the attribute
/// \param[out] Decls If the attribute is semantically valid \p Decls
/// is populated with TypeCoupledDeclRefInfo objects, each
/// describing Decls referred to in \p E.
/// \param CountInBytes If true the attribute is from the "sized_by" family of
/// attributes. If the false the attribute is from
/// "counted_by" family of attributes.
Expand All @@ -15086,10 +15087,8 @@ class Sema final : public SemaBase {
/// `counted_by_or_null` attribute.
///
/// \returns false iff semantically valid.
bool CheckCountedByAttrOnField(
FieldDecl *FD, Expr *E,
llvm::SmallVectorImpl<TypeCoupledDeclRefInfo> &Decls, bool CountInBytes,
bool OrNull);
bool CheckCountedByAttrOnField(FieldDecl *FD, Expr *E, bool CountInBytes,
bool OrNull);

///@}
};
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Sema/SemaConcept.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ enum { ConstraintAlignment = 8 };

struct alignas(ConstraintAlignment) AtomicConstraint {
const Expr *ConstraintExpr;
NamedDecl *ConstraintDecl;
std::optional<ArrayRef<TemplateArgumentLoc>> ParameterMapping;

AtomicConstraint(Sema &S, const Expr *ConstraintExpr) :
ConstraintExpr(ConstraintExpr) { };
AtomicConstraint(const Expr *ConstraintExpr, NamedDecl *ConstraintDecl)
: ConstraintExpr(ConstraintExpr), ConstraintDecl(ConstraintDecl) {};

bool hasMatchingParameterMapping(ASTContext &C,
const AtomicConstraint &Other) const {
Expand Down
38 changes: 36 additions & 2 deletions clang/include/clang/Sema/SemaOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,28 @@ class SemaOpenMP : public SemaBase {
OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc);
/// Process an OpenMP informational directive.
///
/// \param Kind The directive kind.
/// \param DirName Declaration name info.
/// \param Clauses Array of clauses for directive.
/// \param AStmt The associated statement.
/// \param StartLoc The start location.
/// \param EndLoc The end location.
StmtResult ActOnOpenMPInformationalDirective(
OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
/// Process an OpenMP assume directive.
///
/// \param Clauses Array of clauses for directive.
/// \param AStmt The associated statement.
/// \param StartLoc The start location.
/// \param EndLoc The end location.
StmtResult ActOnOpenMPAssumeDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);

/// Called on well-formed '\#pragma omp parallel' after parsing
/// of the associated statement.
StmtResult ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
Expand Down Expand Up @@ -940,6 +962,17 @@ class SemaOpenMP : public SemaBase {
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
/// Called on well-formed 'holds' clause.
OMPClause *ActOnOpenMPHoldsClause(Expr *E, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
/// Called on well-formed 'absent' or 'contains' clauses.
OMPClause *ActOnOpenMPDirectivePresenceClause(
OpenMPClauseKind CK, llvm::ArrayRef<OpenMPDirectiveKind> DKVec,
SourceLocation Loc, SourceLocation LLoc, SourceLocation RLoc);
OMPClause *ActOnOpenMPNullaryAssumptionClause(OpenMPClauseKind CK,
SourceLocation Loc,
SourceLocation RLoc);

OMPClause *ActOnOpenMPSingleExprWithArgClause(
OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr,
Expand Down Expand Up @@ -1226,11 +1259,12 @@ class SemaOpenMP : public SemaBase {
const OMPVarListLocTy &Locs, bool NoDiagnose = false,
ArrayRef<Expr *> UnresolvedMappers = std::nullopt);
/// Called on well-formed 'num_teams' clause.
OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc,
OMPClause *ActOnOpenMPNumTeamsClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
/// Called on well-formed 'thread_limit' clause.
OMPClause *ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
OMPClause *ActOnOpenMPThreadLimitClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
Expand Down
9 changes: 8 additions & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,9 @@ enum ASTRecordTypes {

/// Record code for \#pragma clang unsafe_buffer_usage begin/end
PP_UNSAFE_BUFFER_USAGE = 69,

/// Record code for vtables to emit.
VTABLES_TO_EMIT = 70,
};

/// Record types used within a source manager block.
Expand Down Expand Up @@ -1121,6 +1124,9 @@ enum PredefinedTypeIDs {
// \brief AMDGPU types with auto numeration
#define AMDGPU_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
#include "clang/Basic/AMDGPUTypes.def"
// \brief HLSL intangible types with auto numeration
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
#include "clang/Basic/HLSLIntangibleTypes.def"

/// The placeholder type for unresolved templates.
PREDEF_TYPE_UNRESOLVED_TEMPLATE,
Expand All @@ -1133,7 +1139,7 @@ enum PredefinedTypeIDs {
///
/// Type IDs for non-predefined types will start at
/// NUM_PREDEF_TYPE_IDs.
const unsigned NUM_PREDEF_TYPE_IDS = 504;
const unsigned NUM_PREDEF_TYPE_IDS = 505;

// Ensure we do not overrun the predefined types we reserved
// in the enum PredefinedTypeIDs above.
Expand Down Expand Up @@ -1964,6 +1970,7 @@ enum StmtCode {
STMT_OMP_TARGET_TEAMS_GENERIC_LOOP_DIRECTIVE,
STMT_OMP_PARALLEL_GENERIC_LOOP_DIRECTIVE,
STMT_OMP_TARGET_PARALLEL_GENERIC_LOOP_DIRECTIVE,
STMT_OMP_ASSUME_DIRECTIVE,
EXPR_ARRAY_SECTION,
EXPR_OMP_ARRAY_SHAPING,
EXPR_OMP_ITERATOR,
Expand Down
80 changes: 52 additions & 28 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class ASTReaderListener {
///
/// \returns true to indicate the options are invalid or false otherwise.
virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
bool Complain,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) {
return false;
}
Expand All @@ -139,7 +139,8 @@ class ASTReaderListener {
///
/// \returns true to indicate the target options are invalid, or false
/// otherwise.
virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
virtual bool ReadTargetOptions(const TargetOptions &TargetOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) {
return false;
}
Expand All @@ -150,7 +151,7 @@ class ASTReaderListener {
/// otherwise.
virtual bool
ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
bool Complain) {
StringRef ModuleFilename, bool Complain) {
return false;
}

Expand All @@ -172,6 +173,7 @@ class ASTReaderListener {
/// \returns true to indicate the header search options are invalid, or false
/// otherwise.
virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
StringRef ModuleFilename,
StringRef SpecificModuleCachePath,
bool Complain) {
return false;
Expand Down Expand Up @@ -200,6 +202,7 @@ class ASTReaderListener {
/// \returns true to indicate the preprocessor options are invalid, or false
/// otherwise.
virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
StringRef ModuleFilename,
bool ReadMacros, bool Complain,
std::string &SuggestedPredefines) {
return false;
Expand Down Expand Up @@ -262,20 +265,24 @@ class ChainedASTReaderListener : public ASTReaderListener {
bool ReadFullVersionInformation(StringRef FullVersion) override;
void ReadModuleName(StringRef ModuleName) override;
void ReadModuleMapFile(StringRef ModuleMapPath) override;
bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
bool ReadLanguageOptions(const LangOptions &LangOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) override;
bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
bool ReadTargetOptions(const TargetOptions &TargetOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) override;
bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
bool Complain) override;
StringRef ModuleFilename, bool Complain) override;
bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
bool Complain) override;

bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
StringRef ModuleFilename,
StringRef SpecificModuleCachePath,
bool Complain) override;
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
bool ReadMacros, bool Complain,
StringRef ModuleFilename, bool ReadMacros,
bool Complain,
std::string &SuggestedPredefines) override;

void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
Expand All @@ -299,16 +306,20 @@ class PCHValidator : public ASTReaderListener {
PCHValidator(Preprocessor &PP, ASTReader &Reader)
: PP(PP), Reader(Reader) {}

bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
bool ReadLanguageOptions(const LangOptions &LangOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) override;
bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
bool ReadTargetOptions(const TargetOptions &TargetOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) override;
bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
bool Complain) override;
StringRef ModuleFilename, bool Complain) override;
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
bool ReadMacros, bool Complain,
StringRef ModuleFilename, bool ReadMacros,
bool Complain,
std::string &SuggestedPredefines) override;
bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
StringRef ModuleFilename,
StringRef SpecificModuleCachePath,
bool Complain) override;
void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
Expand All @@ -325,7 +336,8 @@ class SimpleASTReaderListener : public ASTReaderListener {
SimpleASTReaderListener(Preprocessor &PP) : PP(PP) {}

bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
bool ReadMacros, bool Complain,
StringRef ModuleFilename, bool ReadMacros,
bool Complain,
std::string &SuggestedPredefines) override;
};

Expand Down Expand Up @@ -790,6 +802,11 @@ class ASTReader
/// the consumer eagerly.
SmallVector<GlobalDeclID, 16> EagerlyDeserializedDecls;

/// The IDs of all vtables to emit. The referenced declarations are passed
/// to the consumers' HandleVTable eagerly after passing
/// EagerlyDeserializedDecls.
SmallVector<GlobalDeclID, 16> VTablesToEmit;

/// The IDs of all tentative definitions stored in the chain.
///
/// Sema keeps track of all tentative definitions in a TU because it has to
Expand Down Expand Up @@ -1361,10 +1378,12 @@ class ASTReader
SmallVectorImpl<ImportedModule> &Loaded,
const ModuleFile *ImportedBy,
unsigned ClientLoadCapabilities);
static ASTReadResult ReadOptionsBlock(
llvm::BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
std::string &SuggestedPredefines);
static ASTReadResult
ReadOptionsBlock(llvm::BitstreamCursor &Stream, StringRef Filename,
unsigned ClientLoadCapabilities,
bool AllowCompatibleConfigurationMismatch,
ASTReaderListener &Listener,
std::string &SuggestedPredefines);

/// Read the unhashed control block.
///
Expand All @@ -1373,12 +1392,11 @@ class ASTReader
ASTReadResult readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
unsigned ClientLoadCapabilities);

static ASTReadResult
readUnhashedControlBlockImpl(ModuleFile *F, llvm::StringRef StreamData,
unsigned ClientLoadCapabilities,
bool AllowCompatibleConfigurationMismatch,
ASTReaderListener *Listener,
bool ValidateDiagnosticOptions);
static ASTReadResult readUnhashedControlBlockImpl(
ModuleFile *F, llvm::StringRef StreamData, StringRef Filename,
unsigned ClientLoadCapabilities,
bool AllowCompatibleConfigurationMismatch, ASTReaderListener *Listener,
bool ValidateDiagnosticOptions);

llvm::Error ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
llvm::Error ReadExtensionBlock(ModuleFile &F);
Expand All @@ -1391,21 +1409,26 @@ class ASTReader
unsigned ClientLoadCapabilities);
llvm::Error ReadSubmoduleBlock(ModuleFile &F,
unsigned ClientLoadCapabilities);
static bool ParseLanguageOptions(const RecordData &Record, bool Complain,
static bool ParseLanguageOptions(const RecordData &Record,
StringRef ModuleFilename, bool Complain,
ASTReaderListener &Listener,
bool AllowCompatibleDifferences);
static bool ParseTargetOptions(const RecordData &Record, bool Complain,
static bool ParseTargetOptions(const RecordData &Record,
StringRef ModuleFilename, bool Complain,
ASTReaderListener &Listener,
bool AllowCompatibleDifferences);
static bool ParseDiagnosticOptions(const RecordData &Record, bool Complain,
static bool ParseDiagnosticOptions(const RecordData &Record,
StringRef ModuleFilename, bool Complain,
ASTReaderListener &Listener);
static bool ParseFileSystemOptions(const RecordData &Record, bool Complain,
ASTReaderListener &Listener);
static bool ParseHeaderSearchOptions(const RecordData &Record, bool Complain,
static bool ParseHeaderSearchOptions(const RecordData &Record,
StringRef ModuleFilename, bool Complain,
ASTReaderListener &Listener);
static bool ParseHeaderSearchPaths(const RecordData &Record, bool Complain,
ASTReaderListener &Listener);
static bool ParsePreprocessorOptions(const RecordData &Record, bool Complain,
static bool ParsePreprocessorOptions(const RecordData &Record,
StringRef ModuleFilename, bool Complain,
ASTReaderListener &Listener,
std::string &SuggestedPredefines);

Expand Down Expand Up @@ -1500,6 +1523,7 @@ class ASTReader
bool isConsumerInterestedIn(Decl *D);
void PassInterestingDeclsToConsumer();
void PassInterestingDeclToConsumer(Decl *D);
void PassVTableToConsumer(CXXRecordDecl *RD);

void finishPendingActions();
void diagnoseOdrViolations();
Expand Down Expand Up @@ -2478,7 +2502,7 @@ class BitsUnpacker {

inline bool shouldSkipCheckingODR(const Decl *D) {
return D->getASTContext().getLangOpts().SkipODRCheckInGMF &&
D->isFromExplicitGlobalModule();
D->isFromGlobalModule();
}

} // namespace clang
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@ class ASTWriter : public ASTDeserializationListener,
std::vector<SourceRange> NonAffectingRanges;
std::vector<SourceLocation::UIntTy> NonAffectingOffsetAdjustments;

/// A list of classes which need to emit the VTable in the corresponding
/// object file.
llvm::SmallVector<CXXRecordDecl *> PendingEmittingVTables;

/// Computes input files that didn't affect compilation of the current module,
/// and initializes data structures necessary for leaving those files out
/// during \c SourceManager serialization.
Expand Down Expand Up @@ -857,6 +861,8 @@ class ASTWriter : public ASTDeserializationListener,
return PredefinedDecls.count(D);
}

void handleVTable(CXXRecordDecl *RD);

private:
// ASTDeserializationListener implementation
void ReaderInitialized(ASTReader *Reader) override;
Expand Down Expand Up @@ -951,6 +957,7 @@ class PCHGenerator : public SemaConsumer {

void InitializeSema(Sema &S) override { SemaPtr = &S; }
void HandleTranslationUnit(ASTContext &Ctx) override;
void HandleVTable(CXXRecordDecl *RD) override { Writer.handleVTable(RD); }
ASTMutationListener *GetASTMutationListener() override;
ASTDeserializationListener *GetASTDeserializationListener() override;
bool hasEmittedPCH() const { return Buffer->IsComplete; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#ifndef LLVM_CLANG_SERIALIZATION_OBJECTFILEPCHCONTAINERREADER_H
#define LLVM_CLANG_SERIALIZATION_OBJECTFILEPCHCONTAINERREADER_H

#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Serialization/PCHContainerOperations.h"

namespace clang {
/// A PCHContainerReader implementation that uses LLVM to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,8 @@ class FunctionSummariesTy;
class ExprEngine;

//===----------------------------------------------------------------------===//
/// CoreEngine - Implements the core logic of the graph-reachability
/// analysis. It traverses the CFG and generates the ExplodedGraph.
/// Program "states" are treated as opaque void pointers.
/// The template class CoreEngine (which subclasses CoreEngine)
/// provides the matching component to the engine that knows the actual types
/// for states. Note that this engine only dispatches to transfer functions
/// at the statement and block-level. The analyses themselves must implement
/// any transfer function logic and the sub-expression level (if any).
/// CoreEngine - Implements the core logic of the graph-reachability analysis.
/// It traverses the CFG and generates the ExplodedGraph.
class CoreEngine {
friend class CommonNodeBuilder;
friend class EndOfFunctionNodeBuilder;
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Support/RISCVVIntrinsicUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,8 @@ enum RVVRequire : uint32_t {
RVV_REQ_Zvksh = 1 << 15,
RVV_REQ_Zvfbfwma = 1 << 16,
RVV_REQ_Zvfbfmin = 1 << 17,
RVV_REQ_Experimental = 1 << 18,
RVV_REQ_Zvfh = 1 << 18,
RVV_REQ_Experimental = 1 << 19,

LLVM_MARK_AS_BITMASK_ENUM(RVV_REQ_Experimental)
};
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Tooling/Refactoring/ASTSelection.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class CodeRangeASTSelection {
CodeRangeASTSelection(SelectedASTNode::ReferenceType SelectedNode,
ArrayRef<SelectedASTNode::ReferenceType> Parents,
bool AreChildrenSelected)
: SelectedNode(SelectedNode), Parents(Parents.begin(), Parents.end()),
: SelectedNode(SelectedNode), Parents(Parents),
AreChildrenSelected(AreChildrenSelected) {}

/// The reference to the selected node (or reference to the selected
Expand Down
1 change: 1 addition & 0 deletions clang/include/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ module Clang_Basic {
textual header "clang/Basic/DiagnosticOptions.def"
textual header "clang/Basic/FPOptions.def"
textual header "clang/Basic/Features.def"
textual header "clang/Basic/HLSLIntangibleTypes.def"
textual header "clang/Basic/LangOptions.def"
textual header "clang/Basic/MSP430Target.def"
textual header "clang/Basic/OpenACCClauses.def"
Expand Down
59 changes: 51 additions & 8 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,12 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
#include "clang/Basic/OpenCLExtensionTypes.def"
}

if (LangOpts.HLSL) {
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
InitBuiltinType(SingletonId, BuiltinType::Id);
#include "clang/Basic/HLSLIntangibleTypes.def"
}

if (Target.hasAArch64SVETypes() ||
(AuxTarget && AuxTarget->hasAArch64SVETypes())) {
#define SVE_TYPE(Name, Id, SingletonId) \
Expand Down Expand Up @@ -1983,7 +1989,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
// Adjust the alignment for fixed-length SVE predicates.
Align = 16;
else if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
VT->getVectorKind() == VectorKind::RVVFixedLengthMask)
VT->getVectorKind() == VectorKind::RVVFixedLengthMask ||
VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 ||
VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 ||
VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4)
// Adjust the alignment for fixed-length RVV vectors.
Align = std::min<unsigned>(64, Width);
break;
Expand Down Expand Up @@ -2242,6 +2251,11 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Align = ALIGN; \
break;
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
Width = 0;
Align = 8;
break;
}
break;
case Type::ObjCObjectPointer:
Expand Down Expand Up @@ -3355,6 +3369,10 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
case BuiltinType::Id: \
return;
#include "clang/Basic/AArch64SVEACLETypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
case BuiltinType::Id: \
return;
#include "clang/Basic/HLSLIntangibleTypes.def"
case BuiltinType::Dependent:
llvm_unreachable("should never get here");
case BuiltinType::AMDGPUBufferRsrc:
Expand Down Expand Up @@ -5282,15 +5300,15 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
if (TTPDecl) {
QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack);
TypeParm = new (*this, alignof(TemplateTypeParmType))
TemplateTypeParmType(TTPDecl, Canon);
TemplateTypeParmType(Depth, Index, ParameterPack, TTPDecl, Canon);

TemplateTypeParmType *TypeCheck
= TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!TypeCheck && "Template type parameter canonical type broken");
(void)TypeCheck;
} else
TypeParm = new (*this, alignof(TemplateTypeParmType))
TemplateTypeParmType(Depth, Index, ParameterPack);
TypeParm = new (*this, alignof(TemplateTypeParmType)) TemplateTypeParmType(
Depth, Index, ParameterPack, /*TTPDecl=*/nullptr, /*Canon=*/QualType());

Types.push_back(TypeParm);
TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos);
Expand Down Expand Up @@ -8552,6 +8570,8 @@ static char getObjCEncodingForPrimitiveType(const ASTContext *C,
#define PPC_VECTOR_TYPE(Name, Id, Size) \
case BuiltinType::Id:
#include "clang/Basic/PPCTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
#define BUILTIN_TYPE(KIND, ID)
#define PLACEHOLDER_TYPE(KIND, ID) \
case BuiltinType::KIND:
Expand Down Expand Up @@ -9905,7 +9925,13 @@ bool ASTContext::areCompatibleVectorTypes(QualType FirstVec,
First->getVectorKind() != VectorKind::RVVFixedLengthData &&
Second->getVectorKind() != VectorKind::RVVFixedLengthData &&
First->getVectorKind() != VectorKind::RVVFixedLengthMask &&
Second->getVectorKind() != VectorKind::RVVFixedLengthMask)
Second->getVectorKind() != VectorKind::RVVFixedLengthMask &&
First->getVectorKind() != VectorKind::RVVFixedLengthMask_1 &&
Second->getVectorKind() != VectorKind::RVVFixedLengthMask_1 &&
First->getVectorKind() != VectorKind::RVVFixedLengthMask_2 &&
Second->getVectorKind() != VectorKind::RVVFixedLengthMask_2 &&
First->getVectorKind() != VectorKind::RVVFixedLengthMask_4 &&
Second->getVectorKind() != VectorKind::RVVFixedLengthMask_4)
return true;

return false;
Expand Down Expand Up @@ -10023,7 +10049,25 @@ bool ASTContext::areCompatibleRVVTypes(QualType FirstType,
BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT);
return FirstType->isRVVVLSBuiltinType() &&
Info.ElementType == BoolTy &&
getTypeSize(SecondType) == getRVVTypeSize(*this, BT);
getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT)));
}
if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1) {
BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT);
return FirstType->isRVVVLSBuiltinType() &&
Info.ElementType == BoolTy &&
getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT) * 8));
}
if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2) {
BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT);
return FirstType->isRVVVLSBuiltinType() &&
Info.ElementType == BoolTy &&
getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT)) * 4);
}
if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4) {
BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT);
return FirstType->isRVVVLSBuiltinType() &&
Info.ElementType == BoolTy &&
getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT)) * 2);
}
if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
VT->getVectorKind() == VectorKind::Generic)
Expand Down Expand Up @@ -12414,8 +12458,7 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
!isMSStaticDataMemberInlineDefinition(VD))
return false;

// Variables in other module units shouldn't be forced to be emitted.
if (VD->isInAnotherModuleUnit())
if (VD->shouldEmitInExternalSource())
return false;

// Variables that can be needed in other TUs are required.
Expand Down
21 changes: 14 additions & 7 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,10 @@ ExpectedType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
case BuiltinType::Id: \
return Importer.getToContext().SingletonId;
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
case BuiltinType::Id: \
return Importer.getToContext().SingletonId;
#include "clang/Basic/HLSLIntangibleTypes.def"
#define SHARED_SINGLETON_TYPE(Expansion)
#define BUILTIN_TYPE(Id, SingletonId) \
case BuiltinType::Id: return Importer.getToContext().SingletonId;
Expand Down Expand Up @@ -3636,6 +3640,10 @@ class IsTypeDeclaredInsideVisitor
return {};
}

std::optional<bool> VisitUnaryTransformType(const UnaryTransformType *T) {
return CheckType(T->getBaseType());
}

std::optional<bool>
VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
// The "associated declaration" can be the same as ParentDC.
Expand Down Expand Up @@ -3713,21 +3721,18 @@ bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) {
const auto *FromFPT = FromTy->getAs<FunctionProtoType>();
assert(FromFPT && "Must be called on FunctionProtoType");

auto IsCXX11LambdaWithouTrailingReturn = [&]() {
auto IsCXX11Lambda = [&]() {
if (Importer.FromContext.getLangOpts().CPlusPlus14) // C++14 or later
return false;

if (FromFPT->hasTrailingReturn())
return false;

if (const auto *MD = dyn_cast<CXXMethodDecl>(D))
return cast<CXXRecordDecl>(MD->getDeclContext())->isLambda();

return false;
};

QualType RetT = FromFPT->getReturnType();
if (isa<AutoType>(RetT.getTypePtr()) || IsCXX11LambdaWithouTrailingReturn()) {
if (isa<AutoType>(RetT.getTypePtr()) || IsCXX11Lambda()) {
FunctionDecl *Def = D->getDefinition();
IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
return Visitor.CheckType(RetT);
Expand Down Expand Up @@ -8629,13 +8634,15 @@ ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
return UnresolvedLookupExpr::Create(
Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr,
*ToTemplateKeywordLocOrErr, ToNameInfo, E->requiresADL(), &ToTAInfo,
ToDecls.begin(), ToDecls.end(), KnownDependent);
ToDecls.begin(), ToDecls.end(), KnownDependent,
/*KnownInstantiationDependent=*/E->isInstantiationDependent());
}

return UnresolvedLookupExpr::Create(
Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr,
ToNameInfo, E->requiresADL(), ToDecls.begin(), ToDecls.end(),
/*KnownDependent=*/E->isTypeDependent());
/*KnownDependent=*/E->isTypeDependent(),
/*KnownInstantiationDependent=*/E->isInstantiationDependent());
}

ExpectedStmt
Expand Down
22 changes: 10 additions & 12 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,12 +583,6 @@ static bool isSingleLineLanguageLinkage(const Decl &D) {
return false;
}

static bool isDeclaredInModuleInterfaceOrPartition(const NamedDecl *D) {
if (auto *M = D->getOwningModule())
return M->isInterfaceOrPartition();
return false;
}

static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {
return LinkageInfo::external();
}
Expand Down Expand Up @@ -642,7 +636,13 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
// (There is no equivalent in C99.)
if (Context.getLangOpts().CPlusPlus && Var->getType().isConstQualified() &&
!Var->getType().isVolatileQualified() && !Var->isInline() &&
!isDeclaredInModuleInterfaceOrPartition(Var) &&
![Var]() {
// Check if it is module purview except private module fragment
// and implementation unit.
if (auto *M = Var->getOwningModule())
return M->isInterfaceOrPartition() || M->isImplicitGlobalModule();
return false;
}() &&
!isa<VarTemplateSpecializationDecl>(Var) &&
!Var->getDescribedVarTemplate()) {
const VarDecl *PrevVar = Var->getPreviousDecl();
Expand Down Expand Up @@ -3292,11 +3292,9 @@ bool FunctionDecl::isImmediateFunction() const {
}

bool FunctionDecl::isMain() const {
const TranslationUnitDecl *tunit =
dyn_cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext());
return tunit &&
!tunit->getASTContext().getLangOpts().Freestanding &&
isNamed(this, "main");
return isNamed(this, "main") && !getLangOpts().Freestanding &&
(getDeclContext()->getRedeclContext()->isTranslationUnit() ||
isExternC());
}

bool FunctionDecl::isMSVCRTEntryPoint() const {
Expand Down
49 changes: 37 additions & 12 deletions clang/lib/AST/DeclBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1124,26 +1124,46 @@ bool Decl::isInAnotherModuleUnit() const {
if (!M)
return false;

// FIXME or NOTE: maybe we need to be clear about the semantics
// of clang header modules. e.g., if this lives in a clang header
// module included by the current unit, should we return false
// here?
//
// This is clear for header units as the specification says the
// header units live in a synthesised translation unit. So we
// can return false here.
M = M->getTopLevelModule();
// FIXME: It is problematic if the header module lives in another module
// unit. Consider to fix this by techniques like
// ExternalASTSource::hasExternalDefinitions.
if (M->isHeaderLikeModule())
if (!M->isNamedModule())
return false;

// A global module without parent implies that we're parsing the global
// module. So it can't be in another module unit.
if (M->isGlobalModule())
return M != getASTContext().getCurrentNamedModule();
}

bool Decl::isInCurrentModuleUnit() const {
auto *M = getOwningModule();

if (!M || !M->isNamedModule())
return false;

assert(M->isNamedModule() && "New module kind?");
return M != getASTContext().getCurrentNamedModule();
return M == getASTContext().getCurrentNamedModule();
}

bool Decl::shouldEmitInExternalSource() const {
ExternalASTSource *Source = getASTContext().getExternalSource();
if (!Source)
return false;

return Source->hasExternalDefinitions(this) == ExternalASTSource::EK_Always;
}

bool Decl::isFromExplicitGlobalModule() const {
return getOwningModule() && getOwningModule()->isExplicitGlobalModule();
}

bool Decl::isFromGlobalModule() const {
return getOwningModule() && getOwningModule()->isGlobalModule();
}

bool Decl::isInNamedModule() const {
return getOwningModule() && getOwningModule()->isNamedModule();
}
Expand All @@ -1157,15 +1177,20 @@ int64_t Decl::getID() const {

const FunctionType *Decl::getFunctionType(bool BlocksToo) const {
QualType Ty;
if (isa<BindingDecl>(this))
return nullptr;
else if (const auto *D = dyn_cast<ValueDecl>(this))
if (const auto *D = dyn_cast<ValueDecl>(this))
Ty = D->getType();
else if (const auto *D = dyn_cast<TypedefNameDecl>(this))
Ty = D->getUnderlyingType();
else
return nullptr;

if (Ty.isNull()) {
// BindingDecls do not have types during parsing, so return nullptr. This is
// the only known case where `Ty` is null.
assert(isa<BindingDecl>(this));
return nullptr;
}

if (Ty->isFunctionPointerType())
Ty = Ty->castAs<PointerType>()->getPointeeType();
else if (Ty->isFunctionReferenceType())
Expand Down
19 changes: 11 additions & 8 deletions clang/lib/AST/ExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,10 +402,11 @@ UnresolvedLookupExpr::UnresolvedLookupExpr(
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo, bool RequiresADL,
const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
UnresolvedSetIterator End, bool KnownDependent)
UnresolvedSetIterator End, bool KnownDependent,
bool KnownInstantiationDependent)
: OverloadExpr(UnresolvedLookupExprClass, Context, QualifierLoc,
TemplateKWLoc, NameInfo, TemplateArgs, Begin, End,
KnownDependent, false, false),
KnownDependent, KnownInstantiationDependent, false),
NamingClass(NamingClass) {
UnresolvedLookupExprBits.RequiresADL = RequiresADL;
}
Expand All @@ -420,33 +421,35 @@ UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End,
bool KnownDependent) {
bool KnownDependent, bool KnownInstantiationDependent) {
unsigned NumResults = End - Begin;
unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc>(NumResults, 0, 0);
void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
return new (Mem) UnresolvedLookupExpr(
Context, NamingClass, QualifierLoc,
/*TemplateKWLoc=*/SourceLocation(), NameInfo, RequiresADL,
/*TemplateArgs=*/nullptr, Begin, End, KnownDependent);
/*TemplateArgs=*/nullptr, Begin, End, KnownDependent,
KnownInstantiationDependent);
}

UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo, bool RequiresADL,
const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
UnresolvedSetIterator End, bool KnownDependent) {
UnresolvedSetIterator End, bool KnownDependent,
bool KnownInstantiationDependent) {
unsigned NumResults = End - Begin;
bool HasTemplateKWAndArgsInfo = Args || TemplateKWLoc.isValid();
unsigned NumTemplateArgs = Args ? Args->size() : 0;
unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc>(
NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
TemplateKWLoc, NameInfo, RequiresADL,
Args, Begin, End, KnownDependent);
return new (Mem) UnresolvedLookupExpr(
Context, NamingClass, QualifierLoc, TemplateKWLoc, NameInfo, RequiresADL,
Args, Begin, End, KnownDependent, KnownInstantiationDependent);
}

UnresolvedLookupExpr *UnresolvedLookupExpr::CreateEmpty(
Expand Down
112 changes: 108 additions & 4 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,11 @@ namespace {
ArraySize = 2;
MostDerivedLength = I + 1;
IsArray = true;
} else if (const auto *VT = Type->getAs<VectorType>()) {
Type = VT->getElementType();
ArraySize = VT->getNumElements();
MostDerivedLength = I + 1;
IsArray = true;
} else if (const FieldDecl *FD = getAsField(Path[I])) {
Type = FD->getType();
ArraySize = 0;
Expand Down Expand Up @@ -268,7 +273,6 @@ namespace {
/// If the current array is an unsized array, the value of this is
/// undefined.
uint64_t MostDerivedArraySize;

/// The type of the most derived object referred to by this address.
QualType MostDerivedType;

Expand Down Expand Up @@ -442,6 +446,16 @@ namespace {
MostDerivedArraySize = 2;
MostDerivedPathLength = Entries.size();
}

void addVectorElementUnchecked(QualType EltTy, uint64_t Size,
uint64_t Idx) {
Entries.push_back(PathEntry::ArrayIndex(Idx));
MostDerivedType = EltTy;
MostDerivedPathLength = Entries.size();
MostDerivedArraySize = 0;
MostDerivedIsArrayElement = false;
}

void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info, const Expr *E);
void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E,
const APSInt &N);
Expand Down Expand Up @@ -1737,6 +1751,11 @@ namespace {
if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
Designator.addComplexUnchecked(EltTy, Imag);
}
void addVectorElement(EvalInfo &Info, const Expr *E, QualType EltTy,
uint64_t Size, uint64_t Idx) {
if (checkSubobject(Info, E, CSK_VectorElement))
Designator.addVectorElementUnchecked(EltTy, Size, Idx);
}
void clearIsNullPointer() {
IsNullPtr = false;
}
Expand Down Expand Up @@ -3310,6 +3329,19 @@ static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E,
return true;
}

static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E,
LValue &LVal, QualType EltTy,
uint64_t Size, uint64_t Idx) {
if (Idx) {
CharUnits SizeOfElement;
if (!HandleSizeof(Info, E->getExprLoc(), EltTy, SizeOfElement))
return false;
LVal.Offset += SizeOfElement * Idx;
}
LVal.addVectorElement(Info, E, EltTy, Size, Idx);
return true;
}

/// Try to evaluate the initializer for a variable declaration.
///
/// \param Info Information about the ongoing evaluation.
Expand Down Expand Up @@ -3855,6 +3887,27 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
return handler.found(Index ? O->getComplexFloatImag()
: O->getComplexFloatReal(), ObjType);
}
} else if (const auto *VT = ObjType->getAs<VectorType>()) {
uint64_t Index = Sub.Entries[I].getAsArrayIndex();
unsigned NumElements = VT->getNumElements();
if (Index == NumElements) {
if (Info.getLangOpts().CPlusPlus11)
Info.FFDiag(E, diag::note_constexpr_access_past_end)
<< handler.AccessKind;
else
Info.FFDiag(E);
return handler.failed();
}

if (Index > NumElements) {
Info.CCEDiag(E, diag::note_constexpr_array_index)
<< Index << /*array*/ 0 << NumElements;
return handler.failed();
}

ObjType = VT->getElementType();
assert(I == N - 1 && "extracting subobject of scalar?");
return handler.found(O->getVectorElt(Index), ObjType);
} else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
if (Field->isMutable() &&
!Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
Expand Down Expand Up @@ -8509,6 +8562,7 @@ class LValueExprEvaluator
bool VisitCXXTypeidExpr(const CXXTypeidExpr *E);
bool VisitCXXUuidofExpr(const CXXUuidofExpr *E);
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E);
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E);
bool VisitUnaryDeref(const UnaryOperator *E);
bool VisitUnaryReal(const UnaryOperator *E);
bool VisitUnaryImag(const UnaryOperator *E);
Expand Down Expand Up @@ -8850,15 +8904,63 @@ bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {
return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
}

bool LValueExprEvaluator::VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
bool Success = true;

APValue Val;
if (!Evaluate(Val, Info, E->getBase())) {
if (!Info.noteFailure())
return false;
Success = false;
}

SmallVector<uint32_t, 4> Indices;
E->getEncodedElementAccess(Indices);
// FIXME: support accessing more than one element
if (Indices.size() > 1)
return false;

if (Success) {
Result.setFrom(Info.Ctx, Val);
const auto *VT = E->getBase()->getType()->castAs<VectorType>();
HandleLValueVectorElement(Info, E, Result, VT->getElementType(),
VT->getNumElements(), Indices[0]);
}

return Success;
}

bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
// FIXME: Deal with vectors as array subscript bases.
if (E->getBase()->getType()->isVectorType() ||
E->getBase()->getType()->isSveVLSBuiltinType())
if (E->getBase()->getType()->isSveVLSBuiltinType())
return Error(E);

APSInt Index;
bool Success = true;

if (const auto *VT = E->getBase()->getType()->getAs<VectorType>()) {
APValue Val;
if (!Evaluate(Val, Info, E->getBase())) {
if (!Info.noteFailure())
return false;
Success = false;
}

if (!EvaluateInteger(E->getIdx(), Index, Info)) {
if (!Info.noteFailure())
return false;
Success = false;
}

if (Success) {
Result.setFrom(Info.Ctx, Val);
HandleLValueVectorElement(Info, E, Result, VT->getElementType(),
VT->getNumElements(), Index.getExtValue());
}

return Success;
}

// C++17's rules require us to evaluate the LHS first, regardless of which
// side is the base.
for (const Expr *SubExpr : {E->getLHS(), E->getRHS()}) {
Expand Down Expand Up @@ -11879,6 +11981,8 @@ GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
#include "clang/Basic/WebAssemblyReferenceTypes.def"
#define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/HLSLIntangibleTypes.def"
return GCCTypeClass::None;

case BuiltinType::Dependent:
Expand Down
107 changes: 65 additions & 42 deletions clang/lib/AST/Interp/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
public:
DeclScope(Compiler<Emitter> *Ctx, const ValueDecl *VD)
: LocalScope<Emitter>(Ctx, VD), Scope(Ctx->P, VD),
OldGlobalDecl(Ctx->GlobalDecl),
OldInitializingDecl(Ctx->InitializingDecl) {
Ctx->GlobalDecl = Context::shouldBeGloballyIndexed(VD);
Ctx->InitializingDecl = VD;
Ctx->InitStack.push_back(InitLink::Decl(VD));
}
Expand All @@ -41,14 +39,12 @@ template <class Emitter> class DeclScope final : public LocalScope<Emitter> {
}

~DeclScope() {
this->Ctx->GlobalDecl = OldGlobalDecl;
this->Ctx->InitializingDecl = OldInitializingDecl;
this->Ctx->InitStack.pop_back();
}

private:
Program::DeclScope Scope;
bool OldGlobalDecl;
const ValueDecl *OldInitializingDecl;
};

Expand Down Expand Up @@ -339,6 +335,10 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
if (!PointeeType.isNull()) {
if (std::optional<PrimType> T = classify(PointeeType))
Desc = P.createDescriptor(SubExpr, *T);
else
Desc = P.createDescriptor(SubExpr, PointeeType.getTypePtr(),
std::nullopt, true, false,
/*IsMutable=*/false, nullptr);
}
return this->emitNull(classifyPrim(CE->getType()), Desc, CE);
}
Expand Down Expand Up @@ -426,7 +426,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
if (CE->getType()->isAtomicType()) {
if (!this->discard(SubExpr))
return false;
return this->emitInvalidCast(CastKind::Reinterpret, CE);
return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, CE);
}

if (DiscardResult)
Expand Down Expand Up @@ -480,19 +480,25 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
}
}

auto maybeNegate = [&]() -> bool {
if (CE->getCastKind() == CK_BooleanToSignedIntegral)
return this->emitNeg(*ToT, CE);
return true;
};

if (ToT == PT_IntAP)
return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE);
return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE) &&
maybeNegate();
if (ToT == PT_IntAPS)
return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->getType()), CE);
return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->getType()), CE) &&
maybeNegate();

if (FromT == ToT)
return true;
if (!this->emitCast(*FromT, *ToT, CE))
return false;

if (CE->getCastKind() == CK_BooleanToSignedIntegral)
return this->emitNeg(*ToT, CE);
return true;
return maybeNegate();
}

case CK_PointerToBoolean:
Expand Down Expand Up @@ -1380,18 +1386,8 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,

if (R->isUnion()) {
if (Inits.size() == 0) {
// Zero-initialize the first union field.
if (R->getNumFields() == 0)
return this->emitFinishInit(E);
const Record::Field *FieldToInit = R->getField(0u);
QualType FieldType = FieldToInit->Desc->getType();
if (std::optional<PrimType> T = classify(FieldType)) {
if (!this->visitZeroInitializer(*T, FieldType, E))
return false;
if (!this->emitInitField(*T, FieldToInit->Offset, E))
return false;
}
// FIXME: Non-primitive case?
if (!this->visitZeroRecordInitializer(R, E))
return false;
} else {
const Expr *Init = Inits[0];
const FieldDecl *FToInit = nullptr;
Expand Down Expand Up @@ -2265,7 +2261,7 @@ bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(
// the temporary is explicitly static, create a global variable.
std::optional<PrimType> SubExprT = classify(SubExpr);
bool IsStatic = E->getStorageDuration() == SD_Static;
if (GlobalDecl || IsStatic) {
if (IsStatic) {
std::optional<unsigned> GlobalIndex = P.createGlobal(E);
if (!GlobalIndex)
return false;
Expand Down Expand Up @@ -2465,10 +2461,13 @@ bool Compiler<Emitter>::VisitCXXThrowExpr(const CXXThrowExpr *E) {
template <class Emitter>
bool Compiler<Emitter>::VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
if (!this->discard(E->getSubExpr()))
const Expr *SubExpr = E->getSubExpr();

bool TypesMatch = classify(E) == classify(SubExpr);
if (!this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/!TypesMatch, E))
return false;

return this->emitInvalidCast(CastKind::Reinterpret, E);
return this->delegate(SubExpr);
}

template <class Emitter>
Expand Down Expand Up @@ -3158,10 +3157,11 @@ bool Compiler<Emitter>::VisitExtVectorElementExpr(

template <class Emitter>
bool Compiler<Emitter>::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
const Expr *SubExpr = E->getSubExpr();
if (!E->isExpressibleAsConstantInitializer())
return this->emitInvalid(E);
return this->discard(SubExpr) && this->emitInvalid(E);

return this->delegate(E->getSubExpr());
return this->delegate(SubExpr);
}

template <class Emitter>
Expand Down Expand Up @@ -3356,6 +3356,9 @@ bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
assert(R);
// Fields
for (const Record::Field &Field : R->fields()) {
if (Field.Decl->isUnnamedBitField())
continue;

const Descriptor *D = Field.Desc;
if (D->isPrimitive()) {
QualType QT = D->getType();
Expand All @@ -3364,6 +3367,8 @@ bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
return false;
if (!this->emitInitField(T, Field.Offset, E))
return false;
if (R->isUnion())
break;
continue;
}

Expand Down Expand Up @@ -3399,8 +3404,11 @@ bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
assert(false);
}

if (!this->emitPopPtr(E))
if (!this->emitFinishInitPop(E))
return false;

if (R->isUnion())
break;
}

for (const Record::Base &B : R->bases()) {
Expand Down Expand Up @@ -4752,7 +4760,7 @@ bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
if (!this->visitInitializer(InitExpr))
return false;

return this->emitPopPtr(InitExpr);
return this->emitFinishInitPop(InitExpr);
};

// Emit custom code if this is a lambda static invoker.
Expand All @@ -4767,6 +4775,22 @@ bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
if (!R)
return false;

if (R->isUnion() && Ctor->isCopyOrMoveConstructor()) {
// union copy and move ctors are special.
assert(cast<CompoundStmt>(Ctor->getBody())->body_empty());
if (!this->emitThis(Ctor))
return false;

auto PVD = Ctor->getParamDecl(0);
ParamOffset PO = this->Params[PVD]; // Must exist.

if (!this->emitGetParam(PT_Ptr, PO.Offset, Ctor))
return false;

return this->emitMemcpy(Ctor) && this->emitPopPtr(Ctor) &&
this->emitRetVoid(Ctor);
}

InitLinkScope<Emitter> InitScope(this, InitLink::This());
for (const auto *Init : Ctor->inits()) {
// Scope needed for the initializers.
Expand Down Expand Up @@ -5538,22 +5562,21 @@ bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
template <class Emitter>
bool Compiler<Emitter>::emitRecordDestruction(const Record *R) {
assert(R);
// First, destroy all fields.
for (const Record::Field &Field : llvm::reverse(R->fields())) {
const Descriptor *D = Field.Desc;
if (!D->isPrimitive() && !D->isPrimitiveArray()) {
if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
return false;
if (!this->emitDestruction(D))
return false;
if (!this->emitPopPtr(SourceInfo{}))
return false;
if (!R->isUnion()) {
// First, destroy all fields.
for (const Record::Field &Field : llvm::reverse(R->fields())) {
const Descriptor *D = Field.Desc;
if (!D->isPrimitive() && !D->isPrimitiveArray()) {
if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
return false;
if (!this->emitDestruction(D))
return false;
if (!this->emitPopPtr(SourceInfo{}))
return false;
}
}
}

// FIXME: Unions need to be handled differently here. We don't want to
// call the destructor of its members.

// Now emit the destructor and recurse into base classes.
if (const CXXDestructorDecl *Dtor = R->getDestructor();
Dtor && !Dtor->isTrivial()) {
Expand Down
3 changes: 0 additions & 3 deletions clang/lib/AST/Interp/Compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,6 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
llvm::SmallVector<InitLink> InitStack;
bool InitStackActive = false;

/// Flag indicating if we're initializing a global variable.
bool GlobalDecl = false;

/// Type of the expression returned by the function.
std::optional<PrimType> ReturnType;

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/Interp/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) {

if (!Recursing) {
assert(Stk.empty());
C.cleanup();
#ifndef NDEBUG
// Make sure we don't rely on some value being still alive in
// InterpStack memory.
Expand All @@ -82,6 +83,7 @@ bool Context::evaluate(State &Parent, const Expr *E, APValue &Result) {

if (!Recursing) {
assert(Stk.empty());
C.cleanup();
#ifndef NDEBUG
// Make sure we don't rely on some value being still alive in
// InterpStack memory.
Expand Down Expand Up @@ -111,6 +113,7 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,

if (!Recursing) {
assert(Stk.empty());
C.cleanup();
#ifndef NDEBUG
// Make sure we don't rely on some value being still alive in
// InterpStack memory.
Expand Down
73 changes: 47 additions & 26 deletions clang/lib/AST/Interp/Descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ using namespace clang;
using namespace clang::interp;

template <typename T>
static void ctorTy(Block *, std::byte *Ptr, bool, bool, bool,
static void ctorTy(Block *, std::byte *Ptr, bool, bool, bool, bool,
const Descriptor *) {
new (Ptr) T();
}
Expand All @@ -40,7 +40,7 @@ static void moveTy(Block *, const std::byte *Src, std::byte *Dst,
}

template <typename T>
static void ctorArrayTy(Block *, std::byte *Ptr, bool, bool, bool,
static void ctorArrayTy(Block *, std::byte *Ptr, bool, bool, bool, bool,
const Descriptor *D) {
new (Ptr) InitMapPtr(std::nullopt);

Expand Down Expand Up @@ -83,7 +83,8 @@ static void moveArrayTy(Block *, const std::byte *Src, std::byte *Dst,
}

static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst,
bool IsMutable, bool IsActive, const Descriptor *D) {
bool IsMutable, bool IsActive, bool InUnion,
const Descriptor *D) {
const unsigned NumElems = D->getNumElems();
const unsigned ElemSize =
D->ElemDesc->getAllocSize() + sizeof(InlineDescriptor);
Expand All @@ -102,9 +103,11 @@ static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst,
Desc->IsActive = IsActive;
Desc->IsConst = IsConst || D->IsConst;
Desc->IsFieldMutable = IsMutable || D->IsMutable;
Desc->InUnion = InUnion;

if (auto Fn = D->ElemDesc->CtorFn)
Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsActive,
D->ElemDesc);
Desc->InUnion || SD->isUnion(), D->ElemDesc);
}
}

Expand Down Expand Up @@ -146,55 +149,62 @@ static void moveArrayDesc(Block *B, const std::byte *Src, std::byte *Dst,
}

static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsActive, bool IsUnion, const Descriptor *D,
unsigned FieldOffset) {
bool IsActive, bool IsUnionField, bool InUnion,
const Descriptor *D, unsigned FieldOffset) {
auto *Desc = reinterpret_cast<InlineDescriptor *>(Ptr + FieldOffset) - 1;
Desc->Offset = FieldOffset;
Desc->Desc = D;
Desc->IsInitialized = D->IsArray;
Desc->IsBase = false;
Desc->IsActive = IsActive && !IsUnion;
Desc->IsActive = IsActive && !IsUnionField;
Desc->InUnion = InUnion;
Desc->IsConst = IsConst || D->IsConst;
Desc->IsFieldMutable = IsMutable || D->IsMutable;

if (auto Fn = D->CtorFn)
Fn(B, Ptr + FieldOffset, Desc->IsConst, Desc->IsFieldMutable,
Desc->IsActive, D);
Desc->IsActive, InUnion || D->isUnion(), D);
}

static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsActive, const Descriptor *D, unsigned FieldOffset,
bool IsVirtualBase) {
bool IsActive, bool InUnion, const Descriptor *D,
unsigned FieldOffset, bool IsVirtualBase) {
assert(D);
assert(D->ElemRecord);
assert(!D->ElemRecord->isUnion()); // Unions cannot be base classes.

bool IsUnion = D->ElemRecord->isUnion();
auto *Desc = reinterpret_cast<InlineDescriptor *>(Ptr + FieldOffset) - 1;
Desc->Offset = FieldOffset;
Desc->Desc = D;
Desc->IsInitialized = D->IsArray;
Desc->IsBase = true;
Desc->IsVirtualBase = IsVirtualBase;
Desc->IsActive = IsActive && !IsUnion;
Desc->IsActive = IsActive && !InUnion;
Desc->IsConst = IsConst || D->IsConst;
Desc->IsFieldMutable = IsMutable || D->IsMutable;
Desc->InUnion = InUnion;

for (const auto &V : D->ElemRecord->bases())
initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, V.Desc,
V.Offset, false);
initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion,
V.Desc, V.Offset, false);
for (const auto &F : D->ElemRecord->fields())
initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, IsUnion,
F.Desc, F.Offset);
initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion,
InUnion, F.Desc, F.Offset);
}

static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsActive, const Descriptor *D) {
bool IsActive, bool InUnion, const Descriptor *D) {
for (const auto &V : D->ElemRecord->bases())
initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, false);
for (const auto &F : D->ElemRecord->fields())
initField(B, Ptr, IsConst, IsMutable, IsActive, D->ElemRecord->isUnion(), F.Desc, F.Offset);
initBase(B, Ptr, IsConst, IsMutable, IsActive, InUnion, V.Desc, V.Offset,
false);
for (const auto &F : D->ElemRecord->fields()) {
bool IsUnionField = D->isUnion();
initField(B, Ptr, IsConst, IsMutable, IsActive, IsUnionField,
InUnion || IsUnionField, F.Desc, F.Offset);
}
for (const auto &V : D->ElemRecord->virtual_bases())
initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, true);
initBase(B, Ptr, IsConst, IsMutable, IsActive, InUnion, V.Desc, V.Offset,
true);
}

static void destroyField(Block *B, std::byte *Ptr, const Descriptor *D,
Expand Down Expand Up @@ -225,12 +235,21 @@ static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) {

static void moveRecord(Block *B, const std::byte *Src, std::byte *Dst,
const Descriptor *D) {
for (const auto &F : D->ElemRecord->fields()) {
auto FieldOff = F.Offset;
auto *FieldDesc = F.Desc;
assert(D);
assert(D->ElemRecord);

if (auto Fn = FieldDesc->MoveFn)
Fn(B, Src + FieldOff, Dst + FieldOff, FieldDesc);
// FIXME: There might be cases where we need to move over the (v)bases as
// well.
for (const auto &F : D->ElemRecord->fields()) {
auto FieldOffset = F.Offset;
const auto *SrcDesc =
reinterpret_cast<const InlineDescriptor *>(Src + FieldOffset) - 1;
auto *DestDesc =
reinterpret_cast<InlineDescriptor *>(Dst + FieldOffset) - 1;
std::memcpy(DestDesc, SrcDesc, sizeof(InlineDescriptor));

if (auto Fn = F.Desc->MoveFn)
Fn(B, Src + FieldOffset, Dst + FieldOffset, F.Desc);
}
}

Expand Down Expand Up @@ -394,6 +413,8 @@ SourceLocation Descriptor::getLocation() const {
llvm_unreachable("Invalid descriptor type");
}

bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); }

InitMap::InitMap(unsigned N)
: UninitFields(N), Data(std::make_unique<T[]>(numFields(N))) {
std::fill_n(data(), numFields(N), 0);
Expand Down
Loading