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
69 changes: 45 additions & 24 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,51 @@ cplusplus
C++ Checkers.
.. _cplusplus-ArrayDelete:
cplusplus.ArrayDelete (C++)
"""""""""""""""""""""""""""
Reports destructions of arrays of polymorphic objects that are destructed as
their base class. If the dynamic type of the array is different from its static
type, calling `delete[]` is undefined.
This checker corresponds to the SEI CERT rule `EXP51-CPP: Do not delete an array through a pointer of the incorrect type <https://wiki.sei.cmu.edu/confluence/display/cplusplus/EXP51-CPP.+Do+not+delete+an+array+through+a+pointer+of+the+incorrect+type>`_.
.. code-block:: cpp
class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {};
Base *create() {
Base *x = new Derived[10]; // note: Casting from 'Derived' to 'Base' here
return x;
}
void foo() {
Base *x = create();
delete[] x; // warn: Deleting an array of 'Derived' objects as their base class 'Base' is undefined
}
**Limitations**
The checker does not emit note tags when casting to and from reference types,
even though the pointer values are tracked across references.
.. code-block:: cpp
void foo() {
Derived *d = new Derived[10];
Derived &dref = *d;
Base &bref = static_cast<Base&>(dref); // no note
Base *b = &bref;
delete[] b; // warn: Deleting an array of 'Derived' objects as their base class 'Base' is undefined
}
.. _cplusplus-InnerPointer:
cplusplus.InnerPointer (C++)
Expand Down Expand Up @@ -2139,30 +2184,6 @@ Either the comparison is useless or there is division by zero.
alpha.cplusplus
^^^^^^^^^^^^^^^
.. _alpha-cplusplus-ArrayDelete:
alpha.cplusplus.ArrayDelete (C++)
"""""""""""""""""""""""""""""""""
Reports destructions of arrays of polymorphic objects that are destructed as their base class.
This checker corresponds to the CERT rule `EXP51-CPP: Do not delete an array through a pointer of the incorrect type <https://wiki.sei.cmu.edu/confluence/display/cplusplus/EXP51-CPP.+Do+not+delete+an+array+through+a+pointer+of+the+incorrect+type>`_.
.. code-block:: cpp
class Base {
virtual ~Base() {}
};
class Derived : public Base {}
Base *create() {
Base *x = new Derived[10]; // note: Casting from 'Derived' to 'Base' here
return x;
}
void foo() {
Base *x = create();
delete[] x; // warn: Deleting an array of 'Derived' objects as their base class 'Base' is undefined
}
.. _alpha-cplusplus-DeleteWithNonVirtualDtor:
alpha.cplusplus.DeleteWithNonVirtualDtor (C++)
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
8 changes: 7 additions & 1 deletion clang/include/clang/Analysis/PathDiagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,9 @@ class PathDiagnostic : public llvm::FoldingSetNode {
PathDiagnosticLocation UniqueingLoc;
const Decl *UniqueingDecl;

/// The top-level entry point from which this issue was discovered.
const Decl *AnalysisEntryPoint = nullptr;

/// Lines executed in the path.
std::unique_ptr<FilesToLineNumsMap> ExecutedLines;

Expand All @@ -788,7 +791,7 @@ class PathDiagnostic : public llvm::FoldingSetNode {
PathDiagnostic(StringRef CheckerName, const Decl *DeclWithIssue,
StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
StringRef category, PathDiagnosticLocation LocationToUnique,
const Decl *DeclToUnique,
const Decl *DeclToUnique, const Decl *AnalysisEntryPoint,
std::unique_ptr<FilesToLineNumsMap> ExecutedLines);
~PathDiagnostic();

Expand Down Expand Up @@ -852,6 +855,9 @@ class PathDiagnostic : public llvm::FoldingSetNode {
return *ExecutedLines;
}

/// Get the top-level entry point from which this issue was discovered.
const Decl *getAnalysisEntryPoint() const { return AnalysisEntryPoint; }

/// Return the semantic context where an issue occurred. If the
/// issue occurs along a path, this represents the "central" area
/// where the bug manifests.
Expand Down
14 changes: 14 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -3088,6 +3088,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
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -6069,6 +6069,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
12 changes: 10 additions & 2 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -676,15 +676,23 @@ def Clz : Builtin, BitShort_Int_Long_LongLongTemplate {
let Prototype = "int(unsigned T)";
}

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

def Ctz : Builtin, BitShort_Int_Long_LongLongTemplate {
let Spellings = ["__builtin_ctz"];
let Attributes = [NoThrow, Const, Constexpr];
let Prototype = "int(unsigned T)";
}

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

def FFS : Builtin, BitInt_Long_LongLongTemplate {
let Spellings = ["__builtin_ffs"];
Expand Down
11 changes: 4 additions & 7 deletions clang/include/clang/Basic/BuiltinsAMDGPU.def
Original file line number Diff line number Diff line change
Expand Up @@ -432,13 +432,10 @@ TARGET_BUILTIN(__builtin_amdgcn_s_wakeup_barrier, "vi", "n", "gfx12-insts")
TARGET_BUILTIN(__builtin_amdgcn_s_barrier_leave, "b", "n", "gfx12-insts")
TARGET_BUILTIN(__builtin_amdgcn_s_get_barrier_state, "Uii", "n", "gfx12-insts")

TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v2i32, "V2iV2i*1", "nc", "gfx12-insts,wavefrontsize32")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v8i16, "V8sV8s*1", "nc", "gfx12-insts,wavefrontsize32")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v8f16, "V8hV8h*1", "nc", "gfx12-insts,wavefrontsize32")

TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_i32, "ii*1", "nc", "gfx12-insts,wavefrontsize64")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v4i16, "V4sV4s*1", "nc", "gfx12-insts,wavefrontsize64")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v4f16, "V4hV4h*1", "nc", "gfx12-insts,wavefrontsize64")
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_b64_i32, "ii*1", "nc", "gfx12-insts,wavefrontsize64")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4i16, "V4sV4s*1", "nc", "gfx12-insts,wavefrontsize64")

//===----------------------------------------------------------------------===//
// WMMA builtins.
Expand Down
7 changes: 5 additions & 2 deletions clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,10 @@ def SelTypeCast : DiagGroup<"cast-of-sel-type">;
def FunctionDefInObjCContainer : DiagGroup<"function-def-in-objc-container">;
def BadFunctionCast : DiagGroup<"bad-function-cast">;
def CastFunctionTypeStrict : DiagGroup<"cast-function-type-strict">;
def CastFunctionType : DiagGroup<"cast-function-type", [CastFunctionTypeStrict]>;
def CastFunctionTypeMismatch : DiagGroup<"cast-function-type-mismatch">;
def CastFunctionType : DiagGroup<"cast-function-type",
[CastFunctionTypeStrict,
CastFunctionTypeMismatch]>;
def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">;
def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">;
def ObjCPropertyAssignOnObjectType : DiagGroup<"objc-property-assign-on-object-type">;
Expand Down Expand Up @@ -1038,7 +1041,7 @@ def Extra : DiagGroup<"extra", [
EmptyInitStatement,
StringConcatation,
FUseLdPath,
CastFunctionType,
CastFunctionTypeMismatch,
]>;

