6 changes: 4 additions & 2 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ VALUE_CODEGENOPT(Name, Bits, Default)

CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
CODEGENOPT(Crel, 1, 0) ///< -Wa,--crel
CODEGENOPT(RelaxELFRelocations, 1, 1) ///< -Wa,-mrelax-relocations={yes,no}
CODEGENOPT(SSE2AVX , 1, 0) ///< -msse2avx
CODEGENOPT(ImplicitMapSyms, 1, 0) ///< -Wa,-mmapsyms=implicit
CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm.
CODEGENOPT(PreserveAsmComments, 1, 1) ///< -dA, -fno-preserve-as-comments.
CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) operator new
Expand Down Expand Up @@ -178,6 +177,7 @@ CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled.
CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled.
CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled.
CODEGENOPT(MipsMsa , 1, 0) ///< Set when -Wa,-mmsa is enabled.
CODEGENOPT(FatalWarnings , 1, 0) ///< Set when -Wa,--fatal-warnings is
///< enabled.
CODEGENOPT(NoWarn , 1, 0) ///< Set when -Wa,--no-warn is enabled.
Expand All @@ -194,6 +194,8 @@ CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is en
CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get unique names.
CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information.
CODEGENOPT(PPCUseFullRegisterNames, 1, 0) ///< Print full register names in assembly
CODEGENOPT(X86RelaxRelocations, 1, 1) ///< -Wa,-mrelax-relocations={yes,no}
CODEGENOPT(X86Sse2Avx , 1, 0) ///< -Wa,-msse2avx

/// When false, this attempts to generate code as if the result of an
/// overflowing conversion matches the overflowing behavior of a target's native
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Basic/DiagnosticASTKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ def note_constexpr_new : Note<
def note_constexpr_new_non_replaceable : Note<
"call to %select{placement|class-specific}0 %1">;
def note_constexpr_new_placement : Note<
"this placement new expression is not yet supported in constant expressions">;
"this placement new expression is not supported in constant expressions "
"%select{|before C++2c}0">;
def note_constexpr_placement_new_wrong_type : Note<
"placement new would change type of storage from %0 to %1">;
def note_constexpr_new_negative : Note<
Expand Down
3 changes: 0 additions & 3 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -604,9 +604,6 @@ def warn_drv_unsupported_gpopt : Warning<
"ignoring '-mgpopt' option as it cannot be used with %select{|the implicit"
" usage of }0-mabicalls">,
InGroup<UnsupportedGPOpt>;
def warn_drv_unsupported_sdata : Warning<
"ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64">,
InGroup<OptionIgnored>;
def warn_drv_unsupported_longcalls : Warning<
"ignoring '-mlong-calls' option as it is not currently supported with "
"%select{|the implicit usage of }0-mabicalls">,
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -1547,6 +1547,9 @@ def DXILValidation : DiagGroup<"dxil-validation">;
// Warning for HLSL API availability
def HLSLAvailability : DiagGroup<"hlsl-availability">;

// Warnings for legacy binding behavior
def LegacyConstantRegisterBinding : DiagGroup<"legacy-constant-register-binding">;

// Warnings and notes related to const_var_decl_type attribute checks
def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">;

Expand Down
12 changes: 12 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,9 @@ def ext_decomp_decl_empty : ExtWarn<
"ISO C++17 does not allow a decomposition group to be empty">,
InGroup<DiagGroup<"empty-decomposition">>;

def err_function_parameter_limit_exceeded : Error<
"too many function parameters; subsequent parameters will be ignored">;

// C++26 structured bindings
def ext_decl_attrs_on_binding : ExtWarn<
"an attribute specifier sequence attached to a structured binding declaration "
Expand Down Expand Up @@ -965,6 +968,15 @@ def warn_cxx23_delete_with_message : Warning<
"'= delete' with a message is incompatible with C++ standards before C++2c">,
DefaultIgnore, InGroup<CXXPre26Compat>;

def ext_variadic_friends : ExtWarn<
"variadic 'friend' declarations are a C++2c extension">, InGroup<CXX26>;
def warn_cxx23_variadic_friends : Warning<
"variadic 'friend' declarations are incompatible with C++ standards before C++2c">,
DefaultIgnore, InGroup<CXXPre26Compat>;

def err_friend_concept : Error<
"friend declaration cannot be a concept">;

// C++11 default member initialization
def ext_nonstatic_member_init : ExtWarn<
"default member initializer for non-static data member is a C++11 "
Expand Down
31 changes: 21 additions & 10 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1741,6 +1741,10 @@ def ext_friend_tag_redecl_outside_namespace : ExtWarn<
"enclosing namespace is a Microsoft extension; add a nested name specifier">,
InGroup<MicrosoftUnqualifiedFriend>;
def err_pure_friend : Error<"friend declaration cannot have a pure-specifier">;
def err_friend_template_decl_multiple_specifiers: Error<
"a friend declaration that befriends a template must contain exactly one type-specifier">;
def friend_template_decl_malformed_pack_expansion : Error<
"friend declaration expands pack %0 that is declared it its own template parameter list">;

def err_invalid_base_in_interface : Error<
"interface type cannot inherit from "
Expand Down Expand Up @@ -5663,6 +5667,8 @@ def err_explicit_instantiation_internal_linkage : Error<
def err_explicit_instantiation_not_known : Error<
"explicit instantiation of %0 does not refer to a function template, "
"variable template, member function, member class, or static data member">;
def err_explicit_instantiation_no_candidate : Error<
"no viable candidate for explicit instantiation of %0">;
def note_explicit_instantiation_here : Note<
"explicit instantiation refers here">;
def err_explicit_instantiation_data_member_not_instantiated : Error<
Expand Down Expand Up @@ -9359,9 +9365,6 @@ let CategoryName = "Inline Assembly Issue" in {
"invalid input size for constraint '%0'">;
def err_asm_invalid_output_size : Error<
"invalid output size for constraint '%0'">;
def err_invalid_asm_cast_lvalue : Error<
"invalid use of a cast in a inline asm context requiring an lvalue: "
"remove the cast or build with -fheinous-gnu-extensions">;
def err_invalid_asm_value_for_constraint
: Error <"value '%0' out of range for constraint '%1'">;
def err_asm_non_addr_value_in_memory_constraint : Error <
Expand All @@ -9375,9 +9378,8 @@ let CategoryName = "Inline Assembly Issue" in {
def warn_asm_label_on_auto_decl : Warning<
"ignored asm label '%0' on automatic variable">;
def warn_invalid_asm_cast_lvalue : Warning<
"invalid use of a cast in an inline asm context requiring an lvalue: "
"accepted due to -fheinous-gnu-extensions, but clang may remove support "
"for this in the future">;
"invalid use of a cast in an inline asm context requiring an lvalue">,
InGroup<DiagGroup<"invalid-gnu-asm-cast">>, DefaultError;
def warn_asm_mismatched_size_modifier : Warning<
"value size does not match register size specified by the constraint "
"and modifier">,
Expand Down Expand Up @@ -9752,7 +9754,7 @@ def err_defaulted_special_member_quals : Error<
"have 'const'%select{, 'constexpr'|}1 or 'volatile' qualifiers">;
def err_defaulted_special_member_explicit_object_mismatch : Error<
"the type of the explicit object parameter of an explicitly-defaulted "
"%select{copy|move}0 assignment operator should match the type of the class %1">;
"%select{copy|move}0 assignment operator should be reference to %1">;
def err_defaulted_special_member_volatile_param : Error<
"the parameter for an explicitly-defaulted %sub{select_special_member_kind}0 "
"may not be volatile">;
Expand Down Expand Up @@ -10062,8 +10064,9 @@ def warn_null_ret : Warning<
InGroup<NonNull>;

def err_lifetimebound_no_object_param : Error<
"'lifetimebound' attribute cannot be applied; %select{static |non-}0member "
"function has no implicit object parameter">;
"'lifetimebound' attribute cannot be applied; "
"%select{non-|static |explicit object }0"
"member function has no implicit object parameter">;
def err_lifetimebound_ctor_dtor : Error<
"'lifetimebound' attribute cannot be applied to a "
"%select{constructor|destructor}0">;
Expand Down Expand Up @@ -11160,6 +11163,8 @@ def err_omp_loop_diff_cxx : Error<
"upper and lower loop bounds">;
def err_omp_loop_cannot_use_stmt : Error<
"'%0' statement cannot be used in OpenMP for loop">;
def err_omp_loop_bad_collapse_var : Error<
"cannot use variable %1 in collapsed imperfectly-nested loop %select{init|condition|increment}0 statement">;
def err_omp_simd_region_cannot_use_stmt : Error<
"'%0' statement cannot be used in OpenMP simd region">;
def warn_omp_loop_64_bit_var : Warning<
Expand Down Expand Up @@ -12343,7 +12348,13 @@ def err_hlsl_missing_semantic_annotation : Error<
def err_hlsl_init_priority_unsupported : Error<
"initializer priorities are not supported in HLSL">;

def err_hlsl_unsupported_register_type : Error<"invalid resource class specifier '%0' used; expected 'b', 's', 't', or 'u'">;
def warn_hlsl_user_defined_type_missing_member: Warning<"binding type '%select{t|u|b|s|c}0' only applies to types containing %select{SRV resources|UAV resources|constant buffer resources|sampler state|numeric types}0">, InGroup<LegacyConstantRegisterBinding>;
def err_hlsl_binding_type_mismatch: Error<"binding type '%select{t|u|b|s|c}0' only applies to %select{SRV resources|UAV resources|constant buffer resources|sampler state|numeric variables in the global scope}0">;
def err_hlsl_binding_type_invalid: Error<"binding type '%0' is invalid">;
def err_hlsl_duplicate_register_annotation: Error<"binding type '%select{t|u|b|s|c|i}0' cannot be applied more than once">;
def warn_hlsl_register_type_c_packoffset: Warning<"binding type 'c' ignored in buffer declaration. Did you mean 'packoffset'?">, InGroup<LegacyConstantRegisterBinding>, DefaultError;
def warn_hlsl_deprecated_register_type_b: Warning<"binding type 'b' only applies to constant buffers. The 'bool constant' binding type is no longer supported">, InGroup<LegacyConstantRegisterBinding>, DefaultError;
def warn_hlsl_deprecated_register_type_i: Warning<"binding type 'i' ignored. The 'integer constant' binding type is no longer supported">, InGroup<LegacyConstantRegisterBinding>, DefaultError;
def err_hlsl_unsupported_register_number : Error<"register number should be an integer">;
def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; expected 'space' followed by an integer, like space1">;
def warn_hlsl_packoffset_mix : Warning<"cannot mix packoffset elements with nonpackoffset elements in a cbuffer">,
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/DiagnosticSerializationKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ def warn_module_system_bit_conflict : Warning<
"as a non-system module; any difference in diagnostic options will be ignored">,
InGroup<ModuleConflict>;

def warn_decls_in_multiple_modules : Warning<
"declaration %0 is detected to be defined in multiple module units, first is from '%1' and second is from '%2'; "
"the compiler may not be good at merging the definitions. ">,
InGroup<DiagGroup<"decls-in-multiple-modules">>,
DefaultIgnore;

def err_failed_to_find_module_file : Error<
"failed to find module file for module '%0'">;
} // let CategoryName
Expand Down
7 changes: 3 additions & 4 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ LANGOPT(POSIXThreads , 1, 0, "POSIX thread support")
LANGOPT(Blocks , 1, 0, "blocks extension to C")
BENIGN_LANGOPT(EmitAllDecls , 1, 0, "emitting all declarations")
LANGOPT(MathErrno , 1, 1, "errno in math functions")
BENIGN_LANGOPT(HeinousExtensions , 1, 0, "extensions that we really don't like and may be ripped out at any time")
LANGOPT(Modules , 1, 0, "modules semantics")
COMPATIBLE_LANGOPT(CPlusPlusModules, 1, 0, "C++ modules syntax")
LANGOPT(SkipODRCheckInGMF, 1, 0, "Skip ODR checks for decls in the global module fragment")
Expand Down Expand Up @@ -406,8 +405,6 @@ VALUE_LANGOPT(TrivialAutoVarInitMaxSize, 32, 0,
"stop trivial automatic variable initialization if var size exceeds the specified size (in bytes). Must be greater than 0.")
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
"signed integer overflow handling")
LANGOPT(IgnoreNegationOverflow, 1, 0, "ignore overflow caused by negation")
LANGOPT(SanitizeOverflowIdioms, 1, 1, "enable instrumentation for common overflow idioms")
ENUM_LANGOPT(ThreadModel , ThreadModelKind, 2, ThreadModelKind::POSIX, "Thread Model")

