1,728 changes: 777 additions & 951 deletions clang/bindings/python/clang/cindex.py

Large diffs are not rendered by default.

33 changes: 0 additions & 33 deletions clang/bindings/python/clang/enumerations.py

This file was deleted.

22 changes: 12 additions & 10 deletions clang/bindings/python/tests/cindex/test_enums.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import unittest

from clang.cindex import (
TokenKind,
CursorKind,
TemplateArgumentKind,
ExceptionSpecificationKind,
Expand All @@ -14,8 +15,9 @@
)


class TestCursorKind(unittest.TestCase):
class TestEnums(unittest.TestCase):
enums = [
TokenKind,
CursorKind,
TemplateArgumentKind,
ExceptionSpecificationKind,
Expand All @@ -31,17 +33,17 @@ class TestCursorKind(unittest.TestCase):
def test_from_id(self):
"""Check that kinds can be constructed from valid IDs"""
for enum in self.enums:
self.assertEqual(enum.from_id(2), enum._kinds[2])
self.assertEqual(enum.from_id(2), enum(2))
max_value = max([variant.value for variant in enum])
with self.assertRaises(ValueError):
enum.from_id(len(enum._kinds))
enum.from_id(max_value + 1)
with self.assertRaises(ValueError):
enum.from_id(-1)

def test_unique_kinds(self):
"""Check that no kind name has been used multiple times"""
def test_duplicate_ids(self):
"""Check that no two kinds have the same id"""
# for enum in self.enums:
for enum in self.enums:
for id in range(len(enum._kinds)):
try:
enum.from_id(id).name
except ValueError:
pass
num_declared_variants = len(enum._member_map_.keys())
num_unique_variants = len(list(enum))
self.assertEqual(num_declared_variants, num_unique_variants)
20 changes: 0 additions & 20 deletions clang/bindings/python/tests/cindex/test_token_kind.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,6 @@


class TestTokenKind(unittest.TestCase):
def test_constructor(self):
"""Ensure TokenKind constructor works as expected."""

t = TokenKind(5, "foo")

self.assertEqual(t.value, 5)
self.assertEqual(t.name, "foo")

def test_bad_register(self):
"""Ensure a duplicate value is rejected for registration."""

with self.assertRaises(ValueError):
TokenKind.register(2, "foo")

def test_unknown_value(self):
"""Ensure trying to fetch an unknown value raises."""

with self.assertRaises(ValueError):
TokenKind.from_value(-1)

def test_registration(self):
"""Ensure that items registered appear as class attributes."""
self.assertTrue(hasattr(TokenKind, "LITERAL"))
Expand Down
16 changes: 10 additions & 6 deletions clang/cmake/caches/Fuchsia-stage2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -300,14 +300,18 @@ if(FUCHSIA_SDK)
set(LLVM_RUNTIME_MULTILIB_hwasan+noexcept_TARGETS "aarch64-unknown-fuchsia;riscv64-unknown-fuchsia" CACHE STRING "")
endif()

foreach(target armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m-unknown-eabi)
foreach(target armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m.main-unknown-eabi)
list(APPEND BUILTIN_TARGETS "${target}")
set(BUILTINS_${target}_CMAKE_SYSTEM_NAME Generic CACHE STRING "")
set(BUILTINS_${target}_CMAKE_SYSTEM_PROCESSOR arm CACHE STRING "")
set(BUILTINS_${target}_CMAKE_SYSROOT "" CACHE STRING "")
set(BUILTINS_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
set(BUILTINS_${target}_CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "")
foreach(lang C;CXX;ASM)
set(BUILTINS_${target}_CMAKE_${lang}_FLAGS "--target=${target} -mthumb" CACHE STRING "")
set(BUILTINS_${target}_CMAKE_${lang}_local_flags "--target=${target} -mthumb")
if(${target} STREQUAL "armv8m.main-unknown-eabi")
set(BUILTINS_${target}_CMAKE_${lang}_local_flags "${BUILTINS_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=hard -march=armv8m.main+fp+dsp -mcpu=cortex-m33" CACHE STRING "")
endif()
set(BUILTINS_${target}_CMAKE_${lang}_FLAGS "${BUILTINS_${target}_CMAKE_${lang}_local_flags}" CACHE STRING "")
endforeach()
foreach(type SHARED;MODULE;EXE)
set(BUILTINS_${target}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "")
Expand All @@ -318,7 +322,7 @@ foreach(target armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m-unknown-eabi)
set(RUNTIMES_${target}_CMAKE_SYSTEM_NAME Generic CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_SYSTEM_PROCESSOR arm CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_SYSROOT "" CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY CACHE STRING "")
foreach(lang C;CXX;ASM)
set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} -mthumb -Wno-atomic-alignment" CACHE STRING "")
Expand Down Expand Up @@ -353,7 +357,7 @@ foreach(target riscv32-unknown-elf)
set(BUILTINS_${target}_CMAKE_SYSTEM_NAME Generic CACHE STRING "")
set(BUILTINS_${target}_CMAKE_SYSTEM_PROCESSOR RISCV CACHE STRING "")
set(BUILTINS_${target}_CMAKE_SYSROOT "" CACHE STRING "")
set(BUILTINS_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
set(BUILTINS_${target}_CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "")
foreach(lang C;CXX;ASM)
set(BUILTINS_${target}_CMAKE_${lang}_FLAGS "--target=${target} -march=rv32imafc -mabi=ilp32f" CACHE STRING "")
endforeach()
Expand All @@ -366,7 +370,7 @@ foreach(target riscv32-unknown-elf)
set(RUNTIMES_${target}_CMAKE_SYSTEM_NAME Generic CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_SYSTEM_PROCESSOR RISCV CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_SYSROOT "" CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY CACHE STRING "")
foreach(lang C;CXX;ASM)
set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} -march=rv32imafc -mabi=ilp32f" CACHE STRING "")
Expand Down
11 changes: 11 additions & 0 deletions clang/docs/HLSL/ExpectedDifferences.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,16 @@ behavior between Clang and DXC. Some examples include:
void takesDoubles(double, double, double);

cbuffer CB {
bool B;
uint U;
int I;
float X, Y, Z;
double3 A, B;
}

void twoParams(int, int);
void twoParams(float, float);

export void call() {
halfOrInt16(U); // DXC: Fails with call ambiguous between int16_t and uint16_t overloads
// Clang: Resolves to halfOrInt16(uint16_t).
Expand All @@ -98,6 +102,13 @@ behavior between Clang and DXC. Some examples include:
// FXC: Expands to compute double dot product with fmul/fadd
// Clang: Resolves to dot(float3, float3), emits conversion warnings.

#ifndef IGNORE_ERRORS
tan(B); // DXC: resolves to tan(float).
// Clang: Fails to resolve, ambiguous between integer types.

twoParams(I, X); // DXC: resolves twoParams(int, int).
// Clang: Fails to resolve ambiguous conversions.
#endif
}

.. note::
Expand Down
5 changes: 4 additions & 1 deletion clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3977,7 +3977,10 @@ standard library ``<stdarg.h>`` header:
* ``__builtin_va_list``
A predefined typedef for the target-specific ``va_list`` type.
A predefined typedef for the target-specific ``va_list`` type. It is undefined
behavior to use a byte-wise copy of this type produced by calling ``memcpy``,
``memmove``, or similar. Valid explicit copies are only produced by calling
``va_copy`` or ``__builtin_va_copy``.
* ``void __builtin_va_start(__builtin_va_list list, <parameter-name>)``
Expand Down
14 changes: 14 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ code bases.
- Setting the deprecated CMake variable ``GCC_INSTALL_PREFIX`` (which sets the
default ``--gcc-toolchain=``) now leads to a fatal error.

- The ``le32`` and ``le64`` targets have been removed.

C/C++ Language Potentially Breaking Changes
-------------------------------------------

Expand Down Expand Up @@ -165,6 +167,7 @@ Clang Python Bindings Potentially Breaking Changes
of variant 271.
- Renamed ``TypeKind`` variant 162 from ``OBJCCLASS`` to ``OBJCTYPEPARAM``.
The previous name was incorrect, it was a duplicate of variant 28.
- Refactored enum implementation, switching to the standard library `Enum` type.

What's New in Clang |release|?
==============================
Expand Down Expand Up @@ -312,6 +315,7 @@ Resolutions to C++ Defect Reports

- Clang now correctly implements lookup for the terminal name of a member-qualified nested-name-specifier.
(`CWG1835: Dependent member lookup before < <https://cplusplus.github.io/CWG/issues/1835.html>`_).
The warning can be disabled via `-Wno-missing-dependent-template-keyword`.

C Language Changes
------------------
Expand Down Expand Up @@ -823,6 +827,9 @@ Bug Fixes in This Version

- Fixed Clang crashing when failing to perform some C++ Initialization Sequences. (#GH98102)

- ``__is_trivially_equality_comparable`` no longer returns true for types which
have a constrained defaulted comparison operator (#GH89293).

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -1032,6 +1039,9 @@ Bug Fixes to C++ Support
- Fixed a CTAD substitution bug involving type aliases that reference outer template parameters. (#GH94614).
- Clang now correctly handles unexpanded packs in the template parameter list of a generic lambda expression
(#GH48937)
- Fix a crash when parsing an invalid type-requirement in a requires expression. (#GH51868)
- Fix parsing of built-in type-traits such as ``__is_pointer`` in libstdc++ headers. (#GH95598)
- Fixed failed assertion when resolving context of defaulted comparison method outside of struct. (#GH96043).

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -1142,6 +1152,10 @@ RISC-V Support
- ``__attribute__((rvv_vector_bits(N)))`` is now supported for RVV vbool*_t types.
- Profile names in ``-march`` option are now supported.
- Passing empty structs/unions as arguments in C++ is now handled correctly. The behavior is similar to GCC's.
- ``-m[no-]scalar-strict-align`` and ``-m[no-]vector-strict-align`` options have
been added to give separate control of whether scalar or vector misaligned
accesses may be created. ``-m[no-]strict-align`` applies to both scalar and
vector.

CUDA/HIP Language Changes
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
1 change: 0 additions & 1 deletion clang/docs/tools/clang-formatted-files.txt
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,6 @@ clang/lib/Basic/Targets/BPF.cpp
clang/lib/Basic/Targets/BPF.h
clang/lib/Basic/Targets/Hexagon.h
clang/lib/Basic/Targets/Lanai.h
clang/lib/Basic/Targets/Le64.h
clang/lib/Basic/Targets/M68k.h
clang/lib/Basic/Targets/MSP430.h
clang/lib/Basic/Targets/NVPTX.cpp
Expand Down
11 changes: 4 additions & 7 deletions clang/include/clang/AST/ASTConcept.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,10 @@ class ConstraintSatisfaction : public llvm::FoldingSetNode {
bool IsSatisfied = false;
bool ContainsErrors = false;

/// \brief Pairs of unsatisfied atomic constraint expressions along with the
/// substituted constraint expr, if the template arguments could be
/// \brief The substituted constraint expr, if the template arguments could be
/// substituted into them, or a diagnostic if substitution resulted in an
/// invalid expression.
llvm::SmallVector<std::pair<const Expr *, Detail>, 4> Details;
llvm::SmallVector<Detail, 4> Details;

void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
Profile(ID, C, ConstraintOwner, TemplateArgs);
Expand All @@ -69,7 +68,7 @@ class ConstraintSatisfaction : public llvm::FoldingSetNode {

bool HasSubstitutionFailure() {
for (const auto &Detail : Details)
if (Detail.second.dyn_cast<SubstitutionDiagnostic *>())
if (Detail.dyn_cast<SubstitutionDiagnostic *>())
return true;
return false;
}
Expand All @@ -80,9 +79,7 @@ class ConstraintSatisfaction : public llvm::FoldingSetNode {
/// substituted into them, or a diagnostic if substitution resulted in
/// an invalid expression.
using UnsatisfiedConstraintRecord =
std::pair<const Expr *,
llvm::PointerUnion<Expr *,
std::pair<SourceLocation, StringRef> *>>;
llvm::PointerUnion<Expr *, std::pair<SourceLocation, StringRef> *>;

/// \brief The result of a constraint satisfaction check, containing the
/// necessary information to diagnose an unsatisfied constraint.
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,9 @@ class alignas(8) Decl {
/// Whether this declaration comes from explicit global module.
bool isFromExplicitGlobalModule() const;

/// Whether this declaration comes from a named module.
bool isInNamedModule() const;

/// Return true if this declaration has an attribute which acts as
/// definition of the entity, such as 'alias' or 'ifunc'.
bool hasDefiningAttr() const;
Expand Down
3 changes: 0 additions & 3 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -1142,9 +1142,6 @@ class QualType {
/// Return true if this is a trivially relocatable type.
bool isTriviallyRelocatableType(const ASTContext &Context) const;

/// Return true if this is a trivially equality comparable type.
bool isTriviallyEqualityComparableType(const ASTContext &Context) const;

/// Returns true if it is a class and it might be dynamic.
bool mayBeDynamicClass() const;

Expand Down
19 changes: 14 additions & 5 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -4561,11 +4561,7 @@ def HLSLResource : InheritableAttr {
let Spellings = [];
let Subjects = SubjectList<[Struct]>;
let LangOpts = [HLSL];
let Args = [
EnumArgument<"ResourceClass", "llvm::hlsl::ResourceClass",
/*is_string=*/0, ["SRV", "UAV", "CBuffer", "Sampler"],
["SRV", "UAV", "CBuffer", "Sampler"],
/*opt=*/0, /*fake=*/0, /*isExternalType=*/1>,
let Args = [
EnumArgument<
"ResourceKind", "llvm::hlsl::ResourceKind",
/*is_string=*/0,
Expand All @@ -4589,6 +4585,19 @@ def HLSLResource : InheritableAttr {
let Documentation = [InternalOnly];
}

def HLSLResourceClass : InheritableAttr {
let Spellings = [CXX11<"hlsl", "resource_class">];
let Subjects = SubjectList<[Struct]>;
let LangOpts = [HLSL];
let Args = [
EnumArgument<"ResourceClass", "llvm::hlsl::ResourceClass",
/*is_string=*/true, ["SRV", "UAV", "CBuffer", "Sampler"],
["SRV", "UAV", "CBuffer", "Sampler"],
/*opt=*/0, /*fake=*/0, /*isExternalType=*/1>
];
let Documentation = [InternalOnly];
}

def HLSLGroupSharedAddressSpace : TypeAttr {
let Spellings = [CustomKeyword<"groupshared">];
let Subjects = SubjectList<[Var]>;
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,8 @@ def missing_template_arg_list_after_template_kw : Extension<
DefaultError;

def ext_missing_dependent_template_keyword : ExtWarn<
"use 'template' keyword to treat '%0' as a dependent template name">;
"use 'template' keyword to treat '%0' as a dependent template name">,
InGroup<DiagGroup<"missing-dependent-template-keyword">>;

def ext_extern_template : Extension<
"extern templates are a C++11 extension">, InGroup<CXX11>;
Expand Down
23 changes: 0 additions & 23 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Frontend/OpenMP/OMPGridValues.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/VersionTuple.h"
Expand Down Expand Up @@ -1410,7 +1408,6 @@ class TargetInfo : public TransferrableTargetInfo,
bool BranchProtectionPAuthLR;
bool GuardedControlStack;

protected:
const char *getSignReturnAddrStr() const {
switch (SignReturnAddr) {
case LangOptions::SignReturnAddressScopeKind::None:
Expand All @@ -1433,7 +1430,6 @@ class TargetInfo : public TransferrableTargetInfo,
llvm_unreachable("Unexpected SignReturnAddressKeyKind");
}

public:
BranchProtectionInfo()
: SignReturnAddr(LangOptions::SignReturnAddressScopeKind::None),
SignKey(LangOptions::SignReturnAddressKeyKind::AKey),
Expand All @@ -1454,25 +1450,6 @@ class TargetInfo : public TransferrableTargetInfo,
BranchProtectionPAuthLR = LangOpts.BranchProtectionPAuthLR;
GuardedControlStack = LangOpts.GuardedControlStack;
}

void setFnAttributes(llvm::Function &F) {
llvm::AttrBuilder FuncAttrs(F.getContext());
setFnAttributes(FuncAttrs);
F.addFnAttrs(FuncAttrs);
}

void setFnAttributes(llvm::AttrBuilder &FuncAttrs) {
if (SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
FuncAttrs.addAttribute("sign-return-address", getSignReturnAddrStr());
FuncAttrs.addAttribute("sign-return-address-key", getSignKeyStr());
}
if (BranchTargetEnforcement)
FuncAttrs.addAttribute("branch-target-enforcement");
if (BranchProtectionPAuthLR)
FuncAttrs.addAttribute("branch-protection-pauth-lr");
if (GuardedControlStack)
FuncAttrs.addAttribute("guarded-control-stack");
}
};

/// Determine if the Architecture in this TargetInfo supports branch
Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -4854,6 +4854,14 @@ def mstrict_align : Flag<["-"], "mstrict-align">, Group<m_Group>,
HelpText<"Force all memory accesses to be aligned (AArch64/LoongArch/RISC-V only)">;
def mno_strict_align : Flag<["-"], "mno-strict-align">, Group<m_Group>,
HelpText<"Allow memory accesses to be unaligned (AArch64/LoongArch/RISC-V only)">;
def mscalar_strict_align : Flag<["-"], "mscalar-strict-align">, Group<m_Group>,
HelpText<"Force all scalar memory accesses to be aligned (RISC-V only)">;
def mno_scalar_strict_align : Flag<["-"], "mno-scalar-strict-align">, Group<m_Group>,
HelpText<"Allow scalar memory accesses to be unaligned (RISC-V only)">;
def mvector_strict_align : Flag<["-"], "mvector-strict-align">, Group<m_Group>,
HelpText<"Force all vector memory accesses to be aligned (RISC-V only)">;
def mno_vector_strict_align : Flag<["-"], "mno-vector-strict-align">, Group<m_Group>,
HelpText<"Allow vector memory accesses to be unaligned (RISC-V only)">;
def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_arm_Features_Group>;
def mrestrict_it: Flag<["-"], "mrestrict-it">, Group<m_arm_Features_Group>,
HelpText<"Disallow generation of complex IT blocks. It is off by default.">;
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,10 @@ class Parser : public CodeCompletionHandler {
UnaryExprOnly,
PrimaryExprOnly
};

bool isRevertibleTypeTrait(const IdentifierInfo *Id,
clang::tok::TokenKind *Kind = nullptr);

ExprResult ParseCastExpression(CastParseKind ParseKind,
bool isAddressOfOperand,
bool &NotCastExpr,
Expand Down
38 changes: 31 additions & 7 deletions clang/include/clang/Sema/Overload.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ class Sema;
/// HLSL non-decaying array rvalue cast.
ICK_HLSL_Array_RValue,

// HLSL vector splat from scalar or boolean type.
ICK_HLSL_Vector_Splat,

/// The number of conversion kinds
ICK_Num_Conversion_Kinds,
};
Expand All @@ -213,15 +216,27 @@ class Sema;
/// Exact Match
ICR_Exact_Match = 0,

/// HLSL Scalar Widening
ICR_HLSL_Scalar_Widening,

/// Promotion
ICR_Promotion,

/// HLSL Scalar Widening with promotion
ICR_HLSL_Scalar_Widening_Promotion,

/// HLSL Matching Dimension Reduction
ICR_HLSL_Dimension_Reduction,

/// Conversion
ICR_Conversion,

/// OpenCL Scalar Widening
ICR_OCL_Scalar_Widening,

/// HLSL Scalar Widening with conversion
ICR_HLSL_Scalar_Widening_Conversion,

/// Complex <-> Real conversion
ICR_Complex_Real_Conversion,

Expand All @@ -233,11 +248,21 @@ class Sema;

/// Conversion not allowed by the C standard, but that we accept as an
/// extension anyway.
ICR_C_Conversion_Extension
ICR_C_Conversion_Extension,

/// HLSL Dimension reduction with promotion
ICR_HLSL_Dimension_Reduction_Promotion,

/// HLSL Dimension reduction with conversion
ICR_HLSL_Dimension_Reduction_Conversion,
};

ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind);

ImplicitConversionRank
GetDimensionConversionRank(ImplicitConversionRank Base,
ImplicitConversionKind Dimension);

/// NarrowingKind - The kind of narrowing conversion being performed by a
/// standard conversion sequence according to C++11 [dcl.init.list]p7.
enum NarrowingKind {
Expand Down Expand Up @@ -277,11 +302,10 @@ class Sema;
/// pointer-to-member conversion, or boolean conversion.
ImplicitConversionKind Second : 8;

/// Element - Between the second and third conversion a vector or matrix
/// element conversion may occur. If this is not ICK_Identity this
/// conversion is applied element-wise to each element in the vector or
/// matrix.
ImplicitConversionKind Element : 8;
/// Dimension - Between the second and third conversion a vector or matrix
/// dimension conversion may occur. If this is not ICK_Identity this
/// conversion truncates the vector or matrix, or extends a scalar.
ImplicitConversionKind Dimension : 8;

/// Third - The third conversion can be a qualification conversion
/// or a function conversion.
Expand Down Expand Up @@ -379,7 +403,7 @@ class Sema;
void setAsIdentityConversion();

bool isIdentityConversion() const {
return Second == ICK_Identity && Element == ICK_Identity &&
return Second == ICK_Identity && Dimension == ICK_Identity &&
Third == ICK_Identity;
}

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class SemaHLSL : public SemaBase {
void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL);
void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL);
void handleShaderAttr(Decl *D, const ParsedAttr &AL);
void handleResourceClassAttr(Decl *D, const ParsedAttr &AL);
void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL);
void handleParamModifierAttr(Decl *D, const ParsedAttr &AL);

Expand Down
24 changes: 10 additions & 14 deletions clang/lib/AST/ASTConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,31 @@

using namespace clang;

namespace {
void CreatUnsatisfiedConstraintRecord(
const ASTContext &C, const UnsatisfiedConstraintRecord &Detail,
UnsatisfiedConstraintRecord *TrailingObject) {
if (Detail.second.is<Expr *>())
new (TrailingObject) UnsatisfiedConstraintRecord{
Detail.first,
UnsatisfiedConstraintRecord::second_type(Detail.second.get<Expr *>())};
static void
CreateUnsatisfiedConstraintRecord(const ASTContext &C,
const UnsatisfiedConstraintRecord &Detail,
UnsatisfiedConstraintRecord *TrailingObject) {
if (Detail.is<Expr *>())
new (TrailingObject) UnsatisfiedConstraintRecord(Detail.get<Expr *>());
else {
auto &SubstitutionDiagnostic =
*Detail.second.get<std::pair<SourceLocation, StringRef> *>();
*Detail.get<std::pair<SourceLocation, StringRef> *>();
unsigned MessageSize = SubstitutionDiagnostic.second.size();
char *Mem = new (C) char[MessageSize];
memcpy(Mem, SubstitutionDiagnostic.second.data(), MessageSize);
auto *NewSubstDiag = new (C) std::pair<SourceLocation, StringRef>(
SubstitutionDiagnostic.first, StringRef(Mem, MessageSize));
new (TrailingObject) UnsatisfiedConstraintRecord{
Detail.first, UnsatisfiedConstraintRecord::second_type(NewSubstDiag)};
new (TrailingObject) UnsatisfiedConstraintRecord(NewSubstDiag);
}
}
} // namespace

ASTConstraintSatisfaction::ASTConstraintSatisfaction(
const ASTContext &C, const ConstraintSatisfaction &Satisfaction)
: NumRecords{Satisfaction.Details.size()},
IsSatisfied{Satisfaction.IsSatisfied}, ContainsErrors{
Satisfaction.ContainsErrors} {
for (unsigned I = 0; I < NumRecords; ++I)
CreatUnsatisfiedConstraintRecord(
CreateUnsatisfiedConstraintRecord(
C, Satisfaction.Details[I],
getTrailingObjects<UnsatisfiedConstraintRecord>() + I);
}
Expand All @@ -58,7 +54,7 @@ ASTConstraintSatisfaction::ASTConstraintSatisfaction(
IsSatisfied{Satisfaction.IsSatisfied},
ContainsErrors{Satisfaction.ContainsErrors} {
for (unsigned I = 0; I < NumRecords; ++I)
CreatUnsatisfiedConstraintRecord(
CreateUnsatisfiedConstraintRecord(
C, *(Satisfaction.begin() + I),
getTrailingObjects<UnsatisfiedConstraintRecord>() + I);
}
Expand Down
11 changes: 2 additions & 9 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1181,13 +1181,6 @@ Linkage NamedDecl::getLinkageInternal() const {
.getLinkage();
}

/// Determine whether D is attached to a named module.
static bool isInNamedModule(const NamedDecl *D) {
if (auto *M = D->getOwningModule())
return M->isNamedModule();
return false;
}

static bool isExportedFromModuleInterfaceUnit(const NamedDecl *D) {
// FIXME: Handle isModulePrivate.
switch (D->getModuleOwnershipKind()) {
Expand All @@ -1197,7 +1190,7 @@ static bool isExportedFromModuleInterfaceUnit(const NamedDecl *D) {
return false;
case Decl::ModuleOwnershipKind::Visible:
case Decl::ModuleOwnershipKind::VisibleWhenImported:
return isInNamedModule(D);
return D->isInNamedModule();
}
llvm_unreachable("unexpected module ownership kind");
}
Expand All @@ -1215,7 +1208,7 @@ Linkage NamedDecl::getFormalLinkage() const {
// [basic.namespace.general]/p2
// A namespace is never attached to a named module and never has a name with
// module linkage.
if (isInNamedModule(this) && InternalLinkage == Linkage::External &&
if (isInNamedModule() && InternalLinkage == Linkage::External &&
!isExportedFromModuleInterfaceUnit(
cast<NamedDecl>(this->getCanonicalDecl())) &&
!isa<NamespaceDecl>(this))
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/AST/DeclBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,10 @@ bool Decl::isFromExplicitGlobalModule() const {
return getOwningModule() && getOwningModule()->isExplicitGlobalModule();
}

bool Decl::isInNamedModule() const {
return getOwningModule() && getOwningModule()->isNamedModule();
}

static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/Interp/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
assert(Func);
// For not-yet-defined functions, we only create a Function instance and
// compile their body later.
if (!FuncDecl->isDefined()) {
if (!FuncDecl->isDefined() ||
(FuncDecl->willHaveBody() && !FuncDecl->hasBody())) {
Func->setDefined(false);
return Func;
}
Expand Down
56 changes: 49 additions & 7 deletions clang/lib/AST/Interp/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3073,13 +3073,13 @@ bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr *E) {
}

assert(S == Result);
// This better produces a value (i.e. is an expression).
if (const Expr *ResultExpr = dyn_cast<Expr>(S)) {
if (DiscardResult)
return this->discard(ResultExpr);
return this->delegate(ResultExpr);
}
return false;

return this->visitStmt(S);
}

return BS.destroyLocals();
Expand Down Expand Up @@ -3583,7 +3583,19 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, bool Topleve
return checkDecl() && this->emitInitGlobal(*VarT, GlobalIndex, VD);
}

return checkDecl() && this->visitGlobalInitializer(Init, GlobalIndex);
if (!checkDecl())
return false;

if (!this->emitGetPtrGlobal(GlobalIndex, Init))
return false;

if (!visitInitializer(Init))
return false;

if (!this->emitFinishInit(Init))
return false;

return this->emitPopPtr(Init);
};

// We've already seen and initialized this global.
Expand Down Expand Up @@ -3627,7 +3639,16 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, bool Topleve
if (!Init)
return true;

return this->visitLocalInitializer(Init, *Offset);
if (!this->emitGetPtrLocal(*Offset, Init))
return false;

if (!visitInitializer(Init))
return false;

if (!this->emitFinishInit(Init))
return false;

return this->emitPopPtr(Init);
}
return false;
}
Expand Down Expand Up @@ -4685,6 +4706,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
case UO_PostInc: { // x++
if (!Ctx.getLangOpts().CPlusPlus14)
return this->emitInvalid(E);
if (!T)
return this->emitError(E);

if (!this->visit(SubExpr))
return false;
Expand All @@ -4706,6 +4729,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
case UO_PostDec: { // x--
if (!Ctx.getLangOpts().CPlusPlus14)
return this->emitInvalid(E);
if (!T)
return this->emitError(E);

if (!this->visit(SubExpr))
return false;
Expand All @@ -4727,6 +4752,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
case UO_PreInc: { // ++x
if (!Ctx.getLangOpts().CPlusPlus14)
return this->emitInvalid(E);
if (!T)
return this->emitError(E);

if (!this->visit(SubExpr))
return false;
Expand Down Expand Up @@ -4774,6 +4801,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
case UO_PreDec: { // --x
if (!Ctx.getLangOpts().CPlusPlus14)
return this->emitInvalid(E);
if (!T)
return this->emitError(E);

if (!this->visit(SubExpr))
return false;
Expand Down Expand Up @@ -4819,6 +4848,9 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return E->isGLValue() || this->emitLoadPop(*T, E);
}
case UO_LNot: // !x
if (!T)
return this->emitError(E);

if (DiscardResult)
return this->discard(SubExpr);

Expand All @@ -4832,10 +4864,16 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return this->emitCast(PT_Bool, ET, E);
return true;
case UO_Minus: // -x
if (!T)
return this->emitError(E);

if (!this->visit(SubExpr))
return false;
return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
case UO_Plus: // +x
if (!T)
return this->emitError(E);

if (!this->visit(SubExpr)) // noop
return false;
return DiscardResult ? this->emitPop(*T, E) : true;
Expand All @@ -4852,6 +4890,9 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
return this->discard(SubExpr);
return this->visit(SubExpr);
case UO_Not: // ~x
if (!T)
return this->emitError(E);

if (!this->visit(SubExpr))
return false;
return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
Expand Down Expand Up @@ -5094,9 +5135,10 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
if (E->getType()->isVoidType())
return true;
// Convert the dummy pointer to another pointer type if we have to.
if (PrimType PT = classifyPrim(E); PT != PT_Ptr && isPtrType(PT)) {
if (!this->emitDecayPtr(PT_Ptr, PT, E))
return false;
if (PrimType PT = classifyPrim(E); PT != PT_Ptr) {
if (isPtrType(PT))
return this->emitDecayPtr(PT_Ptr, PT, E);
return false;
}
return true;
}
Expand Down
39 changes: 0 additions & 39 deletions clang/lib/AST/Interp/Compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,45 +278,6 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
/// Visits an expression and converts it to a boolean.
bool visitBool(const Expr *E);

/// Visits an initializer for a local.
bool visitLocalInitializer(const Expr *Init, unsigned I) {
if (!this->emitGetPtrLocal(I, Init))
return false;

if (!visitInitializer(Init))
return false;

if (!this->emitFinishInit(Init))
return false;

return this->emitPopPtr(Init);
}

/// Visits an initializer for a global.
bool visitGlobalInitializer(const Expr *Init, unsigned I) {
if (!this->emitGetPtrGlobal(I, Init))
return false;

if (!visitInitializer(Init))
return false;

if (!this->emitFinishInit(Init))
return false;

return this->emitPopPtr(Init);
}

/// Visits a delegated initializer.
bool visitThisInitializer(const Expr *I) {
if (!this->emitThis(I))
return false;

if (!visitInitializer(I))
return false;

return this->emitFinishInitPop(I);
}

bool visitInitList(ArrayRef<const Expr *> Inits, const Expr *ArrayFiller,
const Expr *E);
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init);
Expand Down
54 changes: 30 additions & 24 deletions clang/lib/AST/Interp/Descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,7 @@ static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
}

static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsActive, const Descriptor *D, unsigned FieldOffset,
bool IsVirtualBase) {
bool IsActive, const Descriptor *D, unsigned FieldOffset) {
assert(D);
assert(D->ElemRecord);

Expand All @@ -179,43 +178,46 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,

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

// If this is initializing a virtual base, we do NOT want to consider its
// virtual bases, those are already flattened into the parent record when
// creating it.
if (IsVirtualBase)
return;

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

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

static void destroyField(Block *B, std::byte *Ptr, const Descriptor *D,
unsigned FieldOffset) {
if (auto Fn = D->DtorFn)
Fn(B, Ptr + FieldOffset, D);
}

static void destroyBase(Block *B, std::byte *Ptr, const Descriptor *D,
unsigned FieldOffset) {
assert(D);
assert(D->ElemRecord);

for (const auto &V : D->ElemRecord->bases())
destroyBase(B, Ptr + FieldOffset, V.Desc, V.Offset);
for (const auto &F : D->ElemRecord->fields())
destroyField(B, Ptr + FieldOffset, F.Desc, F.Offset);
}

static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) {
auto DtorSub = [=](unsigned SubOff, const Descriptor *F) {
if (auto Fn = F->DtorFn)
Fn(B, Ptr + SubOff, F);
};
for (const auto &F : D->ElemRecord->bases())
DtorSub(F.Offset, F.Desc);
destroyBase(B, Ptr, F.Desc, F.Offset);
for (const auto &F : D->ElemRecord->fields())
DtorSub(F.Offset, F.Desc);
destroyField(B, Ptr, F.Desc, F.Offset);
for (const auto &F : D->ElemRecord->virtual_bases())
DtorSub(F.Offset, F.Desc);
destroyBase(B, Ptr, F.Desc, F.Offset);
}

static void moveRecord(Block *B, const std::byte *Src, std::byte *Dst,
Expand All @@ -238,6 +240,8 @@ static BlockCtorFn getCtorPrim(PrimType Type) {
return ctorTy<PrimConv<PT_IntAP>::T>;
if (Type == PT_IntAPS)
return ctorTy<PrimConv<PT_IntAPS>::T>;
if (Type == PT_MemberPtr)
return ctorTy<PrimConv<PT_MemberPtr>::T>;

COMPOSITE_TYPE_SWITCH(Type, return ctorTy<T>, return nullptr);
}
Expand All @@ -251,6 +255,8 @@ static BlockDtorFn getDtorPrim(PrimType Type) {
return dtorTy<PrimConv<PT_IntAP>::T>;
if (Type == PT_IntAPS)
return dtorTy<PrimConv<PT_IntAPS>::T>;
if (Type == PT_MemberPtr)
return dtorTy<PrimConv<PT_MemberPtr>::T>;

COMPOSITE_TYPE_SWITCH(Type, return dtorTy<T>, return nullptr);
}
Expand Down
14 changes: 10 additions & 4 deletions clang/lib/AST/Interp/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,10 +405,16 @@ bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {

// The This pointer is writable in constructors and destructors,
// even if isConst() returns true.
if (const Function *Func = S.Current->getFunction();
Func && (Func->isConstructor() || Func->isDestructor()) &&
Ptr.block() == S.Current->getThis().block()) {
return true;
// TODO(perf): We could be hitting this code path quite a lot in complex
// constructors. Is there a better way to do this?
if (S.Current->getFunction()) {
for (const InterpFrame *Frame = S.Current; Frame; Frame = Frame->Caller) {
if (const Function *Func = Frame->getFunction();
Func && (Func->isConstructor() || Func->isDestructor()) &&
Ptr.block() == Frame->getThis().block()) {
return true;
}
}
}

if (!Ptr.isBlockPointer())
Expand Down
130 changes: 83 additions & 47 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,9 @@
#include "Program.h"
#include "State.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Expr.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/Support/Endian.h"
#include <limits>
#include <type_traits>

namespace clang {
Expand Down Expand Up @@ -151,7 +147,7 @@ bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS,
const APSInt Val = RHS.toAPSInt();
QualType Ty = E->getType();
S.CCEDiag(E, diag::note_constexpr_large_shift) << Val << Ty << Bits;
return true; // We will do the shift anyway but fix up the shift amount.
return !(S.getEvalStatus().Diag && !S.getEvalStatus().Diag->empty() && S.getLangOpts().CPlusPlus11);
}

if (LHS.isSigned() && !S.getLangOpts().CPlusPlus20) {
Expand Down Expand Up @@ -306,15 +302,16 @@ bool AddSubMulHelper(InterpState &S, CodePtr OpPC, unsigned Bits, const T &LHS,
auto Loc = E->getExprLoc();
S.report(Loc, diag::warn_integer_constant_overflow)
<< Trunc << Type << E->getSourceRange();
return true;
} else {
S.CCEDiag(E, diag::note_constexpr_overflow) << Value << Type;
if (!S.noteUndefinedBehavior()) {
S.Stk.pop<T>();
return false;
}
return true;
}

S.CCEDiag(E, diag::note_constexpr_overflow) << Value << Type;

if (!S.noteUndefinedBehavior()) {
S.Stk.pop<T>();
return false;
}

return true;
}

template <PrimType Name, class T = typename PrimConv<Name>::T>
Expand Down Expand Up @@ -1848,6 +1845,15 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
else
Result = WideIndex - WideOffset;

// When the pointer is one-past-end, going back to index 0 is the only
// useful thing we can do. Any other index has been diagnosed before and
// we don't get here.
if (Result == 0 && Ptr.isOnePastEnd()) {
S.Stk.push<Pointer>(Ptr.asBlockPointer().Pointee,
Ptr.asBlockPointer().Base);
return true;
}

S.Stk.push<Pointer>(Ptr.atIndex(static_cast<uint64_t>(Result)));
return true;
}
Expand Down Expand Up @@ -2203,66 +2209,90 @@ inline bool RVOPtr(InterpState &S, CodePtr OpPC) {
//===----------------------------------------------------------------------===//
// Shr, Shl
//===----------------------------------------------------------------------===//
enum class ShiftDir { Left, Right };

template <PrimType NameL, PrimType NameR>
inline bool Shr(InterpState &S, CodePtr OpPC) {
using LT = typename PrimConv<NameL>::T;
using RT = typename PrimConv<NameR>::T;
auto RHS = S.Stk.pop<RT>();
const auto &LHS = S.Stk.pop<LT>();
template <class LT, class RT, ShiftDir Dir>
inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) {
const unsigned Bits = LHS.bitWidth();

// OpenCL 6.3j: shift values are effectively % word size of LHS.
if (S.getLangOpts().OpenCL)
RT::bitAnd(RHS, RT::from(LHS.bitWidth() - 1, RHS.bitWidth()),
RHS.bitWidth(), &RHS);

if (RHS.isNegative()) {
// During constant-folding, a negative shift is an opposite shift. Such a
// shift is not a constant expression.
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.CCEDiag(Loc, diag::note_constexpr_negative_shift) << RHS.toAPSInt();
if (S.getLangOpts().CPlusPlus11 && S.getEvalStatus().Diag &&
!S.getEvalStatus().Diag->empty())
return false;
RHS = -RHS;
return DoShift < LT, RT,
Dir == ShiftDir::Left ? ShiftDir::Right
: ShiftDir::Left > (S, OpPC, LHS, RHS);
}

if constexpr (Dir == ShiftDir::Left) {
if (LHS.isNegative() && !S.getLangOpts().CPlusPlus20) {
// C++11 [expr.shift]p2: A signed left shift must have a non-negative
// operand, and must not overflow the corresponding unsigned type.
// C++2a [expr.shift]p2: E1 << E2 is the unique value congruent to
// E1 x 2^E2 module 2^N.
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.CCEDiag(Loc, diag::note_constexpr_lshift_of_negative) << LHS.toAPSInt();
if (S.getLangOpts().CPlusPlus11 && S.getEvalStatus().Diag &&
!S.getEvalStatus().Diag->empty())
return false;
}
}

if (!CheckShift(S, OpPC, LHS, RHS, Bits))
return false;

// Limit the shift amount to Bits - 1. If this happened,
// it has already been diagnosed by CheckShift() above,
// but we still need to handle it.
typename LT::AsUnsigned R;
if (RHS > RT::from(Bits - 1, RHS.bitWidth()))
LT::AsUnsigned::shiftRight(LT::AsUnsigned::from(LHS),
LT::AsUnsigned::from(Bits - 1), Bits, &R);
else
LT::AsUnsigned::shiftRight(LT::AsUnsigned::from(LHS),
LT::AsUnsigned::from(RHS, Bits), Bits, &R);
if constexpr (Dir == ShiftDir::Left) {
if (RHS > RT::from(Bits - 1, RHS.bitWidth()))
LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(LHS),
LT::AsUnsigned::from(Bits - 1), Bits, &R);
else
LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(LHS),
LT::AsUnsigned::from(RHS, Bits), Bits, &R);
} else {
if (RHS > RT::from(Bits - 1, RHS.bitWidth()))
LT::AsUnsigned::shiftRight(LT::AsUnsigned::from(LHS),
LT::AsUnsigned::from(Bits - 1), Bits, &R);
else
LT::AsUnsigned::shiftRight(LT::AsUnsigned::from(LHS),
LT::AsUnsigned::from(RHS, Bits), Bits, &R);
}

S.Stk.push<LT>(LT::from(R));
return true;
}

template <PrimType NameL, PrimType NameR>
inline bool Shl(InterpState &S, CodePtr OpPC) {
inline bool Shr(InterpState &S, CodePtr OpPC) {
using LT = typename PrimConv<NameL>::T;
using RT = typename PrimConv<NameR>::T;
auto RHS = S.Stk.pop<RT>();
const auto &LHS = S.Stk.pop<LT>();
const unsigned Bits = LHS.bitWidth();

// OpenCL 6.3j: shift values are effectively % word size of LHS.
if (S.getLangOpts().OpenCL)
RT::bitAnd(RHS, RT::from(LHS.bitWidth() - 1, RHS.bitWidth()),
RHS.bitWidth(), &RHS);
auto LHS = S.Stk.pop<LT>();

if (!CheckShift(S, OpPC, LHS, RHS, Bits))
return false;
return DoShift<LT, RT, ShiftDir::Right>(S, OpPC, LHS, RHS);
}

// Limit the shift amount to Bits - 1. If this happened,
// it has already been diagnosed by CheckShift() above,
// but we still need to handle it.
typename LT::AsUnsigned R;
if (RHS > RT::from(Bits - 1, RHS.bitWidth()))
LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(LHS),
LT::AsUnsigned::from(Bits - 1), Bits, &R);
else
LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(LHS),
LT::AsUnsigned::from(RHS, Bits), Bits, &R);
template <PrimType NameL, PrimType NameR>
inline bool Shl(InterpState &S, CodePtr OpPC) {
using LT = typename PrimConv<NameL>::T;
using RT = typename PrimConv<NameR>::T;
auto RHS = S.Stk.pop<RT>();
auto LHS = S.Stk.pop<LT>();

S.Stk.push<LT>(LT::from(R));
return true;
return DoShift<LT, RT, ShiftDir::Left>(S, OpPC, LHS, RHS);
}

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -2569,6 +2599,12 @@ inline bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize,

assert(F);

// This happens when the call expression has been cast to
// something else, but we don't support that.
if (S.Ctx.classify(F->getDecl()->getReturnType()) !=
S.Ctx.classify(CE->getType()))
return false;

// Check argument nullability state.
if (F->hasNonNullAttr()) {
if (!CheckNonNullArgs(S, OpPC, F, CE, ArgSize))
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/AST/Interp/InterpFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,10 @@ void InterpFrame::describe(llvm::raw_ostream &OS) const {
print(OS, This, S.getCtx(), S.getCtx().getRecordType(M->getParent()));
OS << "->";
}
OS << *F << "(";

F->getNameForDiagnostic(OS, S.getCtx().getPrintingPolicy(),
/*Qualified=*/false);
OS << '(';
unsigned Off = 0;

Off += Func->hasRVO() ? primSize(PT_Ptr) : 0;
Expand Down
8 changes: 2 additions & 6 deletions clang/lib/AST/Interp/InterpFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@

#include "Frame.h"
#include "Program.h"
#include <cstdint>
#include <vector>

namespace clang {
namespace interp {
Expand Down Expand Up @@ -85,11 +83,9 @@ class InterpFrame final : public Frame {
/// Returns the value of an argument.
template <typename T> const T &getParam(unsigned Offset) const {
auto Pt = Params.find(Offset);
if (Pt == Params.end()) {
if (Pt == Params.end())
return stackRef<T>(Offset);
} else {
return Pointer(reinterpret_cast<Block *>(Pt->second.get())).deref<T>();
}
return Pointer(reinterpret_cast<Block *>(Pt->second.get())).deref<T>();
}

/// Mutates a local copy of a parameter.
Expand Down
10 changes: 9 additions & 1 deletion clang/lib/AST/Interp/InterpState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,15 @@ InterpState::~InterpState() {
}
}

void InterpState::cleanup() {}
void InterpState::cleanup() {
// As a last resort, make sure all pointers still pointing to a dead block
// don't point to it anymore.
for (DeadBlock *DB = DeadBlocks; DB; DB = DB->Next) {
for (Pointer *P = DB->B.Pointers; P; P = P->Next) {
P->PointeeStorage.BS.Pointee = nullptr;
}
}
}

Frame *InterpState::getCurrentFrame() {
if (Current && Current->Caller)
Expand Down
15 changes: 10 additions & 5 deletions clang/lib/AST/Interp/Pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/raw_ostream.h"

namespace clang {
Expand Down Expand Up @@ -211,14 +210,17 @@ class Pointer {

/// Expands a pointer to the containing array, undoing narrowing.
[[nodiscard]] Pointer expand() const {
assert(isBlockPointer());
Block *Pointee = asBlockPointer().Pointee;

if (isElementPastEnd()) {
// Revert to an outer one-past-end pointer.
unsigned Adjust;
if (inPrimitiveArray())
Adjust = sizeof(InitMapPtr);
else
Adjust = sizeof(InlineDescriptor);
return Pointer(asBlockPointer().Pointee, asBlockPointer().Base,
return Pointer(Pointee, asBlockPointer().Base,
asBlockPointer().Base + getSize() + Adjust);
}

Expand All @@ -228,15 +230,17 @@ class Pointer {

// If at base, point to an array of base types.
if (isRoot())
return Pointer(asBlockPointer().Pointee, RootPtrMark, 0);
return Pointer(Pointee, RootPtrMark, 0);

// Step into the containing array, if inside one.
unsigned Next = asBlockPointer().Base - getInlineDesc()->Offset;
const Descriptor *Desc =
Next == 0 ? getDeclDesc() : getDescriptor(Next)->Desc;
(Next == Pointee->getDescriptor()->getMetadataSize())
? getDeclDesc()
: getDescriptor(Next)->Desc;
if (!Desc->IsArray)
return *this;
return Pointer(asBlockPointer().Pointee, Next, Offset);
return Pointer(Pointee, Next, Offset);
}

/// Checks if the pointer is null.
Expand Down Expand Up @@ -631,6 +635,7 @@ class Pointer {
friend class Block;
friend class DeadBlock;
friend class MemberPointer;
friend class InterpState;
friend struct InitMap;

Pointer(Block *Pointee, unsigned Base, uint64_t Offset);
Expand Down
49 changes: 25 additions & 24 deletions clang/lib/AST/Interp/Program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,40 +288,41 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
Record::BaseList Bases;
Record::VirtualBaseList VirtBases;
if (const auto *CD = dyn_cast<CXXRecordDecl>(RD)) {

for (const CXXBaseSpecifier &Spec : CD->bases()) {
if (Spec.isVirtual())
continue;

// In error cases, the base might not be a RecordType.
if (const auto *RT = Spec.getType()->getAs<RecordType>()) {
const RecordDecl *BD = RT->getDecl();
const Record *BR = getOrCreateRecord(BD);

if (const Descriptor *Desc = GetBaseDesc(BD, BR)) {
BaseSize += align(sizeof(InlineDescriptor));
Bases.push_back({BD, BaseSize, Desc, BR});
BaseSize += align(BR->getSize());
continue;
}
}
return nullptr;
const auto *RT = Spec.getType()->getAs<RecordType>();
if (!RT)
return nullptr;
const RecordDecl *BD = RT->getDecl();
const Record *BR = getOrCreateRecord(BD);

const Descriptor *Desc = GetBaseDesc(BD, BR);
if (!Desc)
return nullptr;

BaseSize += align(sizeof(InlineDescriptor));
Bases.push_back({BD, BaseSize, Desc, BR});
BaseSize += align(BR->getSize());
}

for (const CXXBaseSpecifier &Spec : CD->vbases()) {
const auto *RT = Spec.getType()->getAs<RecordType>();
if (!RT)
return nullptr;

if (const auto *RT = Spec.getType()->getAs<RecordType>()) {
const RecordDecl *BD = RT->getDecl();
const Record *BR = getOrCreateRecord(BD);
const RecordDecl *BD = RT->getDecl();
const Record *BR = getOrCreateRecord(BD);

if (const Descriptor *Desc = GetBaseDesc(BD, BR)) {
VirtSize += align(sizeof(InlineDescriptor));
VirtBases.push_back({BD, VirtSize, Desc, BR});
VirtSize += align(BR->getSize());
continue;
}
}
return nullptr;
const Descriptor *Desc = GetBaseDesc(BD, BR);
if (!Desc)
return nullptr;

VirtSize += align(sizeof(InlineDescriptor));
VirtBases.push_back({BD, VirtSize, Desc, BR});
VirtSize += align(BR->getSize());
}
}

Expand Down
60 changes: 0 additions & 60 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2815,66 +2815,6 @@ bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const {
}
}

static bool
HasNonDeletedDefaultedEqualityComparison(const CXXRecordDecl *Decl) {
if (Decl->isUnion())
return false;
if (Decl->isLambda())
return Decl->isCapturelessLambda();

auto IsDefaultedOperatorEqualEqual = [&](const FunctionDecl *Function) {
return Function->getOverloadedOperator() ==
OverloadedOperatorKind::OO_EqualEqual &&
Function->isDefaulted() && Function->getNumParams() > 0 &&
(Function->getParamDecl(0)->getType()->isReferenceType() ||
Decl->isTriviallyCopyable());
};

if (llvm::none_of(Decl->methods(), IsDefaultedOperatorEqualEqual) &&
llvm::none_of(Decl->friends(), [&](const FriendDecl *Friend) {
if (NamedDecl *ND = Friend->getFriendDecl()) {
return ND->isFunctionOrFunctionTemplate() &&
IsDefaultedOperatorEqualEqual(ND->getAsFunction());
}
return false;
}))
return false;

return llvm::all_of(Decl->bases(),
[](const CXXBaseSpecifier &BS) {
if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
return HasNonDeletedDefaultedEqualityComparison(RD);
return true;
}) &&
llvm::all_of(Decl->fields(), [](const FieldDecl *FD) {
auto Type = FD->getType();
if (Type->isArrayType())
Type = Type->getBaseElementTypeUnsafe()->getCanonicalTypeUnqualified();

if (Type->isReferenceType() || Type->isEnumeralType())
return false;
if (const auto *RD = Type->getAsCXXRecordDecl())
return HasNonDeletedDefaultedEqualityComparison(RD);
return true;
});
}

bool QualType::isTriviallyEqualityComparableType(
const ASTContext &Context) const {
QualType CanonicalType = getCanonicalType();
if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType() ||
CanonicalType->isEnumeralType() || CanonicalType->isArrayType())
return false;

if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
if (!HasNonDeletedDefaultedEqualityComparison(RD))
return false;
}

return Context.hasUniqueObjectRepresentations(
CanonicalType, /*CheckIfTriviallyCopyable=*/false);
}

bool QualType::isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const {
return !Context.getLangOpts().ObjCAutoRefCount &&
Context.getLangOpts().ObjCWeak &&
Expand Down
10 changes: 8 additions & 2 deletions clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
Expand Down Expand Up @@ -414,8 +415,8 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
// lowest-level AST node that initializes a given object, and nothing
// below them can initialize the same object (or part of it).
if (isa<CXXConstructExpr>(E) || isa<CallExpr>(E) || isa<LambdaExpr>(E) ||
isa<CXXDefaultArgExpr>(E) || isa<CXXDefaultInitExpr>(E) ||
isa<CXXStdInitializerListExpr>(E) || isa<AtomicExpr>(E) ||
isa<CXXDefaultArgExpr>(E) || isa<CXXStdInitializerListExpr>(E) ||
isa<AtomicExpr>(E) ||
// We treat `BuiltinBitCastExpr` as an "original initializer" too as
// it may not even be casting from a record type -- and even if it is,
// the two objects are in general of unrelated type.
Expand Down Expand Up @@ -463,6 +464,11 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
return;
}

if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(E)) {
PropagateResultObject(DIE->getExpr(), Loc);
return;
}

// All other expression nodes that propagate a record prvalue should have
// exactly one child.
SmallVector<Stmt *, 1> Children(E->child_begin(), E->child_end());
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Basic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ add_clang_library(clangBasic
Targets/DirectX.cpp
Targets/Hexagon.cpp
Targets/Lanai.cpp
Targets/Le64.cpp
Targets/LoongArch.cpp
Targets/M68k.cpp
Targets/MSP430.cpp
Expand Down
12 changes: 0 additions & 12 deletions clang/lib/Basic/Targets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include "Targets/DirectX.h"
#include "Targets/Hexagon.h"
#include "Targets/Lanai.h"
#include "Targets/Le64.h"
#include "Targets/LoongArch.h"
#include "Targets/M68k.h"
#include "Targets/MSP430.h"
Expand Down Expand Up @@ -344,17 +343,6 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
return std::make_unique<M68kTargetInfo>(Triple, Opts);
}

case llvm::Triple::le32:
switch (os) {
case llvm::Triple::NaCl:
return std::make_unique<NaClTargetInfo<PNaClTargetInfo>>(Triple, Opts);
default:
return nullptr;
}

case llvm::Triple::le64:
return std::make_unique<Le64TargetInfo>(Triple, Opts);

case llvm::Triple::ppc:
switch (os) {
case llvm::Triple::Linux:
Expand Down
30 changes: 0 additions & 30 deletions clang/lib/Basic/Targets/Le64.cpp

This file was deleted.

64 changes: 0 additions & 64 deletions clang/lib/Basic/Targets/Le64.h

This file was deleted.

3 changes: 1 addition & 2 deletions clang/lib/Basic/Targets/NVPTX.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
}

BuiltinVaListKind getBuiltinVaListKind() const override {
// FIXME: implement
return TargetInfo::CharPtrBuiltinVaList;
return TargetInfo::VoidPtrBuiltinVaList;
}

bool isValidCPUName(StringRef Name) const override {
Expand Down
3 changes: 0 additions & 3 deletions clang/lib/Basic/Targets/OSTargets.h
Original file line number Diff line number Diff line change
Expand Up @@ -841,9 +841,6 @@ class LLVM_LIBRARY_VISIBILITY NaClTargetInfo : public OSTargetInfo<Target> {
"i64:64-i128:128-n8:16:32:64-S128");
} else if (Triple.getArch() == llvm::Triple::mipsel) {
// Handled on mips' setDataLayout.
} else {
assert(Triple.getArch() == llvm::Triple::le32);
this->resetDataLayout("e-p:32:32-i64:64");
}
}
};
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Basic/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__riscv_v_fixed_vlen",
Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock));

if (FastUnalignedAccess)
if (FastScalarUnalignedAccess)
Builder.defineMacro("__riscv_misaligned_fast");
else
Builder.defineMacro("__riscv_misaligned_avoid");
Expand Down Expand Up @@ -353,8 +353,8 @@ bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
if (ISAInfo->hasExtension("zfh") || ISAInfo->hasExtension("zhinx"))
HasLegalHalfType = true;

FastUnalignedAccess = llvm::is_contained(Features, "+unaligned-scalar-mem") &&
llvm::is_contained(Features, "+unaligned-vector-mem");
FastScalarUnalignedAccess =
llvm::is_contained(Features, "+unaligned-scalar-mem");

if (llvm::is_contained(Features, "+experimental"))
HasExperimental = true;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class RISCVTargetInfo : public TargetInfo {
std::unique_ptr<llvm::RISCVISAInfo> ISAInfo;

private:
bool FastUnalignedAccess;
bool FastScalarUnalignedAccess;
bool HasExperimental = false;

public:
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2030,6 +2030,9 @@ static void getTrivialDefaultFunctionAttributes(
std::tie(Var, Value) = Attr.split('=');
FuncAttrs.addAttribute(Var, Value);
}

TargetInfo::BranchProtectionInfo BPI(LangOpts);
TargetCodeGenInfo::setBranchProtectionFnAttributes(BPI, FuncAttrs);
}

/// Merges `target-features` from \TargetOpts and \F, and sets the result in
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3842,9 +3842,10 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,

llvm::CallInst *TrapCall = Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
llvm::ConstantInt::get(CGM.Int8Ty, ClSanitizeDebugDeoptimization
? TrapBB->getParent()->size()
: CheckHandlerID));
llvm::ConstantInt::get(CGM.Int8Ty,
ClSanitizeDebugDeoptimization
? TrapBB->getParent()->size()
: static_cast<uint64_t>(CheckHandlerID)));

if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
Expand Down
11 changes: 6 additions & 5 deletions clang/lib/CodeGen/CGHLSLRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,13 +280,14 @@ void CGHLSLRuntime::annotateHLSLResource(const VarDecl *D, GlobalVariable *GV) {
const auto *RD = Ty->getAsCXXRecordDecl();
if (!RD)
return;
const auto *Attr = RD->getAttr<HLSLResourceAttr>();
if (!Attr)
const auto *HLSLResAttr = RD->getAttr<HLSLResourceAttr>();
const auto *HLSLResClassAttr = RD->getAttr<HLSLResourceClassAttr>();
if (!HLSLResAttr || !HLSLResClassAttr)
return;

llvm::hlsl::ResourceClass RC = Attr->getResourceClass();
llvm::hlsl::ResourceKind RK = Attr->getResourceKind();
bool IsROV = Attr->getIsROV();
llvm::hlsl::ResourceClass RC = HLSLResClassAttr->getResourceClass();
llvm::hlsl::ResourceKind RK = HLSLResAttr->getResourceKind();
bool IsROV = HLSLResAttr->getIsROV();
llvm::hlsl::ElementType ET = calculateElementType(CGM.getContext(), Ty);

BufferResBinding Binding(D->getAttr<HLSLResourceBindingAttr>());
Expand Down
5 changes: 2 additions & 3 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ createTargetCodeGenInfo(CodeGenModule &CGM) {
default:
return createDefaultTargetCodeGenInfo(CGM);

case llvm::Triple::le32:
return createPNaClTargetCodeGenInfo(CGM);
case llvm::Triple::m68k:
return createM68kTargetCodeGenInfo(CGM);
case llvm::Triple::mips:
Expand Down Expand Up @@ -5935,7 +5933,8 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,

void CodeGenModule::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
auto DK = VD->isThisDeclarationADefinition();
if (DK == VarDecl::Definition && VD->hasAttr<DLLImportAttr>())
if ((DK == VarDecl::Definition && VD->hasAttr<DLLImportAttr>()) ||
(LangOpts.CUDA && !shouldEmitCUDAGlobalVar(VD)))
return;

TemplateSpecializationKind TSK = VD->getTemplateSpecializationKind();
Expand Down
7 changes: 0 additions & 7 deletions clang/lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,13 +576,6 @@ CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {
return new XLCXXABI(CGM);

case TargetCXXABI::GenericItanium:
if (CGM.getContext().getTargetInfo().getTriple().getArch()
== llvm::Triple::le32) {
// For PNaCl, use ARM-style method pointers so that PNaCl code
// does not assume anything about the alignment of function
// pointers.
return new ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true);
}
return new ItaniumCXXABI(CGM);

case TargetCXXABI::Microsoft:
Expand Down
22 changes: 22 additions & 0 deletions clang/lib/CodeGen/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "clang/CodeGen/CGFunctionInfo.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/raw_ostream.h"

Expand Down Expand Up @@ -206,6 +207,27 @@ llvm::Value *TargetCodeGenInfo::createEnqueuedBlockKernel(
return F;
}

void TargetCodeGenInfo::setBranchProtectionFnAttributes(
const TargetInfo::BranchProtectionInfo &BPI, llvm::Function &F) {
llvm::AttrBuilder FuncAttrs(F.getContext());
setBranchProtectionFnAttributes(BPI, FuncAttrs);
F.addFnAttrs(FuncAttrs);
}

void TargetCodeGenInfo::setBranchProtectionFnAttributes(
const TargetInfo::BranchProtectionInfo &BPI, llvm::AttrBuilder &FuncAttrs) {
if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
FuncAttrs.addAttribute("sign-return-address", BPI.getSignReturnAddrStr());
FuncAttrs.addAttribute("sign-return-address-key", BPI.getSignKeyStr());
}
if (BPI.BranchTargetEnforcement)
FuncAttrs.addAttribute("branch-target-enforcement");
if (BPI.BranchProtectionPAuthLR)
FuncAttrs.addAttribute("branch-protection-pauth-lr");
if (BPI.GuardedControlStack)
FuncAttrs.addAttribute("guarded-control-stack");
}

namespace {
class DefaultTargetCodeGenInfo : public TargetCodeGenInfo {
public:
Expand Down
11 changes: 10 additions & 1 deletion clang/lib/CodeGen/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
#define LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H

#include "CGBuilder.h"
#include "CodeGenModule.h"
#include "CGValue.h"
#include "CodeGenModule.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SyncScope.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"

Expand Down Expand Up @@ -413,6 +414,14 @@ class TargetCodeGenInfo {
return nullptr;
}

static void
setBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI,
llvm::Function &F);

static void
setBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI,
llvm::AttrBuilder &FuncAttrs);

protected:
static std::string qualifyWindowsLibrary(StringRef Lib);

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
}
}
auto *Fn = cast<llvm::Function>(GV);
BPI.setFnAttributes(*Fn);
setBranchProtectionFnAttributes(BPI, *Fn);
}

bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF,
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/CodeGen/Targets/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,8 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
D->getLocation(),
diag::warn_target_unsupported_branch_protection_attribute)
<< Arch;
} else {
BPI.setFnAttributes(*Fn);
}
} else
setBranchProtectionFnAttributes(BPI, (*Fn));
} else if (CGM.getLangOpts().BranchTargetEnforcement ||
CGM.getLangOpts().hasSignReturnAddress()) {
// If the Branch Protection attribute is missing, validate the target
Expand All @@ -168,7 +167,7 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
} else if (CGM.getTarget().isBranchProtectionSupportedArch(
CGM.getTarget().getTargetOpts().CPU)) {
TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts());
BPI.setFnAttributes(*Fn);
setBranchProtectionFnAttributes(BPI, (*Fn));
}

const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();
Expand Down
12 changes: 9 additions & 3 deletions clang/lib/CodeGen/Targets/NVPTX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,11 @@ ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const {
void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const {
if (!getCXXABI().classifyReturnType(FI))
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
for (auto &I : FI.arguments())
I.info = classifyArgumentType(I.type);

for (auto &&[ArgumentsCount, I] : llvm::enumerate(FI.arguments()))
I.info = ArgumentsCount < FI.getNumRequiredArgs()
? classifyArgumentType(I.type)
: ABIArgInfo::getDirect();

// Always honor user-specified calling convention.
if (FI.getCallingConvention() != llvm::CallingConv::C)
Expand All @@ -215,7 +218,10 @@ void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const {

RValue NVPTXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty, AggValueSlot Slot) const {
llvm_unreachable("NVPTX does not support varargs");
return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*IsIndirect=*/false,
getContext().getTypeInfoInChars(Ty),
CharUnits::fromQuantity(1),
/*AllowHigherAlign=*/true, Slot);
}

void NVPTXTargetCodeGenInfo::setTargetAttributes(
Expand Down
42 changes: 31 additions & 11 deletions clang/lib/Driver/ToolChains/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
if (!getArchFeatures(D, MArch, Features, Args))
return;

bool CPUFastUnaligned = false;
bool CPUFastScalarUnaligned = false;
bool CPUFastVectorUnaligned = false;

// If users give march and mcpu, get std extension feature from MArch
// and other features (ex. mirco architecture feature) from mcpu
Expand All @@ -88,8 +89,10 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,

getRISCFeaturesFromMcpu(D, A, Triple, CPU, Features);

if (llvm::RISCV::hasFastUnalignedAccess(CPU))
CPUFastUnaligned = true;
if (llvm::RISCV::hasFastScalarUnalignedAccess(CPU))
CPUFastScalarUnaligned = true;
if (llvm::RISCV::hasFastVectorUnalignedAccess(CPU))
CPUFastVectorUnaligned = true;
}

// Handle features corresponding to "-ffixed-X" options
Expand Down Expand Up @@ -169,20 +172,37 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
Features.push_back("-relax");
}

// If -mstrict-align or -mno-strict-align is passed, use it. Otherwise, the
// unaligned-*-mem is enabled if the CPU supports it or the target is
// If -mstrict-align, -mno-strict-align, -mscalar-strict-align, or
// -mno-scalar-strict-align is passed, use it. Otherwise, the
// unaligned-scalar-mem is enabled if the CPU supports it or the target is
// Android.
if (const Arg *A = Args.getLastArg(options::OPT_mno_strict_align,
options::OPT_mstrict_align)) {
if (A->getOption().matches(options::OPT_mno_strict_align)) {
if (const Arg *A = Args.getLastArg(
options::OPT_mno_strict_align, options::OPT_mscalar_strict_align,
options::OPT_mstrict_align, options::OPT_mno_scalar_strict_align)) {
if (A->getOption().matches(options::OPT_mno_strict_align) ||
A->getOption().matches(options::OPT_mno_scalar_strict_align)) {
Features.push_back("+unaligned-scalar-mem");
Features.push_back("+unaligned-vector-mem");
} else {
Features.push_back("-unaligned-scalar-mem");
Features.push_back("-unaligned-vector-mem");
}
} else if (CPUFastUnaligned || Triple.isAndroid()) {
} else if (CPUFastScalarUnaligned || Triple.isAndroid()) {
Features.push_back("+unaligned-scalar-mem");
}

// If -mstrict-align, -mno-strict-align, -mvector-strict-align, or
// -mno-vector-strict-align is passed, use it. Otherwise, the
// unaligned-vector-mem is enabled if the CPU supports it or the target is
// Android.
if (const Arg *A = Args.getLastArg(
options::OPT_mno_strict_align, options::OPT_mvector_strict_align,
options::OPT_mstrict_align, options::OPT_mno_vector_strict_align)) {
if (A->getOption().matches(options::OPT_mno_strict_align) ||
A->getOption().matches(options::OPT_mno_vector_strict_align)) {
Features.push_back("+unaligned-vector-mem");
} else {
Features.push_back("-unaligned-vector-mem");
}
} else if (CPUFastVectorUnaligned || Triple.isAndroid()) {
Features.push_back("+unaligned-vector-mem");
}

Expand Down
8 changes: 1 addition & 7 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3815,12 +3815,6 @@ static void RenderBuiltinOptions(const ToolChain &TC, const llvm::Triple &T,
if (UseBuiltins)
A->render(Args, CmdArgs);
}

// le32-specific flags:
// -fno-math-builtin: clang should not convert math builtins to intrinsics
// by default.
if (TC.getArch() == llvm::Triple::le32)
CmdArgs.push_back("-fno-math-builtin");
}

bool Driver::getDefaultModuleCachePath(SmallVectorImpl<char> &Result) {
Expand Down Expand Up @@ -5825,7 +5819,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}

// If toolchain choose to use MCAsmParser for inline asm don't pass the
// option to disable integrated-as explictly.
// option to disable integrated-as explicitly.
if (!TC.useIntegratedAs() && !TC.parseInlineAsmUsingAsmParser())
CmdArgs.push_back("-no-integrated-as");

Expand Down
163 changes: 84 additions & 79 deletions clang/lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,87 @@ class CastExpressionIdValidator final : public CorrectionCandidateCallback {
};
}

bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II,
tok::TokenKind *Kind) {
if (RevertibleTypeTraits.empty()) {
#define RTT_JOIN(X, Y) X##Y
#define REVERTIBLE_TYPE_TRAIT(Name) \
RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] = RTT_JOIN(tok::kw_, Name)

REVERTIBLE_TYPE_TRAIT(__is_abstract);
REVERTIBLE_TYPE_TRAIT(__is_aggregate);
REVERTIBLE_TYPE_TRAIT(__is_arithmetic);
REVERTIBLE_TYPE_TRAIT(__is_array);
REVERTIBLE_TYPE_TRAIT(__is_assignable);
REVERTIBLE_TYPE_TRAIT(__is_base_of);
REVERTIBLE_TYPE_TRAIT(__is_bounded_array);
REVERTIBLE_TYPE_TRAIT(__is_class);
REVERTIBLE_TYPE_TRAIT(__is_complete_type);
REVERTIBLE_TYPE_TRAIT(__is_compound);
REVERTIBLE_TYPE_TRAIT(__is_const);
REVERTIBLE_TYPE_TRAIT(__is_constructible);
REVERTIBLE_TYPE_TRAIT(__is_convertible);
REVERTIBLE_TYPE_TRAIT(__is_convertible_to);
REVERTIBLE_TYPE_TRAIT(__is_destructible);
REVERTIBLE_TYPE_TRAIT(__is_empty);
REVERTIBLE_TYPE_TRAIT(__is_enum);
REVERTIBLE_TYPE_TRAIT(__is_floating_point);
REVERTIBLE_TYPE_TRAIT(__is_final);
REVERTIBLE_TYPE_TRAIT(__is_function);
REVERTIBLE_TYPE_TRAIT(__is_fundamental);
REVERTIBLE_TYPE_TRAIT(__is_integral);
REVERTIBLE_TYPE_TRAIT(__is_interface_class);
REVERTIBLE_TYPE_TRAIT(__is_layout_compatible);
REVERTIBLE_TYPE_TRAIT(__is_literal);
REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr);
REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference);
REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer);
REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer);
REVERTIBLE_TYPE_TRAIT(__is_member_pointer);
REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable);
REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible);
REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible);
REVERTIBLE_TYPE_TRAIT(__is_nullptr);
REVERTIBLE_TYPE_TRAIT(__is_object);
REVERTIBLE_TYPE_TRAIT(__is_pod);
REVERTIBLE_TYPE_TRAIT(__is_pointer);
REVERTIBLE_TYPE_TRAIT(__is_polymorphic);
REVERTIBLE_TYPE_TRAIT(__is_reference);
REVERTIBLE_TYPE_TRAIT(__is_referenceable);
REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr);
REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference);
REVERTIBLE_TYPE_TRAIT(__is_same);
REVERTIBLE_TYPE_TRAIT(__is_scalar);
REVERTIBLE_TYPE_TRAIT(__is_scoped_enum);
REVERTIBLE_TYPE_TRAIT(__is_sealed);
REVERTIBLE_TYPE_TRAIT(__is_signed);
REVERTIBLE_TYPE_TRAIT(__is_standard_layout);
REVERTIBLE_TYPE_TRAIT(__is_trivial);
REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable);
REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible);
REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable);
REVERTIBLE_TYPE_TRAIT(__is_unbounded_array);
REVERTIBLE_TYPE_TRAIT(__is_union);
REVERTIBLE_TYPE_TRAIT(__is_unsigned);
REVERTIBLE_TYPE_TRAIT(__is_void);
REVERTIBLE_TYPE_TRAIT(__is_volatile);
REVERTIBLE_TYPE_TRAIT(__reference_binds_to_temporary);
#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait));
#include "clang/Basic/TransformTypeTraits.def"
#undef REVERTIBLE_TYPE_TRAIT
#undef RTT_JOIN
}
llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known =
RevertibleTypeTraits.find(II);
if (Known != RevertibleTypeTraits.end()) {
if (Kind)
*Kind = Known->second;
return true;
}
return false;
}

