9 changes: 5 additions & 4 deletions clang-tools-extra/clangd/unittests/InlayHintTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace clangd {

llvm::raw_ostream &operator<<(llvm::raw_ostream &Stream,
const InlayHint &Hint) {
return Stream << Hint.label << "@" << Hint.range;
return Stream << Hint.joinLabels() << "@" << Hint.range;
}

namespace {
Expand Down Expand Up @@ -57,10 +57,11 @@ struct ExpectedHint {

MATCHER_P2(HintMatcher, Expected, Code, llvm::to_string(Expected)) {
llvm::StringRef ExpectedView(Expected.Label);
if (arg.label != ExpectedView.trim(" ") ||
std::string ResultLabel = arg.joinLabels();
if (ResultLabel != ExpectedView.trim(" ") ||
arg.paddingLeft != ExpectedView.starts_with(" ") ||
arg.paddingRight != ExpectedView.ends_with(" ")) {
*result_listener << "label is '" << arg.label << "'";
*result_listener << "label is '" << ResultLabel << "'";
return false;
}
if (arg.range != Code.range(Expected.RangeName)) {
Expand All @@ -72,7 +73,7 @@ MATCHER_P2(HintMatcher, Expected, Code, llvm::to_string(Expected)) {
return true;
}

MATCHER_P(labelIs, Label, "") { return arg.label == Label; }
MATCHER_P(labelIs, Label, "") { return arg.joinLabels() == Label; }

Config noHintsConfig() {
Config C;
Expand Down
31 changes: 21 additions & 10 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,13 @@ Changes in existing checks
<clang-tidy/checks/cppcoreguidelines/owning-memory>` check to properly handle
return type in lambdas and in nested functions.

- Cleaned up :doc:`cppcoreguidelines-prefer-member-initializer
<clang-tidy/checks/cppcoreguidelines/prefer-member-initializer>`
- Improved :doc:`cppcoreguidelines-prefer-member-initializer
<clang-tidy/checks/cppcoreguidelines/prefer-member-initializer>` check
by removing enforcement of rule `C.48
<https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c48-prefer-in-class-initializers-to-member-initializers-in-constructors-for-constant-initializers>`_,
which was deprecated since :program:`clang-tidy` 17. This rule is now covered
by :doc:`cppcoreguidelines-use-default-member-init
<clang-tidy/checks/cppcoreguidelines/use-default-member-init>` and fixes
<clang-tidy/checks/cppcoreguidelines/use-default-member-init>`. Fixed
incorrect hints when using list-initialization.

- Improved :doc:`google-build-namespaces
Expand All @@ -201,6 +201,9 @@ Changes in existing checks
<clang-tidy/checks/google/global-names-in-headers>` check by replacing the local
option `HeaderFileExtensions` by the global option of the same name.

- Improved :doc:`google-runtime-int <clang-tidy/checks/google/runtime-int>`
check performance through optimizations.

- Improved :doc:`llvm-header-guard
<clang-tidy/checks/llvm/header-guard>` check by replacing the local
option `HeaderFileExtensions` by the global option of the same name.
Expand Down Expand Up @@ -233,12 +236,20 @@ Changes in existing checks
<clang-tidy/checks/modernize/use-override>` check to also remove any trailing
whitespace when deleting the ``virtual`` keyword.

- Improved :doc:`modernize-use-using <clang-tidy/checks/modernize/use-using>`
check by adding support for detection of typedefs declared on function level.

- Improved :doc:`performance-unnecessary-copy-initialization
<clang-tidy/checks/performance/unnecessary-copy-initialization>` check by
detecting more cases of constant access. In particular, pointers can be
analyzed, se the check now handles the common patterns
`const auto e = (*vector_ptr)[i]` and `const auto e = vector_ptr->at(i);`.

- Improved :doc:`readability-identifier-naming
<clang-tidy/checks/readability/identifier-naming>` check in `GetConfigPerFile`
mode by resolving symbolic links to header files. Fixed handling of Hungarian
Prefix when configured to `LowerCase`.

- Improved :doc:`readability-implicit-bool-conversion
<clang-tidy/checks/readability/implicit-bool-conversion>` check to provide
valid fix suggestions for ``static_cast`` without a preceding space and
Expand All @@ -248,10 +259,10 @@ Changes in existing checks
<clang-tidy/checks/readability/redundant-inline-specifier>` check to properly
emit warnings for static data member with an in-class initializer.

- Improved :doc:`readability-identifier-naming
<clang-tidy/checks/readability/identifier-naming>` check in `GetConfigPerFile`
mode by resolving symbolic links to header files. Fixed handling of Hungarian
Prefix when configured to `LowerCase`.
- Improved :doc:`readability-static-definition-in-anonymous-namespace
<clang-tidy/checks/readability/static-definition-in-anonymous-namespace>`
check by resolving fix-it overlaps in template code by disregarding implicit
instances.

Removed checks
^^^^^^^^^^^^^^
Expand All @@ -262,9 +273,9 @@ Removed checks
Miscellaneous
^^^^^^^^^^^^^

- Fixed incorrect formatting in ``clang-apply-replacements`` when no ``--format``
option is specified. Now ``clang-apply-replacements`` applies formatting only with
the option.
- Fixed incorrect formatting in :program:`clang-apply-replacements` when no
``--format`` option is specified. Now :program:`clang-apply-replacements`
applies formatting only with the option.

Improvements to include-fixer
-----------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %check_clang_tidy %s modernize-use-using %t -- -- -I %S/Inputs/use-using/
// RUN: %check_clang_tidy %s modernize-use-using %t -- -- -fno-delayed-template-parsing -I %S/Inputs/use-using/

typedef int Type;
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
Expand Down Expand Up @@ -342,3 +342,44 @@ typedef int InExternCPP;
// CHECK-FIXES: using InExternCPP = int;

}

namespace ISSUE_72179
{
void foo()
{
typedef int a;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'using' instead of 'typedef' [modernize-use-using]
// CHECK-FIXES: using a = int;

}

void foo2()
{
typedef struct { int a; union { int b; }; } c;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'using' instead of 'typedef' [modernize-use-using]
// CHECK-FIXES: using c = struct { int a; union { int b; }; };
}

template <typename T>
void foo3()
{
typedef T b;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'using' instead of 'typedef' [modernize-use-using]
// CHECK-FIXES: using b = T;
}

template <typename T>
class MyClass
{
void foo()
{
typedef MyClass c;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'using' instead of 'typedef' [modernize-use-using]
// CHECK-FIXES: using c = MyClass;
}
};

const auto foo4 = [](int a){typedef int d;};
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use 'using' instead of 'typedef' [modernize-use-using]
// CHECK-FIXES: const auto foo4 = [](int a){using d = int;};
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ static int c = 1;
} // namespace deep_inner
} // namespace inner

template<typename T>
static void printTemplate(T&&) {}
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: 'printTemplate' is a static definition in anonymous namespace; static is redundant here [readability-static-definition-in-anonymous-namespace]
// CHECK-FIXES: {{^}}void printTemplate(T&&) {}

void testTemplate() {
printTemplate(5);
printTemplate(5U);
printTemplate("some string");
}

} // namespace

namespace N {
Expand Down
2 changes: 2 additions & 0 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5420,10 +5420,12 @@ The following builtin intrinsics can be used in constant expressions:
* ``__builtin_clzl``
* ``__builtin_clzll``
* ``__builtin_clzs``
* ``__builtin_clzg``
* ``__builtin_ctz``
* ``__builtin_ctzl``
* ``__builtin_ctzll``
* ``__builtin_ctzs``
* ``__builtin_ctzg``
* ``__builtin_ffs``
* ``__builtin_ffsl``
* ``__builtin_ffsll``
Expand Down
14 changes: 14 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ Non-comprehensive list of changes in this release

- Lambda expressions are now accepted in C++03 mode as an extension.

- Added ``__builtin_clzg`` and ``__builtin_ctzg`` as type-generic alternatives
to ``__builtin_clz{,s,l,ll}`` and ``__builtin_ctz{,s,l,ll}`` respectively,
with support for any unsigned integer type. Like the previous builtins, these
new builtins are constexpr and may be used in constant expressions.

New Compiler Flags
------------------

Expand Down Expand Up @@ -295,6 +300,10 @@ Improvements to Clang's diagnostics
- Clang now correctly diagnoses no arguments to a variadic macro parameter as a C23/C++20 extension.
Fixes #GH84495.

- Clang no longer emits a ``-Wexit-time destructors`` warning on static variables explicitly
annotated with the ``clang::always_destroy`` attribute.
Fixes #GH68686, #GH86486

Improvements to Clang's time-trace
----------------------------------

Expand Down Expand Up @@ -445,6 +454,7 @@ Bug Fixes to C++ Support
- Fix a crash when instantiating a lambda that captures ``this`` outside of its context. Fixes (#GH85343).
- Fix an issue where a namespace alias could be defined using a qualified name (all name components
following the first `::` were ignored).
- Fix an out-of-bounds crash when checking the validity of template partial specializations. (part of #GH86757).

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -617,6 +627,10 @@ Sanitizers
manually disable potentially noisy signed integer overflow checks with
``-fno-sanitize=signed-integer-overflow``

- ``-fsanitize=cfi -fsanitize-cfi-cross-dso`` (cross-DSO CFI instrumentation)
now generates the ``__cfi_check`` function with proper target-specific
attributes, for example allowing unwind table generation.

Python Binding Changes
----------------------

Expand Down
60 changes: 47 additions & 13 deletions clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2441,20 +2441,39 @@ usual build cycle when using sample profilers for optimization:

1. Build the code with source line table information. You can use all the
usual build flags that you always build your application with. The only
requirement is that you add ``-gline-tables-only`` or ``-g`` to the
command line. This is important for the profiler to be able to map
instructions back to source line locations.
requirement is that DWARF debug info including source line information is
generated. This DWARF information is important for the profiler to be able
to map instructions back to source line locations.

On Linux, ``-g`` or just ``-gline-tables-only`` is sufficient:

.. code-block:: console
$ clang++ -O2 -gline-tables-only code.cc -o code
While MSVC-style targets default to CodeView debug information, DWARF debug
information is required to generate source-level LLVM profiles. Use
``-gdwarf`` to include DWARF debug information:

.. code-block:: console
$ clang-cl -O2 -gdwarf -gline-tables-only coff-profile.cpp -fuse-ld=lld -link -debug:dwarf
2. Run the executable under a sampling profiler. The specific profiler
you use does not really matter, as long as its output can be converted
into the format that the LLVM optimizer understands. Currently, there
exists a conversion tool for the Linux Perf profiler
(https://perf.wiki.kernel.org/), so these examples assume that you
are using Linux Perf to profile your code.
into the format that the LLVM optimizer understands.

Two such profilers are the the Linux Perf profiler
(https://perf.wiki.kernel.org/) and Intel's Sampling Enabling Product (SEP),
available as part of `Intel VTune
<https://software.intel.com/content/www/us/en/develop/tools/oneapi/components/vtune-profiler.html>`_.
While Perf is Linux-specific, SEP can be used on Linux, Windows, and FreeBSD.

The LLVM tool ``llvm-profgen`` can convert output of either Perf or SEP. An
external project, `AutoFDO <https://github.com/google/autofdo>`_, also
provides a ``create_llvm_prof`` tool which supports Linux Perf output.

When using Perf:

.. code-block:: console
Expand All @@ -2465,11 +2484,19 @@ usual build cycle when using sample profilers for optimization:
it provides better call information, which improves the accuracy of
the profile data.

3. Convert the collected profile data to LLVM's sample profile format.
This is currently supported via the AutoFDO converter ``create_llvm_prof``.
It is available at https://github.com/google/autofdo. Once built and
installed, you can convert the ``perf.data`` file to LLVM using
the command:
When using SEP:

.. code-block:: console
$ sep -start -out code.tb7 -ec BR_INST_RETIRED.NEAR_TAKEN:precise=yes:pdir -lbr no_filter:usr -perf-script brstack -app ./code
This produces a ``code.perf.data.script`` output which can be used with
``llvm-profgen``'s ``--perfscript`` input option.

3. Convert the collected profile data to LLVM's sample profile format. This is
currently supported via the `AutoFDO <https://github.com/google/autofdo>`_
converter ``create_llvm_prof``. Once built and installed, you can convert
the ``perf.data`` file to LLVM using the command:

.. code-block:: console
Expand All @@ -2485,7 +2512,14 @@ usual build cycle when using sample profilers for optimization:

.. code-block:: console
$ llvm-profgen --binary=./code --output=code.prof--perfdata=perf.data
$ llvm-profgen --binary=./code --output=code.prof --perfdata=perf.data
When using SEP the output is in the textual format corresponding to
``llvm-profgen --perfscript``. For example:

.. code-block:: console
$ llvm-profgen --binary=./code --output=code.prof --perfscript=code.perf.data.script
4. Build the code again using the collected profile. This step feeds
Expand Down
83 changes: 81 additions & 2 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -849,10 +849,89 @@ Check for performance anti-patterns when using Grand Central Dispatch.
.. _optin-performance-Padding:
optin.performance.Padding
"""""""""""""""""""""""""
optin.performance.Padding (C, C++, ObjC)
""""""""""""""""""""""""""""""""""""""""
Check for excessively padded structs.
This checker detects structs with excessive padding, which can lead to wasted
memory thus decreased performance by reducing the effectiveness of the
processor cache. Padding bytes are added by compilers to align data accesses
as some processors require data to be aligned to certain boundaries. On others,
unaligned data access are possible, but impose significantly larger latencies.
To avoid padding bytes, the fields of a struct should be ordered by decreasing
by alignment. Usually, its easier to think of the ``sizeof`` of the fields, and
ordering the fields by ``sizeof`` would usually also lead to the same optimal
layout.
In rare cases, one can use the ``#pragma pack(1)`` directive to enforce a packed
layout too, but it can significantly increase the access times, so reordering the
fields is usually a better solution.
.. code-block:: cpp
// warn: Excessive padding in 'struct NonOptimal' (35 padding bytes, where 3 is optimal)
struct NonOptimal {
char c1;
// 7 bytes of padding
std::int64_t big1; // 8 bytes
char c2;
// 7 bytes of padding
std::int64_t big2; // 8 bytes
char c3;
// 7 bytes of padding
std::int64_t big3; // 8 bytes
char c4;
// 7 bytes of padding
std::int64_t big4; // 8 bytes
char c5;
// 7 bytes of padding
};
static_assert(sizeof(NonOptimal) == 4*8+5+5*7);
// no-warning: The fields are nicely aligned to have the minimal amount of padding bytes.
struct Optimal {
std::int64_t big1; // 8 bytes
std::int64_t big2; // 8 bytes
std::int64_t big3; // 8 bytes
std::int64_t big4; // 8 bytes
char c1;
char c2;
char c3;
char c4;
char c5;
// 3 bytes of padding
};
static_assert(sizeof(Optimal) == 4*8+5+3);
// no-warning: Bit packing representation is also accepted by this checker, but
// it can significantly increase access times, so prefer reordering the fields.
#pragma pack(1)
struct BitPacked {
char c1;
std::int64_t big1; // 8 bytes
char c2;
std::int64_t big2; // 8 bytes
char c3;
std::int64_t big3; // 8 bytes
char c4;
std::int64_t big4; // 8 bytes
char c5;
};
static_assert(sizeof(BitPacked) == 4*8+5);
The ``AllowedPad`` option can be used to specify a threshold for the number
padding bytes raising the warning. If the number of padding bytes of the struct
and the optimal number of padding bytes differ by more than the threshold value,
a warning will be raised.
By default, the ``AllowedPad`` threshold is 24 bytes.
To override this threshold to e.g. 4 bytes, use the
``-analyzer-config optin.performance.Padding:AllowedPad=4`` option.
.. _optin-portability-UnixAPI:
optin.portability.UnixAPI
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang-c/Index.h
Original file line number Diff line number Diff line change
Expand Up @@ -2991,6 +2991,7 @@ enum CXCallingConv {
CXCallingConv_AArch64SVEPCS = 18,
CXCallingConv_M68kRTD = 19,
CXCallingConv_PreserveNone = 20,
CXCallingConv_RISCVVectorCall = 21,

CXCallingConv_Invalid = 100,
CXCallingConv_Unexposed = 200
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/DeclContextInternals.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ class StoredDeclsList {
Data.setPointer(Head);
}

/// Return an array of all the decls that this list represents.
/// Return the list of all the decls.
DeclContext::lookup_result getLookupResult() const {
return DeclContext::lookup_result(Data.getPointer());
}
Expand Down
108 changes: 84 additions & 24 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -1690,7 +1690,10 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {

/// Whether we have a stored size expression.
LLVM_PREFERRED_TYPE(bool)
unsigned HasStoredSizeExpr : 1;
unsigned HasExternalSize : 1;

LLVM_PREFERRED_TYPE(unsigned)
unsigned SizeWidth : 5;
};

class BuiltinTypeBitfields {
Expand Down Expand Up @@ -3338,35 +3341,93 @@ class ArrayType : public Type, public llvm::FoldingSetNode {
/// Represents the canonical version of C arrays with a specified constant size.
/// For example, the canonical type for 'int A[4 + 4*100]' is a
/// ConstantArrayType where the element type is 'int' and the size is 404.
class ConstantArrayType final
: public ArrayType,
private llvm::TrailingObjects<ConstantArrayType, const Expr *> {
class ConstantArrayType final : public ArrayType {
friend class ASTContext; // ASTContext creates these.
friend TrailingObjects;

llvm::APInt Size; // Allows us to unique the type.
struct ExternalSize {
ExternalSize(const llvm::APInt &Sz, const Expr *SE)
: Size(Sz), SizeExpr(SE) {}
llvm::APInt Size; // Allows us to unique the type.
const Expr *SizeExpr;
};

ConstantArrayType(QualType et, QualType can, const llvm::APInt &size,
const Expr *sz, ArraySizeModifier sm, unsigned tq)
: ArrayType(ConstantArray, et, can, sm, tq, sz), Size(size) {
ConstantArrayTypeBits.HasStoredSizeExpr = sz != nullptr;
if (ConstantArrayTypeBits.HasStoredSizeExpr) {
assert(!can.isNull() && "canonical constant array should not have size");
*getTrailingObjects<const Expr*>() = sz;
}
union {
uint64_t Size;
ExternalSize *SizePtr;
};

ConstantArrayType(QualType Et, QualType Can, uint64_t Width, uint64_t Sz,
ArraySizeModifier SM, unsigned TQ)
: ArrayType(ConstantArray, Et, Can, SM, TQ, nullptr), Size(Sz) {
ConstantArrayTypeBits.HasExternalSize = false;
ConstantArrayTypeBits.SizeWidth = Width / 8;
// The in-structure size stores the size in bytes rather than bits so we
// drop the three least significant bits since they're always zero anyways.
assert(Width < 0xFF && "Type width in bits must be less than 8 bits");
}

unsigned numTrailingObjects(OverloadToken<const Expr*>) const {
return ConstantArrayTypeBits.HasStoredSizeExpr;
ConstantArrayType(QualType Et, QualType Can, ExternalSize *SzPtr,
ArraySizeModifier SM, unsigned TQ)
: ArrayType(ConstantArray, Et, Can, SM, TQ, SzPtr->SizeExpr),
SizePtr(SzPtr) {
ConstantArrayTypeBits.HasExternalSize = true;
ConstantArrayTypeBits.SizeWidth = 0;

assert((SzPtr->SizeExpr == nullptr || !Can.isNull()) &&
"canonical constant array should not have size expression");
}

static ConstantArrayType *Create(const ASTContext &Ctx, QualType ET,
QualType Can, const llvm::APInt &Sz,
const Expr *SzExpr, ArraySizeModifier SzMod,
unsigned Qual);

public:
const llvm::APInt &getSize() const { return Size; }
/// Return the constant array size as an APInt.
llvm::APInt getSize() const {
return ConstantArrayTypeBits.HasExternalSize
? SizePtr->Size
: llvm::APInt(ConstantArrayTypeBits.SizeWidth * 8, Size);
}

/// Return the bit width of the size type.
unsigned getSizeBitWidth() const {
return ConstantArrayTypeBits.HasExternalSize
? SizePtr->Size.getBitWidth()
: static_cast<unsigned>(ConstantArrayTypeBits.SizeWidth * 8);
}

/// Return true if the size is zero.
bool isZeroSize() const {
return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.isZero()
: 0 == Size;
}

/// Return the size zero-extended as a uint64_t.
uint64_t getZExtSize() const {
return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getZExtValue()
: Size;
}

/// Return the size sign-extended as a uint64_t.
int64_t getSExtSize() const {
return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getSExtValue()
: static_cast<int64_t>(Size);
}

/// Return the size zero-extended to uint64_t or UINT64_MAX if the value is
/// larger than UINT64_MAX.
uint64_t getLimitedSize() const {
return ConstantArrayTypeBits.HasExternalSize
? SizePtr->Size.getLimitedValue()
: Size;
}

/// Return a pointer to the size expression.
const Expr *getSizeExpr() const {
return ConstantArrayTypeBits.HasStoredSizeExpr
? *getTrailingObjects<const Expr *>()
: nullptr;
return ConstantArrayTypeBits.HasExternalSize ? SizePtr->SizeExpr : nullptr;
}

bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }

Expand All @@ -3383,14 +3444,13 @@ class ConstantArrayType final
static unsigned getMaxSizeBits(const ASTContext &Context);

void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
Profile(ID, Ctx, getElementType(), getSize(), getSizeExpr(),
Profile(ID, Ctx, getElementType(), getZExtSize(), getSizeExpr(),
getSizeModifier(), getIndexTypeCVRQualifiers());
}

static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx,
QualType ET, const llvm::APInt &ArraySize,
const Expr *SizeExpr, ArraySizeModifier SizeMod,
unsigned TypeQuals);
QualType ET, uint64_t ArraySize, const Expr *SizeExpr,
ArraySizeModifier SizeMod, unsigned TypeQuals);

static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray;
Expand Down
21 changes: 21 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -3011,6 +3011,13 @@ def PreserveNone : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86> {
let Documentation = [PreserveNoneDocs];
}

def RISCVVectorCC: DeclOrTypeAttr, TargetSpecificAttr<TargetRISCV> {
let Spellings = [CXX11<"riscv", "vector_cc">,
C23<"riscv", "vector_cc">,
Clang<"riscv_vector_cc">];
let Documentation = [RISCVVectorCCDocs];
}

def Target : InheritableAttr {
let Spellings = [GCC<"target">];
let Args = [StringArgument<"featuresStr">];
Expand Down Expand Up @@ -3088,6 +3095,20 @@ def TargetClones : InheritableAttr {
StringRef getFeatureStr(unsigned Index) const {
return *(featuresStrs_begin() + Index);
}
bool isDefaultVersion(unsigned Index) const {
return getFeatureStr(Index) == "default";
}
void getFeatures(llvm::SmallVectorImpl<StringRef> &Out,
unsigned Index) const {
if (isDefaultVersion(Index)) return;
StringRef Features = getFeatureStr(Index);
SmallVector<StringRef, 8> AttrFeatures;
Features.split(AttrFeatures, "+");
for (auto &Feature : AttrFeatures) {
Feature = Feature.trim();
Out.push_back(Feature);
}
}
// Given an index into the 'featuresStrs' sequence, compute a unique
// ID to be used with function name mangling for the associated variant.
// This mapping is necessary due to a requirement that the mangling ID
Expand Down
14 changes: 14 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -5494,6 +5494,17 @@ for clang builtin functions.
}];
}

def RISCVVectorCCDocs : Documentation {
let Category = DocCatCallingConvs;
let Heading = "riscv::vector_cc, riscv_vector_cc, clang::riscv_vector_cc";
let Content = [{
The ``riscv_vector_cc`` attribute can be applied to a function. It preserves 15
registers namely, v1-v7 and v24-v31 as callee-saved. Callers thus don't need
to save these registers before function calls, and callees only need to save
them if they use them.
}];
}

def PreferredNameDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
Expand Down Expand Up @@ -6069,6 +6080,9 @@ def AlwaysDestroyDocs : Documentation {
The ``always_destroy`` attribute specifies that a variable with static or thread
storage duration should have its exit-time destructor run. This attribute is the
default unless clang was invoked with -fno-c++-static-destructors.

If a variable is explicitly declared with this attribute, Clang will silence
otherwise applicable ``-Wexit-time-destructors`` warnings.
}];
}

Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ def Clz : Builtin, BitShort_Int_Long_LongLongTemplate {

def Clzg : Builtin {
let Spellings = ["__builtin_clzg"];
let Attributes = [NoThrow, Const, CustomTypeChecking];
let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
let Prototype = "int(...)";
}

Expand All @@ -690,7 +690,7 @@ def Ctz : Builtin, BitShort_Int_Long_LongLongTemplate {

def Ctzg : Builtin {
let Spellings = ["__builtin_ctzg"];
let Attributes = [NoThrow, Const, CustomTypeChecking];
let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
let Prototype = "int(...)";
}

Expand Down
5 changes: 0 additions & 5 deletions clang/include/clang/Basic/BuiltinsAMDGPU.def
Original file line number Diff line number Diff line change
Expand Up @@ -434,13 +434,8 @@ TARGET_BUILTIN(__builtin_amdgcn_s_get_barrier_state, "Uii", "n", "gfx12-insts")

TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b64_v2i32, "V2iV2i*1", "nc", "gfx12-insts,wavefrontsize32")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v8i16, "V8sV8s*1", "nc", "gfx12-insts,wavefrontsize32")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v8f16, "V8hV8h*1", "nc", "gfx12-insts,wavefrontsize32")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v8bf16, "V8yV8y*1", "nc", "gfx12-insts,wavefrontsize32")

TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b64_i32, "ii*1", "nc", "gfx12-insts,wavefrontsize64")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4i16, "V4sV4s*1", "nc", "gfx12-insts,wavefrontsize64")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4f16, "V4hV4h*1", "nc", "gfx12-insts,wavefrontsize64")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4bf16, "V4yV4y*1", "nc", "gfx12-insts,wavefrontsize64")

//===----------------------------------------------------------------------===//
// WMMA builtins.
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def err_no_output_file: Error<"no output file specified">;
def err_no_such_header_file : Error<"no such %select{public|private|project}1 header file: '%0'">;
def warn_no_such_excluded_header_file : Warning<"no such excluded %select{public|private}0 header file: '%1'">, InGroup<InstallAPIViolation>;
def warn_glob_did_not_match: Warning<"glob '%0' did not match any header file">, InGroup<InstallAPIViolation>;
def err_no_such_umbrella_header_file : Error<"%select{public|private|project}1 umbrella header file not found in input: '%0'">;
} // end of command line category.

let CategoryName = "Verification" in {
Expand Down
43 changes: 22 additions & 21 deletions clang/include/clang/Basic/Specifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,29 +273,30 @@ namespace clang {

/// CallingConv - Specifies the calling convention that a function uses.
enum CallingConv {
CC_C, // __attribute__((cdecl))
CC_X86StdCall, // __attribute__((stdcall))
CC_X86FastCall, // __attribute__((fastcall))
CC_X86ThisCall, // __attribute__((thiscall))
CC_X86VectorCall, // __attribute__((vectorcall))
CC_X86Pascal, // __attribute__((pascal))
CC_Win64, // __attribute__((ms_abi))
CC_X86_64SysV, // __attribute__((sysv_abi))
CC_X86RegCall, // __attribute__((regcall))
CC_AAPCS, // __attribute__((pcs("aapcs")))
CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
CC_SpirFunction, // default for OpenCL functions on SPIR target
CC_OpenCLKernel, // inferred for OpenCL kernels
CC_Swift, // __attribute__((swiftcall))
CC_C, // __attribute__((cdecl))
CC_X86StdCall, // __attribute__((stdcall))
CC_X86FastCall, // __attribute__((fastcall))
CC_X86ThisCall, // __attribute__((thiscall))
CC_X86VectorCall, // __attribute__((vectorcall))
CC_X86Pascal, // __attribute__((pascal))
CC_Win64, // __attribute__((ms_abi))
CC_X86_64SysV, // __attribute__((sysv_abi))
CC_X86RegCall, // __attribute__((regcall))
CC_AAPCS, // __attribute__((pcs("aapcs")))
CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
CC_SpirFunction, // default for OpenCL functions on SPIR target
CC_OpenCLKernel, // inferred for OpenCL kernels
CC_Swift, // __attribute__((swiftcall))
CC_SwiftAsync, // __attribute__((swiftasynccall))
CC_PreserveMost, // __attribute__((preserve_most))
CC_PreserveAll, // __attribute__((preserve_all))
CC_PreserveMost, // __attribute__((preserve_most))
CC_PreserveAll, // __attribute__((preserve_all))
CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
CC_AArch64SVEPCS, // __attribute__((aarch64_sve_pcs))
CC_AMDGPUKernelCall, // __attribute__((amdgpu_kernel))
CC_M68kRTD, // __attribute__((m68k_rtd))
CC_PreserveNone, // __attribute__((preserve_none))
CC_AArch64SVEPCS, // __attribute__((aarch64_sve_pcs))
CC_AMDGPUKernelCall, // __attribute__((amdgpu_kernel))
CC_M68kRTD, // __attribute__((m68k_rtd))
CC_PreserveNone, // __attribute__((preserve_none))
CC_RISCVVectorCall, // __attribute__((riscv_vector_cc))
};

/// Checks whether the given calling convention supports variadic
Expand Down
3 changes: 1 addition & 2 deletions clang/include/clang/Basic/SyncScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,7 @@ class AtomicScopeGenericModel : public AtomicScopeModel {
}

bool isValid(unsigned S) const override {
return S >= static_cast<unsigned>(System) &&
S <= static_cast<unsigned>(Last);
return S <= static_cast<unsigned>(Last);
}

ArrayRef<unsigned> getRuntimeValues() const override {
Expand Down
8 changes: 2 additions & 6 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -4105,12 +4105,8 @@ defm strict_return : BoolFOption<"strict-return",
" of a non-void function as unreachable">,
PosFlag<SetTrue>>;

let Group = f_Group in {
let Visibility = [ClangOption,CC1Option] in {
def fptrauth_intrinsics : Flag<["-"], "fptrauth-intrinsics">,
HelpText<"Enable pointer authentication intrinsics">;
}
def fno_ptrauth_intrinsics : Flag<["-"], "fno-ptrauth-intrinsics">;
let Flags = [TargetSpecific] in {
defm ptrauth_intrinsics : OptInCC1FFlag<"ptrauth-intrinsics", "Enable pointer authentication intrinsics">;
}

def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
Expand Down
16 changes: 11 additions & 5 deletions clang/include/clang/InstallAPI/HeaderFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@

namespace clang::installapi {
enum class HeaderType {
/// Unset or unknown type.
Unknown,
/// Represents declarations accessible to all clients.
Public,
/// Represents declarations accessible to a disclosed set of clients.
Private,
/// Represents declarations only accessible as implementation details to the
/// input library.
Project,
/// Unset or unknown type.
Unknown,
};

inline StringRef getName(const HeaderType T) {
Expand Down Expand Up @@ -62,6 +62,8 @@ class HeaderFile {
bool Excluded{false};
/// Add header file to processing.
bool Extra{false};
/// Specify that header file is the umbrella header for library.
bool Umbrella{false};

public:
HeaderFile() = delete;
Expand All @@ -79,17 +81,21 @@ class HeaderFile {

void setExtra(bool V = true) { Extra = V; }
void setExcluded(bool V = true) { Excluded = V; }
void setUmbrellaHeader(bool V = true) { Umbrella = V; }
bool isExtra() const { return Extra; }
bool isExcluded() const { return Excluded; }
bool isUmbrellaHeader() const { return Umbrella; }

bool useIncludeName() const {
return Type != HeaderType::Project && !IncludeName.empty();
}

bool operator==(const HeaderFile &Other) const {
return std::tie(Type, FullPath, IncludeName, Language, Excluded, Extra) ==
std::tie(Other.Type, Other.FullPath, Other.IncludeName,
Other.Language, Other.Excluded, Other.Extra);
return std::tie(Type, FullPath, IncludeName, Language, Excluded, Extra,
Umbrella) == std::tie(Other.Type, Other.FullPath,
Other.IncludeName, Other.Language,
Other.Excluded, Other.Extra,
Other.Umbrella);
}
};

Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2234,7 +2234,8 @@ class Sema final {
bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
CallExpr *TheCall);
void checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D);
void checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D,
const llvm::StringMap<bool> &FeatureMap);
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI,
unsigned BuiltinID, CallExpr *TheCall);
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI,
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@ def PaddingChecker : Checker<"Padding">,
"24",
Released>
]>,
Documentation<NotDocumented>;
Documentation<HasDocumentation>;

} // end: "padding"

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/APValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,9 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy,
return;
}

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

switch (getKind()) {
case APValue::None:
Out << "<out of lifetime>";
Expand Down
36 changes: 15 additions & 21 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,7 @@ TypeInfoChars
static getConstantArrayInfoInChars(const ASTContext &Context,
const ConstantArrayType *CAT) {
TypeInfoChars EltInfo = Context.getTypeInfoInChars(CAT->getElementType());
uint64_t Size = CAT->getSize().getZExtValue();
uint64_t Size = CAT->getZExtSize();
assert((Size == 0 || static_cast<uint64_t>(EltInfo.Width.getQuantity()) <=
(uint64_t)(-1)/Size) &&
"Overflow in array type char size evaluation");
Expand Down Expand Up @@ -1910,7 +1910,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
// Model non-constant sized arrays as size zero, but track the alignment.
uint64_t Size = 0;
if (const auto *CAT = dyn_cast<ConstantArrayType>(T))
Size = CAT->getSize().getZExtValue();
Size = CAT->getZExtSize();

TypeInfo EltInfo = getTypeInfo(cast<ArrayType>(T)->getElementType());
assert((Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) &&
Expand Down Expand Up @@ -3560,8 +3560,8 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
ArySize = ArySize.zextOrTrunc(Target->getMaxPointerWidth());

llvm::FoldingSetNodeID ID;
ConstantArrayType::Profile(ID, *this, EltTy, ArySize, SizeExpr, ASM,
IndexTypeQuals);
ConstantArrayType::Profile(ID, *this, EltTy, ArySize.getZExtValue(), SizeExpr,
ASM, IndexTypeQuals);

void *InsertPos = nullptr;
if (ConstantArrayType *ATP =
Expand All @@ -3585,11 +3585,8 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}

void *Mem = Allocate(
ConstantArrayType::totalSizeToAlloc<const Expr *>(SizeExpr ? 1 : 0),
alignof(ConstantArrayType));
auto *New = new (Mem)
ConstantArrayType(EltTy, Canon, ArySize, SizeExpr, ASM, IndexTypeQuals);
auto *New = ConstantArrayType::Create(*this, EltTy, Canon, ArySize, SizeExpr,
ASM, IndexTypeQuals);
ConstantArrayTypes.InsertNode(New, InsertPos);
Types.push_back(New);
return QualType(New, 0);
Expand Down Expand Up @@ -7051,7 +7048,7 @@ uint64_t
ASTContext::getConstantArrayElementCount(const ConstantArrayType *CA) const {
uint64_t ElementCount = 1;
do {
ElementCount *= CA->getSize().getZExtValue();
ElementCount *= CA->getZExtSize();
CA = dyn_cast_or_null<ConstantArrayType>(
CA->getElementType()->getAsArrayTypeUnsafe());
} while (CA);
Expand Down Expand Up @@ -8374,7 +8371,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
S += '[';

if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
S += llvm::utostr(CAT->getSize().getZExtValue());
S += llvm::utostr(CAT->getZExtSize());
else {
//Variable length arrays are encoded as a regular array with 0 elements.
assert((isa<VariableArrayType>(AT) || isa<IncompleteArrayType>(AT)) &&
Expand Down Expand Up @@ -10808,7 +10805,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, bool OfBlockPointer,
{
const ConstantArrayType* LCAT = getAsConstantArrayType(LHS);
const ConstantArrayType* RCAT = getAsConstantArrayType(RHS);
if (LCAT && RCAT && RCAT->getSize() != LCAT->getSize())
if (LCAT && RCAT && RCAT->getZExtSize() != LCAT->getZExtSize())
return {};

QualType LHSElem = getAsArrayType(LHS)->getElementType();
Expand Down Expand Up @@ -13676,22 +13673,19 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
} else if (const auto *TC = FD->getAttr<TargetClonesAttr>()) {
std::vector<std::string> Features;
StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
if (Target->getTriple().isAArch64()) {
// TargetClones for AArch64
if (VersionStr != "default") {
SmallVector<StringRef, 1> VersionFeatures;
VersionStr.split(VersionFeatures, "+");
for (auto &VFeature : VersionFeatures) {
VFeature = VFeature.trim();
llvm::SmallVector<StringRef, 8> Feats;
TC->getFeatures(Feats, GD.getMultiVersionIndex());
for (StringRef Feat : Feats)
if (Target->validateCpuSupports(Feat.str()))
// Use '?' to mark features that came from AArch64 TargetClones.
Features.push_back((StringRef{"?"} + VFeature).str());
}
}
Features.push_back("?" + Feat.str());
Features.insert(Features.begin(),
Target->getTargetOpts().FeaturesAsWritten.begin(),
Target->getTargetOpts().FeaturesAsWritten.end());
} else {
StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
if (VersionStr.starts_with("arch="))
TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1);
else if (VersionStr != "default")
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2840,7 +2840,7 @@ bool VarDecl::hasFlexibleArrayInit(const ASTContext &Ctx) const {
auto InitTy = Ctx.getAsConstantArrayType(FlexibleInit->getType());
if (!InitTy)
return false;
return InitTy->getSize() != 0;
return !InitTy->isZeroSize();
}

CharUnits VarDecl::getFlexibleArrayInitChars(const ASTContext &Ctx) const {
Expand Down
68 changes: 43 additions & 25 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ namespace {
IsArray = true;

if (auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
ArraySize = CAT->getSize().getZExtValue();
ArraySize = CAT->getZExtSize();
} else {
assert(I == 0 && "unexpected unsized array designator");
FirstEntryIsUnsizedArray = true;
Expand Down Expand Up @@ -401,7 +401,7 @@ namespace {
// This is a most-derived object.
MostDerivedType = CAT->getElementType();
MostDerivedIsArrayElement = true;
MostDerivedArraySize = CAT->getSize().getZExtValue();
MostDerivedArraySize = CAT->getZExtSize();
MostDerivedPathLength = Entries.size();
}
/// Update this designator to refer to the first element within the array of
Expand Down Expand Up @@ -3476,7 +3476,7 @@ static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S,
QualType CharType = CAT->getElementType();
assert(CharType->isIntegerType() && "unexpected character type");

unsigned Elts = CAT->getSize().getZExtValue();
unsigned Elts = CAT->getZExtSize();
Result = APValue(APValue::UninitArray(),
std::min(S->getLength(), Elts), Elts);
APSInt Value(Info.Ctx.getTypeSize(CharType),
Expand Down Expand Up @@ -3619,7 +3619,7 @@ static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT,
SourceLocation CallLoc = {}) {
return Info.CheckArraySize(
CAT->getSizeExpr() ? CAT->getSizeExpr()->getBeginLoc() : CallLoc,
CAT->getNumAddressingBits(Info.Ctx), CAT->getSize().getZExtValue(),
CAT->getNumAddressingBits(Info.Ctx), CAT->getZExtSize(),
/*Diag=*/true);
}

Expand Down Expand Up @@ -4908,7 +4908,7 @@ static bool handleDefaultInitValue(QualType T, APValue &Result) {

if (auto *AT =
dyn_cast_or_null<ConstantArrayType>(T->getAsArrayTypeUnsafe())) {
Result = APValue(APValue::UninitArray(), 0, AT->getSize().getZExtValue());
Result = APValue(APValue::UninitArray(), 0, AT->getZExtSize());
if (Result.hasArrayFiller())
Success &=
handleDefaultInitValue(AT->getElementType(), Result.getArrayFiller());
Expand Down Expand Up @@ -6595,7 +6595,7 @@ static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange,

// For arrays, destroy elements right-to-left.
if (const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(T)) {
uint64_t Size = CAT->getSize().getZExtValue();
uint64_t Size = CAT->getZExtSize();
QualType ElemT = CAT->getElementType();

if (!CheckArraySize(Info, CAT, CallRange.getBegin()))
Expand Down Expand Up @@ -7396,7 +7396,7 @@ class BufferToAPValueConverter {
}

std::optional<APValue> visit(const ConstantArrayType *Ty, CharUnits Offset) {
size_t Size = Ty->getSize().getLimitedValue();
size_t Size = Ty->getLimitedSize();
CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->getElementType());

APValue ArrayValue(APValue::UninitArray(), Size, Size);
Expand Down Expand Up @@ -9951,7 +9951,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
assert(CAT && "unexpected type for array initializer");

unsigned Bits =
std::max(CAT->getSize().getBitWidth(), ArrayBound.getBitWidth());
std::max(CAT->getSizeBitWidth(), ArrayBound.getBitWidth());
llvm::APInt InitBound = CAT->getSize().zext(Bits);
llvm::APInt AllocBound = ArrayBound.zext(Bits);
if (InitBound.ugt(AllocBound)) {
Expand Down Expand Up @@ -10410,7 +10410,7 @@ bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(

if (Field->getType()->isIncompleteArrayType()) {
if (auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType())) {
if (!CAT->getSize().isZero()) {
if (!CAT->isZeroSize()) {
// Bail out for now. This might sort of "work", but the rest of the
// code isn't really prepared to handle it.
Info.FFDiag(Init, diag::note_constexpr_unsupported_flexible_array);
Expand Down Expand Up @@ -10554,7 +10554,7 @@ bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
// End pointer.
if (!HandleLValueArrayAdjustment(Info, E, Array,
ArrayType->getElementType(),
ArrayType->getSize().getZExtValue()))
ArrayType->getZExtSize()))
return false;
Array.moveInto(Result.getStructField(1));
} else if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType()))
Expand Down Expand Up @@ -10996,8 +10996,7 @@ namespace {
return Error(E);
}

Result = APValue(APValue::UninitArray(), 0,
CAT->getSize().getZExtValue());
Result = APValue(APValue::UninitArray(), 0, CAT->getZExtSize());
if (!Result.hasArrayFiller())
return true;

Expand Down Expand Up @@ -11122,7 +11121,7 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
Filler = Result.getArrayFiller();

unsigned NumEltsToInit = Args.size();
unsigned NumElts = CAT->getSize().getZExtValue();
unsigned NumElts = CAT->getZExtSize();

// If the initializer might depend on the array index, run it for each
// array element.
Expand Down Expand Up @@ -11180,7 +11179,7 @@ bool ArrayExprEvaluator::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {

auto *CAT = cast<ConstantArrayType>(E->getType()->castAsArrayTypeUnsafe());

uint64_t Elements = CAT->getSize().getZExtValue();
uint64_t Elements = CAT->getZExtSize();
Result = APValue(APValue::UninitArray(), Elements, Elements);

LValue Subobject = This;
Expand Down Expand Up @@ -11225,7 +11224,7 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
bool HadZeroInit = Value->hasValue();

if (const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(Type)) {
unsigned FinalSize = CAT->getSize().getZExtValue();
unsigned FinalSize = CAT->getZExtSize();

// Preserve the array filler if we had prior zero-initialization.
APValue Filler =
Expand Down Expand Up @@ -11940,7 +11939,7 @@ static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) {
return true;
const auto *CAT = cast<ConstantArrayType>(Ctx.getAsArrayType(BaseType));
uint64_t Index = Entry.getAsArrayIndex();
if (Index + 1 != CAT->getSize())
if (Index + 1 != CAT->getZExtSize())
return false;
BaseType = CAT->getElementType();
} else if (BaseType->isAnyComplexType()) {
Expand Down Expand Up @@ -12354,21 +12353,31 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
case Builtin::BI__builtin_clzl:
case Builtin::BI__builtin_clzll:
case Builtin::BI__builtin_clzs:
case Builtin::BI__builtin_clzg:
case Builtin::BI__lzcnt16: // Microsoft variants of count leading-zeroes
case Builtin::BI__lzcnt:
case Builtin::BI__lzcnt64: {
APSInt Val;
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;

// When the argument is 0, the result of GCC builtins is undefined, whereas
// for Microsoft intrinsics, the result is the bit-width of the argument.
bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
BuiltinOp != Builtin::BI__lzcnt &&
BuiltinOp != Builtin::BI__lzcnt64;
if (!Val) {
if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) {
if (!EvaluateInteger(E->getArg(1), Val, Info))
return false;
return Success(Val, E);
}

if (ZeroIsUndefined && !Val)
return Error(E);
// When the argument is 0, the result of GCC builtins is undefined,
// whereas for Microsoft intrinsics, the result is the bit-width of the
// argument.
bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
BuiltinOp != Builtin::BI__lzcnt &&
BuiltinOp != Builtin::BI__lzcnt64;

if (ZeroIsUndefined)
return Error(E);
}

return Success(Val.countl_zero(), E);
}
Expand Down Expand Up @@ -12410,12 +12419,21 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
case Builtin::BI__builtin_ctz:
case Builtin::BI__builtin_ctzl:
case Builtin::BI__builtin_ctzll:
case Builtin::BI__builtin_ctzs: {
case Builtin::BI__builtin_ctzs:
case Builtin::BI__builtin_ctzg: {
APSInt Val;
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;
if (!Val)

if (!Val) {
if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) {
if (!EvaluateInteger(E->getArg(1), Val, Info))
return false;
return Success(Val, E);
}

return Error(E);
}

return Success(Val.countr_zero(), E);
}
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ bool ByteCodeExprGen<Emitter>::VisitImplicitValueInitExpr(const ImplicitValueIni
const ArrayType *AT = QT->getAsArrayTypeUnsafe();
assert(AT);
const auto *CAT = cast<ConstantArrayType>(AT);
size_t NumElems = CAT->getSize().getZExtValue();
size_t NumElems = CAT->getZExtSize();
PrimType ElemT = classifyPrim(CAT->getElementType());

for (size_t I = 0; I != NumElems; ++I) {
Expand Down Expand Up @@ -992,7 +992,7 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
if (const Expr *Filler = E->getArrayFiller()) {
const ConstantArrayType *CAT =
Ctx.getASTContext().getAsConstantArrayType(E->getType());
uint64_t NumElems = CAT->getSize().getZExtValue();
uint64_t NumElems = CAT->getZExtSize();

for (; ElementIndex != NumElems; ++ElementIndex) {
if (!this->visitArrayElemInit(ElementIndex, Filler))
Expand Down Expand Up @@ -1318,7 +1318,7 @@ bool ByteCodeExprGen<Emitter>::VisitStringLiteral(const StringLiteral *E) {

// If the initializer string is too long, a diagnostic has already been
// emitted. Read only the array length from the string literal.
unsigned ArraySize = CAT->getSize().getZExtValue();
unsigned ArraySize = CAT->getZExtSize();
unsigned N = std::min(ArraySize, E->getLength());
size_t CharWidth = E->getCharByteWidth();

Expand Down Expand Up @@ -1919,7 +1919,7 @@ bool ByteCodeExprGen<Emitter>::VisitCXXConstructExpr(
const ConstantArrayType *CAT =
Ctx.getASTContext().getAsConstantArrayType(E->getType());
assert(CAT);
size_t NumElems = CAT->getSize().getZExtValue();
size_t NumElems = CAT->getZExtSize();
const Function *Func = getFunction(E->getConstructor());
if (!Func || !Func->isConstexpr())
return false;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Interp/EvaluationResult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static bool CheckArrayInitialized(InterpState &S, SourceLocation Loc,
const Pointer &BasePtr,
const ConstantArrayType *CAT) {
bool Result = true;
size_t NumElems = CAT->getSize().getZExtValue();
size_t NumElems = CAT->getZExtSize();
QualType ElemType = CAT->getElementType();

if (ElemType->isRecordType()) {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Interp/Program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
QualType ElemTy = ArrayType->getElementType();
// Array of well-known bounds.
if (auto CAT = dyn_cast<ConstantArrayType>(ArrayType)) {
size_t NumElems = CAT->getSize().getZExtValue();
size_t NumElems = CAT->getZExtSize();
if (std::optional<PrimType> T = Ctx.classify(ElemTy)) {
// Arrays of primitives.
unsigned ElemSize = primSize(*T);
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3445,6 +3445,7 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) {
case CC_PreserveAll:
case CC_M68kRTD:
case CC_PreserveNone:
case CC_RISCVVectorCall:
// FIXME: we should be mangling all of the above.
return "";

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/JSONNodeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ void JSONNodeDumper::VisitArrayType(const ArrayType *AT) {
void JSONNodeDumper::VisitConstantArrayType(const ConstantArrayType *CAT) {
// FIXME: this should use ZExt instead of SExt, but JSON doesn't allow a
// narrowing conversion to int64_t so it cannot be expressed.
JOS.attribute("size", CAT->getSize().getSExtValue());
JOS.attribute("size", CAT->getSExtSize());
VisitArrayType(CAT);
}

Expand Down
6 changes: 2 additions & 4 deletions clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4023,10 +4023,8 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
// char bar[42] = "foobar";
// Where it is truncated or zero-padded to fit the array. This is the length
// used for mangling, and any trailing null-bytes also need to be mangled.
unsigned StringLength = getASTContext()
.getAsConstantArrayType(SL->getType())
->getSize()
.getZExtValue();
unsigned StringLength =
getASTContext().getAsConstantArrayType(SL->getType())->getZExtSize();
unsigned StringByteLength = StringLength * SL->getCharByteWidth();

// <char-type>: The "kind" of string literal is encoded into the mangled name.
Expand Down
4 changes: 1 addition & 3 deletions clang/lib/AST/ScanfFormatString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,7 @@ bool ScanfSpecifier::fixType(QualType QT, QualType RawQT,
if (const ConstantArrayType *CAT = Ctx.getAsConstantArrayType(RawQT)) {
if (CAT->getSizeModifier() == ArraySizeModifier::Normal)
FieldWidth = OptionalAmount(OptionalAmount::Constant,
CAT->getSize().getZExtValue() - 1,
"", 0, false);

CAT->getZExtSize() - 1, "", 0, false);
}
return true;
}
Expand Down
33 changes: 24 additions & 9 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,22 @@ ArrayType::ArrayType(TypeClass tc, QualType et, QualType can,
ArrayTypeBits.SizeModifier = llvm::to_underlying(sm);
}

ConstantArrayType *
ConstantArrayType::Create(const ASTContext &Ctx, QualType ET, QualType Can,
const llvm::APInt &Sz, const Expr *SzExpr,
ArraySizeModifier SzMod, unsigned Qual) {
bool NeedsExternalSize = SzExpr != nullptr || Sz.ugt(0x0FFFFFFFFFFFFFFF) ||
Sz.getBitWidth() > 0xFF;
if (!NeedsExternalSize)
return new (Ctx, alignof(ConstantArrayType)) ConstantArrayType(
ET, Can, Sz.getBitWidth(), Sz.getZExtValue(), SzMod, Qual);

auto *SzPtr = new (Ctx, alignof(ConstantArrayType::ExternalSize))
ConstantArrayType::ExternalSize(Sz, SzExpr);
return new (Ctx, alignof(ConstantArrayType))
ConstantArrayType(ET, Can, SzPtr, SzMod, Qual);
}

unsigned ConstantArrayType::getNumAddressingBits(const ASTContext &Context,
QualType ElementType,
const llvm::APInt &NumElements) {
Expand Down Expand Up @@ -213,11 +229,10 @@ unsigned ConstantArrayType::getMaxSizeBits(const ASTContext &Context) {

void ConstantArrayType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context, QualType ET,
const llvm::APInt &ArraySize,
const Expr *SizeExpr, ArraySizeModifier SizeMod,
unsigned TypeQuals) {
uint64_t ArraySize, const Expr *SizeExpr,
ArraySizeModifier SizeMod, unsigned TypeQuals) {
ID.AddPointer(ET.getAsOpaquePtr());
ID.AddInteger(ArraySize.getZExtValue());
ID.AddInteger(ArraySize);
ID.AddInteger(llvm::to_underlying(SizeMod));
ID.AddInteger(TypeQuals);
ID.AddBoolean(SizeExpr != nullptr);
Expand Down Expand Up @@ -452,12 +467,8 @@ QualType QualType::getSingleStepDesugaredTypeImpl(QualType type,
// Check that no type class has a non-trival destructor. Types are
// allocated with the BumpPtrAllocator from ASTContext and therefore
// their destructor is not executed.
//
// FIXME: ConstantArrayType is not trivially destructible because of its
// APInt member. It should be replaced in favor of ASTContext allocation.
#define TYPE(CLASS, BASE) \
static_assert(std::is_trivially_destructible<CLASS##Type>::value || \
std::is_same<CLASS##Type, ConstantArrayType>::value, \
static_assert(std::is_trivially_destructible<CLASS##Type>::value, \
#CLASS "Type should be trivially destructible!");
#include "clang/AST/TypeNodes.inc"

Expand Down Expand Up @@ -3473,6 +3484,9 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
case CC_PreserveAll: return "preserve_all";
case CC_M68kRTD: return "m68k_rtd";
case CC_PreserveNone: return "preserve_none";
// clang-format off
case CC_RISCVVectorCall: return "riscv_vector_cc";
// clang-format on
}

llvm_unreachable("Invalid calling convention.");
Expand Down Expand Up @@ -4063,6 +4077,7 @@ bool AttributedType::isCallingConv() const {
case attr::PreserveAll:
case attr::M68kRTD:
case attr::PreserveNone:
case attr::RISCVVectorCC:
return true;
}
llvm_unreachable("invalid attr kind");
Expand Down
21 changes: 11 additions & 10 deletions clang/lib/AST/TypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
if (T->getSizeModifier() == ArraySizeModifier::Static)
OS << "static ";

OS << T->getSize().getZExtValue() << ']';
OS << T->getZExtSize() << ']';
printAfter(T->getElementType(), OS);
}

Expand Down Expand Up @@ -1071,6 +1071,9 @@ void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
case CC_PreserveNone:
OS << " __attribute__((preserve_none))";
break;
case CC_RISCVVectorCall:
OS << "__attribute__((riscv_vector_cc))";
break;
}
}

Expand Down Expand Up @@ -1960,6 +1963,9 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case attr::PreserveNone:
OS << "preserve_none";
break;
case attr::RISCVVectorCC:
OS << "riscv_vector_cc";
break;
case attr::NoDeref:
OS << "noderef";
break;
Expand Down Expand Up @@ -2303,15 +2309,10 @@ printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
} else {
if (!FirstArg)
OS << Comma;
if (!Policy.SuppressTagKeyword &&
Argument.getKind() == TemplateArgument::Type &&
isa<TagType>(Argument.getAsType()))
OS << Argument.getAsType().getAsString();
else
// Tries to print the argument with location info if exists.
printArgument(Arg, Policy, ArgOS,
TemplateParameterList::shouldIncludeTypeForArgument(
Policy, TPL, ParmIndex));
// Tries to print the argument with location info if exists.
printArgument(Arg, Policy, ArgOS,
TemplateParameterList::shouldIncludeTypeForArgument(
Policy, TPL, ParmIndex));
}
StringRef ArgString = ArgOS.str();

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Analysis/CFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2039,7 +2039,7 @@ void CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) {
QualType QT = FI->getType();
// It may be a multidimensional array.
while (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) {
if (AT->getSize() == 0)
if (AT->isZeroSize())
break;
QT = AT->getElementType();
}
Expand Down Expand Up @@ -2133,7 +2133,7 @@ bool CFGBuilder::hasTrivialDestructor(const VarDecl *VD) const {

// Check for constant size array. Set type to array element type.
while (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) {
if (AT->getSize() == 0)
if (AT->isZeroSize())
return true;
QT = AT->getElementType();
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ void Environment::initialize() {
assert(Parent != nullptr);

if (Parent->isLambda()) {
for (auto Capture : Parent->captures()) {
for (const auto &Capture : Parent->captures()) {
if (Capture.capturesVariable()) {
const auto *VarDecl = Capture.getCapturedVar();
assert(VarDecl != nullptr);
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Analysis/UnsafeBufferUsage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,11 @@ AST_MATCHER(CXXConstructExpr, isSafeSpanTwoParamConstruct) {
QualType Arg0Ty = Arg0->IgnoreImplicit()->getType();

if (Arg0Ty->isConstantArrayType()) {
const APInt &ConstArrSize = cast<ConstantArrayType>(Arg0Ty)->getSize();
const APSInt ConstArrSize =
APSInt(cast<ConstantArrayType>(Arg0Ty)->getSize());

// Check form 4:
return Arg1CV && APSInt::compareValues(APSInt(ConstArrSize), *Arg1CV) == 0;
return Arg1CV && APSInt::compareValues(ConstArrSize, *Arg1CV) == 0;
}
return false;
}
Expand All @@ -429,14 +430,13 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
BaseDRE->getDecl()->getType());
if (!CATy)
return false;
const APInt ArrSize = CATy->getSize();

if (const auto *IdxLit = dyn_cast<IntegerLiteral>(Node.getIdx())) {
const APInt ArrIdx = IdxLit->getValue();
// FIXME: ArrIdx.isNegative() we could immediately emit an error as that's a
// bug
if (ArrIdx.isNonNegative() &&
ArrIdx.getLimitedValue() < ArrSize.getLimitedValue())
ArrIdx.getLimitedValue() < CATy->getLimitedSize())
return true;
}

Expand Down
11 changes: 11 additions & 0 deletions clang/lib/Basic/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,3 +467,14 @@ ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const {
}
return Ret;
}

TargetInfo::CallingConvCheckResult
RISCVTargetInfo::checkCallingConvention(CallingConv CC) const {
switch (CC) {
default:
return CCCR_Warning;
case CC_C:
case CC_RISCVVectorCall:
return CCCR_OK;
}
}
2 changes: 2 additions & 0 deletions clang/lib/Basic/Targets/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class RISCVTargetInfo : public TargetInfo {

bool hasBFloat16Type() const override { return true; }

CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;

bool useFP16ConversionIntrinsics() const override {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/ABIInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ bool ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const {
bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base,
uint64_t &Members) const {
if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
uint64_t NElements = AT->getSize().getZExtValue();
uint64_t NElements = AT->getZExtSize();
if (NElements == 0)
return false;
if (!isHomogeneousAggregate(AT->getElementType(), Base, Members))
Expand Down Expand Up @@ -98,7 +98,7 @@ bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base,
QualType FT = FD->getType();
while (const ConstantArrayType *AT =
getContext().getAsConstantArrayType(FT)) {
if (AT->getSize().getZExtValue() == 0)
if (AT->isZeroSize())
return false;
FT = AT->getElementType();
}
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/ABIInfoImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD,
bool WasArray = false;
if (AllowArrays)
while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) {
if (AT->getSize() == 0)
if (AT->isZeroSize())
return true;
FT = AT->getElementType();
// The [[no_unique_address]] special case below does not apply to
Expand Down Expand Up @@ -352,7 +352,7 @@ const Type *CodeGen::isSingleElementStruct(QualType T, ASTContext &Context) {

// Treat single element arrays as the element.
while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) {
if (AT->getSize().getZExtValue() != 1)
if (AT->getZExtSize() != 1)
break;
FT = AT->getElementType();
}
Expand Down
44 changes: 9 additions & 35 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,8 @@ EncompassingIntegerType(ArrayRef<struct WidthAndSignedness> Types) {

Value *CodeGenFunction::EmitVAStartEnd(Value *ArgValue, bool IsStart) {
Intrinsic::ID inst = IsStart ? Intrinsic::vastart : Intrinsic::vaend;
return Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue);
return Builder.CreateCall(CGM.getIntrinsic(inst, {ArgValue->getType()}),
ArgValue);
}

/// Checks if using the result of __builtin_object_size(p, @p From) in place of
Expand Down Expand Up @@ -3018,7 +3019,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_va_copy: {
Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer();
Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer();
Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy), {DstPtr, SrcPtr});
Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy, {DstPtr->getType()}),
{DstPtr, SrcPtr});
return RValue::get(nullptr);
}
case Builtin::BIabs:
Expand Down Expand Up @@ -18540,51 +18542,23 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
}
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b64_i32:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b64_v2i32:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4bf16:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4f16:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4i16:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8bf16:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8f16:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8i16: {

llvm::Type *ArgTy;
Intrinsic::ID IID;
switch (BuiltinID) {
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b64_i32:
ArgTy = llvm::Type::getInt32Ty(getLLVMContext());
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b64_v2i32:
ArgTy = llvm::FixedVectorType::get(
llvm::Type::getInt32Ty(getLLVMContext()), 2);
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4bf16:
ArgTy = llvm::FixedVectorType::get(
llvm::Type::getBFloatTy(getLLVMContext()), 4);
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4f16:
ArgTy = llvm::FixedVectorType::get(
llvm::Type::getHalfTy(getLLVMContext()), 4);
IID = Intrinsic::amdgcn_global_load_tr_b64;
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4i16:
ArgTy = llvm::FixedVectorType::get(
llvm::Type::getInt16Ty(getLLVMContext()), 4);
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8bf16:
ArgTy = llvm::FixedVectorType::get(
llvm::Type::getBFloatTy(getLLVMContext()), 8);
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8f16:
ArgTy = llvm::FixedVectorType::get(
llvm::Type::getHalfTy(getLLVMContext()), 8);
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8i16:
ArgTy = llvm::FixedVectorType::get(
llvm::Type::getInt16Ty(getLLVMContext()), 8);
IID = Intrinsic::amdgcn_global_load_tr_b128;
break;
}

llvm::Type *LoadTy = ConvertType(E->getType());
llvm::Value *Addr = EmitScalarExpr(E->getArg(0));
llvm::Function *F =
CGM.getIntrinsic(Intrinsic::amdgcn_global_load_tr, {ArgTy});
llvm::Function *F = CGM.getIntrinsic(IID, {LoadTy});
return Builder.CreateCall(F, {Addr});
}
case AMDGPU::BI__builtin_amdgcn_get_fpenv: {
Expand Down
12 changes: 9 additions & 3 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
case CC_SwiftAsync: return llvm::CallingConv::SwiftTail;
case CC_M68kRTD: return llvm::CallingConv::M68k_RTD;
case CC_PreserveNone: return llvm::CallingConv::PreserveNone;
// clang-format off
case CC_RISCVVectorCall: return llvm::CallingConv::RISCV_VectorCall;
// clang-format on
}
}

Expand Down Expand Up @@ -260,6 +263,9 @@ static CallingConv getCallingConventionForDecl(const ObjCMethodDecl *D,
if (D->hasAttr<PreserveNoneAttr>())
return CC_PreserveNone;

if (D->hasAttr<RISCVVectorCCAttr>())
return CC_RISCVVectorCall;

return CC_C;
}

Expand Down Expand Up @@ -933,8 +939,8 @@ struct NoExpansion : TypeExpansion {
static std::unique_ptr<TypeExpansion>
getTypeExpansion(QualType Ty, const ASTContext &Context) {
if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
return std::make_unique<ConstantArrayExpansion>(
AT->getElementType(), AT->getSize().getZExtValue());
return std::make_unique<ConstantArrayExpansion>(AT->getElementType(),
AT->getZExtSize());
}
if (const RecordType *RT = Ty->getAs<RecordType>()) {
SmallVector<const CXXBaseSpecifier *, 1> Bases;
Expand Down Expand Up @@ -3086,7 +3092,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
llvm::Align Alignment =
CGM.getNaturalTypeAlignment(ETy).getAsAlign();
AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr(Alignment));
uint64_t ArrSize = ArrTy->getSize().getZExtValue();
uint64_t ArrSize = ArrTy->getZExtSize();
if (!ETy->isIncompleteType() && ETy->isConstantSizeType() &&
ArrSize) {
llvm::AttrBuilder Attrs(getLLVMContext());
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1452,6 +1452,8 @@ static unsigned getDwarfCC(CallingConv CC) {
return llvm::dwarf::DW_CC_LLVM_M68kRTD;
case CC_PreserveNone:
return llvm::dwarf::DW_CC_LLVM_PreserveNone;
case CC_RISCVVectorCall:
return llvm::dwarf::DW_CC_LLVM_RISCVVectorCall;
}
return 0;
}
Expand Down Expand Up @@ -3239,7 +3241,7 @@ llvm::DIType *CGDebugInfo::CreateType(const ArrayType *Ty, llvm::DIFile *Unit) {
// };
int64_t Count = -1; // Count == -1 is an unbounded array.
if (const auto *CAT = dyn_cast<ConstantArrayType>(Ty))
Count = CAT->getSize().getZExtValue();
Count = CAT->getZExtSize();
else if (const auto *VAT = dyn_cast<VariableArrayType>(Ty)) {
if (Expr *Size = VAT->getSizeExpr()) {
Expr::EvalResult Result;
Expand Down
21 changes: 19 additions & 2 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3663,12 +3663,29 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
// symbol in LTO mode.
void CodeGenFunction::EmitCfiCheckStub() {
llvm::Module *M = &CGM.getModule();
auto &Ctx = M->getContext();
ASTContext &C = getContext();
QualType QInt64Ty = C.getIntTypeForBitwidth(64, false);

FunctionArgList FnArgs;
ImplicitParamDecl ArgCallsiteTypeId(C, QInt64Ty, ImplicitParamKind::Other);
ImplicitParamDecl ArgAddr(C, C.VoidPtrTy, ImplicitParamKind::Other);
ImplicitParamDecl ArgCFICheckFailData(C, C.VoidPtrTy,
ImplicitParamKind::Other);
FnArgs.push_back(&ArgCallsiteTypeId);
FnArgs.push_back(&ArgAddr);
FnArgs.push_back(&ArgCFICheckFailData);
const CGFunctionInfo &FI =
CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, FnArgs);

llvm::Function *F = llvm::Function::Create(
llvm::FunctionType::get(VoidTy, {Int64Ty, Int8PtrTy, Int8PtrTy}, false),
llvm::FunctionType::get(VoidTy, {Int64Ty, VoidPtrTy, VoidPtrTy}, false),
llvm::GlobalValue::WeakAnyLinkage, "__cfi_check", M);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F, /*IsThunk=*/false);
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
F->setAlignment(llvm::Align(4096));
CGM.setDSOLocal(F);

llvm::LLVMContext &Ctx = M->getContext();
llvm::BasicBlock *BB = llvm::BasicBlock::Create(Ctx, "entry", F);
// CrossDSOCFI pass is not executed if there is no executable code.
SmallVector<llvm::Value*> Args{F->getArg(2), F->getArg(1)};
Expand Down
6 changes: 2 additions & 4 deletions clang/lib/CodeGen/CGExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1073,8 +1073,7 @@ void CodeGenFunction::EmitNewArrayInitializer(
// Move past these elements.
InitListElements =
cast<ConstantArrayType>(Init->getType()->getAsArrayTypeUnsafe())
->getSize()
.getZExtValue();
->getZExtSize();
CurPtr = Builder.CreateConstInBoundsGEP(
CurPtr, InitListElements, "string.init.end");

Expand Down Expand Up @@ -1591,8 +1590,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
isa<StringLiteral>(IgnoreParen) || isa<ObjCEncodeExpr>(IgnoreParen)) {
minElements =
cast<ConstantArrayType>(Init->getType()->getAsArrayTypeUnsafe())
->getSize()
.getZExtValue();
->getZExtSize();
} else if (ILE || CPLIE) {
minElements = ILE ? ILE->getNumInits() : CPLIE->getInitExprs().size();
}
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/CodeGen/CGExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
}

unsigned NumElementsToUpdate =
FillC ? CAT->getSize().getZExtValue() : Updater->getNumInits();
FillC ? CAT->getZExtSize() : Updater->getNumInits();
for (unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
Expr *Init = nullptr;
if (I < Updater->getNumInits())
Expand Down Expand Up @@ -1249,7 +1249,7 @@ class ConstExprEmitter :
auto *CAT = CGM.getContext().getAsConstantArrayType(ILE->getType());
assert(CAT && "can't emit array init for non-constant-bound array");
unsigned NumInitElements = ILE->getNumInits();
unsigned NumElements = CAT->getSize().getZExtValue();
unsigned NumElements = CAT->getZExtSize();

// Initialising an array requires us to automatically
// initialise any elements that have not been initialised explicitly
Expand Down Expand Up @@ -1374,7 +1374,7 @@ class ConstExprEmitter :

// Resize the string to the right size, adding zeros at the end, or
// truncating as needed.
Str.resize(CAT->getSize().getZExtValue(), '\0');
Str.resize(CAT->getZExtSize(), '\0');
return llvm::ConstantDataArray::getString(VMContext, Str, false);
}

Expand Down Expand Up @@ -2382,7 +2382,7 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {

llvm::Constant *Element =
ConstantEmitter::emitNullForMemory(*this, ElementTy);
unsigned NumElements = CAT->getSize().getZExtValue();
unsigned NumElements = CAT->getZExtSize();
SmallVector<llvm::Constant *, 8> Array(NumElements, Element);
return llvm::ConstantArray::get(ATy, Array);
}
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/CodeGen/CGObjCMac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2501,12 +2501,12 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,

if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
auto *CArray = cast<ConstantArrayType>(Array);
uint64_t ElCount = CArray->getSize().getZExtValue();
uint64_t ElCount = CArray->getZExtSize();
assert(CArray && "only array with known element size is supported");
FQT = CArray->getElementType();
while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
auto *CArray = cast<ConstantArrayType>(Array);
ElCount *= CArray->getSize().getZExtValue();
ElCount *= CArray->getZExtSize();
FQT = CArray->getElementType();
}
if (FQT->isRecordType() && ElCount) {
Expand Down Expand Up @@ -5326,7 +5326,7 @@ void IvarLayoutBuilder::visitField(const FieldDecl *field,
}
// Unlike incomplete arrays, constant arrays can be nested.
while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
numElts *= arrayType->getSize().getZExtValue();
numElts *= arrayType->getZExtSize();
fieldType = arrayType->getElementType();
}

Expand Down
6 changes: 3 additions & 3 deletions clang/lib/CodeGen/CGOpenMPRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6796,7 +6796,7 @@ class MappableExprsHandler {
OASE->getBase()->IgnoreParenImpCasts())
.getCanonicalType();
if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
return ATy->getSize().getSExtValue() != 1;
return ATy->getSExtSize() != 1;
// If we don't have a constant dimension length, we have to consider
// the current section as having any size, so it is not necessarily
// unitary. If it happen to be unity size, that's user fault.
Expand Down Expand Up @@ -7546,8 +7546,8 @@ class MappableExprsHandler {
// it.
if (DimSizes.size() < Components.size() - 1) {
if (CAT)
DimSizes.push_back(llvm::ConstantInt::get(
CGF.Int64Ty, CAT->getSize().getZExtValue()));
DimSizes.push_back(
llvm::ConstantInt::get(CGF.Int64Ty, CAT->getZExtSize()));
else if (VAT)
DimSizes.push_back(CGF.Builder.CreateIntCast(
CGF.EmitScalarExpr(VAT->getSizeExpr()), CGF.Int64Ty,
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2189,8 +2189,8 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType,
dyn_cast<llvm::ArrayType>(addr.getElementType());
while (llvmArrayType) {
assert(isa<ConstantArrayType>(arrayType));
assert(cast<ConstantArrayType>(arrayType)->getSize().getZExtValue()
== llvmArrayType->getNumElements());
assert(cast<ConstantArrayType>(arrayType)->getZExtSize() ==
llvmArrayType->getNumElements());

gepIndices.push_back(zero);
countFromCLAs *= llvmArrayType->getNumElements();
Expand All @@ -2208,8 +2208,7 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType,
// as some other type (probably a packed struct). Compute the array
// size, and just emit the 'begin' expression as a bitcast.
while (arrayType) {
countFromCLAs *=
cast<ConstantArrayType>(arrayType)->getSize().getZExtValue();
countFromCLAs *= cast<ConstantArrayType>(arrayType)->getZExtSize();
eltType = arrayType->getElementType();
arrayType = getContext().getAsArrayType(eltType);
}
Expand Down
107 changes: 51 additions & 56 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3712,7 +3712,8 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
// Forward declarations are emitted lazily on first use.
if (!FD->doesThisDeclarationHaveABody()) {
if (!FD->doesDeclarationForceExternallyVisibleDefinition() &&
!FD->isTargetVersionMultiVersion())
(!FD->isMultiVersion() ||
!FD->getASTContext().getTargetInfo().getTriple().isAArch64()))
return;

StringRef MangledName = getMangledName(GD);
Expand Down Expand Up @@ -3994,10 +3995,11 @@ void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD,
auto *Spec = FD->getAttr<CPUSpecificAttr>();
for (unsigned I = 0; I < Spec->cpus_size(); ++I)
EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr);
} else if (FD->isTargetClonesMultiVersion()) {
auto *Clone = FD->getAttr<TargetClonesAttr>();
for (unsigned I = 0; I < Clone->featuresStrs_size(); ++I)
if (Clone->isFirstOfVersion(I))
} else if (auto *TC = FD->getAttr<TargetClonesAttr>()) {
for (unsigned I = 0; I < TC->featuresStrs_size(); ++I)
// AArch64 favors the default target version over the clone if any.
if ((!TC->isDefaultVersion(I) || !getTarget().getTriple().isAArch64()) &&
TC->isFirstOfVersion(I))
EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr);
// Ensure that the resolver function is also emitted.
GetOrCreateMultiVersionResolver(GD);
Expand Down Expand Up @@ -4137,57 +4139,49 @@ void CodeGenModule::emitMultiVersionFunctions() {
};

bool HasDefaultDecl = !FD->isTargetVersionMultiVersion();
bool ShouldEmitResolver = !FD->isTargetVersionMultiVersion();
bool ShouldEmitResolver =
!getContext().getTargetInfo().getTriple().isAArch64();
SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options;
if (FD->isTargetMultiVersion()) {
getContext().forEachMultiversionedFunctionVersion(
FD, [&](const FunctionDecl *CurFD) {
llvm::SmallVector<StringRef, 8> Feats;
llvm::Function *Func = createFunction(CurFD);

if (const auto *TA = CurFD->getAttr<TargetAttr>()) {
TA->getAddedFeatures(Feats);
Options.emplace_back(Func, TA->getArchitecture(), Feats);
} else if (const auto *TVA = CurFD->getAttr<TargetVersionAttr>()) {
bool HasDefaultDef = TVA->isDefaultVersion() &&
CurFD->doesThisDeclarationHaveABody();
HasDefaultDecl |= TVA->isDefaultVersion();
ShouldEmitResolver |= (CurFD->isUsed() || HasDefaultDef);
TVA->getFeatures(Feats);
Options.emplace_back(Func, /*Architecture*/ "", Feats);
} else
llvm_unreachable("unexpected MultiVersionKind");
});
} else if (const auto *TC = FD->getAttr<TargetClonesAttr>()) {
for (unsigned I = 0; I < TC->featuresStrs_size(); ++I) {
if (!TC->isFirstOfVersion(I))
continue;
getContext().forEachMultiversionedFunctionVersion(
FD, [&](const FunctionDecl *CurFD) {
llvm::SmallVector<StringRef, 8> Feats;

llvm::Function *Func = createFunction(FD, I);
StringRef Version = TC->getFeatureStr(I);
StringRef Architecture;
llvm::SmallVector<StringRef, 1> Feature;

if (getTarget().getTriple().isAArch64()) {
if (Version != "default") {
llvm::SmallVector<StringRef, 8> VerFeats;
Version.split(VerFeats, "+");
for (auto &CurFeat : VerFeats)
Feature.push_back(CurFeat.trim());
}
} else {
if (Version.starts_with("arch="))
Architecture = Version.drop_front(sizeof("arch=") - 1);
else if (Version != "default")
Feature.push_back(Version);
}

Options.emplace_back(Func, Architecture, Feature);
}
} else {
assert(0 && "Expected a target or target_clones multiversion function");
continue;
}
if (const auto *TA = CurFD->getAttr<TargetAttr>()) {
TA->getAddedFeatures(Feats);
llvm::Function *Func = createFunction(CurFD);
Options.emplace_back(Func, TA->getArchitecture(), Feats);
} else if (const auto *TVA = CurFD->getAttr<TargetVersionAttr>()) {
bool HasDefaultDef = TVA->isDefaultVersion() &&
CurFD->doesThisDeclarationHaveABody();
HasDefaultDecl |= TVA->isDefaultVersion();
ShouldEmitResolver |= (CurFD->isUsed() || HasDefaultDef);
TVA->getFeatures(Feats);
llvm::Function *Func = createFunction(CurFD);
Options.emplace_back(Func, /*Architecture*/ "", Feats);
} else if (const auto *TC = CurFD->getAttr<TargetClonesAttr>()) {
ShouldEmitResolver |= CurFD->doesThisDeclarationHaveABody();
for (unsigned I = 0; I < TC->featuresStrs_size(); ++I) {
if (!TC->isFirstOfVersion(I))
continue;

llvm::Function *Func = createFunction(CurFD, I);
StringRef Architecture;
Feats.clear();
if (getTarget().getTriple().isAArch64())
TC->getFeatures(Feats, I);
else {
StringRef Version = TC->getFeatureStr(I);
if (Version.starts_with("arch="))
Architecture = Version.drop_front(sizeof("arch=") - 1);
else if (Version != "default")
Feats.push_back(Version);
}
Options.emplace_back(Func, Architecture, Feats);
}
} else
llvm_unreachable("unexpected MultiVersionKind");
});

if (!ShouldEmitResolver)
continue;
Expand Down Expand Up @@ -4378,7 +4372,7 @@ void CodeGenModule::AddDeferredMultiVersionResolverToEmit(GlobalDecl GD) {
const auto *FD = cast<FunctionDecl>(GD.getDecl());
assert(FD && "Not a FunctionDecl?");

if (FD->isTargetVersionMultiVersion()) {
if (FD->isTargetVersionMultiVersion() || FD->isTargetClonesMultiVersion()) {
std::string MangledName =
getMangledNameImpl(*this, GD, FD, /*OmitMultiVersionMangling=*/true);
if (!DeferredResolversToEmit.insert(MangledName).second)
Expand Down Expand Up @@ -4489,7 +4483,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(

if (FD->isMultiVersion()) {
UpdateMultiVersionNames(GD, FD, MangledName);
if (FD->isTargetVersionMultiVersion() && !FD->isUsed())
if (FD->getASTContext().getTargetInfo().getTriple().isAArch64() &&
!FD->isUsed())
AddDeferredMultiVersionResolverToEmit(GD);
else if (!IsForDefinition)
return GetOrCreateMultiVersionResolver(GD);
Expand Down Expand Up @@ -6286,7 +6281,7 @@ CodeGenModule::GetConstantArrayFromStringLiteral(const StringLiteral *E) {
// Resize the string to the right size, which is indicated by its type.
const ConstantArrayType *CAT = Context.getAsConstantArrayType(E->getType());
assert(CAT && "String literal not of constant array type!");
Str.resize(CAT->getSize().getZExtValue());
Str.resize(CAT->getZExtSize());
return llvm::ConstantDataArray::getString(VMContext, Str, false);
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
EltTy = llvm::Type::getInt8Ty(getLLVMContext());
}

ResultType = llvm::ArrayType::get(EltTy, A->getSize().getZExtValue());
ResultType = llvm::ArrayType::get(EltTy, A->getZExtSize());
break;
}
case Type::ExtVector:
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/SwiftCallingConv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void SwiftAggLowering::addTypedData(QualType type, CharUnits begin) {

QualType eltType = arrayType->getElementType();
auto eltSize = CGM.getContext().getTypeSizeInChars(eltType);
for (uint64_t i = 0, e = arrayType->getSize().getZExtValue(); i != e; ++i) {
for (uint64_t i = 0, e = arrayType->getZExtSize(); i != e; ++i) {
addTypedData(eltType, begin + i * eltSize);
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/Targets/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ bool ARMABIInfo::isIllegalVectorType(QualType Ty) const {
/// Return true if a type contains any 16-bit floating point vectors
bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty) const {
if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
uint64_t NElements = AT->getSize().getZExtValue();
uint64_t NElements = AT->getZExtSize();
if (NElements == 0)
return false;
return containsAnyFP16Vectors(AT->getElementType());
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/Targets/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper(
}

if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
uint64_t ArraySize = ATy->getSize().getZExtValue();
uint64_t ArraySize = ATy->getZExtSize();
QualType EltTy = ATy->getElementType();
// Non-zero-length arrays of empty records make the struct ineligible to be
// passed via FARs in C++.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
}

if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
uint64_t ArraySize = ATy->getSize().getZExtValue();
uint64_t ArraySize = ATy->getZExtSize();
QualType EltTy = ATy->getElementType();
// Non-zero-length arrays of empty records make the struct ineligible for
// the FP calling convention in C++.
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/CodeGen/Targets/X86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1993,7 +1993,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
// this, but it isn't worth it and would be harder to verify.
Current = NoClass;
uint64_t EltSize = getContext().getTypeSize(AT->getElementType());
uint64_t ArraySize = AT->getSize().getZExtValue();
uint64_t ArraySize = AT->getZExtSize();

// The only case a 256-bit wide vector could be used is when the array
// contains a single 256-bit element. Since Lo and Hi logic isn't extended
Expand Down Expand Up @@ -2295,7 +2295,7 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit,

if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
unsigned EltSize = (unsigned)Context.getTypeSize(AT->getElementType());
unsigned NumElts = (unsigned)AT->getSize().getZExtValue();
unsigned NumElts = (unsigned)AT->getZExtSize();

// Check each element to see if the element overlaps with the queried range.
for (unsigned i = 0; i != NumElts; ++i) {
Expand Down Expand Up @@ -2788,12 +2788,11 @@ X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned freeIntRegs,
// memory), except in situations involving unions.
case X87Up:
case SSE:
++neededSSE;
HighPart = GetSSETypeAtOffset(CGT.ConvertType(Ty), 8, Ty, 8);

if (Lo == NoClass) // Pass HighPart at offset 8 in memory.
return ABIArgInfo::getDirect(HighPart, 8);

++neededSSE;
break;

// AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
}

AddUnalignedAccessWarning(CmdArgs);

Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_intrinsics,
options::OPT_fno_ptrauth_intrinsics);
}

void Clang::AddLoongArchTargetArgs(const ArgList &Args,
Expand Down Expand Up @@ -7258,10 +7261,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fno-common is the default, set -fcommon only when that flag is set.
Args.addOptInFlag(CmdArgs, options::OPT_fcommon, options::OPT_fno_common);

if (Args.hasFlag(options::OPT_fptrauth_intrinsics,
options::OPT_fno_ptrauth_intrinsics, false))
CmdArgs.push_back("-fptrauth-intrinsics");

// -fsigned-bitfields is default, and clang doesn't yet support
// -funsigned-bitfields.
if (!Args.hasFlag(options::OPT_fsigned_bitfields,
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Format/WhitespaceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,10 +464,11 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
if (i + 1 != Changes.size())
Changes[i + 1].PreviousEndOfTokenColumn += Shift;

// If PointerAlignment is PAS_Right, keep *s or &s next to the token
// If PointerAlignment is PAS_Right, keep *s or &s next to the token,
// except if the token is equal, then a space is needed.
if ((Style.PointerAlignment == FormatStyle::PAS_Right ||
Style.ReferenceAlignment == FormatStyle::RAS_Right) &&
CurrentChange.Spaces != 0) {
CurrentChange.Spaces != 0 && CurrentChange.Tok->isNot(tok::equal)) {
const bool ReferenceNotRightAligned =
Style.ReferenceAlignment != FormatStyle::RAS_Right &&
Style.ReferenceAlignment != FormatStyle::RAS_Pointer;
Expand Down
40 changes: 0 additions & 40 deletions clang/lib/Headers/hlsl/hlsl_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,15 +392,6 @@ float3 cos(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
float4 cos(float4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
double cos(double);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
double2 cos(double2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
double3 cos(double3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
double4 cos(double4);

//===----------------------------------------------------------------------===//
// dot product builtins
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1156,19 +1147,6 @@ float4 pow(float4, float4);
/// \param Val The input value.

#ifdef __HLSL_ENABLE_16_BIT
_HLSL_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int16_t reversebits(int16_t);
_HLSL_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int16_t2 reversebits(int16_t2);
_HLSL_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int16_t3 reversebits(int16_t3);
_HLSL_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int16_t4 reversebits(int16_t4);

_HLSL_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
uint16_t reversebits(uint16_t);
Expand All @@ -1183,15 +1161,6 @@ _HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
uint16_t4 reversebits(uint16_t4);
#endif

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int reversebits(int);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int2 reversebits(int2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int3 reversebits(int3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int4 reversebits(int4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
uint reversebits(uint);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
Expand All @@ -1201,15 +1170,6 @@ uint3 reversebits(uint3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
uint4 reversebits(uint4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int64_t reversebits(int64_t);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int64_t2 reversebits(int64_t2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int64_t3 reversebits(int64_t3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
int64_t4 reversebits(int64_t4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
uint64_t reversebits(uint64_t);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/InstallAPI/DylibVerifier.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
//===- DylibVerifier.cpp ----------------------------------------*- C++--*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/InstallAPI/DylibVerifier.h"
#include "clang/InstallAPI/FrontendRecords.h"
#include "clang/InstallAPI/InstallAPIDiagnostic.h"
Expand Down
18 changes: 12 additions & 6 deletions clang/lib/Interpreter/IncrementalParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,16 +375,22 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) {
TranslationUnitDecl *MostRecentTU = PTU.TUPart;
TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl();
if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) {
for (auto I = Map->begin(); I != Map->end(); ++I) {
StoredDeclsList &List = I->second;
for (auto &&[Key, List] : *Map) {
DeclContextLookupResult R = List.getLookupResult();
std::vector<NamedDecl *> NamedDeclsToRemove;
bool RemoveAll = true;
for (NamedDecl *D : R) {
if (D->getTranslationUnitDecl() == MostRecentTU) {
if (D->getTranslationUnitDecl() == MostRecentTU)
NamedDeclsToRemove.push_back(D);
else
RemoveAll = false;
}
if (LLVM_LIKELY(RemoveAll)) {
Map->erase(Key);
} else {
for (NamedDecl *D : NamedDeclsToRemove)
List.remove(D);
}
}
if (List.isNull())
Map->erase(I);
}
}
}
Expand Down
16 changes: 10 additions & 6 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ namespace sema {
class SemaPPCallbacks : public PPCallbacks {
Sema *S = nullptr;
llvm::SmallVector<SourceLocation, 8> IncludeStack;
llvm::SmallVector<llvm::TimeTraceProfilerEntry *, 8> ProfilerStack;

public:
void set(Sema &S) { this->S = &S; }
Expand All @@ -153,8 +154,8 @@ class SemaPPCallbacks : public PPCallbacks {
if (IncludeLoc.isValid()) {
if (llvm::timeTraceProfilerEnabled()) {
OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getFileID(Loc));
llvm::timeTraceProfilerBegin("Source", FE ? FE->getName()
: StringRef("<unknown>"));
ProfilerStack.push_back(llvm::timeTraceAsyncProfilerBegin(
"Source", FE ? FE->getName() : StringRef("<unknown>")));
}

IncludeStack.push_back(IncludeLoc);
Expand All @@ -167,7 +168,7 @@ class SemaPPCallbacks : public PPCallbacks {
case ExitFile:
if (!IncludeStack.empty()) {
if (llvm::timeTraceProfilerEnabled())
llvm::timeTraceProfilerEnd();
llvm::timeTraceProfilerEnd(ProfilerStack.pop_back_val());

S->DiagnoseNonDefaultPragmaAlignPack(
Sema::PragmaAlignPackDiagnoseKind::ChangedStateAtExit,
Expand Down Expand Up @@ -2064,8 +2065,11 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) {
targetDiag(D->getLocation(), diag::note_defined_here, FD) << D;
}

if (TI.hasRISCVVTypes() && Ty->isRVVSizelessBuiltinType())
checkRVVTypeSupport(Ty, Loc, D);
if (TI.hasRISCVVTypes() && Ty->isRVVSizelessBuiltinType() && FD) {
llvm::StringMap<bool> CallerFeatureMap;
Context.getFunctionFeatureMap(CallerFeatureMap, FD);
checkRVVTypeSupport(Ty, Loc, D, CallerFeatureMap);
}

// Don't allow SVE types in functions without a SVE target.
if (Ty->isSVESizelessBuiltinType() && FD && FD->hasBody()) {
Expand Down Expand Up @@ -2206,7 +2210,7 @@ static void checkEscapingByref(VarDecl *VD, Sema &S) {
// block copy/destroy functions. Resolve it here.
if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
if (CXXDestructorDecl *DD = RD->getDestructor()) {
auto *FPT = DD->getType()->getAs<FunctionProtoType>();
auto *FPT = DD->getType()->castAs<FunctionProtoType>();
S.ResolveExceptionSpec(Loc, FPT);
}
}
Expand Down
41 changes: 23 additions & 18 deletions clang/lib/Sema/SemaAPINotes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,49 +52,54 @@ static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability,
if (!Metadata.IsActive)
return;

auto IsModified = [&](Decl *D, QualType QT,
NullabilityKind Nullability) -> bool {
auto GetModified =
[&](Decl *D, QualType QT,
NullabilityKind Nullability) -> std::optional<QualType> {
QualType Original = QT;
S.CheckImplicitNullabilityTypeSpecifier(QT, Nullability, D->getLocation(),
isa<ParmVarDecl>(D),
/*OverrideExisting=*/true);
return QT.getTypePtr() != Original.getTypePtr();
return (QT.getTypePtr() != Original.getTypePtr()) ? std::optional(QT)
: std::nullopt;
};

if (auto Function = dyn_cast<FunctionDecl>(D)) {
if (IsModified(D, Function->getReturnType(), Nullability)) {
QualType FnType = Function->getType();
Function->setType(FnType);
if (auto Modified =
GetModified(D, Function->getReturnType(), Nullability)) {
const FunctionType *FnType = Function->getType()->castAs<FunctionType>();
if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(FnType))
Function->setType(S.Context.getFunctionType(
*Modified, proto->getParamTypes(), proto->getExtProtoInfo()));
else
Function->setType(
S.Context.getFunctionNoProtoType(*Modified, FnType->getExtInfo()));
}
} else if (auto Method = dyn_cast<ObjCMethodDecl>(D)) {
QualType Type = Method->getReturnType();
if (IsModified(D, Type, Nullability)) {
Method->setReturnType(Type);
if (auto Modified = GetModified(D, Method->getReturnType(), Nullability)) {
Method->setReturnType(*Modified);

// Make it a context-sensitive keyword if we can.
if (!isIndirectPointerType(Type))
if (!isIndirectPointerType(*Modified))
Method->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
Method->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
}
} else if (auto Value = dyn_cast<ValueDecl>(D)) {
QualType Type = Value->getType();
if (IsModified(D, Type, Nullability)) {
Value->setType(Type);
if (auto Modified = GetModified(D, Value->getType(), Nullability)) {
Value->setType(*Modified);

// Make it a context-sensitive keyword if we can.
if (auto Parm = dyn_cast<ParmVarDecl>(D)) {
if (Parm->isObjCMethodParameter() && !isIndirectPointerType(Type))
if (Parm->isObjCMethodParameter() && !isIndirectPointerType(*Modified))
Parm->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
Parm->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
}
}
} else if (auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
QualType Type = Property->getType();
if (IsModified(D, Type, Nullability)) {
Property->setType(Type, Property->getTypeSourceInfo());
if (auto Modified = GetModified(D, Property->getType(), Nullability)) {
Property->setType(*Modified, Property->getTypeSourceInfo());

// Make it a property attribute if we can.
if (!isIndirectPointerType(Type))
if (!isIndirectPointerType(*Modified))
Property->setPropertyAttributes(
ObjCPropertyAttribute::kind_null_resettable);
}
Expand Down
Loading