BENIGN_LANGOPT(ArrowDepth, 32, 256,
Expand Down Expand Up @@ -467,7 +464,9 @@ LANGOPT(FixedPoint, 1, 0, "fixed point types")
LANGOPT(PaddingOnUnsignedFixedPoint, 1, 0,
"unsigned fixed point types having one extra padding bit")

LANGOPT(RegisterStaticDestructors, 1, 1, "Register C++ static destructors")
ENUM_LANGOPT(RegisterStaticDestructors, RegisterStaticDestructorsKind, 2,
RegisterStaticDestructorsKind::All,
"Register C++ static destructors")

LANGOPT(RegCall4, 1, 0, "Set __regcall4 as a default calling convention to respect __regcall ABI v.4")

Expand Down
18 changes: 15 additions & 3 deletions clang/include/clang/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,11 +375,13 @@ class LangOptionsBase {
/// Exclude all overflow patterns (below)
All = 1 << 1,
/// if (a + b < a)
AddOverflowTest = 1 << 2,
AddSignedOverflowTest = 1 << 2,
/// if (a + b < a)
AddUnsignedOverflowTest = 1 << 3,
/// -1UL
NegUnsignedConst = 1 << 3,
NegUnsignedConst = 1 << 4,
/// while (count--)
PostDecrInWhile = 1 << 4,
PostDecrInWhile = 1 << 5,
};

enum class DefaultVisiblityExportMapping {
Expand Down Expand Up @@ -456,6 +458,16 @@ class LangOptionsBase {
CX_None
};

/// Controls which variables have static destructors registered.
enum class RegisterStaticDestructorsKind {
/// Register static destructors for all variables.
All,
/// Register static destructors only for thread-local variables.
ThreadLocal,
/// Don't register static destructors for any variables.
None,
};

// Define simple language options (with no accessors).
#define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits;
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/Sanitizers.def
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ SANITIZER("thread", Thread)
// Numerical stability sanitizer.
SANITIZER("numerical", NumericalStability)

// RealtimeSanitizer
SANITIZER("realtime", Realtime)

// LeakSanitizer
SANITIZER("leak", Leak)

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,9 @@ KEYWORD(out , KEYHLSL)
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) KEYWORD(Name, KEYHLSL)
#include "clang/Basic/HLSLIntangibleTypes.def"

// HLSL Type traits.
TYPE_TRAIT_2(__builtin_hlsl_is_scalarized_layout_compatible, IsScalarizedLayoutCompatible, KEYHLSL)

// OpenMP Type Traits
UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL)