/// Parse a cast-expression, or, if \pisUnaryExpression is true, parse
/// a unary-expression.
///
Expand Down Expand Up @@ -1118,85 +1199,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
else if (Next.is(tok::l_paren) && Tok.is(tok::identifier) &&
Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) {
IdentifierInfo *II = Tok.getIdentifierInfo();
// Build up the mapping of revertible type traits, for future use.
if (RevertibleTypeTraits.empty()) {
#define RTT_JOIN(X,Y) X##Y
#define REVERTIBLE_TYPE_TRAIT(Name) \
RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \
= RTT_JOIN(tok::kw_,Name)

REVERTIBLE_TYPE_TRAIT(__is_abstract);
REVERTIBLE_TYPE_TRAIT(__is_aggregate);
REVERTIBLE_TYPE_TRAIT(__is_arithmetic);
REVERTIBLE_TYPE_TRAIT(__is_array);
REVERTIBLE_TYPE_TRAIT(__is_assignable);
REVERTIBLE_TYPE_TRAIT(__is_base_of);
REVERTIBLE_TYPE_TRAIT(__is_bounded_array);
REVERTIBLE_TYPE_TRAIT(__is_class);
REVERTIBLE_TYPE_TRAIT(__is_complete_type);
REVERTIBLE_TYPE_TRAIT(__is_compound);
REVERTIBLE_TYPE_TRAIT(__is_const);
REVERTIBLE_TYPE_TRAIT(__is_constructible);
REVERTIBLE_TYPE_TRAIT(__is_convertible);
REVERTIBLE_TYPE_TRAIT(__is_convertible_to);
REVERTIBLE_TYPE_TRAIT(__is_destructible);
REVERTIBLE_TYPE_TRAIT(__is_empty);
REVERTIBLE_TYPE_TRAIT(__is_enum);
REVERTIBLE_TYPE_TRAIT(__is_floating_point);
REVERTIBLE_TYPE_TRAIT(__is_final);
REVERTIBLE_TYPE_TRAIT(__is_function);
REVERTIBLE_TYPE_TRAIT(__is_fundamental);
REVERTIBLE_TYPE_TRAIT(__is_integral);
REVERTIBLE_TYPE_TRAIT(__is_interface_class);
REVERTIBLE_TYPE_TRAIT(__is_layout_compatible);
REVERTIBLE_TYPE_TRAIT(__is_literal);
REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr);
REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference);
REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer);
REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer);
REVERTIBLE_TYPE_TRAIT(__is_member_pointer);
REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable);
REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible);
REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible);
REVERTIBLE_TYPE_TRAIT(__is_nullptr);
REVERTIBLE_TYPE_TRAIT(__is_object);
REVERTIBLE_TYPE_TRAIT(__is_pod);
REVERTIBLE_TYPE_TRAIT(__is_pointer);
REVERTIBLE_TYPE_TRAIT(__is_polymorphic);
REVERTIBLE_TYPE_TRAIT(__is_reference);
REVERTIBLE_TYPE_TRAIT(__is_referenceable);
REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr);
REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference);
REVERTIBLE_TYPE_TRAIT(__is_same);
REVERTIBLE_TYPE_TRAIT(__is_scalar);
REVERTIBLE_TYPE_TRAIT(__is_scoped_enum);
REVERTIBLE_TYPE_TRAIT(__is_sealed);
REVERTIBLE_TYPE_TRAIT(__is_signed);
REVERTIBLE_TYPE_TRAIT(__is_standard_layout);
REVERTIBLE_TYPE_TRAIT(__is_trivial);
REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable);
REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible);
REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable);
REVERTIBLE_TYPE_TRAIT(__is_unbounded_array);
REVERTIBLE_TYPE_TRAIT(__is_union);
REVERTIBLE_TYPE_TRAIT(__is_unsigned);
REVERTIBLE_TYPE_TRAIT(__is_void);
REVERTIBLE_TYPE_TRAIT(__is_volatile);
REVERTIBLE_TYPE_TRAIT(__reference_binds_to_temporary);
#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait));
#include "clang/Basic/TransformTypeTraits.def"
#undef REVERTIBLE_TYPE_TRAIT
#undef RTT_JOIN
}