def Most : DiagGroup<"most", [
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ let CategoryName = "Command line" in {
def err_cannot_write_file : Error<"cannot write file '%0': %1">;
def err_no_install_name : Error<"no install name specified: add -install_name <path>">;
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>;
} // end of command line category.

let CategoryName = "Verification" in {
Expand All @@ -26,6 +29,7 @@ def warn_library_hidden_symbol : Warning<"declaration has external linkage, but
def warn_header_hidden_symbol : Warning<"symbol exported in dynamic library, but marked hidden in declaration '%0'">, InGroup<InstallAPIViolation>;
def err_header_hidden_symbol : Error<"symbol exported in dynamic library, but marked hidden in declaration '%0'">;
def err_header_symbol_missing : Error<"no declaration found for exported symbol '%0' in dynamic library">;
def warn_header_symbol_missing : Warning<"no declaration was found for exported symbol '%0' in dynamic library">, InGroup<InstallAPIViolation>;
def warn_header_availability_mismatch : Warning<"declaration '%0' is marked %select{available|unavailable}1,"
" but symbol is %select{not |}2exported in dynamic library">, InGroup<InstallAPIViolation>;
def err_header_availability_mismatch : Error<"declaration '%0' is marked %select{available|unavailable}1,"
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ def err_expected_semi_after_namespace_name : Error<
"expected ';' after namespace name">;
def err_unexpected_namespace_attributes_alias : Error<
"attributes cannot be specified on namespace alias">;
def err_unexpected_qualified_namespace_alias : Error<
"namespace alias must be a single identifier">;
def err_unexpected_nested_namespace_attribute : Error<
"attributes cannot be specified on a nested namespace definition">;
def err_inline_namespace_alias : Error<"namespace alias cannot be inline">;
Expand Down Expand Up @@ -1029,6 +1031,7 @@ def err_expected_lambda_body : Error<"expected body of lambda expression">;
def warn_cxx98_compat_lambda : Warning<
"lambda expressions are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def ext_lambda : ExtWarn<"lambdas are a C++11 extension">, InGroup<CXX11>;
def err_lambda_decl_specifier_repeated : Error<
"%select{'mutable'|'static'|'constexpr'|'consteval'}0 cannot "
"appear multiple times in a lambda declarator">;
Expand Down
17 changes: 9 additions & 8 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -9058,7 +9058,7 @@ def warn_bad_function_cast : Warning<
InGroup<BadFunctionCast>, DefaultIgnore;
def warn_cast_function_type : Warning<
"cast %diff{from $ to $ |}0,1converts to incompatible function type">,
InGroup<CastFunctionType>, DefaultIgnore;
InGroup<CastFunctionTypeMismatch>, DefaultIgnore;
def warn_cast_function_type_strict : Warning<warn_cast_function_type.Summary>,
InGroup<CastFunctionTypeStrict>, DefaultIgnore;
def err_cast_pointer_to_non_pointer_int : Error<
Expand Down Expand Up @@ -12020,13 +12020,14 @@ def err_builtin_launder_invalid_arg : Error<
"'__builtin_launder' is not allowed">;

def err_builtin_invalid_arg_type: Error <
"%ordinal0 argument must be a "
"%select{vector, integer or floating point type|matrix|"
"pointer to a valid matrix element type|"
"signed integer or floating point type|vector type|"
"floating point type|"
"vector of integers|"
"type of unsigned integer}1 (was %2)">;
"%ordinal0 argument must be "
"%select{a vector, integer or floating point type|a matrix|"
"a pointer to a valid matrix element type|"
"a signed integer or floating point type|a vector type|"
"a floating point type|"
"a vector of integers|"
"an unsigned integer|"
"an 'int'}1 (was %2)">;

def err_builtin_matrix_disabled: Error<
"matrix types extension is disabled. Pass -fenable-matrix to enable it">;
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ EXTENSION(cxx_defaulted_functions, LangOpts.CPlusPlus)
EXTENSION(cxx_deleted_functions, LangOpts.CPlusPlus)
EXTENSION(cxx_explicit_conversions, LangOpts.CPlusPlus)
EXTENSION(cxx_inline_namespaces, LangOpts.CPlusPlus)
EXTENSION(cxx_lambdas, LangOpts.CPlusPlus)
EXTENSION(cxx_local_type_template_args, LangOpts.CPlusPlus)
EXTENSION(cxx_nonstatic_member_init, LangOpts.CPlusPlus)
EXTENSION(cxx_override_control, LangOpts.CPlusPlus)
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Basic/LangStandard.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ enum class Language : uint8_t {
/// Assembly: we accept this only so that we can preprocess it.
Asm,

/// LLVM IR: we accept this so that we can run the optimizer on it,
/// and compile it to assembly or object code.
/// LLVM IR & CIR: we accept these so that we can run the optimizer on them,
/// and compile them to assembly or object code (or LLVM for CIR).
CIR,
LLVM_IR,

///@{ Languages that the frontend can parse and compile.
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
11 changes: 5 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 Expand Up @@ -6688,6 +6684,9 @@ def analyzer_opt_analyze_headers : Flag<["-"], "analyzer-opt-analyze-headers">,
def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">,
HelpText<"Emit verbose output about the analyzer's progress">,
MarshallingInfoFlag<AnalyzerOpts<"AnalyzerDisplayProgress">>;
def analyzer_note_analysis_entry_points : Flag<["-"], "analyzer-note-analysis-entry-points">,
HelpText<"Add a note for each bug report to denote their analysis entry points">,
MarshallingInfoFlag<AnalyzerOpts<"AnalyzerNoteAnalysisEntryPoints">>;
def analyze_function : Separate<["-"], "analyze-function">,
HelpText<"Run analysis on specific function (for C++ include parameters in name)">,
MarshallingInfoString<AnalyzerOpts<"AnalyzeSpecificFunction">>;
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Driver/Types.def
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ TYPE("ir", LLVM_BC, INVALID, "bc", phases
TYPE("lto-ir", LTO_IR, INVALID, "s", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("lto-bc", LTO_BC, INVALID, "o", phases::Compile, phases::Backend, phases::Assemble, phases::Link)

TYPE("cir", CIR, INVALID, "cir", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
// Misc.
TYPE("ast", AST, INVALID, "ast", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("ifs", IFS, INVALID, "ifs", phases::IfsMerge)
Expand Down
17 changes: 17 additions & 0 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,21 @@ struct FormatStyle {
/// \version 17
ShortCaseStatementsAlignmentStyle AlignConsecutiveShortCaseStatements;

/// Style of aligning consecutive TableGen DAGArg operator colons.
/// If enabled, align the colon inside DAGArg which have line break inside.
/// This works only when TableGenBreakInsideDAGArg is BreakElements or
/// BreakAll and the DAGArg is not excepted by
/// TableGenBreakingDAGArgOperators's effect.
/// \code
/// let dagarg = (ins
/// a :$src1,
/// aa :$src2,
/// aaa:$src3
/// )
/// \endcode
/// \version 19
AlignConsecutiveStyle AlignConsecutiveTableGenBreakingDAGArgColons;

/// Style of aligning consecutive TableGen cond operator colons.
/// Align the colons of cases inside !cond operators.
/// \code
Expand Down Expand Up @@ -4879,6 +4894,8 @@ struct FormatStyle {
AlignConsecutiveMacros == R.AlignConsecutiveMacros &&
AlignConsecutiveShortCaseStatements ==
R.AlignConsecutiveShortCaseStatements &&
AlignConsecutiveTableGenBreakingDAGArgColons ==
R.AlignConsecutiveTableGenBreakingDAGArgColons &&
AlignConsecutiveTableGenCondOperatorColons ==
R.AlignConsecutiveTableGenCondOperatorColons &&
AlignConsecutiveTableGenDefinitionColons ==
Expand Down
13 changes: 12 additions & 1 deletion clang/include/clang/InstallAPI/DylibVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ enum class VerificationMode {
/// lifetime of InstallAPI.
/// As declarations are collected during AST traversal, they are
/// compared as symbols against what is available in the binary dylib.
class DylibVerifier {
class DylibVerifier : llvm::MachO::RecordVisitor {
private:
struct SymbolContext;

Expand Down Expand Up @@ -72,6 +72,9 @@ class DylibVerifier {
Result verify(ObjCIVarRecord *R, const FrontendAttrs *FA,
const StringRef SuperClass);

// Scan through dylib slices and report any remaining missing exports.
Result verifyRemainingSymbols();

/// Initialize target for verification.
void setTarget(const Target &T);

Expand Down Expand Up @@ -128,6 +131,14 @@ class DylibVerifier {
/// Find matching dylib slice for target triple that is being parsed.
void assignSlice(const Target &T);

/// Shared implementation for verifying exported symbols in dylib.
void visitSymbolInDylib(const Record &R, SymbolContext &SymCtx);

void visitGlobal(const GlobalRecord &R) override;
void visitObjCInterface(const ObjCInterfaceRecord &R) override;
void visitObjCCategory(const ObjCCategoryRecord &R) override;
void visitObjCIVar(const ObjCIVarRecord &R, const StringRef Super);

/// Gather annotations for symbol for error reporting.
std::string getAnnotatedName(const Record *R, SymbolContext &SymCtx,
bool ValidSourceLoc = true);
Expand Down
54 changes: 52 additions & 2 deletions clang/include/clang/InstallAPI/HeaderFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
#ifndef LLVM_CLANG_INSTALLAPI_HEADERFILE_H
#define LLVM_CLANG_INSTALLAPI_HEADERFILE_H

#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangStandard.h"
#include "clang/InstallAPI/MachO.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Regex.h"
Expand Down Expand Up @@ -56,6 +58,10 @@ class HeaderFile {
std::string IncludeName;
/// Supported language mode for header.
std::optional<clang::Language> Language;
/// Exclude header file from processing.
bool Excluded{false};
/// Add header file to processing.
bool Extra{false};

public:
HeaderFile() = delete;
Expand All @@ -71,17 +77,48 @@ class HeaderFile {
StringRef getIncludeName() const { return IncludeName; }
StringRef getPath() const { return FullPath; }

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

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

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

/// Glob that represents a pattern of header files to retreive.
class HeaderGlob {
private:
std::string GlobString;
llvm::Regex Rule;
HeaderType Type;
bool FoundMatch{false};

public:
HeaderGlob(StringRef GlobString, llvm::Regex &&, HeaderType Type);

/// Create a header glob from string for the header access level.
static llvm::Expected<std::unique_ptr<HeaderGlob>>
create(StringRef GlobString, HeaderType Type);

/// Query if provided header matches glob.
bool match(const HeaderFile &Header);

/// Query if a header was matched in the glob, used primarily for error
/// reporting.
bool didMatch() { return FoundMatch; }

/// Provide back input glob string.
StringRef str() { return GlobString; }
};

/// Assemble expected way header will be included by clients.
/// As in what maps inside the brackets of `#include <IncludeName.h>`
/// For example,
Expand All @@ -93,6 +130,19 @@ class HeaderFile {
std::optional<std::string> createIncludeHeaderName(const StringRef FullPath);
using HeaderSeq = std::vector<HeaderFile>;

/// Determine if Path is a header file.
/// It does not touch the file system.
///
/// \param Path File path to file.
bool isHeaderFile(StringRef Path);

/// Given input directory, collect all header files.
///
/// \param FM FileManager for finding input files.
/// \param Directory Path to directory file.
llvm::Expected<PathSeq> enumerateFiles(clang::FileManager &FM,
StringRef Directory);

} // namespace clang::installapi

#endif // LLVM_CLANG_INSTALLAPI_HEADERFILE_H
1 change: 1 addition & 0 deletions clang/include/clang/InstallAPI/MachO.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ using SymbolSet = llvm::MachO::SymbolSet;
using SimpleSymbol = llvm::MachO::SimpleSymbol;
using FileType = llvm::MachO::FileType;
using PackedVersion = llvm::MachO::PackedVersion;
using PathSeq = llvm::MachO::PathSeq;
using Target = llvm::MachO::Target;
using TargetList = llvm::MachO::TargetList;

Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/Interpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
namespace llvm {
namespace orc {
class LLJIT;
class LLJITBuilder;
class ThreadSafeContext;
} // namespace orc
} // namespace llvm
Expand Down Expand Up @@ -127,6 +128,13 @@ class Interpreter {
// custom runtime.
virtual std::unique_ptr<RuntimeInterfaceBuilder> FindRuntimeInterface();

// Lazily construct thev ORCv2 JITBuilder. This called when the internal
// IncrementalExecutor is created. The default implementation populates an
// in-process JIT with debugging support. Override this to configure the JIT
// engine used for execution.
virtual llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
CreateJITBuilder(CompilerInstance &CI);

public:
virtual ~Interpreter();

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Interpreter/Value.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class QualType;
X(bool, Bool) \
X(char, Char_S) \
X(signed char, SChar) \
X(unsigned char, Char_U) \
X(unsigned char, UChar) \
X(short, Short) \
X(unsigned short, UShort) \
Expand Down
10 changes: 5 additions & 5 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,11 @@ def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,

let ParentPackage = Cplusplus in {

def ArrayDeleteChecker : Checker<"ArrayDelete">,
HelpText<"Reports destructions of arrays of polymorphic objects that are "
"destructed as their base class.">,
Documentation<HasDocumentation>;

def InnerPointerChecker : Checker<"InnerPointer">,
HelpText<"Check for inner pointers of C++ containers used after "
"re/deallocation">,
Expand Down Expand Up @@ -777,11 +782,6 @@ def ContainerModeling : Checker<"ContainerModeling">,
Documentation<NotDocumented>,
Hidden;

def CXXArrayDeleteChecker : Checker<"ArrayDelete">,
HelpText<"Reports destructions of arrays of polymorphic objects that are "
"destructed as their base class.">,
Documentation<HasDocumentation>;

def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">,
HelpText<"Reports destructions of polymorphic objects with a non-virtual "
"destructor in their base class">,
Expand Down
9 changes: 5 additions & 4 deletions clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
unsigned AnalyzeAll : 1;
unsigned AnalyzerDisplayProgress : 1;
unsigned AnalyzerNoteAnalysisEntryPoints : 1;

unsigned eagerlyAssumeBinOpBifurcation : 1;

Expand Down Expand Up @@ -291,10 +292,10 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
ShowConfigOptionsList(false),
ShouldEmitErrorsOnInvalidConfigValue(false), AnalyzeAll(false),
AnalyzerDisplayProgress(false), eagerlyAssumeBinOpBifurcation(false),
TrimGraph(false), visualizeExplodedGraphWithGraphViz(false),
UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false),
AnalyzerWerror(false) {}
AnalyzerDisplayProgress(false), AnalyzerNoteAnalysisEntryPoints(false),
eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false),
PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) {}

/// Interprets an option's string value as a boolean. The "true" string is
/// interpreted as true and the "false" string is interpreted as false.
Expand Down
12 changes: 12 additions & 0 deletions clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,9 @@ class BugReporter {
private:
BugReporterData& D;

/// The top-level entry point for the issue to be reported.
const Decl *AnalysisEntryPoint = nullptr;

/// Generate and flush the diagnostics for the given bug report.
void FlushReport(BugReportEquivClass& EQ);

Expand Down Expand Up @@ -623,6 +626,14 @@ class BugReporter {

Preprocessor &getPreprocessor() { return D.getPreprocessor(); }

/// Get the top-level entry point for the issue to be reported.
const Decl *getAnalysisEntryPoint() const { return AnalysisEntryPoint; }

void setAnalysisEntryPoint(const Decl *EntryPoint) {
assert(EntryPoint);
AnalysisEntryPoint = EntryPoint;
}

/// Add the given report to the set of reports tracked by BugReporter.
///
/// The reports are usually generated by the checkers. Further, they are
Expand Down Expand Up @@ -713,6 +724,7 @@ class BugReporterContext {
virtual ~BugReporterContext() = default;

PathSensitiveBugReporter& getBugReporter() { return BR; }
const PathSensitiveBugReporter &getBugReporter() const { return BR; }

ProgramStateManager& getStateManager() const {
return BR.getStateManager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,8 @@ class CallDescription {
/// - We also accept calls where the number of arguments or parameters is
/// greater than the specified value.
/// For the exact heuristics, see CheckerContext::isCLibraryFunction().
/// Note that functions whose declaration context is not a TU (e.g.
/// methods, functions in namespaces) are not accepted as C library
/// functions.
/// FIXME: If I understand it correctly, this discards calls where C++ code
/// refers a C library function through the namespace `std::` via headers
/// like <cstdlib>.
/// (This mode only matches functions that are declared either directly
/// within a TU or in the namespace `std`.)
CLibrary,

/// Matches "simple" functions that are not methods. (Static methods are
Expand Down
72 changes: 72 additions & 0 deletions clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace ento {

enum CallEventKind {
CE_Function,
CE_CXXStaticOperator,
CE_CXXMember,
CE_CXXMemberOperator,
CE_CXXDestructor,
Expand Down Expand Up @@ -709,6 +710,77 @@ class CXXInstanceCall : public AnyFunctionCall {
}
};

/// Represents a static C++ operator call.
///
/// "A" in this example.
/// However, "B" and "C" are represented by SimpleFunctionCall.
/// \code
/// struct S {
/// int pad;
/// static void operator()(int x, int y);
/// };
/// S s{10};
/// void (*fptr)(int, int) = &S::operator();
///
/// s(1, 2); // A
/// S::operator()(1, 2); // B
/// fptr(1, 2); // C
/// \endcode
class CXXStaticOperatorCall : public SimpleFunctionCall {
friend class CallEventManager;

protected:
CXXStaticOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx,
CFGBlock::ConstCFGElementRef ElemRef)
: SimpleFunctionCall(CE, St, LCtx, ElemRef) {}
CXXStaticOperatorCall(const CXXStaticOperatorCall &Other) = default;

void cloneTo(void *Dest) const override {
new (Dest) CXXStaticOperatorCall(*this);
}

public:
const CXXOperatorCallExpr *getOriginExpr() const override {
return cast<CXXOperatorCallExpr>(SimpleFunctionCall::getOriginExpr());
}

unsigned getNumArgs() const override {
// Ignore the object parameter that is not used for static member functions.
assert(getOriginExpr()->getNumArgs() > 0);
return getOriginExpr()->getNumArgs() - 1;
}

const Expr *getArgExpr(unsigned Index) const override {
// Ignore the object parameter that is not used for static member functions.
return getOriginExpr()->getArg(Index + 1);
}

std::optional<unsigned>
getAdjustedParameterIndex(unsigned ASTArgumentIndex) const override {
// Ignore the object parameter that is not used for static member functions.
if (ASTArgumentIndex == 0)
return std::nullopt;
return ASTArgumentIndex - 1;
}

unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const override {
// Account for the object parameter for the static member function.
return CallArgumentIndex + 1;
}

OverloadedOperatorKind getOverloadedOperator() const {
return getOriginExpr()->getOperator();
}

Kind getKind() const override { return CE_CXXStaticOperator; }
StringRef getKindAsString() const override { return "CXXStaticOperatorCall"; }

static bool classof(const CallEvent *CA) {
return CA->getKind() == CE_CXXStaticOperator;
}
};

/// Represents a non-static C++ member function call.
///
/// Example: \c obj.fun()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

#include "ProgramState_Fwd.h"
#include "SVals.h"

#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/Basic/OperatorKinds.h"
Expand Down Expand Up @@ -113,8 +112,7 @@ class OperatorKind {
OperatorKind operationKindFromOverloadedOperator(OverloadedOperatorKind OOK,
bool IsBinary);

std::optional<DefinedSVal> getPointeeDefVal(SVal PtrSVal,
ProgramStateRef State);
std::optional<SVal> getPointeeVal(SVal PtrSVal, ProgramStateRef State);

} // namespace ento

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ class ExprEngine {

/// Returns true if there is still simulation state on the worklist.
bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
assert(L->inTopFrame());
BR.setAnalysisEntryPoint(L->getDecl());
return Engine.ExecuteWorkList(L, Steps, nullptr);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,8 @@ class ProgramState : public llvm::FoldingSetNode {
InvalidatedSymbols *IS,
RegionAndSymbolInvalidationTraits *HTraits,
const CallEvent *Call) const;

SVal wrapSymbolicRegion(SVal Base) const;
};

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -782,20 +784,6 @@ inline SVal ProgramState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
return getStateManager().StoreMgr->getLValueIvar(D, Base);
}

inline SVal ProgramState::getLValue(const FieldDecl *D, SVal Base) const {
return getStateManager().StoreMgr->getLValueField(D, Base);
}

inline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
SVal Base) const {
StoreManager &SM = *getStateManager().StoreMgr;
for (const auto *I : D->chain()) {
Base = SM.getLValueField(cast<FieldDecl>(I), Base);
}

return Base;
}

inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
if (std::optional<NonLoc> N = Idx.getAs<NonLoc>())
return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ class EntryRef {
/// The underlying cached entry.
const CachedFileSystemEntry &Entry;

friend class DependencyScanningWorkerFilesystem;

public:
EntryRef(StringRef Name, const CachedFileSystemEntry &Entry)
: Filename(Name), Entry(Entry) {}
Expand Down Expand Up @@ -300,14 +302,15 @@ class DependencyScanningWorkerFilesystem
///
/// Attempts to use the local and shared caches first, then falls back to
/// using the underlying filesystem.
llvm::ErrorOr<EntryRef>
getOrCreateFileSystemEntry(StringRef Filename,
bool DisableDirectivesScanning = false);
llvm::ErrorOr<EntryRef> getOrCreateFileSystemEntry(StringRef Filename);

private:
/// Check whether the file should be scanned for preprocessor directives.
bool shouldScanForDirectives(StringRef Filename);
/// Ensure the directive tokens are populated for this file entry.
///
/// Returns true if the directive tokens are populated for this file entry,
/// false if not (i.e. this entry is not a file or its scan fails).
bool ensureDirectiveTokensArePopulated(EntryRef Entry);

private:
/// For a filename that's not yet associated with any entry in the caches,
/// uses the underlying filesystem to either look up the entry based in the
/// shared cache indexed by unique ID, or creates new entry from scratch.
Expand All @@ -317,11 +320,6 @@ class DependencyScanningWorkerFilesystem
computeAndStoreResult(StringRef OriginalFilename,
StringRef FilenameForLookup);

/// Scan for preprocessor directives for the given entry if necessary and
/// returns a wrapper object with reference semantics.
EntryRef scanForDirectivesIfNecessary(const CachedFileSystemEntry &Entry,
StringRef Filename, bool Disable);

/// Represents a filesystem entry that has been stat-ed (and potentially read)
/// and that's about to be inserted into the cache as `CachedFileSystemEntry`.
struct TentativeEntry {
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
31 changes: 15 additions & 16 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
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
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
9 changes: 4 additions & 5 deletions clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3911,7 +3911,8 @@ void MicrosoftMangleContextImpl::mangleReferenceTemporary(
msvc_hashing_ostream MHO(Out);
MicrosoftCXXNameMangler Mangler(*this, MHO);

Mangler.getStream() << "?$RT" << ManglingNumber << '@';
Mangler.getStream() << "?";
Mangler.mangleSourceName("$RT" + llvm::utostr(ManglingNumber));
Mangler.mangle(VD, "");
}

Expand Down Expand Up @@ -4022,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
29 changes: 20 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
15 changes: 5 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 @@ -2303,15 +2303,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/AdornedCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ llvm::Expected<AdornedCFG> AdornedCFG::build(const Decl &D, Stmt &S,

// The shape of certain elements of the AST can vary depending on the
// language. We currently only support C++.
if (!C.getLangOpts().CPlusPlus)
if (!C.getLangOpts().CPlusPlus || C.getLangOpts().ObjC)
return llvm::createStringError(
std::make_error_code(std::errc::invalid_argument),
"Can only analyze C++");
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
7 changes: 5 additions & 2 deletions clang/lib/Analysis/PathDiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,17 @@ PathDiagnostic::PathDiagnostic(
StringRef CheckerName, const Decl *declWithIssue, StringRef bugtype,
StringRef verboseDesc, StringRef shortDesc, StringRef category,
PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique,
const Decl *AnalysisEntryPoint,
std::unique_ptr<FilesToLineNumsMap> ExecutedLines)
: CheckerName(CheckerName), DeclWithIssue(declWithIssue),
BugType(StripTrailingDots(bugtype)),
VerboseDesc(StripTrailingDots(verboseDesc)),
ShortDesc(StripTrailingDots(shortDesc)),
Category(StripTrailingDots(category)), UniqueingLoc(LocationToUnique),
UniqueingDecl(DeclToUnique), ExecutedLines(std::move(ExecutedLines)),
path(pathImpl) {}
UniqueingDecl(DeclToUnique), AnalysisEntryPoint(AnalysisEntryPoint),
ExecutedLines(std::move(ExecutedLines)), path(pathImpl) {
assert(AnalysisEntryPoint);
}

void PathDiagnosticConsumer::anchor() {}

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
3 changes: 3 additions & 0 deletions clang/lib/Basic/LangStandards.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ StringRef clang::languageToString(Language L) {
return "Asm";
case Language::LLVM_IR:
return "LLVM IR";
case Language::CIR:
return "ClangIR";
case Language::C:
return "C";
case Language::CXX:
Expand Down Expand Up @@ -92,6 +94,7 @@ LangStandard::Kind clang::getDefaultLanguageStandard(clang::Language Lang,
switch (Lang) {
case Language::Unknown:
case Language::LLVM_IR:
case Language::CIR:
llvm_unreachable("Invalid input kind!");
case Language::OpenCL:
return LangStandard::lang_opencl12;
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
105 changes: 68 additions & 37 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3128,36 +3128,66 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_ctzs:
case Builtin::BI__builtin_ctz:
case Builtin::BI__builtin_ctzl:
case Builtin::BI__builtin_ctzll: {
Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero);
case Builtin::BI__builtin_ctzll:
case Builtin::BI__builtin_ctzg: {
bool HasFallback = BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_ctzg &&
E->getNumArgs() > 1;

Value *ArgValue =
HasFallback ? EmitScalarExpr(E->getArg(0))
: EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero);

llvm::Type *ArgType = ArgValue->getType();
Function *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);

llvm::Type *ResultType = ConvertType(E->getType());
Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
Value *ZeroUndef =
Builder.getInt1(HasFallback || getTarget().isCLZForZeroUndef());
Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
if (Result->getType() != ResultType)
Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
"cast");
return RValue::get(Result);
if (!HasFallback)
return RValue::get(Result);

Value *Zero = Constant::getNullValue(ArgType);
Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero");
Value *FallbackValue = EmitScalarExpr(E->getArg(1));
Value *ResultOrFallback =
Builder.CreateSelect(IsZero, FallbackValue, Result, "ctzg");
return RValue::get(ResultOrFallback);
}
case Builtin::BI__builtin_clzs:
case Builtin::BI__builtin_clz:
case Builtin::BI__builtin_clzl:
case Builtin::BI__builtin_clzll: {
Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero);
case Builtin::BI__builtin_clzll:
case Builtin::BI__builtin_clzg: {
bool HasFallback = BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_clzg &&
E->getNumArgs() > 1;

Value *ArgValue =
HasFallback ? EmitScalarExpr(E->getArg(0))
: EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero);

llvm::Type *ArgType = ArgValue->getType();
Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);

llvm::Type *ResultType = ConvertType(E->getType());
Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
Value *ZeroUndef =
Builder.getInt1(HasFallback || getTarget().isCLZForZeroUndef());
Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
if (Result->getType() != ResultType)
Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
"cast");
return RValue::get(Result);
if (!HasFallback)
return RValue::get(Result);

Value *Zero = Constant::getNullValue(ArgType);
Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero");
Value *FallbackValue = EmitScalarExpr(E->getArg(1));
Value *ResultOrFallback =
Builder.CreateSelect(IsZero, FallbackValue, Result, "clzg");
return RValue::get(ResultOrFallback);
}
case Builtin::BI__builtin_ffs:
case Builtin::BI__builtin_ffsl:
Expand Down Expand Up @@ -18036,15 +18066,22 @@ llvm::Value *CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments,
return Arg;
}

Intrinsic::ID getDotProductIntrinsic(QualType QT) {
Intrinsic::ID getDotProductIntrinsic(QualType QT, int elementCount) {
if (QT->hasFloatingRepresentation()) {
switch (elementCount) {
case 2:
return Intrinsic::dx_dot2;
case 3:
return Intrinsic::dx_dot3;
case 4:
return Intrinsic::dx_dot4;
}
}
if (QT->hasSignedIntegerRepresentation())
return Intrinsic::dx_sdot;
if (QT->hasUnsignedIntegerRepresentation())
return Intrinsic::dx_udot;

assert(QT->hasFloatingRepresentation());
return Intrinsic::dx_dot;
;
assert(QT->hasUnsignedIntegerRepresentation());
return Intrinsic::dx_udot;
}

Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
Expand Down Expand Up @@ -18098,8 +18135,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
assert(T0->getScalarType() == T1->getScalarType() &&
"Dot product of vectors need the same element types.");

[[maybe_unused]] auto *VecTy0 =
E->getArg(0)->getType()->getAs<VectorType>();
auto *VecTy0 = E->getArg(0)->getType()->getAs<VectorType>();
[[maybe_unused]] auto *VecTy1 =
E->getArg(1)->getType()->getAs<VectorType>();
// A HLSLVectorTruncation should have happend
Expand All @@ -18108,7 +18144,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,

return Builder.CreateIntrinsic(
/*ReturnType=*/T0->getScalarType(),
getDotProductIntrinsic(E->getArg(0)->getType()),
getDotProductIntrinsic(E->getArg(0)->getType(),
VecTy0->getNumElements()),
ArrayRef<Value *>{Op0, Op1}, nullptr, "dx.dot");
} break;
case Builtin::BI__builtin_hlsl_lerp: {
Expand Down Expand Up @@ -18501,43 +18538,37 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
llvm::Function *F = CGM.getIntrinsic(IID, {ArgTy});
return Builder.CreateCall(F, {Addr, Val, ZeroI32, ZeroI32, ZeroI1});
}
case AMDGPU::BI__builtin_amdgcn_global_load_tr_i32:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_v2i32:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_v4f16:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_v4i16:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_v8f16:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_v8i16: {
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_v4i16:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v8i16: {

Intrinsic::ID IID;
llvm::Type *ArgTy;
switch (BuiltinID) {
case AMDGPU::BI__builtin_amdgcn_global_load_tr_i32:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b64_i32:
ArgTy = llvm::Type::getInt32Ty(getLLVMContext());
IID = Intrinsic::amdgcn_global_load_tr_b64;
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_v2i32:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b64_v2i32:
ArgTy = llvm::FixedVectorType::get(
llvm::Type::getInt32Ty(getLLVMContext()), 2);
IID = Intrinsic::amdgcn_global_load_tr_b64;
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_v4f16:
ArgTy = llvm::FixedVectorType::get(
llvm::Type::getHalfTy(getLLVMContext()), 4);
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_v4i16:
case AMDGPU::BI__builtin_amdgcn_global_load_tr_b128_v4i16:
ArgTy = llvm::FixedVectorType::get(
llvm::Type::getInt16Ty(getLLVMContext()), 4);
IID = Intrinsic::amdgcn_global_load_tr_b128;
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_v8f16:
ArgTy = llvm::FixedVectorType::get(
llvm::Type::getHalfTy(getLLVMContext()), 8);
break;
case AMDGPU::BI__builtin_amdgcn_global_load_tr_v8i16:
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::Value *Addr = EmitScalarExpr(E->getArg(0));
llvm::Function *F =
CGM.getIntrinsic(Intrinsic::amdgcn_global_load_tr, {ArgTy});
llvm::Function *F = CGM.getIntrinsic(IID, {ArgTy});
return Builder.CreateCall(F, {Addr});
}
case AMDGPU::BI__builtin_amdgcn_get_fpenv: {
Expand Down
27 changes: 9 additions & 18 deletions clang/lib/CodeGen/CGCUDANV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,20 +605,10 @@ llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() {
uint64_t VarSize =
CGM.getDataLayout().getTypeAllocSize(Var->getValueType());
if (Info.Flags.isManaged()) {
auto *ManagedVar = new llvm::GlobalVariable(
CGM.getModule(), Var->getType(),
/*isConstant=*/false, Var->getLinkage(),
/*Init=*/Var->isDeclaration()
? nullptr
: llvm::ConstantPointerNull::get(Var->getType()),
/*Name=*/"", /*InsertBefore=*/nullptr,
llvm::GlobalVariable::NotThreadLocal);
ManagedVar->setDSOLocal(Var->isDSOLocal());
ManagedVar->setVisibility(Var->getVisibility());
ManagedVar->setExternallyInitialized(true);
ManagedVar->takeName(Var);
Var->setName(Twine(ManagedVar->getName() + ".managed"));
replaceManagedVar(Var, ManagedVar);
assert(Var->getName().ends_with(".managed") &&
"HIP managed variables not transformed");
auto *ManagedVar = CGM.getModule().getNamedGlobal(
Var->getName().drop_back(StringRef(".managed").size()));
llvm::Value *Args[] = {
&GpuBinaryHandlePtr,
ManagedVar,
Expand Down Expand Up @@ -1093,7 +1083,9 @@ void CGNVCUDARuntime::transformManagedVars() {
: llvm::ConstantPointerNull::get(Var->getType()),
/*Name=*/"", /*InsertBefore=*/nullptr,
llvm::GlobalVariable::NotThreadLocal,
CGM.getContext().getTargetAddressSpace(LangAS::cuda_device));
CGM.getContext().getTargetAddressSpace(CGM.getLangOpts().CUDAIsDevice
? LangAS::cuda_device
: LangAS::Default));
ManagedVar->setDSOLocal(Var->isDSOLocal());
ManagedVar->setVisibility(Var->getVisibility());
ManagedVar->setExternallyInitialized(true);
Expand All @@ -1102,7 +1094,7 @@ void CGNVCUDARuntime::transformManagedVars() {
Var->setName(Twine(ManagedVar->getName()) + ".managed");
// Keep managed variables even if they are not used in device code since
// they need to be allocated by the runtime.
if (!Var->isDeclaration()) {
if (CGM.getLangOpts().CUDAIsDevice && !Var->isDeclaration()) {
assert(!ManagedVar->isDeclaration());
CGM.addCompilerUsedGlobal(Var);
CGM.addCompilerUsedGlobal(ManagedVar);
Expand Down Expand Up @@ -1160,9 +1152,8 @@ void CGNVCUDARuntime::createOffloadingEntries() {

// Returns module constructor to be added.
llvm::Function *CGNVCUDARuntime::finalizeModule() {
transformManagedVars();
if (CGM.getLangOpts().CUDAIsDevice) {
transformManagedVars();

// Mark ODR-used device variables as compiler used to prevent it from being
// eliminated by optimization. This is necessary for device variables
// ODR-used by host functions. Sema correctly marks them as ODR-used no
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -933,8 +933,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 +3086,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
5 changes: 4 additions & 1 deletion clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3239,7 +3239,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 Expand Up @@ -3463,6 +3463,9 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
case Type::BTFTagAttributed:
T = cast<BTFTagAttributedType>(T)->getWrappedType();
break;
case Type::CountAttributed:
T = cast<CountAttributedType>(T)->desugar();
break;
case Type::Elaborated:
T = cast<ElaboratedType>(T)->getNamedType();
break;
Expand Down
43 changes: 27 additions & 16 deletions clang/lib/CodeGen/CGDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1242,27 +1242,38 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
return;
}

// If the initializer is small, use a handful of stores.
// If the initializer is small or trivialAutoVarInit is set, use a handful of
// stores.
bool IsTrivialAutoVarInitPattern =
CGM.getContext().getLangOpts().getTrivialAutoVarInit() ==
LangOptions::TrivialAutoVarInitKind::Pattern;
if (shouldSplitConstantStore(CGM, ConstantSize)) {
if (auto *STy = dyn_cast<llvm::StructType>(Ty)) {
const llvm::StructLayout *Layout =
CGM.getDataLayout().getStructLayout(STy);
for (unsigned i = 0; i != constant->getNumOperands(); i++) {
CharUnits CurOff = CharUnits::fromQuantity(Layout->getElementOffset(i));
Address EltPtr = Builder.CreateConstInBoundsByteGEP(
Loc.withElementType(CGM.Int8Ty), CurOff);
emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
constant->getAggregateElement(i), IsAutoInit);
if (STy == Loc.getElementType() ||
(STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) {
const llvm::StructLayout *Layout =
CGM.getDataLayout().getStructLayout(STy);
for (unsigned i = 0; i != constant->getNumOperands(); i++) {
CharUnits CurOff =
CharUnits::fromQuantity(Layout->getElementOffset(i));
Address EltPtr = Builder.CreateConstInBoundsByteGEP(
Loc.withElementType(CGM.Int8Ty), CurOff);
emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
constant->getAggregateElement(i), IsAutoInit);
}
return;
}
return;
} else if (auto *ATy = dyn_cast<llvm::ArrayType>(Ty)) {
for (unsigned i = 0; i != ATy->getNumElements(); i++) {
Address EltPtr = Builder.CreateConstGEP(
Loc.withElementType(ATy->getElementType()), i);
emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
constant->getAggregateElement(i), IsAutoInit);
if (ATy == Loc.getElementType() ||
(ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) {
for (unsigned i = 0; i != ATy->getNumElements(); i++) {
Address EltPtr = Builder.CreateConstGEP(
Loc.withElementType(ATy->getElementType()), i);
emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
constant->getAggregateElement(i), IsAutoInit);
}
return;
}
return;
}
}

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
Loading