Expand Down
3 changes: 1 addition & 2 deletions clang/include/clang/Driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,7 @@ class Driver {

/// Takes the path to a binary that's either in bin/ or lib/ and returns
/// the path to clang's resource directory.
static std::string GetResourcesPath(StringRef BinaryPath,
StringRef CustomResourceDir = "");
static std::string GetResourcesPath(StringRef BinaryPath);

Driver(StringRef ClangExecutable, StringRef TargetTriple,
DiagnosticsEngine &Diags, std::string Title = "clang LLVM compiler",
Expand Down
59 changes: 44 additions & 15 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,8 @@ def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>,
Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>,
Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
def Winvalid_gnu_asm_cast : Flag<["-"], "Winvalid-gnu-asm-cast">, Group<W_Group>,
Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
def W_Joined : Joined<["-"], "W">, Group<W_Group>,
Visibility<[ClangOption, CC1Option, CLOption, DXCOption, FC1Option, FlangOption]>,
MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
Expand Down Expand Up @@ -2300,11 +2302,18 @@ defm fixed_point : BoolFOption<"fixed-point",
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
NegFlag<SetFalse, [], [ClangOption], "Disable">,
BothFlags<[], [ClangOption], " fixed point types">>;
defm cxx_static_destructors : BoolFOption<"c++-static-destructors",
LangOpts<"RegisterStaticDestructors">, DefaultTrue,
NegFlag<SetFalse, [], [ClangOption, CC1Option],
"Disable C++ static destructor registration">,
PosFlag<SetTrue>>;
def cxx_static_destructors_EQ : Joined<["-"], "fc++-static-destructors=">, Group<f_Group>,
HelpText<"Controls which variables C++ static destructors are registered for">,
Values<"all,thread-local,none">,
NormalizedValues<["All", "ThreadLocal", "None"]>,
NormalizedValuesScope<"LangOptions::RegisterStaticDestructorsKind">,
MarshallingInfoEnum<LangOpts<"RegisterStaticDestructors">, "All">,
Visibility<[ClangOption, CC1Option]>;
def cxx_static_destructors : Flag<["-"], "fc++-static-destructors">, Group<f_Group>,
Alias<cxx_static_destructors_EQ>, AliasArgs<["all"]>;
def no_cxx_static_destructors : Flag<["-"], "fno-c++-static-destructors">, Group<f_Group>,
Alias<cxx_static_destructors_EQ>, AliasArgs<["none"]>,
HelpText<"Disable C++ static destructor registration">;
def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
MarshallingInfoString<CodeGenOpts<"SymbolPartition">>;
Expand Down Expand Up @@ -2565,10 +2574,10 @@ defm sanitize_stats : BoolOption<"f", "sanitize-stats",
"Disable">,
BothFlags<[], [ClangOption], " sanitizer statistics gathering.">>,
Group<f_clang_Group>;
def fsanitize_overflow_pattern_exclusion_EQ : CommaJoined<["-"], "fsanitize-overflow-pattern-exclusion=">,
def fsanitize_undefined_ignore_overflow_pattern_EQ : CommaJoined<["-"], "fsanitize-undefined-ignore-overflow-pattern=">,
HelpText<"Specify the overflow patterns to exclude from artihmetic sanitizer instrumentation">,
Visibility<[ClangOption, CC1Option]>,
Values<"none,all,add-overflow-test,negated-unsigned-const,post-decr-while">,
Values<"none,all,add-unsigned-overflow-test,add-signed-overflow-test,negated-unsigned-const,unsigned-post-decr-while">,
MarshallingInfoStringVector<LangOpts<"OverflowPatternExclusionValues">>;
def fsanitize_thread_memory_access : Flag<["-"], "fsanitize-thread-memory-access">,
Group<f_clang_Group>,
Expand Down Expand Up @@ -2761,9 +2770,13 @@ defm gnu89_inline : BoolFOption<"gnu89-inline",
NegFlag<SetFalse>>, ShouldParseIf<!strconcat("!", cplusplus.KeyPath)>;
def fgnu_runtime : Flag<["-"], "fgnu-runtime">, Group<f_Group>,
HelpText<"Generate output compatible with the standard GNU Objective-C runtime">;
// This used to be a standalone flag but is now mapped to
// -Wno-error=invalid-gnu-asm-cast, which is the only thing the flag used to
// control.
def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">,
Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<LangOpts<"HeinousExtensions">>;
Alias<W_Joined>, AliasArgs<["no-error=invalid-gnu-asm-cast"]>,
HelpText<"(Deprecated) Controls whether '-Winvalid-gnu-asm-cast' defaults to "
"an error or a warning">;
def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>,
Group<Link_Group>;
def : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
Expand Down Expand Up @@ -5033,8 +5046,8 @@ def mexception_handing : Flag<["-"], "mexception-handling">, Group<m_wasm_Featur
def mno_exception_handing : Flag<["-"], "mno-exception-handling">, Group<m_wasm_Features_Group>;
def mextended_const : Flag<["-"], "mextended-const">, Group<m_wasm_Features_Group>;
def mno_extended_const : Flag<["-"], "mno-extended-const">, Group<m_wasm_Features_Group>;
def mhalf_precision : Flag<["-"], "mhalf-precision">, Group<m_wasm_Features_Group>;
def mno_half_precision : Flag<["-"], "mno-half-precision">, Group<m_wasm_Features_Group>;
def mfp16 : Flag<["-"], "mfp16">, Group<m_wasm_Features_Group>;
def mno_fp16 : Flag<["-"], "mno-fp16">, Group<m_wasm_Features_Group>;
def mmultimemory : Flag<["-"], "mmultimemory">, Group<m_wasm_Features_Group>;
def mno_multimemory : Flag<["-"], "mno-multimemory">, Group<m_wasm_Features_Group>;
def mmultivalue : Flag<["-"], "mmultivalue">, Group<m_wasm_Features_Group>;
Expand Down Expand Up @@ -5236,7 +5249,7 @@ let Flags = [TargetSpecific] in {
def msse2avx : Flag<["-"], "msse2avx">, Group<m_Group>,
Visibility<[ClangOption, CC1Option, CC1AsOption]>,
HelpText<"Specify that the assembler should encode SSE instructions with VEX prefix">,
MarshallingInfoFlag<CodeGenOpts<"SSE2AVX">>;
MarshallingInfoFlag<CodeGenOpts<"X86Sse2Avx">>;
} // let Flags = [TargetSpecific]

defm zvector : BoolFOption<"zvector",
Expand Down Expand Up @@ -5388,7 +5401,9 @@ def mmadd4 : Flag<["-"], "mmadd4">, Group<m_mips_Features_Group>,
def mno_madd4 : Flag<["-"], "mno-madd4">, Group<m_mips_Features_Group>,
HelpText<"Disable the generation of 4-operand madd.s, madd.d and related instructions.">;
def mmsa : Flag<["-"], "mmsa">, Group<m_mips_Features_Group>,
HelpText<"Enable MSA ASE (MIPS only)">;
Visibility<[ClangOption, CC1Option, CC1AsOption]>,
HelpText<"Enable MSA ASE (MIPS only)">,
MarshallingInfoFlag<CodeGenOpts<"MipsMsa">>;
def mno_msa : Flag<["-"], "mno-msa">, Group<m_mips_Features_Group>,
HelpText<"Disable MSA ASE (MIPS only)">;
def mmt : Flag<["-"], "mmt">, Group<m_mips_Features_Group>,
Expand Down Expand Up @@ -6149,6 +6164,14 @@ def mvis3 : Flag<["-"], "mvis3">, Group<m_sparc_Features_Group>;
def mno_vis3 : Flag<["-"], "mno-vis3">, Group<m_sparc_Features_Group>;
def mhard_quad_float : Flag<["-"], "mhard-quad-float">, Group<m_sparc_Features_Group>;
def msoft_quad_float : Flag<["-"], "msoft-quad-float">, Group<m_sparc_Features_Group>;
def mv8plus : Flag<["-"], "mv8plus">, Group<m_sparc_Features_Group>,
HelpText<"Enable V8+ mode, allowing use of 64-bit V9 instructions in 32-bit code">;
def mno_v8plus : Flag<["-"], "mno-v8plus">, Group<m_sparc_Features_Group>,
HelpText<"Disable V8+ mode">;
def mfix_gr712rc : Flag<["-"], "mfix-gr712rc">, Group<m_sparc_Features_Group>,
HelpText<"Enable workarounds for GR712RC errata">;
def mfix_ut700 : Flag<["-"], "mfix-ut700">, Group<m_sparc_Features_Group>,
HelpText<"Enable workarounds for UT700 errata">;
foreach i = 1 ... 7 in
def ffixed_g#i : Flag<["-"], "ffixed-g"#i>, Group<m_sparc_Features_Group>,
HelpText<"Reserve the G"#i#" register (SPARC only)">;
Expand Down Expand Up @@ -7132,9 +7155,15 @@ def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">,
def crel : Flag<["--"], "crel">,
HelpText<"Enable CREL relocation format (ELF only)">,
MarshallingInfoFlag<CodeGenOpts<"Crel">>;
def mmapsyms_implicit : Flag<["-"], "mmapsyms=implicit">,
HelpText<"Allow mapping symbol at section beginning to be implicit, "
"lowering number of mapping symbols at the expense of some "
"portability. Recommended for projects that can build all their "
"object files using this option">,
MarshallingInfoFlag<CodeGenOpts<"ImplicitMapSyms">>;
def mrelax_relocations_no : Flag<["-"], "mrelax-relocations=no">,
HelpText<"Disable x86 relax relocations">,
MarshallingInfoNegativeFlag<CodeGenOpts<"RelaxELFRelocations">>;
MarshallingInfoNegativeFlag<CodeGenOpts<"X86RelaxRelocations">>;
def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
HelpText<"Save temporary labels in the symbol table. "
"Note this may change .s semantics and shouldn't generally be used "
Expand Down Expand Up @@ -8841,7 +8870,7 @@ def dxil_validator_version : Option<["/", "-"], "validator-version", KIND_SEPARA
Visibility<[DXCOption, ClangOption, CC1Option]>,
HelpText<"Override validator version for module. Format: <major.minor>;"
"Default: DXIL.dll version or current internal version">,
MarshallingInfoString<TargetOpts<"DxilValidatorVersion">>;
MarshallingInfoString<TargetOpts<"DxilValidatorVersion">, "\"1.8\"">;
def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">,
HelpText<"Set target profile">,
Values<"ps_6_0, ps_6_1, ps_6_2, ps_6_3, ps_6_4, ps_6_5, ps_6_6, ps_6_7,"
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Driver/SanitizerArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class SanitizerArgs {
bool needsNsanRt() const {
return Sanitizers.has(SanitizerKind::NumericalStability);
}
bool needsRtsanRt() const { return Sanitizers.has(SanitizerKind::Realtime); }

bool hasMemTag() const {
return hasMemtagHeap() || hasMemtagStack() || hasMemtagGlobals();
Expand Down
25 changes: 12 additions & 13 deletions clang/include/clang/ExtractAPI/API.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,13 @@
#define LLVM_CLANG_EXTRACTAPI_API_H

#include "clang/AST/Availability.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/RawCommentList.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/ExtractAPI/DeclarationFragments.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
#include <cstddef>
#include <iterator>
Expand Down Expand Up @@ -328,6 +320,8 @@ class RecordContext {
/// chain.
void stealRecordChain(RecordContext &Other);

void removeFromRecordChain(APIRecord *Record);

APIRecord::RecordKind getKind() const { return Kind; }

struct record_iterator {
Expand Down Expand Up @@ -1426,10 +1420,15 @@ class APISet {
typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);

ArrayRef<const APIRecord *> getTopLevelRecords() const {
return TopLevelRecords;
auto getTopLevelRecords() const {
return llvm::iterator_range<decltype(TopLevelRecords)::iterator>(
TopLevelRecords);
}

void removeRecord(StringRef USR);

void removeRecord(APIRecord *Record);

APISet(const llvm::Triple &Target, Language Lang,
const std::string &ProductName)
: Target(Target), Lang(Lang), ProductName(ProductName) {}
Expand All @@ -1456,7 +1455,7 @@ class APISet {
// lives in the BumpPtrAllocator.
using APIRecordStoredPtr = std::unique_ptr<APIRecord, APIRecordDeleter>;
llvm::DenseMap<StringRef, APIRecordStoredPtr> USRBasedLookupTable;
std::vector<const APIRecord *> TopLevelRecords;
llvm::SmallPtrSet<const APIRecord *, 32> TopLevelRecords;

public:
const std::string ProductName;
Expand All @@ -1482,7 +1481,7 @@ APISet::createRecord(StringRef USR, StringRef Name,
dyn_cast_if_present<RecordContext>(Record->Parent.Record))
ParentContext->addToRecordChain(Record);
else
TopLevelRecords.push_back(Record);
TopLevelRecords.insert(Record);
} else {
Record = dyn_cast<RecordTy>(Result.first->second.get());
}
Expand Down
37 changes: 35 additions & 2 deletions clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ namespace impl {

template <typename Derived>
class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
using Base = RecursiveASTVisitor<Derived>;

protected:
ExtractAPIVisitorBase(ASTContext &Context, APISet &API)
: Context(Context), API(API) {}
Expand Down Expand Up @@ -81,8 +83,10 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {

bool VisitNamespaceDecl(const NamespaceDecl *Decl);

bool TraverseRecordDecl(RecordDecl *Decl);
bool VisitRecordDecl(const RecordDecl *Decl);

bool TraverseCXXRecordDecl(CXXRecordDecl *Decl);
bool VisitCXXRecordDecl(const CXXRecordDecl *Decl);

bool VisitCXXMethodDecl(const CXXMethodDecl *Decl);
Expand Down Expand Up @@ -240,7 +244,7 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {

bool isEmbeddedInVarDeclarator(const TagDecl &D) {
return D.getName().empty() && getTypedefName(&D).empty() &&
D.isEmbeddedInDeclarator();
D.isEmbeddedInDeclarator() && !D.isFreeStanding();
}

void maybeMergeWithAnonymousTag(const DeclaratorDecl &D,
Expand All @@ -252,8 +256,10 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
clang::index::generateUSRForDecl(Tag, TagUSR);
if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
API.findRecordForUSR(TagUSR))) {
if (Record->IsEmbeddedInVarDeclarator)
if (Record->IsEmbeddedInVarDeclarator) {
NewRecordContext->stealRecordChain(*Record);
API.removeRecord(Record);
}
}
}
};
Expand Down Expand Up @@ -548,6 +554,19 @@ bool ExtractAPIVisitorBase<Derived>::VisitNamespaceDecl(
return true;
}

template <typename Derived>
bool ExtractAPIVisitorBase<Derived>::TraverseRecordDecl(RecordDecl *Decl) {
bool Ret = Base::TraverseRecordDecl(Decl);

if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
SmallString<128> USR;
index::generateUSRForDecl(Decl, USR);
API.removeRecord(USR);
}

return Ret;
}

template <typename Derived>
bool ExtractAPIVisitorBase<Derived>::VisitRecordDecl(const RecordDecl *Decl) {
if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
Expand Down Expand Up @@ -588,6 +607,20 @@ bool ExtractAPIVisitorBase<Derived>::VisitRecordDecl(const RecordDecl *Decl) {
return true;
}

template <typename Derived>
bool ExtractAPIVisitorBase<Derived>::TraverseCXXRecordDecl(
CXXRecordDecl *Decl) {
bool Ret = Base::TraverseCXXRecordDecl(Decl);

if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
SmallString<128> USR;
index::generateUSRForDecl(Decl, USR);
API.removeRecord(USR);
}

return Ret;
}

template <typename Derived>
bool ExtractAPIVisitorBase<Derived>::VisitCXXRecordDecl(
const CXXRecordDecl *Decl) {
Expand Down
84 changes: 62 additions & 22 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ struct FormatStyle {

/// If the function declaration doesn't fit on a line,
/// allow putting all parameters of a function declaration onto
/// the next line even if ``BinPackParameters`` is ``false``.
/// the next line even if ``BinPackParameters`` is ``OnePerLine``.
/// \code
/// true:
/// void myFunction(
Expand Down Expand Up @@ -1192,20 +1192,36 @@ struct FormatStyle {
/// \version 3.7
bool BinPackArguments;

/// If ``false``, a function declaration's or function definition's
/// parameters will either all be on the same line or will have one line each.
/// \code
/// true:
/// void f(int aaaaaaaaaaaaaaaaaaaa, int aaaaaaaaaaaaaaaaaaaa,
/// int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}
///
/// false:
/// void f(int aaaaaaaaaaaaaaaaaaaa,
/// int aaaaaaaaaaaaaaaaaaaa,
/// int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}
/// \endcode
/// Different way to try to fit all parameters on a line.
enum BinPackParametersStyle : int8_t {
/// Bin-pack parameters.
/// \code
/// void f(int a, int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
/// int ccccccccccccccccccccccccccccccccccccccccccc);
/// \endcode
BPPS_BinPack,
/// Put all parameters on the current line if they fit.
/// Otherwise, put each one on its own line.
/// \code
/// void f(int a, int b, int c);
///
/// void f(int a,
/// int b,
/// int ccccccccccccccccccccccccccccccccccccc);
/// \endcode
BPPS_OnePerLine,
/// Always put each parameter on its own line.
/// \code
/// void f(int a,
/// int b,
/// int c);
/// \endcode
BPPS_AlwaysOnePerLine,
};

/// The bin pack parameters style to use.
/// \version 3.7
bool BinPackParameters;
BinPackParametersStyle BinPackParameters;

/// Styles for adding spacing around ``:`` in bitfield definitions.
enum BitFieldColonSpacingStyle : int8_t {
Expand Down Expand Up @@ -2858,7 +2874,8 @@ struct FormatStyle {
PPDirectiveIndentStyle IndentPPDirectives;

/// Indent the requires clause in a template. This only applies when
/// ``RequiresClausePosition`` is ``OwnLine``, or ``WithFollowing``.
/// ``RequiresClausePosition`` is ``OwnLine``, ``OwnLineWithBrace``,
/// or ``WithFollowing``.
///
/// In clang-format 12, 13 and 14 it was named ``IndentRequires``.
/// \code
Expand Down Expand Up @@ -3413,7 +3430,7 @@ struct FormatStyle {
/// items into as few lines as possible when they go over ``ColumnLimit``.
///
/// If ``Auto`` (the default), delegates to the value in
/// ``BinPackParameters``. If that is ``true``, bin-packs Objective-C
/// ``BinPackParameters``. If that is ``BinPack``, bin-packs Objective-C
/// protocol conformance list items into as few lines as possible
/// whenever they go over ``ColumnLimit``.
///
Expand All @@ -3425,13 +3442,13 @@ struct FormatStyle {
/// onto individual lines whenever they go over ``ColumnLimit``.
///
/// \code{.objc}
/// Always (or Auto, if BinPackParameters=true):
/// Always (or Auto, if BinPackParameters==BinPack):
/// @interface ccccccccccccc () <
/// ccccccccccccc, ccccccccccccc,
/// ccccccccccccc, ccccccccccccc> {
/// }
///
/// Never (or Auto, if BinPackParameters=false):
/// Never (or Auto, if BinPackParameters!=BinPack):
/// @interface ddddddddddddd () <
/// ddddddddddddd,
/// ddddddddddddd,
Expand Down Expand Up @@ -3944,22 +3961,45 @@ struct FormatStyle {
/// ``IndentRequires`` option is only used if the ``requires`` is put on the
/// start of a line.
enum RequiresClausePositionStyle : int8_t {
/// Always put the ``requires`` clause on its own line.
/// Always put the ``requires`` clause on its own line (possibly followed by
/// a semicolon).
/// \code
/// template <typename T>
/// requires C<T>
/// requires C<T>
/// struct Foo {...
///
/// template <typename T>
/// requires C<T>
/// void bar(T t)
/// requires C<T>;
///
/// template <typename T>
/// requires C<T>
/// void bar(T t) {...
///
/// template <typename T>
/// void baz(T t)
/// requires C<T>
/// requires C<T>
/// {...
/// \endcode
RCPS_OwnLine,
/// As with ``OwnLine``, except, unless otherwise prohibited, place a
/// following open brace (of a function definition) to follow on the same
/// line.
/// \code
/// void bar(T t)
/// requires C<T> {
/// return;
/// }
///
/// void bar(T t)
/// requires C<T> {}
///
/// template <typename T>
/// requires C<T>
/// void baz(T t) {
/// ...
/// \endcode
RCPS_OwnLineWithBrace,
/// Try to put the clause together with the preceding part of a declaration.
/// For class templates: stick to the template declaration.
/// For function templates: stick to the template declaration.
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3021,15 +3021,17 @@ class Parser : public CodeCompletionHandler {
SemaCodeCompletion::AttributeCompletion::None,
const IdentifierInfo *EnclosingScope = nullptr);

void MaybeParseHLSLAnnotations(Declarator &D,
bool MaybeParseHLSLAnnotations(Declarator &D,
SourceLocation *EndLoc = nullptr,
bool CouldBeBitField = false) {
assert(getLangOpts().HLSL && "MaybeParseHLSLAnnotations is for HLSL only");
if (Tok.is(tok::colon)) {
ParsedAttributes Attrs(AttrFactory);
ParseHLSLAnnotations(Attrs, EndLoc, CouldBeBitField);
D.takeAttributes(Attrs);
return true;
}
return false;
}

void MaybeParseHLSLAnnotations(ParsedAttributes &Attrs,
Expand Down
50 changes: 0 additions & 50 deletions clang/include/clang/Rewrite/Core/DeltaTree.h

This file was deleted.

11 changes: 7 additions & 4 deletions clang/include/clang/Rewrite/Core/HTMLRewrite.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
#include "clang/Basic/SourceLocation.h"
#include <string>

namespace llvm {
class RewriteBuffer;
} // namespace llvm

namespace clang {

class Rewriter;
class RewriteBuffer;
class Preprocessor;

namespace html {
Expand Down Expand Up @@ -53,9 +56,9 @@ namespace html {

/// HighlightRange - This is the same as the above method, but takes
/// decomposed file locations.
void HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
const char *BufferStart,
const char *StartTag, const char *EndTag);
void HighlightRange(llvm::RewriteBuffer &RB, unsigned B, unsigned E,
const char *BufferStart, const char *StartTag,
const char *EndTag);

/// EscapeText - HTMLize a specified file so that special characters are
/// are translated so that they are not interpreted as HTML tags.
Expand Down
223 changes: 0 additions & 223 deletions clang/include/clang/Rewrite/Core/RewriteRope.h

This file was deleted.

19 changes: 10 additions & 9 deletions clang/include/clang/Rewrite/Core/Rewriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Rewrite/Core/RewriteBuffer.h"
#include "llvm/ADT/RewriteBuffer.h"
#include "llvm/ADT/StringRef.h"
#include <map>
#include <string>
Expand All @@ -32,7 +32,7 @@ class SourceManager;
class Rewriter {
SourceManager *SourceMgr = nullptr;
const LangOptions *LangOpts = nullptr;
std::map<FileID, RewriteBuffer> RewriteBuffers;
std::map<FileID, llvm::RewriteBuffer> RewriteBuffers;

public:
struct RewriteOptions {
Expand All @@ -49,7 +49,7 @@ class Rewriter {
///
/// FIXME: This sometimes corrupts the file's rewrite buffer due to
/// incorrect indexing in the implementation (see the FIXME in
/// clang::RewriteBuffer::RemoveText). Moreover, it's inefficient because
/// llvm::RewriteBuffer::RemoveText). Moreover, it's inefficient because
/// it must scan the buffer from the beginning to find the start of the
/// line. When feasible, it's better for the caller to check for a blank
/// line and then, if found, expand the removal range to include it.
Expand All @@ -62,8 +62,9 @@ class Rewriter {
RewriteOptions() {}
};

using buffer_iterator = std::map<FileID, RewriteBuffer>::iterator;
using const_buffer_iterator = std::map<FileID, RewriteBuffer>::const_iterator;
using buffer_iterator = std::map<FileID, llvm::RewriteBuffer>::iterator;
using const_buffer_iterator =
std::map<FileID, llvm::RewriteBuffer>::const_iterator;

explicit Rewriter() = default;
explicit Rewriter(SourceManager &SM, const LangOptions &LO)
Expand Down Expand Up @@ -191,13 +192,13 @@ class Rewriter {
/// buffer, and allows you to write on it directly. This is useful if you
/// want efficient low-level access to apis for scribbling on one specific
/// FileID's buffer.
RewriteBuffer &getEditBuffer(FileID FID);
llvm::RewriteBuffer &getEditBuffer(FileID FID);

/// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
/// If no modification has been made to it, return null.
const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
std::map<FileID, RewriteBuffer>::const_iterator I =
RewriteBuffers.find(FID);
const llvm::RewriteBuffer *getRewriteBufferFor(FileID FID) const {
std::map<FileID, llvm::RewriteBuffer>::const_iterator I =
RewriteBuffers.find(FID);
return I == RewriteBuffers.end() ? nullptr : &I->second;
}

Expand Down
340 changes: 155 additions & 185 deletions clang/include/clang/Sema/Sema.h

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions clang/include/clang/Sema/SemaAMDGPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
#ifndef LLVM_CLANG_SEMA_SEMAAMDGPU_H
#define LLVM_CLANG_SEMA_SEMAAMDGPU_H

#include "clang/AST/Attr.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Sema/ParsedAttr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class AttributeCommonInfo;
class ParsedAttr;

class SemaAMDGPU : public SemaBase {
public:
SemaAMDGPU(Sema &S);
Expand Down
19 changes: 11 additions & 8 deletions clang/include/clang/Sema/SemaARM.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@
#ifndef LLVM_CLANG_SEMA_SEMAARM_H
#define LLVM_CLANG_SEMA_SEMAARM_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <tuple>

namespace llvm {
template <typename T, unsigned N> class SmallVector;
} // namespace llvm

namespace clang {
class ParsedAttr;
class TargetInfo;

class SemaARM : public SemaBase {
public:
Expand Down Expand Up @@ -60,10 +63,10 @@ class SemaARM : public SemaBase {
unsigned ExpectedFieldNum, bool AllowName);
bool BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall);

bool MveAliasValid(unsigned BuiltinID, StringRef AliasName);
bool CdeAliasValid(unsigned BuiltinID, StringRef AliasName);
bool SveAliasValid(unsigned BuiltinID, StringRef AliasName);
bool SmeAliasValid(unsigned BuiltinID, StringRef AliasName);
bool MveAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);
bool CdeAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);
bool SveAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);
bool SmeAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);
void handleBuiltinAliasAttr(Decl *D, const ParsedAttr &AL);
void handleNewAttr(Decl *D, const ParsedAttr &AL);
void handleCmseNSEntryAttr(Decl *D, const ParsedAttr &AL);
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaAVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#ifndef LLVM_CLANG_SEMA_SEMAAVR_H
#define LLVM_CLANG_SEMA_SEMAAVR_H

#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaAVR : public SemaBase {
Expand Down
4 changes: 1 addition & 3 deletions clang/include/clang/Sema/SemaBPF.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
#ifndef LLVM_CLANG_SEMA_SEMABPF_H
#define LLVM_CLANG_SEMA_SEMABPF_H

#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
Expand Down
20 changes: 15 additions & 5 deletions clang/include/clang/Sema/SemaCUDA.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,34 @@
#ifndef LLVM_CLANG_SEMA_SEMACUDA_H
#define LLVM_CLANG_SEMA_SEMACUDA_H

#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/Redeclarable.h"
#include "clang/Basic/Cuda.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/ParsedAttr.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallVector.h"
#include <string>
#include <utility>

namespace clang {
namespace sema {
class Capture;
} // namespace sema

class ASTReader;
class ASTWriter;
enum class CUDAFunctionTarget;
enum class CXXSpecialMemberKind;
class ParsedAttributesView;
class Scope;

class SemaCUDA : public SemaBase {
public:
Expand Down
10 changes: 5 additions & 5 deletions clang/include/clang/Sema/SemaCodeCompletion.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,26 @@
#ifndef LLVM_CLANG_SEMA_SEMACODECOMPLETION_H
#define LLVM_CLANG_SEMA_SEMACODECOMPLETION_H

#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/ModuleLoader.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Designator.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/StringRef.h"
#include <optional>

namespace clang {
class DeclGroupRef;
class MacroInfo;
class Scope;
class TemplateName;

class SemaCodeCompletion : public SemaBase {
public:
Expand Down
14 changes: 8 additions & 6 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,18 @@
#ifndef LLVM_CLANG_SEMA_SEMAHLSL_H
#define LLVM_CLANG_SEMA_SEMAHLSL_H

#include "clang/AST/ASTFwd.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/TargetParser/Triple.h"
#include <initializer_list>

namespace clang {
class AttributeCommonInfo;
class IdentifierInfo;
class ParsedAttr;
class Scope;

class SemaHLSL : public SemaBase {
public:
Expand Down Expand Up @@ -62,6 +61,9 @@ class SemaHLSL : public SemaBase {
void handleParamModifierAttr(Decl *D, const ParsedAttr &AL);

bool CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);

// HLSL Type trait implementations
bool IsScalarizedLayoutCompatible(QualType T1, QualType T2) const;
};

} // namespace clang
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaHexagon.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#ifndef LLVM_CLANG_SEMA_SEMAHEXAGON_H
#define LLVM_CLANG_SEMA_SEMAHEXAGON_H

#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Sema/SemaLoongArch.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
#ifndef LLVM_CLANG_SEMA_SEMALOONGARCH_H
#define LLVM_CLANG_SEMA_SEMALOONGARCH_H

#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class TargetInfo;

class SemaLoongArch : public SemaBase {
public:
SemaLoongArch(Sema &S);
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaM68k.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#ifndef LLVM_CLANG_SEMA_SEMAM68K_H
#define LLVM_CLANG_SEMA_SEMAM68K_H

#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaM68k : public SemaBase {
Expand Down
5 changes: 2 additions & 3 deletions clang/include/clang/Sema/SemaMIPS.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@
#ifndef LLVM_CLANG_SEMA_SEMAMIPS_H
#define LLVM_CLANG_SEMA_SEMAMIPS_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class ParsedAttr;
class TargetInfo;

class SemaMIPS : public SemaBase {
public:
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaMSP430.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#ifndef LLVM_CLANG_SEMA_SEMAMSP430_H
#define LLVM_CLANG_SEMA_SEMAMSP430_H

#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaMSP430 : public SemaBase {
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Sema/SemaNVPTX.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
#ifndef LLVM_CLANG_SEMA_SEMANVPTX_H
#define LLVM_CLANG_SEMA_SEMANVPTX_H

#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class TargetInfo;

class SemaNVPTX : public SemaBase {
public:
SemaNVPTX(Sema &S);
Expand Down
16 changes: 9 additions & 7 deletions clang/include/clang/Sema/SemaObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@
#ifndef LLVM_CLANG_SEMA_SEMAOBJC_H
#define LLVM_CLANG_SEMA_SEMAOBJC_H

#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/NSAPI.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Type.h"
Expand All @@ -27,24 +24,29 @@
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TokenKinds.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/ObjCMethodList.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Redeclaration.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include <memory>
#include <optional>
#include <type_traits>
#include <utility>

namespace clang {

class AttributeCommonInfo;
class AvailabilitySpec;
enum class CheckedConversionKind;
class DeclGroupRef;
class LookupResult;
struct ObjCDictionaryElement;
class ParsedAttr;
class ParsedAttributesView;
class Scope;
struct SkipBodyInfo;

class SemaObjC : public SemaBase {
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Sema/SemaOpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@

#include "clang/AST/DeclGroup.h"
#include "clang/AST/StmtOpenACC.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/OpenACCKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <optional>
#include <utility>
#include <variant>

namespace clang {
class IdentifierInfo;
class OpenACCClause;

class SemaOpenACC : public SemaBase {
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaOpenCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#ifndef LLVM_CLANG_SEMA_SEMAOPENCL_H
#define LLVM_CLANG_SEMA_SEMAOPENCL_H

#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaOpenCL : public SemaBase {
Expand Down
19 changes: 10 additions & 9 deletions clang/include/clang/Sema/SemaOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,36 @@
#ifndef LLVM_CLANG_SEMA_SEMAOPENMP_H
#define LLVM_CLANG_SEMA_SEMAOPENMP_H

#include "clang/AST/ASTFwd.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/Type.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Frontend/OpenMP/OMP.h.inc"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include <optional>
#include <string>
#include <utility>

namespace clang {
namespace sema {
class FunctionScopeInfo;
} // namespace sema

class DeclContext;
class DeclGroupRef;
class ParsedAttr;
class Scope;

class SemaOpenMP : public SemaBase {
public:
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Sema/SemaPPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
#ifndef LLVM_CLANG_SEMA_SEMAPPC_H
#define LLVM_CLANG_SEMA_SEMAPPC_H

#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class TargetInfo;

class SemaPPC : public SemaBase {
public:
SemaPPC(Sema &S);
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Sema/SemaPseudoObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
#ifndef LLVM_CLANG_SEMA_SEMAPSEUDOOBJECT_H
#define LLVM_CLANG_SEMA_SEMAPSEUDOOBJECT_H

#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/OperationKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class Scope;

class SemaPseudoObject : public SemaBase {
public:
Expand Down
13 changes: 8 additions & 5 deletions clang/include/clang/Sema/SemaRISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@
#ifndef LLVM_CLANG_SEMA_SEMARISCV_H
#define LLVM_CLANG_SEMA_SEMARISCV_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/RISCVIntrinsicManager.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <memory>

namespace clang {
namespace sema {
class RISCVIntrinsicManager;
} // namespace sema

class ParsedAttr;
class TargetInfo;

class SemaRISCV : public SemaBase {
public:
Expand All @@ -39,7 +42,7 @@ class SemaRISCV : public SemaBase {
bool isValidRVVBitcast(QualType srcType, QualType destType);

void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
bool isAliasValid(unsigned BuiltinID, StringRef AliasName);
bool isAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);

/// Indicate RISC-V vector builtin functions enabled or not.
bool DeclareRVVBuiltins = false;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaSYCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#ifndef LLVM_CLANG_SEMA_SEMASYCL_H
#define LLVM_CLANG_SEMA_SEMASYCL_H

#include "clang/AST/Decl.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Sema/SemaSwift.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
#ifndef LLVM_CLANG_SEMA_SEMASWIFT_H
#define LLVM_CLANG_SEMA_SEMASWIFT_H

#include "clang/AST/Attr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/StringRef.h"

namespace clang {
class AttributeCommonInfo;
class Decl;
enum class ParameterABI;
class ParsedAttr;
class SwiftNameAttr;

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaSystemZ.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#ifndef LLVM_CLANG_SEMA_SEMASYSTEMZ_H
#define LLVM_CLANG_SEMA_SEMASYSTEMZ_H

#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
Expand Down
9 changes: 4 additions & 5 deletions clang/include/clang/Sema/SemaWasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
#ifndef LLVM_CLANG_SEMA_SEMAWASM_H
#define LLVM_CLANG_SEMA_SEMAWASM_H

#include "clang/AST/Attr.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/ParsedAttr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class ParsedAttr;
class TargetInfo;

class SemaWasm : public SemaBase {
public:
SemaWasm(Sema &S);
Expand Down
5 changes: 2 additions & 3 deletions clang/include/clang/Sema/SemaX86.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
#ifndef LLVM_CLANG_SEMA_SEMAX86_H
#define LLVM_CLANG_SEMA_SEMAX86_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class ParsedAttr;
class TargetInfo;

class SemaX86 : public SemaBase {
public:
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,12 @@ class ASTReader
/// performed deduplication.
llvm::SetVector<NamedDecl *> PendingMergedDefinitionsToDeduplicate;

/// The duplicated definitions in module units which are pending to be warned.
/// We need to delay it to wait for the loading of definitions since we don't
/// want to warn for forward declarations.
llvm::SmallVector<std::pair<Decl *, Decl *>>
PendingWarningForDuplicatedDefsInModuleUnits;

/// Read the record that describes the lexical contents of a DC.
bool ReadLexicalDeclContextStorage(ModuleFile &M,
llvm::BitstreamCursor &Cursor,
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,11 @@ ANALYZER_OPTION(
ANALYZER_OPTION(unsigned, MaxSymbolComplexity, "max-symbol-complexity",
"The maximum complexity of symbolic constraint.", 35)

// HACK:https://discourse.llvm.org/t/rfc-make-istainted-and-complex-symbols-friends/79570
// Ideally, we should get rid of this option soon.
ANALYZER_OPTION(unsigned, MaxTaintedSymbolComplexity, "max-tainted-symbol-complexity",
"[DEPRECATED] The maximum complexity of a symbol to carry taint", 9)

ANALYZER_OPTION(unsigned, MaxTimesInlineLarge, "max-times-inline-large",
"The maximum times a large function could be inlined.", 32)

Expand Down
20 changes: 19 additions & 1 deletion clang/lib/APINotes/APINotesFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const uint16_t VERSION_MAJOR = 0;
/// API notes file minor version number.
///
/// When the format changes IN ANY WAY, this number should be incremented.
const uint16_t VERSION_MINOR = 29; // SwiftConformsTo
const uint16_t VERSION_MINOR = 30; // fields

const uint8_t kSwiftCopyable = 1;
const uint8_t kSwiftNonCopyable = 2;
Expand Down Expand Up @@ -72,6 +72,10 @@ enum BlockID {
/// used in other tables.
OBJC_SELECTOR_BLOCK_ID,

/// The fields data block, which maps names fields of C records to
/// information about the field.
FIELD_BLOCK_ID,

/// The global variables data block, which maps global variable names to
/// information about the global variable.
GLOBAL_VARIABLE_BLOCK_ID,
Expand Down Expand Up @@ -199,6 +203,20 @@ using CXXMethodDataLayout =
>;
} // namespace cxx_method_block

namespace field_block {
enum {
FIELD_DATA = 1,
};

using FieldDataLayout =
llvm::BCRecordLayout<FIELD_DATA, // record ID
llvm::BCVBR<16>, // table offset within the blob (see
// below)
llvm::BCBlob // map from C (context id, name)
// tuples to C field information
>;
} // namespace field_block

namespace objc_selector_block {
enum {
OBJC_SELECTOR_DATA = 1,
Expand Down
130 changes: 130 additions & 0 deletions clang/lib/APINotes/APINotesReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,28 @@ class ObjCPropertyTableInfo
}
};

/// Used to deserialize the on-disk C record field table.
class FieldTableInfo
: public VersionedTableInfo<FieldTableInfo, SingleDeclTableKey, FieldInfo> {
public:
static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
return {CtxID, NameID};
}

hash_value_type ComputeHash(internal_key_type Key) {
return static_cast<size_t>(Key.hashValue());
}

static FieldInfo readUnversioned(internal_key_type Key,
const uint8_t *&Data) {
FieldInfo Info;
ReadVariableInfo(Data, Info);
return Info;
}
};

/// Read serialized ParamInfo.
void ReadParamInfo(const uint8_t *&Data, ParamInfo &Info) {
ReadVariableInfo(Data, Info);
Expand Down Expand Up @@ -653,6 +675,12 @@ class APINotesReader::Implementation {
/// The Objective-C property table.
std::unique_ptr<SerializedObjCPropertyTable> ObjCPropertyTable;

using SerializedFieldTable =
llvm::OnDiskIterableChainedHashTable<FieldTableInfo>;

/// The C record field table.
std::unique_ptr<SerializedFieldTable> FieldTable;

using SerializedObjCMethodTable =
llvm::OnDiskIterableChainedHashTable<ObjCMethodTableInfo>;

Expand Down Expand Up @@ -720,6 +748,8 @@ class APINotesReader::Implementation {
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readCXXMethodBlock(llvm::BitstreamCursor &Cursor,
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readFieldBlock(llvm::BitstreamCursor &Cursor,
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readObjCSelectorBlock(llvm::BitstreamCursor &Cursor,
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readGlobalVariableBlock(llvm::BitstreamCursor &Cursor,
Expand Down Expand Up @@ -1252,6 +1282,81 @@ bool APINotesReader::Implementation::readCXXMethodBlock(
return false;
}

bool APINotesReader::Implementation::readFieldBlock(
llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
if (Cursor.EnterSubBlock(FIELD_BLOCK_ID))
return true;

llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
if (!MaybeNext) {
// FIXME this drops the error on the floor.
consumeError(MaybeNext.takeError());
return false;
}
llvm::BitstreamEntry Next = MaybeNext.get();
while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
if (Next.Kind == llvm::BitstreamEntry::Error)
return true;

if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
// Unknown sub-block, possibly for use by a future version of the
// API notes format.
if (Cursor.SkipBlock())
return true;

MaybeNext = Cursor.advance();
if (!MaybeNext) {
// FIXME this drops the error on the floor.
consumeError(MaybeNext.takeError());
return false;
}
Next = MaybeNext.get();
continue;
}

Scratch.clear();
llvm::StringRef BlobData;
llvm::Expected<unsigned> MaybeKind =
Cursor.readRecord(Next.ID, Scratch, &BlobData);
if (!MaybeKind) {
// FIXME this drops the error on the floor.
consumeError(MaybeKind.takeError());
return false;
}
unsigned Kind = MaybeKind.get();
switch (Kind) {
case field_block::FIELD_DATA: {
// Already saw field table.
if (FieldTable)
return true;

uint32_t tableOffset;
field_block::FieldDataLayout::readRecord(Scratch, tableOffset);
auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

FieldTable.reset(SerializedFieldTable::Create(
base + tableOffset, base + sizeof(uint32_t), base));
break;
}

default:
// Unknown record, possibly for use by a future version of the
// module format.
break;
}

MaybeNext = Cursor.advance();
if (!MaybeNext) {
// FIXME this drops the error on the floor.
consumeError(MaybeNext.takeError());
return false;
}
Next = MaybeNext.get();
}

return false;
}

bool APINotesReader::Implementation::readObjCSelectorBlock(
llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
if (Cursor.EnterSubBlock(OBJC_SELECTOR_BLOCK_ID))
Expand Down Expand Up @@ -1812,6 +1917,14 @@ APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer,
}
break;

case FIELD_BLOCK_ID:
if (!HasValidControlBlock ||
Implementation->readFieldBlock(Cursor, Scratch)) {
Failed = true;
return;
}
break;

case OBJC_SELECTOR_BLOCK_ID:
if (!HasValidControlBlock ||
Implementation->readObjCSelectorBlock(Cursor, Scratch)) {
Expand Down Expand Up @@ -2031,6 +2144,23 @@ auto APINotesReader::lookupObjCMethod(ContextID CtxID, ObjCSelectorRef Selector,
return {Implementation->SwiftVersion, *Known};
}

auto APINotesReader::lookupField(ContextID CtxID, llvm::StringRef Name)
-> VersionedInfo<FieldInfo> {
if (!Implementation->FieldTable)
return std::nullopt;

std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
if (!NameID)
return std::nullopt;

auto Known = Implementation->FieldTable->find(
SingleDeclTableKey(CtxID.Value, *NameID));
if (Known == Implementation->FieldTable->end())
return std::nullopt;

return {Implementation->SwiftVersion, *Known};
}

auto APINotesReader::lookupCXXMethod(ContextID CtxID, llvm::StringRef Name)
-> VersionedInfo<CXXMethodInfo> {
if (!Implementation->CXXMethodTable)
Expand Down
73 changes: 73 additions & 0 deletions clang/lib/APINotes/APINotesWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ class APINotesWriter::Implementation {
llvm::SmallVector<std::pair<VersionTuple, ObjCPropertyInfo>, 1>>
ObjCProperties;

/// Information about C record fields.
///
/// Indexed by the context ID and name ID.
llvm::DenseMap<SingleDeclTableKey,
llvm::SmallVector<std::pair<VersionTuple, FieldInfo>, 1>>
Fields;

/// Information about Objective-C methods.
///
/// Indexed by the context ID, selector ID, and Boolean (stored as a char)
Expand Down Expand Up @@ -158,6 +165,7 @@ class APINotesWriter::Implementation {
void writeObjCPropertyBlock(llvm::BitstreamWriter &Stream);
void writeObjCMethodBlock(llvm::BitstreamWriter &Stream);
void writeCXXMethodBlock(llvm::BitstreamWriter &Stream);
void writeFieldBlock(llvm::BitstreamWriter &Stream);
void writeObjCSelectorBlock(llvm::BitstreamWriter &Stream);
void writeGlobalVariableBlock(llvm::BitstreamWriter &Stream);
void writeGlobalFunctionBlock(llvm::BitstreamWriter &Stream);
Expand Down Expand Up @@ -190,6 +198,7 @@ void APINotesWriter::Implementation::writeToStream(llvm::raw_ostream &OS) {
writeObjCPropertyBlock(Stream);
writeObjCMethodBlock(Stream);
writeCXXMethodBlock(Stream);
writeFieldBlock(Stream);
writeObjCSelectorBlock(Stream);
writeGlobalVariableBlock(Stream);
writeGlobalFunctionBlock(Stream);
Expand Down Expand Up @@ -858,6 +867,62 @@ void APINotesWriter::Implementation::writeCXXMethodBlock(
}
}

namespace {
/// Used to serialize the on-disk C field table.
class FieldTableInfo
: public VersionedTableInfo<FieldTableInfo, SingleDeclTableKey, FieldInfo> {
public:
unsigned getKeyLength(key_type_ref) {
return sizeof(uint32_t) + sizeof(uint32_t);
}

void EmitKey(raw_ostream &OS, key_type_ref Key, unsigned) {
llvm::support::endian::Writer writer(OS, llvm::endianness::little);
writer.write<uint32_t>(Key.parentContextID);
writer.write<uint32_t>(Key.nameID);
}

hash_value_type ComputeHash(key_type_ref key) {
return static_cast<size_t>(key.hashValue());
}

unsigned getUnversionedInfoSize(const FieldInfo &FI) {
return getVariableInfoSize(FI);
}

void emitUnversionedInfo(raw_ostream &OS, const FieldInfo &FI) {
emitVariableInfo(OS, FI);
}
};
} // namespace

void APINotesWriter::Implementation::writeFieldBlock(
llvm::BitstreamWriter &Stream) {
llvm::BCBlockRAII Scope(Stream, FIELD_BLOCK_ID, 3);

if (Fields.empty())
return;

{
llvm::SmallString<4096> HashTableBlob;
uint32_t Offset;
{
llvm::OnDiskChainedHashTableGenerator<FieldTableInfo> Generator;
for (auto &FD : Fields)
Generator.insert(FD.first, FD.second);

llvm::raw_svector_ostream BlobStream(HashTableBlob);
// Make sure that no bucket is at offset 0
llvm::support::endian::write<uint32_t>(BlobStream, 0,
llvm::endianness::little);
Offset = Generator.Emit(BlobStream);
}

field_block::FieldDataLayout FieldData(Stream);
FieldData.emit(Scratch, Offset, HashTableBlob);
}
}

namespace {
/// Used to serialize the on-disk Objective-C selector table.
class ObjCSelectorTableInfo {
Expand Down Expand Up @@ -1423,6 +1488,14 @@ void APINotesWriter::addCXXMethod(ContextID CtxID, llvm::StringRef Name,
Implementation->CXXMethods[Key].push_back({SwiftVersion, Info});
}

void APINotesWriter::addField(ContextID CtxID, llvm::StringRef Name,
const FieldInfo &Info,
VersionTuple SwiftVersion) {
IdentifierID NameID = Implementation->getIdentifier(Name);
SingleDeclTableKey Key(CtxID.Value, NameID);
Implementation->Fields[Key].push_back({SwiftVersion, Info});
}

void APINotesWriter::addGlobalVariable(std::optional<Context> Ctx,
llvm::StringRef Name,
const GlobalVariableInfo &Info,
Expand Down
64 changes: 52 additions & 12 deletions clang/lib/APINotes/APINotesYAMLCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,38 @@ template <> struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
} // namespace yaml
} // namespace llvm

namespace {
struct Field {
StringRef Name;
std::optional<NullabilityKind> Nullability;
AvailabilityItem Availability;
std::optional<bool> SwiftPrivate;
StringRef SwiftName;
StringRef Type;
};

typedef std::vector<Field> FieldsSeq;
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Field)

namespace llvm {
namespace yaml {
template <> struct MappingTraits<Field> {
static void mapping(IO &IO, Field &F) {
IO.mapRequired("Name", F.Name);
IO.mapOptional("Nullability", F.Nullability, std::nullopt);
IO.mapOptional("Availability", F.Availability.Mode,
APIAvailability::Available);
IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef(""));
IO.mapOptional("SwiftPrivate", F.SwiftPrivate);
IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));
IO.mapOptional("Type", F.Type, StringRef(""));
}
};
} // namespace yaml
} // namespace llvm

namespace {
struct Tag;
typedef std::vector<Tag> TagsSeq;
Expand All @@ -425,6 +457,7 @@ struct Tag {
std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
std::optional<bool> SwiftCopyable;
FunctionsSeq Methods;
FieldsSeq Fields;

/// Tags that are declared within the current tag. Only the tags that have
/// corresponding API Notes will be listed.
Expand Down Expand Up @@ -463,6 +496,7 @@ template <> struct MappingTraits<Tag> {
IO.mapOptional("EnumKind", T.EnumConvenienceKind);
IO.mapOptional("SwiftCopyable", T.SwiftCopyable);
IO.mapOptional("Methods", T.Methods);
IO.mapOptional("Fields", T.Fields);
IO.mapOptional("Tags", T.Tags);
}
};
Expand Down Expand Up @@ -793,6 +827,16 @@ class YAMLConverter {
SwiftVersion);
}

template <typename T>
void convertVariable(const T &Entity, VariableInfo &VI) {
convertAvailability(Entity.Availability, VI, Entity.Name);
VI.setSwiftPrivate(Entity.SwiftPrivate);
VI.SwiftName = std::string(Entity.SwiftName);
if (Entity.Nullability)
VI.setNullabilityAudited(*Entity.Nullability);
VI.setType(std::string(Entity.Type));
}

void convertContext(std::optional<ContextID> ParentContextID, const Class &C,
ContextKind Kind, VersionTuple SwiftVersion) {
// Write the class.
Expand Down Expand Up @@ -848,14 +892,9 @@ class YAMLConverter {

// Translate from Property into ObjCPropertyInfo.
ObjCPropertyInfo PI;
convertAvailability(Property.Availability, PI, Property.Name);
PI.setSwiftPrivate(Property.SwiftPrivate);
PI.SwiftName = std::string(Property.SwiftName);
if (Property.Nullability)
PI.setNullabilityAudited(*Property.Nullability);
convertVariable(Property, PI);
if (Property.SwiftImportAsAccessors)
PI.setSwiftImportAsAccessors(*Property.SwiftImportAsAccessors);
PI.setType(std::string(Property.Type));

// Add both instance and class properties with this name.
if (Property.Kind) {
Expand Down Expand Up @@ -970,6 +1009,12 @@ class YAMLConverter {
CI, SwiftVersion);
Context TagCtx(TagCtxID, ContextKind::Tag);

for (const auto &Field : T.Fields) {
FieldInfo FI;
convertVariable(Field, FI);
Writer.addField(TagCtxID, Field.Name, FI, SwiftVersion);
}

for (const auto &CXXMethod : T.Methods) {
CXXMethodInfo MI;
convertFunction(CXXMethod, MI);
Expand Down Expand Up @@ -1037,12 +1082,7 @@ class YAMLConverter {
}

GlobalVariableInfo GVI;
convertAvailability(Global.Availability, GVI, Global.Name);
GVI.setSwiftPrivate(Global.SwiftPrivate);
GVI.SwiftName = std::string(Global.SwiftName);
if (Global.Nullability)
GVI.setNullabilityAudited(*Global.Nullability);
GVI.setType(std::string(Global.Type));
convertVariable(Global, GVI);
Writer.addGlobalVariable(Ctx, Global.Name, GVI, SwiftVersion);
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/ARCMigrate/ARCMT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ bool MigrationProcess::applyTransform(TransformFn trans,
for (Rewriter::buffer_iterator
I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) {
FileID FID = I->first;
RewriteBuffer &buf = I->second;
llvm::RewriteBuffer &buf = I->second;
OptionalFileEntryRef file =
Ctx.getSourceManager().getFileEntryRefForID(FID);
assert(file);
Expand Down
1 change: 1 addition & 0 deletions clang/lib/ARCMigrate/ObjCMT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
using namespace clang;
using namespace arcmt;
using namespace ento;
using llvm::RewriteBuffer;

namespace {

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "ByteCode/Context.h"
#include "CXXABI.h"
#include "Interp/Context.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTConcept.h"
#include "clang/AST/ASTMutationListener.h"
Expand Down Expand Up @@ -3279,7 +3279,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,

case Type::MemberPointer: {
OS << "M";
const auto *MPT = T->getAs<MemberPointerType>();
const auto *MPT = T->castAs<MemberPointerType>();
encodeTypeForFunctionPointerAuth(Ctx, OS, QualType(MPT->getClass(), 0));
encodeTypeForFunctionPointerAuth(Ctx, OS, MPT->getPointeeType());
return;
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4429,11 +4429,14 @@ ExpectedDecl ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
auto FriendLocOrErr = import(D->getFriendLoc());
if (!FriendLocOrErr)
return FriendLocOrErr.takeError();
auto EllipsisLocOrErr = import(D->getEllipsisLoc());
if (!EllipsisLocOrErr)
return EllipsisLocOrErr.takeError();

FriendDecl *FrD;
if (GetImportedOrCreateDecl(FrD, D, Importer.getToContext(), DC,
*LocationOrErr, ToFU,
*FriendLocOrErr, ToTPLists))
*LocationOrErr, ToFU, *FriendLocOrErr,
*EllipsisLocOrErr, ToTPLists))
return FrD;

FrD->setAccess(D->getAccess());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@
#ifndef LLVM_CLANG_AST_INTERP_BOOLEAN_H
#define LLVM_CLANG_AST_INTERP_BOOLEAN_H

#include <cstddef>
#include <cstdint>
#include "Integral.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ComparisonCategories.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cstddef>
#include <cstdint>

namespace clang {
namespace interp {

/// Wrapper around boolean types.
class Boolean final {
private:
private:
/// Underlying boolean.
bool V;

public:
public:
/// Zero-initializes a boolean.
Boolean() : V(false) {}
explicit Boolean(bool V) : V(V) {}
Expand All @@ -44,6 +44,7 @@ class Boolean final {
Boolean operator-() const { return Boolean(V); }
Boolean operator-(const Boolean &Other) const { return Boolean(V - Other.V); }
Boolean operator~() const { return Boolean(true); }
Boolean operator!() const { return Boolean(!V); }

template <typename Ty, typename = std::enable_if_t<std::is_integral_v<Ty>>>
explicit operator Ty() const {
Expand Down Expand Up @@ -104,8 +105,7 @@ class Boolean final {

static Boolean zero() { return from(false); }

template <typename T>
static Boolean from(T Value, unsigned NumBits) {
template <typename T> static Boolean from(T Value, unsigned NumBits) {
return Boolean(Value);
}

Expand Down Expand Up @@ -153,7 +153,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Boolean &B) {
return OS;
}

} // namespace interp
} // namespace clang
} // namespace interp
} // namespace clang

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,48 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
return Func;
}

/// Compile an ObjC block, i.e. ^(){}, that thing.
///
/// FIXME: We do not support calling the block though, so we create a function
/// here but do not compile any code for it.
Function *ByteCodeEmitter::compileObjCBlock(const BlockExpr *BE) {
const BlockDecl *BD = BE->getBlockDecl();
// Set up argument indices.
unsigned ParamOffset = 0;
SmallVector<PrimType, 8> ParamTypes;
SmallVector<unsigned, 8> ParamOffsets;
llvm::DenseMap<unsigned, Function::ParamDescriptor> ParamDescriptors;

// Assign descriptors to all parameters.
// Composite objects are lowered to pointers.
for (const ParmVarDecl *PD : BD->parameters()) {
std::optional<PrimType> T = Ctx.classify(PD->getType());
PrimType PT = T.value_or(PT_Ptr);
Descriptor *Desc = P.createDescriptor(PD, PT);
ParamDescriptors.insert({ParamOffset, {PT, Desc}});
Params.insert({PD, {ParamOffset, T != std::nullopt}});
ParamOffsets.push_back(ParamOffset);
ParamOffset += align(primSize(PT));
ParamTypes.push_back(PT);
}

if (BD->hasCaptures())
return nullptr;

// Create a handle over the emitted code.
Function *Func =
P.createFunction(BE, ParamOffset, std::move(ParamTypes),
std::move(ParamDescriptors), std::move(ParamOffsets),
/*HasThisPointer=*/false, /*HasRVO=*/false,
/*IsUnevaluatedBuiltin=*/false);

assert(Func);
Func->setDefined(true);
// We don't compile the BlockDecl code at all right now.
Func->setIsFullyCompiled(true);
return Func;
}

Scope::Local ByteCodeEmitter::createLocal(Descriptor *D) {
NextLocalOffset += sizeof(Block);
unsigned Location = NextLocalOffset;
Expand All @@ -206,8 +248,7 @@ void ByteCodeEmitter::emitLabel(LabelTy Label) {
const size_t Target = Code.size();
LabelOffsets.insert({Label, Target});

if (auto It = LabelRelocs.find(Label);
It != LabelRelocs.end()) {
if (auto It = LabelRelocs.find(Label); It != LabelRelocs.end()) {
for (unsigned Reloc : It->second) {
using namespace llvm::support;

Expand All @@ -228,8 +269,7 @@ int32_t ByteCodeEmitter::getOffset(LabelTy Label) {
assert(aligned(Position));

// If target is known, compute jump offset.
if (auto It = LabelOffsets.find(Label);
It != LabelOffsets.end())
if (auto It = LabelOffsets.find(Label); It != LabelOffsets.end())
return It->second - Position;

// Otherwise, record relocation and return dummy offset.
Expand Down Expand Up @@ -308,7 +348,8 @@ void emit(Program &P, std::vector<std::byte> &Code, const IntegralAP<true> &Val,
}

template <typename... Tys>
bool ByteCodeEmitter::emitOp(Opcode Op, const Tys &... Args, const SourceInfo &SI) {
bool ByteCodeEmitter::emitOp(Opcode Op, const Tys &...Args,
const SourceInfo &SI) {
bool Success = true;

// The opcode is followed by arguments. The source info is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class ByteCodeEmitter {
public:
/// Compiles the function into the module.
Function *compileFunc(const FunctionDecl *FuncDecl);
Function *compileObjCBlock(const BlockExpr *BE);

protected:
ByteCodeEmitter(Context &Ctx, Program &P) : Ctx(Ctx), P(P) {}
Expand Down Expand Up @@ -92,7 +93,7 @@ class ByteCodeEmitter {

/// Emits an opcode.
template <typename... Tys>
bool emitOp(Opcode Op, const Tys &... Args, const SourceInfo &L);
bool emitOp(Opcode Op, const Tys &...Args, const SourceInfo &L);

protected:
#define GET_LINK_PROTO
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0),
QualType(FromMP->getClass(), 0));

if (!this->visit(SubExpr))
if (!this->delegate(SubExpr))
return false;

return this->emitGetMemberPtrBasePop(DerivedOffset, CE);
Expand All @@ -229,14 +229,14 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0),
QualType(ToMP->getClass(), 0));

if (!this->visit(SubExpr))
if (!this->delegate(SubExpr))
return false;
return this->emitGetMemberPtrBasePop(-DerivedOffset, CE);
}

case CK_UncheckedDerivedToBase:
case CK_DerivedToBase: {
if (!this->visit(SubExpr))
if (!this->delegate(SubExpr))
return false;

const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
Expand Down Expand Up @@ -265,7 +265,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
}

case CK_BaseToDerived: {
if (!this->visit(SubExpr))
if (!this->delegate(SubExpr))
return false;

unsigned DerivedOffset =
Expand Down Expand Up @@ -327,6 +327,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {

case CK_NullToPointer:
case CK_NullToMemberPointer: {
if (!this->discard(SubExpr))
return false;
if (DiscardResult)
return true;

Expand Down Expand Up @@ -389,8 +391,6 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
return this->emitPop(T, CE);

QualType PtrType = CE->getType();
assert(PtrType->isPointerType());

const Descriptor *Desc;
if (std::optional<PrimType> T = classify(PtrType->getPointeeType()))
Desc = P.createDescriptor(SubExpr, *T);
Expand Down Expand Up @@ -533,10 +533,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
// We're creating a complex value here, so we need to
// allocate storage for it.
if (!Initializing) {
std::optional<unsigned> LocalIndex = allocateLocal(CE);
if (!LocalIndex)
return false;
if (!this->emitGetPtrLocal(*LocalIndex, CE))
unsigned LocalIndex = allocateTemporary(CE);
if (!this->emitGetPtrLocal(LocalIndex, CE))
return false;
}

Expand Down Expand Up @@ -671,10 +669,8 @@ bool Compiler<Emitter>::VisitImaginaryLiteral(const ImaginaryLiteral *E) {
return true;

if (!Initializing) {
std::optional<unsigned> LocalIndex = allocateLocal(E);
if (!LocalIndex)
return false;
if (!this->emitGetPtrLocal(*LocalIndex, E))
unsigned LocalIndex = allocateTemporary(E);
if (!this->emitGetPtrLocal(LocalIndex, E))
return false;
}

Expand Down Expand Up @@ -889,34 +885,60 @@ bool Compiler<Emitter>::VisitPointerArithBinOp(const BinaryOperator *E) {
if (!LT || !RT)
return false;

// Visit the given pointer expression and optionally convert to a PT_Ptr.
auto visitAsPointer = [&](const Expr *E, PrimType T) -> bool {
if (!this->visit(E))
return false;
if (T != PT_Ptr)
return this->emitDecayPtr(T, PT_Ptr, E);
return true;
};

if (LHS->getType()->isPointerType() && RHS->getType()->isPointerType()) {
if (Op != BO_Sub)
return false;

assert(E->getType()->isIntegerType());
if (!visit(RHS) || !visit(LHS))
if (!visitAsPointer(RHS, *RT) || !visitAsPointer(LHS, *LT))
return false;

return this->emitSubPtr(classifyPrim(E->getType()), E);
}

PrimType OffsetType;
if (LHS->getType()->isIntegerType()) {
if (!visit(RHS) || !visit(LHS))
if (!visitAsPointer(RHS, *RT))
return false;
if (!this->visit(LHS))
return false;
OffsetType = *LT;
} else if (RHS->getType()->isIntegerType()) {
if (!visit(LHS) || !visit(RHS))
if (!visitAsPointer(LHS, *LT))
return false;
if (!this->visit(RHS))
return false;
OffsetType = *RT;
} else {
return false;
}

if (Op == BO_Add)
return this->emitAddOffset(OffsetType, E);
else if (Op == BO_Sub)
return this->emitSubOffset(OffsetType, E);
// Do the operation and optionally transform to
// result pointer type.
if (Op == BO_Add) {
if (!this->emitAddOffset(OffsetType, E))
return false;

if (classifyPrim(E) != PT_Ptr)
return this->emitDecayPtr(PT_Ptr, classifyPrim(E), E);
return true;
} else if (Op == BO_Sub) {
if (!this->emitSubOffset(OffsetType, E))
return false;

if (classifyPrim(E) != PT_Ptr)
return this->emitDecayPtr(PT_Ptr, classifyPrim(E), E);
return true;
}

return false;
}
Expand Down Expand Up @@ -986,10 +1008,8 @@ template <class Emitter>
bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
// Prepare storage for result.
if (!Initializing) {
std::optional<unsigned> LocalIndex = allocateLocal(E);
if (!LocalIndex)
return false;
if (!this->emitGetPtrLocal(*LocalIndex, E))
unsigned LocalIndex = allocateTemporary(E);
if (!this->emitGetPtrLocal(LocalIndex, E))
return false;
}

Expand Down Expand Up @@ -1045,10 +1065,7 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {

if (!LHSIsComplex) {
// This is using the RHS type for the fake-complex LHS.
if (auto LHSO = allocateLocal(RHS))
LHSOffset = *LHSO;
else
return false;
LHSOffset = allocateTemporary(RHS);

if (!this->emitGetPtrLocal(LHSOffset, E))
return false;
Expand Down Expand Up @@ -1327,14 +1344,15 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
template <class Emitter>
bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
const Expr *ArrayFiller, const Expr *E) {

QualType QT = E->getType();

if (const auto *AT = QT->getAs<AtomicType>())
QT = AT->getValueType();

if (QT->isVoidType())
if (QT->isVoidType()) {
if (Inits.size() == 0)
return true;
return this->emitInvalid(E);
}

// Handle discarding first.
if (DiscardResult) {
Expand Down Expand Up @@ -1881,15 +1899,26 @@ bool Compiler<Emitter>::VisitAbstractConditionalOperator(
if (!this->jumpFalse(LabelFalse))
return false;

if (!this->delegate(TrueExpr))
return false;
{
LocalScope<Emitter> S(this);
if (!this->delegate(TrueExpr))
return false;
if (!S.destroyLocals())
return false;
}

if (!this->jump(LabelEnd))
return false;

this->emitLabel(LabelFalse);

if (!this->delegate(FalseExpr))
return false;
{
LocalScope<Emitter> S(this);
if (!this->delegate(FalseExpr))
return false;
if (!S.destroyLocals())
return false;
}

this->fallthrough(LabelEnd);
this->emitLabel(LabelEnd);
Expand Down Expand Up @@ -2238,8 +2267,6 @@ bool Compiler<Emitter>::VisitExprWithCleanups(const ExprWithCleanups *E) {
LocalScope<Emitter> ES(this);
const Expr *SubExpr = E->getSubExpr();

assert(E->getNumObjects() == 0 && "TODO: Implement cleanups");

return this->delegate(SubExpr) && ES.destroyLocals(E);
}

Expand Down Expand Up @@ -2325,6 +2352,9 @@ bool Compiler<Emitter>::VisitCXXBindTemporaryExpr(
template <class Emitter>
bool Compiler<Emitter>::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
const Expr *Init = E->getInitializer();
if (DiscardResult)
return this->discard(Init);

if (Initializing) {
// We already have a value, just initialize that.
return this->visitInitializer(Init) && this->emitFinishInit(E);
Expand Down Expand Up @@ -2378,9 +2408,6 @@ bool Compiler<Emitter>::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
if (!this->visitInitializer(Init) || !this->emitFinishInit(E))
return false;
}

if (DiscardResult)
return this->emitPopPtr(E);
return true;
}

Expand Down Expand Up @@ -2556,7 +2583,7 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {

if (DiscardResult)
return this->emitPopPtr(E);
return true;
return this->emitFinishInit(E);
}

if (T->isArrayType()) {
Expand Down Expand Up @@ -2909,6 +2936,17 @@ bool Compiler<Emitter>::VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
return this->emitFree(E->isArrayForm(), E);
}

template <class Emitter>
bool Compiler<Emitter>::VisitBlockExpr(const BlockExpr *E) {
const Function *Func = nullptr;
if (auto F = Compiler<ByteCodeEmitter>(Ctx, P).compileObjCBlock(E))
Func = F;

if (!Func)
return false;
return this->emitGetFnPtr(Func, E);
}

template <class Emitter>
bool Compiler<Emitter>::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
assert(Ctx.getLangOpts().CPlusPlus);
Expand Down Expand Up @@ -3227,9 +3265,6 @@ template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
}

template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) {
if (E->containsErrors())
return this->emitError(E);

// We're basically doing:
// OptionScope<Emitter> Scope(this, DicardResult, Initializing);
// but that's unnecessary of course.
Expand Down Expand Up @@ -3266,9 +3301,6 @@ template <class Emitter>
bool Compiler<Emitter>::visitInitializer(const Expr *E) {
assert(!classify(E->getType()));

if (E->containsErrors())
return this->emitError(E);

if (!this->checkLiteralType(E))
return false;

Expand Down Expand Up @@ -3549,6 +3581,27 @@ Compiler<Emitter>::allocateLocal(DeclTy &&Src, const ValueDecl *ExtendingDecl) {
return Local.Offset;
}

template <class Emitter>
unsigned Compiler<Emitter>::allocateTemporary(const Expr *E) {
QualType Ty = E->getType();
assert(!Ty->isRecordType());

Descriptor *D = P.createDescriptor(
E, Ty.getTypePtr(), Descriptor::InlineDescMD, Ty.isConstQualified(),
/*IsTemporary=*/true, /*IsMutable=*/false, /*Init=*/nullptr);
assert(D);

Scope::Local Local = this->createLocal(D);
VariableScope<Emitter> *S = VarScope;
assert(S);
// Attach to topmost scope.
while (S->getParent())
S = S->getParent();
assert(S && !S->getParent());
S->addLocal(Local);
return Local.Offset;
}

template <class Emitter>
const RecordType *Compiler<Emitter>::getRecordTy(QualType Ty) {
if (const PointerType *PT = dyn_cast<PointerType>(Ty))
Expand Down Expand Up @@ -3699,7 +3752,8 @@ bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
}

template <class Emitter>
VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, bool Toplevel) {
VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
bool Toplevel) {
// We don't know what to do with these, so just return false.
if (VD->getType().isNull())
return false;
Expand Down Expand Up @@ -4331,11 +4385,6 @@ bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt *RS) {
}

template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
if (IS->isNonNegatedConsteval())
return visitStmt(IS->getThen());
if (IS->isNegatedConsteval())
return IS->getElse() ? visitStmt(IS->getElse()) : true;

if (auto *CondInit = IS->getInit())
if (!visitStmt(CondInit))
return false;
Expand All @@ -4344,8 +4393,19 @@ template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
if (!visitDeclStmt(CondDecl))
return false;

if (!this->visitBool(IS->getCond()))
return false;
// Compile condition.
if (IS->isNonNegatedConsteval()) {
if (!this->emitIsConstantContext(IS))
return false;
} else if (IS->isNegatedConsteval()) {
if (!this->emitIsConstantContext(IS))
return false;
if (!this->emitInv(IS))
return false;
} else {
if (!this->visitBool(IS->getCond()))
return false;
}

if (const Stmt *Else = IS->getElse()) {
LabelTy LabelElse = this->getLabel();
Expand Down Expand Up @@ -5088,7 +5148,7 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
if (!this->visitBool(SubExpr))
return false;

if (!this->emitInvBool(E))
if (!this->emitInv(E))
return false;

if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
Expand All @@ -5101,7 +5161,7 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
if (!this->visit(SubExpr))
return false;
return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
case UO_Plus: // +x
case UO_Plus: // +x
if (!T)
return this->emitError(E);

Expand Down Expand Up @@ -5207,7 +5267,7 @@ bool Compiler<Emitter>::VisitComplexUnaryOperator(const UnaryOperator *E) {
return false;
if (!this->emitComplexBoolCast(SubExpr))
return false;
if (!this->emitInvBool(E))
if (!this->emitInv(E))
return false;
if (PrimType ET = classifyPrim(E->getType()); ET != PT_Bool)
return this->emitCast(PT_Bool, ET, E);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
bool VisitStmtExpr(const StmtExpr *E);
bool VisitCXXNewExpr(const CXXNewExpr *E);
bool VisitCXXDeleteExpr(const CXXDeleteExpr *E);
bool VisitBlockExpr(const BlockExpr *E);

// Statements.
bool visitCompoundStmt(const CompoundStmt *S);
Expand Down Expand Up @@ -297,6 +298,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
/// Allocates a space storing a local given its type.
std::optional<unsigned>
allocateLocal(DeclTy &&Decl, const ValueDecl *ExtendingDecl = nullptr);
unsigned allocateTemporary(const Expr *E);

private:
friend class VariableScope<Emitter>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ std::optional<PrimType> Context::classify(QualType T) const {
return PT_Uint16;
case 8:
return PT_Uint8;
case 1:
// Might happen for enum types.
return PT_Bool;
default:
return PT_IntAP;
}
Expand All @@ -176,7 +179,7 @@ std::optional<PrimType> Context::classify(QualType T) const {
return PT_MemberPtr;

if (T->isFunctionPointerType() || T->isFunctionReferenceType() ||
T->isFunctionType())
T->isFunctionType() || T->isBlockPointerType())
return PT_FnPtr;

if (T->isPointerOrReferenceType() || T->isObjCObjectPointerType())
Expand Down
File renamed without changes.
Loading