// If we find that this is in fact the name of a type trait,
// update the token kind in place and parse again to treat it as
// the appropriate kind of type trait.
llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known
= RevertibleTypeTraits.find(II);
if (Known != RevertibleTypeTraits.end()) {
Tok.setKind(Known->second);
tok::TokenKind Kind;
if (isRevertibleTypeTrait(II, &Kind)) {
Tok.setKind(Kind);
return ParseCastExpression(ParseKind, isAddressOfOperand,
NotCastExpr, isTypeCast,
isVectorLiteral, NotPrimaryExpression);
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/Parse/ParseTentative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,15 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
if (!getLangOpts().ObjC && Next.is(tok::identifier))
return TPResult::True;

// If this identifier was reverted from a token ID, and the next token
// is a '(', we assume it to be a use of a type trait, so this
// can never be a type name.
if (Next.is(tok::l_paren) &&
Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier() &&
isRevertibleTypeTrait(Tok.getIdentifierInfo())) {
return TPResult::False;
}

if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
// Determine whether this is a valid expression. If not, we will hit
// a parse error one way or another. In that case, tell the caller that
Expand Down
13 changes: 7 additions & 6 deletions clang/lib/Sema/HLSLExternalSemaSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,14 @@ struct BuiltinTypeDeclBuilder {
return addMemberVariable("h", Ty, Access);
}

BuiltinTypeDeclBuilder &annotateResourceClass(ResourceClass RC,
ResourceKind RK, bool IsROV) {
BuiltinTypeDeclBuilder &annotateHLSLResource(ResourceClass RC,
ResourceKind RK, bool IsROV) {
if (Record->isCompleteDefinition())
return *this;
Record->addAttr(HLSLResourceAttr::CreateImplicit(Record->getASTContext(),
RC, RK, IsROV));
Record->addAttr(
HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC));
Record->addAttr(
HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK, IsROV));
return *this;
}

Expand Down Expand Up @@ -171,7 +173,6 @@ struct BuiltinTypeDeclBuilder {

DeclRefExpr *Fn =
lookupBuiltinFunction(AST, S, "__builtin_hlsl_create_handle");

Expr *RCExpr = emitResourceClassExpr(AST, RC);
Expr *Call = CallExpr::Create(AST, Fn, {RCExpr}, AST.VoidPtrTy, VK_PRValue,
SourceLocation(), FPOptionsOverride());
Expand Down Expand Up @@ -496,7 +497,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
return BuiltinTypeDeclBuilder(Decl)
.addHandleMember()
.addDefaultHandleConstructor(S, RC)
.annotateResourceClass(RC, RK, IsROV);
.annotateHLSLResource(RC, RK, IsROV);
}

void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
Expand Down
33 changes: 15 additions & 18 deletions clang/lib/Sema/SemaConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
char *Mem = new (S.Context) char[MessageSize];
memcpy(Mem, DiagString.c_str(), MessageSize);
Satisfaction.Details.emplace_back(
ConstraintExpr,
new (S.Context) ConstraintSatisfaction::SubstitutionDiagnostic{
SubstitutedAtomicExpr.get()->getBeginLoc(),
StringRef(Mem, MessageSize)});
Expand Down Expand Up @@ -302,8 +301,7 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
"evaluating bool expression didn't produce int");
Satisfaction.IsSatisfied = EvalResult.Val.getInt().getBoolValue();
if (!Satisfaction.IsSatisfied)
Satisfaction.Details.emplace_back(ConstraintExpr,
SubstitutedAtomicExpr.get());
Satisfaction.Details.emplace_back(SubstitutedAtomicExpr.get());

return SubstitutedAtomicExpr;
}
Expand Down Expand Up @@ -393,9 +391,8 @@ static ExprResult calculateConstraintSatisfaction(
char *Mem = new (S.Context) char[MessageSize];
memcpy(Mem, DiagString.c_str(), MessageSize);
Satisfaction.Details.emplace_back(
AtomicExpr,
new (S.Context) ConstraintSatisfaction::SubstitutionDiagnostic{
SubstDiag.first, StringRef(Mem, MessageSize)});
SubstDiag.first, StringRef(Mem, MessageSize)});
Satisfaction.IsSatisfied = false;
return ExprEmpty();
}
Expand Down Expand Up @@ -1056,13 +1053,14 @@ static void diagnoseUnsatisfiedRequirement(Sema &S,
concepts::NestedRequirement *Req,
bool First) {
using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
for (auto &Pair : Req->getConstraintSatisfaction()) {
if (auto *SubstDiag = Pair.second.dyn_cast<SubstitutionDiagnostic *>())
for (auto &Record : Req->getConstraintSatisfaction()) {
if (auto *SubstDiag = Record.dyn_cast<SubstitutionDiagnostic *>())
S.Diag(SubstDiag->first, diag::note_nested_requirement_substitution_error)
<< (int)First << Req->getInvalidConstraintEntity() << SubstDiag->second;
<< (int)First << Req->getInvalidConstraintEntity()
<< SubstDiag->second;
else
diagnoseWellFormedUnsatisfiedConstraintExpr(
S, Pair.second.dyn_cast<Expr *>(), First);
diagnoseWellFormedUnsatisfiedConstraintExpr(S, Record.dyn_cast<Expr *>(),
First);
First = false;
}
}
Expand Down Expand Up @@ -1176,12 +1174,11 @@ static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S,
<< (int)First << SubstExpr;
}

template<typename SubstitutionDiagnostic>
template <typename SubstitutionDiagnostic>
static void diagnoseUnsatisfiedConstraintExpr(
Sema &S, const Expr *E,
const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record,
Sema &S, const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record,
bool First = true) {
if (auto *Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()){
if (auto *Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()) {
S.Diag(Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
<< Diag->second;
return;
Expand All @@ -1196,8 +1193,8 @@ Sema::DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction,
bool First) {
assert(!Satisfaction.IsSatisfied &&
"Attempted to diagnose a satisfied constraint");
for (auto &Pair : Satisfaction.Details) {
diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
for (auto &Record : Satisfaction.Details) {
diagnoseUnsatisfiedConstraintExpr(*this, Record, First);
First = false;
}
}
Expand All @@ -1207,8 +1204,8 @@ void Sema::DiagnoseUnsatisfiedConstraint(
bool First) {
assert(!Satisfaction.IsSatisfied &&
"Attempted to diagnose a satisfied constraint");
for (auto &Pair : Satisfaction) {
diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
for (auto &Record : Satisfaction) {
diagnoseUnsatisfiedConstraintExpr(*this, Record, First);
First = false;
}
}
Expand Down
11 changes: 10 additions & 1 deletion clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1676,6 +1676,15 @@ bool Sema::CheckRedeclarationExported(NamedDecl *New, NamedDecl *Old) {
if (IsOldExported)
return false;

// If the Old declaration are not attached to named modules
// and the New declaration are attached to global module.
// It should be fine to allow the export since it doesn't change
// the linkage of declarations. See
// https://github.com/llvm/llvm-project/issues/98583 for details.
if (!Old->isInNamedModule() && New->getOwningModule() &&
New->getOwningModule()->isImplicitGlobalModule())
return false;

assert(IsNewExported);

auto Lk = Old->getFormalLinkage();
Expand Down Expand Up @@ -10094,7 +10103,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// check at the end of the TU (or when the PMF starts) to see that we
// have a definition at that point.
if (isInline && !D.isFunctionDefinition() && getLangOpts().CPlusPlus20 &&
NewFD->hasOwningModule() && NewFD->getOwningModule()->isNamedModule()) {
NewFD->isInNamedModule()) {
PendingInlineFuncDecls.insert(NewFD);
}
}
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7053,6 +7053,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_HLSLResourceBinding:
S.HLSL().handleResourceBindingAttr(D, AL);
break;
case ParsedAttr::AT_HLSLResourceClass:
S.HLSL().handleResourceClassAttr(D, AL);
break;
case ParsedAttr::AT_HLSLParamModifier:
S.HLSL().handleParamModifierAttr(D, AL);
break;
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9070,7 +9070,10 @@ ComputeDefaultedComparisonExceptionSpec(Sema &S, SourceLocation Loc,
EnterExpressionEvaluationContext Context(
S, Sema::ExpressionEvaluationContext::Unevaluated);

CXXRecordDecl *RD = cast<CXXRecordDecl>(FD->getLexicalParent());
CXXRecordDecl *RD =
cast<CXXRecordDecl>(FD->getFriendObjectKind() == Decl::FOK_None
? FD->getDeclContext()
: FD->getLexicalDeclContext());
SourceLocation BodyLoc =
FD->getEndLoc().isValid() ? FD->getEndLoc() : FD->getLocation();
StmtResult Body =
Expand Down
Loading