Original file line number Diff line number Diff line change
Expand Up @@ -3,60 +3,61 @@
#define MACRO_A "defining macros outside namespace is valid"

class ClassB;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be enclosed within the 'LIBC_NAMESPACE_DECL' namespace
struct StructC {};
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
char *VarD = MACRO_A;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: declaration must be enclosed within the 'LIBC_NAMESPACE_DECL' namespace
const char *VarD = MACRO_A;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: declaration must be enclosed within the 'LIBC_NAMESPACE_DECL' namespace
typedef int typeE;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: declaration must be enclosed within the 'LIBC_NAMESPACE_DECL' namespace
void funcF() {}
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: declaration must be enclosed within the 'LIBC_NAMESPACE_DECL' namespace

namespace outer_most {
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should be the 'LIBC_NAMESPACE' macro
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should be the 'LIBC_NAMESPACE_DECL' macro
class A {};
}

// Wrapped in anonymous namespace.
namespace {
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: declaration must be enclosed within the 'LIBC_NAMESPACE_DECL' namespace
class A {};
}

namespace namespaceG {
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should be the 'LIBC_NAMESPACE' macro
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the outermost namespace should be the 'LIBC_NAMESPACE_DECL' macro
namespace __llvm_libc {
namespace namespaceH {
class ClassB;
} // namespace namespaceH
struct StructC {};
} // namespace __llvm_libc
char *VarD = MACRO_A;
const char *VarD = MACRO_A;
typedef int typeE;
void funcF() {}
} // namespace namespaceG

// Wrapped in macro namespace but with an incorrect name
#define LIBC_NAMESPACE custom_namespace
namespace LIBC_NAMESPACE {
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the 'LIBC_NAMESPACE' macro should start with '__llvm_libc'
#define LIBC_NAMESPACE_DECL [[gnu::visibility("hidden")]] custom_namespace
namespace LIBC_NAMESPACE_DECL {
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the 'LIBC_NAMESPACE_DECL' macro expansion should start with '__llvm_libc'

namespace namespaceH {
class ClassB;
} // namespace namespaceH
} // namespace LIBC_NAMESPACE
} // namespace LIBC_NAMESPACE_DECL


// Wrapped in macro namespace with a valid name, LIBC_NAMESPACE starts with '__llvm_libc'
#undef LIBC_NAMESPACE
#define LIBC_NAMESPACE __llvm_libc_xyz
namespace LIBC_NAMESPACE {
// Wrapped in macro namespace with a valid name, LIBC_NAMESPACE_DECL starts with '__llvm_libc'
#undef LIBC_NAMESPACE_DECL
#define LIBC_NAMESPACE_DECL [[gnu::visibility("hidden")]] __llvm_libc_xyz
namespace LIBC_NAMESPACE_DECL {
namespace namespaceI {
class ClassB;
} // namespace namespaceI
struct StructC {};
char *VarD = MACRO_A;
const char *VarD = MACRO_A;
typedef int typeE;
void funcF() {}
extern "C" void extern_funcJ() {}
} // namespace LIBC_NAMESPACE
} // namespace LIBC_NAMESPACE_DECL
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ int global_in_extern_c_1;
}

extern "C" int global_in_extern_c_2;

const int const_global = 123;
constexpr int constexpr_global = 123;
208 changes: 208 additions & 0 deletions clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
// RUN: %check_clang_tidy -std=c++20 %s modernize-use-ranges %t
// RUN: %check_clang_tidy -std=c++23 %s modernize-use-ranges %t -check-suffixes=,CPP23

// CHECK-FIXES: #include <algorithm>
// CHECK-FIXES-CPP23: #include <numeric>
// CHECK-FIXES: #include <ranges>

namespace std {

template <typename T> class vector {
public:
using iterator = T *;
using const_iterator = const T *;
using reverse_iterator = T*;
using reverse_const_iterator = const T*;

constexpr const_iterator begin() const;
constexpr const_iterator end() const;
constexpr const_iterator cbegin() const;
constexpr const_iterator cend() const;
constexpr iterator begin();
constexpr iterator end();
constexpr reverse_const_iterator rbegin() const;
constexpr reverse_const_iterator rend() const;
constexpr reverse_const_iterator crbegin() const;
constexpr reverse_const_iterator crend() const;
constexpr reverse_iterator rbegin();
constexpr reverse_iterator rend();
};

template <typename Container> constexpr auto begin(const Container &Cont) {
return Cont.begin();
}

template <typename Container> constexpr auto begin(Container &Cont) {
return Cont.begin();
}

template <typename Container> constexpr auto end(const Container &Cont) {
return Cont.end();
}

template <typename Container> constexpr auto end(Container &Cont) {
return Cont.end();
}

template <typename Container> constexpr auto cbegin(const Container &Cont) {
return Cont.cbegin();
}

template <typename Container> constexpr auto cend(const Container &Cont) {
return Cont.cend();
}

template <typename Container> constexpr auto rbegin(const Container &Cont) {
return Cont.rbegin();
}

template <typename Container> constexpr auto rbegin(Container &Cont) {
return Cont.rbegin();
}

template <typename Container> constexpr auto rend(const Container &Cont) {
return Cont.rend();
}

template <typename Container> constexpr auto rend(Container &Cont) {
return Cont.rend();
}

template <typename Container> constexpr auto crbegin(const Container &Cont) {
return Cont.crbegin();
}

template <typename Container> constexpr auto crend(const Container &Cont) {
return Cont.crend();
}
// Find
template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );

// Reverse
template <typename Iter> void reverse(Iter begin, Iter end);

// Includes
template <class InputIt1, class InputIt2>
bool includes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2);

// IsPermutation
template <class ForwardIt1, class ForwardIt2>
bool is_permutation(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2);
template <class ForwardIt1, class ForwardIt2>
bool is_permutation(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2,
ForwardIt2 last2);

// Equal
template <class InputIt1, class InputIt2>
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2);

template <class InputIt1, class InputIt2>
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2);

template <class InputIt1, class InputIt2, class BinaryPred>
bool equal(InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2, BinaryPred p) {
// Need a definition to suppress undefined_internal_type when invoked with lambda
return true;
}

template <class ForwardIt, class T>
void iota(ForwardIt first, ForwardIt last, T value);

} // namespace std

void Positives() {
std::vector<int> I, J;
std::find(I.begin(), I.end(), 0);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::find(I, 0);

std::find(I.cbegin(), I.cend(), 1);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::find(I, 1);

std::find(std::begin(I), std::end(I), 2);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::find(I, 2);

std::find(std::cbegin(I), std::cend(I), 3);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::find(I, 3);

std::find(std::cbegin(I), I.cend(), 4);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::find(I, 4);

std::reverse(I.begin(), I.end());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::reverse(I);

std::includes(I.begin(), I.end(), I.begin(), I.end());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::includes(I, I);

std::includes(I.begin(), I.end(), J.begin(), J.end());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::includes(I, J);

std::is_permutation(I.begin(), I.end(), J.begin(), J.end());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::is_permutation(I, J);

std::equal(I.begin(), I.end(), J.begin(), J.end());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::equal(I, J);

std::equal(I.begin(), I.end(), J.begin(), J.end(), [](int a, int b){ return a == b; });
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::equal(I, J, [](int a, int b){ return a == b; });

std::iota(I.begin(), I.end(), 0);
// CHECK-MESSAGES-CPP23: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES-CPP23: std::ranges::iota(I, 0);

using std::find;
namespace my_std = std;

// Potentially these could be updated to better qualify the replaced function name
find(I.begin(), I.end(), 5);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::find(I, 5);

my_std::find(I.begin(), I.end(), 6);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::find(I, 6);
}

void Reverse(){
std::vector<int> I, J;
std::find(I.rbegin(), I.rend(), 0);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::find(std::views::reverse(I), 0);

std::equal(std::rbegin(I), std::rend(I), J.begin(), J.end());
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::equal(std::views::reverse(I), J);

std::equal(I.begin(), I.end(), std::crbegin(J), std::crend(J));
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES: std::ranges::equal(I, std::views::reverse(J));
}

void Negatives() {
std::vector<int> I, J;
std::find(I.begin(), J.end(), 0);
std::find(I.begin(), I.begin(), 0);
std::find(I.end(), I.begin(), 0);


// Need both ranges for this one
std::is_permutation(I.begin(), I.end(), J.begin());

// We only have one valid match here and the ranges::equal function needs 2 complete ranges
std::equal(I.begin(), I.end(), J.begin());
std::equal(I.begin(), I.end(), J.end(), J.end());
std::equal(std::rbegin(I), std::rend(I), std::rend(J), std::rbegin(J));
std::equal(I.begin(), J.end(), I.begin(), I.end());
}
2 changes: 1 addition & 1 deletion clang/cmake/caches/Fuchsia-stage2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ if(WIN32 OR LLVM_WINSYSROOT)
set(RUNTIMES_${target}_CMAKE_MODULE_LINKER_FLAGS ${WINDOWS_LINK_FLAGS} CACHE STRING "")
endif()

foreach(target aarch64-linux-gnu;armv7-linux-gnueabihf;i386-linux-gnu;riscv64-linux-gnu;x86_64-linux-gnu)
foreach(target aarch64-unknown-linux-gnu;armv7-unknown-linux-gnueabihf;i386-unknown-linux-gnu;riscv64-unknown-linux-gnu;x86_64-unknown-linux-gnu)
if(LINUX_${target}_SYSROOT)
# Set the per-target builtins options.
list(APPEND BUILTIN_TARGETS "${target}")
Expand Down
6 changes: 6 additions & 0 deletions clang/docs/CommandGuide/clang.rst
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,12 @@ number of cross compilers, or may only support a native target.
allowed to generate instructions that are valid on i486 and later processors,
but which may not exist on earlier ones.

.. option:: --print-enabled-extensions

Prints the list of extensions that are enabled for the target specified by the
combination of `--target`, `-march`, and `-mcpu` values. Currently, this
option is only supported on AArch64 and RISC-V. On RISC-V, this option also
prints out the ISA string of enabled extensions.

Code Generation Options
~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
107 changes: 97 additions & 10 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ code bases.
C/C++ Language Potentially Breaking Changes
-------------------------------------------

- Clang now supports raw string literals in ``-std=gnuXY`` mode as an extension in
C99 and later. This behaviour can also be overridden using ``-f[no-]raw-string-literals``.
Support of raw string literals in C++ is not affected. Fixes (#GH85703).

C++ Specific Potentially Breaking Changes
-----------------------------------------
- Clang now diagnoses function/variable templates that shadow their own template parameters, e.g. ``template<class T> void T();``.
Expand Down Expand Up @@ -99,7 +103,7 @@ ABI Changes in This Version
ifuncs. Its purpose was to preserve backwards compatibility when the ".ifunc"
suffix got removed from the name mangling. The alias interacts badly with
GlobalOpt (see the issue #96197).

- Fixed Microsoft name mangling for auto non-type template arguments of pointer
type for MSVC 1920+. This change resolves incompatibilities with code compiled
by MSVC 1920+ but will introduce incompatibilities with code compiled by
Expand Down Expand Up @@ -306,6 +310,9 @@ Resolutions to C++ Defect Reports
- Clang now considers ``noexcept(typeid(expr))`` more carefully, instead of always assuming that ``std::bad_typeid`` can be thrown.
(`CWG2191: Incorrect result for noexcept(typeid(v)) <https://cplusplus.github.io/CWG/issues/2191.html>`_).

- Clang now correctly implements lookup for the terminal name of a member-qualified nested-name-specifier.
(`CWG1835: Dependent member lookup before < <https://cplusplus.github.io/CWG/issues/1835.html>`_).

C Language Changes
------------------

Expand Down Expand Up @@ -348,6 +355,12 @@ C23 Feature Support
but C23 added them to ``<float.h>`` in
`WG14 N2848 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2848.pdf>`_.

- Clang now supports `N3017 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3017.htm>`_
``#embed`` - a scannable, tooling-friendly binary resource inclusion mechanism.

- Added the ``FLT_NORM_MAX``, ``DBL_NORM_MAX``, and ``LDBL_NORM_MAX`` to the
freestanding implementation of ``<float.h>`` that ships with Clang.

Non-comprehensive list of changes in this release
-------------------------------------------------

Expand Down Expand Up @@ -442,6 +455,14 @@ New Compiler Flags
- ``-Wc++2c-compat`` group was added to help migrating existing codebases
to upcoming C++26.

- ``-fdisable-block-signature-string`` instructs clang not to emit the signature
string for blocks. Disabling the string can potentially break existing code
that relies on it. Users should carefully consider this possibiilty when using
the flag.

- For the ARM target, added ``-Warm-interrupt-vfp-clobber`` that will emit a
diagnostic when an interrupt handler is declared and VFP is enabled.

Deprecated Compiler Flags
-------------------------

Expand Down Expand Up @@ -484,6 +505,13 @@ Modified Compiler Flags
now include dianostics about C++26 features that are not present in older
versions.

- Removed the "arm interrupt calling convention" warning that was included in
``-Wextra`` without its own flag. This warning suggested adding
``__attribute__((interrupt))`` to functions that are called from interrupt
handlers to prevent clobbering VFP registers. Following this suggestion leads
to unpredictable behavior by causing multiple exception returns from one
exception. Fixes #GH34876.

Removed Compiler Flags
-------------------------

Expand Down Expand Up @@ -546,6 +574,19 @@ Attribute Changes in Clang
size_t count;
};
- The attributes ``sized_by``, ``counted_by_or_null`` and ``sized_by_or_null```
have been added as variants on ``counted_by``, each with slightly different semantics.
``sized_by`` takes a byte size parameter instead of an element count, allowing pointees
with unknown size. The ``counted_by_or_null`` and ``sized_by_or_null`` variants are equivalent
to their base variants, except the pointer can be null regardless of count/size value.
If the pointer is null the size is effectively 0. ``sized_by_or_null`` is needed to properly
annotate allocator functions like ``malloc`` that return a buffer of a given byte size, but can
also return null.

- The ``guarded_by``, ``pt_guarded_by``, ``acquired_after``, ``acquired_before``
attributes now support referencing struct members in C. The arguments are also
now late parsed when ``-fexperimental-late-parse-attributes`` is passed like
for ``counted_by``.

- Introduced new function type attributes ``[[clang::nonblocking]]``, ``[[clang::nonallocating]]``,
``[[clang::blocking]]``, and ``[[clang::allocating]]``, with GNU-style variants as well.
Expand All @@ -554,6 +595,9 @@ Attribute Changes in Clang

Improvements to Clang's diagnostics
-----------------------------------
- Clang now emits an error instead of a warning for ``-Wundefined-internal``
when compiling with `-pedantic-errors` to conform to the C standard

- Clang now applies syntax highlighting to the code snippets it
prints.

Expand Down Expand Up @@ -662,6 +706,13 @@ Improvements to Clang's diagnostics

- Clang now shows implicit deduction guides when diagnosing overload resolution failure. #GH92393.

- Clang no longer emits a "no previous prototype" warning for Win32 entry points under ``-Wmissing-prototypes``.
Fixes #GH94366.

- For the ARM target, calling an interrupt handler from another function is now an error. #GH95359.

- Clang now diagnoses integer constant expressions that are folded to a constant value as an extension in more circumstances. Fixes #GH59863

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

Expand Down Expand Up @@ -770,6 +821,8 @@ Bug Fixes in This Version

- Fixed `static_cast` to array of unknown bound. Fixes (#GH62863).

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

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

Expand Down Expand Up @@ -958,7 +1011,8 @@ Bug Fixes to C++ Support
- Fixed a type constraint substitution issue involving a generic lambda expression. (#GH93821)
- Fix a crash caused by improper use of ``__array_extent``. (#GH80474)
- Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307),
(#GH88081), (#GH89496), (#GH90669) and (#GH91633).
(#GH88081), (#GH89496), (#GH90669), (#GH91633) and (#GH97453).
- Fixed a crash in constraint instantiation under nested lambdas with dependent parameters.
- Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368).
- Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849)
- Fixed a failed assertion when attempting to convert an integer representing the difference
Expand All @@ -975,6 +1029,9 @@ Bug Fixes to C++ Support
evaluated to an integer. (#GH96670).
- Fixed a bug where references to lambda capture inside a ``noexcept`` specifier were not correctly
instantiated. (#GH95735).
- Fixed a CTAD substitution bug involving type aliases that reference outer template parameters. (#GH94614).
- Clang now correctly handles unexpanded packs in the template parameter list of a generic lambda expression
(#GH48937)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -1084,6 +1141,7 @@ RISC-V Support

- ``__attribute__((rvv_vector_bits(N)))`` is now supported for RVV vbool*_t types.
- Profile names in ``-march`` option are now supported.
- Passing empty structs/unions as arguments in C++ is now handled correctly. The behavior is similar to GCC's.

CUDA/HIP Language Changes
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -1166,27 +1224,56 @@ libclang
Static Analyzer
---------------

New features
^^^^^^^^^^^^

- The attribute ``[[clang::suppress]]`` can now be applied to declarations.
(#GH80371)

- Support C++23 static operator calls. (#GH84972)

Crash and bug fixes
^^^^^^^^^^^^^^^^^^^

- Fixed crashing on loops if the loop variable was declared in switch blocks
but not under any case blocks if ``unroll-loops=true`` analyzer config is
set. (#GH68819)
- Support C++23 static operator calls. (#GH84972)

- Fixed a crash in ``security.cert.env.InvalidPtr`` checker when accidentally
matched user-defined ``strerror`` and similar library functions. (GH#88181)
- Fixed a crash when storing through an address that refers to the address of
a label. (GH#89185)
matched user-defined ``strerror`` and similar library functions. (#GH88181)

New features
^^^^^^^^^^^^
- Fixed a crash when storing through an address that refers to the address of
a label. (#GH89185)

Crash and bug fixes
^^^^^^^^^^^^^^^^^^^
- Z3 crosschecking (aka. Z3 refutation) is now bounded, and can't consume
more total time than the eymbolic execution itself. (#GH97298)

Improvements
^^^^^^^^^^^^

Moved checkers
^^^^^^^^^^^^^^

- Moved ``alpha.cplusplus.ArrayDelete`` out of the ``alpha`` package
to ``cplusplus.ArrayDelete``. (#GH83985)
`Documentation <https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-arraydelete-c>`__.

- Moved ``alpha.unix.Stream`` out of the ``alpha`` package to
``unix.Stream``. (#GH89247)
`Documentation <https://clang.llvm.org/docs/analyzer/checkers.html#unix-stream-c>`__.

- Moved ``alpha.unix.BlockInCriticalSection`` out of the ``alpha`` package to
``unix.BlockInCriticalSection``. (#GH93815)
`Documentation <https://clang.llvm.org/docs/analyzer/checkers.html#unix-blockincriticalsection-c-c>`__.

- Moved ``alpha.security.cert.pos.34c`` out of the ``alpha`` package to
``security.PutenvStackArray``. (#GH92424, #GH93815)
`Documentation <https://clang.llvm.org/docs/analyzer/checkers.html#security-putenvstackarray-c>`__.

- Moved ``alpha.core.SizeofPtr`` into ``clang-tidy``
``bugprone-sizeof-expression``. (#GH95118, #GH94356)
`Documentation <https://clang.llvm.org/extra/clang-tidy/checks/bugprone/sizeof-expression.html>`__.

.. _release-notes-sanitizers:

Sanitizers
Expand Down
68 changes: 68 additions & 0 deletions clang/docs/StandardCPlusPlusModules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,74 @@ A high-level overview of support for standards features, including modules, can
be found on the `C++ Feature Status <https://clang.llvm.org/cxx_status.html>`_
page.

Missing VTables for classes attached to modules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Now the compiler may miss emitting the definition of vtables
for classes attached to modules, if the definition of the class
doesn't contain any key function in that module units
(The key function is the first non-pure virtual function that is
not inline at the point of class definition.)

(Note: technically, the key function is not a thing for modules.
We use the concept here for convinient.)

For example,

.. code-block:: c++

// layer1.cppm
export module foo:layer1;
struct Fruit {
virtual ~Fruit() = default;
virtual void eval() = 0;
};
struct Banana : public Fruit {
Banana() {}
void eval() override;
};

// layer2.cppm
export module foo:layer2;
import :layer1;
export void layer2_fun() {
Banana *b = new Banana();
b->eval();
}
void Banana::eval() {
}
For the above example, we can't find the definition for the vtable of
class ``Banana`` in any object files.

The expected behavior is, for dynamic classes attached to named modules,
the vtable should always be emitted to the module units the class attaches
to.

To workaround the problem, users can add the key function manually in the
corresponding module units. e.g.,

.. code-block:: c++

// layer1.cppm
export module foo:layer1;
struct Fruit {
virtual ~Fruit() = default;
virtual void eval() = 0;
};
struct Banana : public Fruit {
// Hack a key function to hint the compiler to emit the virtual table.
virtual void anchor();

Banana() {}
void eval() override;
};

void Banana::anchor() {}

This is tracked by
`#70585 <https://github.com/llvm/llvm-project/issues/70585>`_.

Including headers after import is not well-supported
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
7 changes: 4 additions & 3 deletions clang/docs/ThreadSafetyAnalysis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -764,10 +764,11 @@ doesn't know that munl.mu == mutex. The SCOPED_CAPABILITY attribute handles
aliasing for MutexLocker, but does so only for that particular pattern.


ACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) are currently unimplemented.
-------------------------------------------------------------------------
ACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) support is still experimental.
---------------------------------------------------------------------------

To be fixed in a future update.
ACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) are currently being developed under
the ``-Wthread-safety-beta`` flag.


.. _mutexheader:
Expand Down
6 changes: 6 additions & 0 deletions clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,12 @@ Clang options that don't fit neatly into other categories.
binary compatibility issues on older x86_64 targets, however, so use it with
caution.

.. option:: -fdisable-block-signature-string

Instruct clang not to emit the signature string for blocks. Disabling the
string can potentially break existing code that relies on it. Users should
carefully consider this possibiilty when using the flag.

.. _configuration-files:

Configuration files
Expand Down
11 changes: 4 additions & 7 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1003,17 +1003,14 @@ array new C++ operator is tainted (potentially attacker controlled).
If an attacker can inject a large value as the size parameter, memory exhaustion
denial of service attack can be carried out.
The ``alpha.security.taint.TaintPropagation`` checker also needs to be enabled for
this checker to give warnings.
The analyzer emits warning only if it cannot prove that the size parameter is
within reasonable bounds (``<= SIZE_MAX/4``). This functionality partially
covers the SEI Cert coding standard rule `INT04-C
<https://wiki.sei.cmu.edu/confluence/display/c/INT04-C.+Enforce+limits+on+integer+values+originating+from+tainted+sources>`_.
You can silence this warning either by bound checking the ``size`` parameter, or
by explicitly marking the ``size`` parameter as sanitized. See the
:ref:`alpha-security-taint-TaintPropagation` checker for more details.
:ref:`alpha-security-taint-GenericTaint` checker for an example.
.. code-block:: c
Expand Down Expand Up @@ -3011,10 +3008,10 @@ alpha.security.taint
Checkers implementing
`taint analysis <https://en.wikipedia.org/wiki/Taint_checking>`_.
.. _alpha-security-taint-TaintPropagation:
.. _alpha-security-taint-GenericTaint:
alpha.security.taint.TaintPropagation (C, C++)
""""""""""""""""""""""""""""""""""""""""""""""
alpha.security.taint.GenericTaint (C, C++)
""""""""""""""""""""""""""""""""""""""""""
Taint analysis identifies potential security vulnerabilities where the
attacker can inject malicious data to the program to execute an attack
Expand Down
13 changes: 8 additions & 5 deletions clang/docs/analyzer/user-docs/TaintAnalysisConfiguration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
Taint Analysis Configuration
============================

The Clang Static Analyzer uses taint analysis to detect security-related issues in code.
The backbone of taint analysis in the Clang SA is the `GenericTaintChecker`, which the user can access via the :ref:`alpha-security-taint-TaintPropagation` checker alias and this checker has a default taint-related configuration.
The built-in default settings are defined in code, and they are always in effect once the checker is enabled, either directly or via the alias.
The checker also provides a configuration interface for extending the default settings by providing a configuration file in `YAML <http://llvm.org/docs/YamlIO.html#introduction-to-yaml>`_ format.
The Clang Static Analyzer uses taint analysis to detect injection vulnerability related issues in code.
The backbone of taint analysis in the Clang SA is the ``TaintPropagation`` modeling checker.
The reports are emitted via the :ref:`alpha-security-taint-GenericTaint` checker.
The ``TaintPropagation`` checker has a default taint-related configuration.
The built-in default settings are defined in code, and they are always in effect.
The checker also provides a configuration interface for extending the default settings via the ``alpha.security.taint.TaintPropagation:Config`` checker config parameter
by providing a configuration file to the in `YAML <http://llvm.org/docs/YamlIO.html#introduction-to-yaml>`_ format.
This documentation describes the syntax of the configuration file and gives the informal semantics of the configuration options.

.. contents::
Expand All @@ -18,7 +21,7 @@ ________

Taint analysis works by checking for the occurrence of special operations during the symbolic execution of the program.
Taint analysis defines sources, sinks, and propagation rules. It identifies errors by detecting a flow of information that originates from a taint source, reaches a taint sink, and propagates through the program paths via propagation rules.
A source, sink, or an operation that propagates taint is mainly domain-specific knowledge, but there are some built-in defaults provided by :ref:`alpha-security-taint-TaintPropagation`.
A source, sink, or an operation that propagates taint is mainly domain-specific knowledge, but there are some built-in defaults provided by the ``TaintPropagation`` checker.
It is possible to express that a statement sanitizes tainted values by providing a ``Filters`` section in the external configuration (see :ref:`clangsa-taint-configuration-example` and :ref:`clangsa-taint-filter-details`).
There are no default filters defined in the built-in settings.
The checker's documentation also specifies how to provide a custom taint configuration with command-line options.
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/APINotes/APINotesReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class APINotesReader {
/// \param Name The name of the class we're looking for.
///
/// \returns The information about the class, if known.
VersionedInfo<ObjCContextInfo> lookupObjCClassInfo(llvm::StringRef Name);
VersionedInfo<ContextInfo> lookupObjCClassInfo(llvm::StringRef Name);

/// Look for the context ID of the given Objective-C protocol.
///
Expand All @@ -115,7 +115,7 @@ class APINotesReader {
/// \param Name The name of the protocol we're looking for.
///
/// \returns The information about the protocol, if known.
VersionedInfo<ObjCContextInfo> lookupObjCProtocolInfo(llvm::StringRef Name);
VersionedInfo<ContextInfo> lookupObjCProtocolInfo(llvm::StringRef Name);

/// Look for information regarding the given Objective-C property in
/// the given context.
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/APINotes/APINotesWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ class APINotesWriter {
///
/// \returns the ID of the class, protocol, or namespace, which can be used to
/// add properties and methods to the class/protocol/namespace.
ContextID addObjCContext(std::optional<ContextID> ParentCtxID,
llvm::StringRef Name, ContextKind Kind,
const ObjCContextInfo &Info,
llvm::VersionTuple SwiftVersion);
ContextID addContext(std::optional<ContextID> ParentCtxID,
llvm::StringRef Name, ContextKind Kind,
const ContextInfo &Info,
llvm::VersionTuple SwiftVersion);

/// Add information about a specific Objective-C property.
///
Expand Down
19 changes: 10 additions & 9 deletions clang/include/clang/APINotes/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,9 @@ inline bool operator!=(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
return !(LHS == RHS);
}

/// Describes API notes data for an Objective-C class or protocol.
class ObjCContextInfo : public CommonTypeInfo {
/// Describes API notes data for an Objective-C class or protocol or a C++
/// namespace.
class ContextInfo : public CommonTypeInfo {
/// Whether this class has a default nullability.
LLVM_PREFERRED_TYPE(bool)
unsigned HasDefaultNullability : 1;
Expand All @@ -217,7 +218,7 @@ class ObjCContextInfo : public CommonTypeInfo {
unsigned SwiftObjCMembers : 1;

public:
ObjCContextInfo()
ContextInfo()
: HasDefaultNullability(0), DefaultNullability(0), HasDesignatedInits(0),
SwiftImportAsNonGenericSpecified(false), SwiftImportAsNonGeneric(false),
SwiftObjCMembersSpecified(false), SwiftObjCMembers(false) {}
Expand Down Expand Up @@ -269,9 +270,9 @@ class ObjCContextInfo : public CommonTypeInfo {
DefaultNullability = 0;
}

friend bool operator==(const ObjCContextInfo &, const ObjCContextInfo &);
friend bool operator==(const ContextInfo &, const ContextInfo &);

ObjCContextInfo &operator|=(const ObjCContextInfo &RHS) {
ContextInfo &operator|=(const ContextInfo &RHS) {
// Merge inherited info.
static_cast<CommonTypeInfo &>(*this) |= RHS;

Expand All @@ -294,15 +295,15 @@ class ObjCContextInfo : public CommonTypeInfo {
LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
};

inline bool operator==(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) {
inline bool operator==(const ContextInfo &LHS, const ContextInfo &RHS) {
return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
LHS.getDefaultNullability() == RHS.getDefaultNullability() &&
LHS.HasDesignatedInits == RHS.HasDesignatedInits &&
LHS.getSwiftImportAsNonGeneric() == RHS.getSwiftImportAsNonGeneric() &&
LHS.getSwiftObjCMembers() == RHS.getSwiftObjCMembers();
}

inline bool operator!=(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) {
inline bool operator!=(const ContextInfo &LHS, const ContextInfo &RHS) {
return !(LHS == RHS);
}

Expand Down Expand Up @@ -387,7 +388,7 @@ class ObjCPropertyInfo : public VariableInfo {
friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &);

/// Merge class-wide information into the given property.
ObjCPropertyInfo &operator|=(const ObjCContextInfo &RHS) {
ObjCPropertyInfo &operator|=(const ContextInfo &RHS) {
static_cast<CommonEntityInfo &>(*this) |= RHS;

// Merge nullability.
Expand Down Expand Up @@ -626,7 +627,7 @@ class ObjCMethodInfo : public FunctionInfo {

friend bool operator==(const ObjCMethodInfo &, const ObjCMethodInfo &);

ObjCMethodInfo &operator|=(const ObjCContextInfo &RHS) {
ObjCMethodInfo &operator|=(const ContextInfo &RHS) {
// Merge Nullability.
if (!NullabilityAudited) {
if (auto Nullable = RHS.getDefaultNullability()) {
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
uint16_t
getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);

/// Return the "other" type-specific discriminator for the given type.
uint16_t getPointerAuthTypeDiscriminator(QualType T) const;

/// Apply Objective-C protocol qualifiers to the given type.
/// \param allowOnPointerType specifies if we can apply protocol
/// qualifiers on ObjCObjectPointerType. It can be set to true when
Expand Down
10 changes: 0 additions & 10 deletions clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -670,16 +670,6 @@ class alignas(8) Decl {
/// Whether this declaration comes from another module unit.
bool isInAnotherModuleUnit() const;

/// Whether this declaration comes from the same module unit being compiled.
bool isInCurrentModuleUnit() const;

/// Whether the definition of the declaration should be emitted in external
/// sources.
bool shouldEmitInExternalSource() const;

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

/// Whether this declaration comes from explicit global module.
bool isFromExplicitGlobalModule() const;

Expand Down
92 changes: 49 additions & 43 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -3676,9 +3676,9 @@ class CXXUnresolvedConstructExpr final
/// an implicit access if a qualifier is provided.
class CXXDependentScopeMemberExpr final
: public Expr,
private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc, NamedDecl *> {
private llvm::TrailingObjects<
CXXDependentScopeMemberExpr, NestedNameSpecifierLoc, DeclAccessPair,
ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
friend class ASTStmtReader;
friend class ASTStmtWriter;
friend TrailingObjects;
Expand All @@ -3691,17 +3691,15 @@ class CXXDependentScopeMemberExpr final
/// implicit accesses.
QualType BaseType;

/// The nested-name-specifier that precedes the member name, if any.
/// FIXME: This could be in principle store as a trailing object.
/// However the performance impact of doing so should be investigated first.
NestedNameSpecifierLoc QualifierLoc;

/// The member to which this member expression refers, which
/// can be name, overloaded operator, or destructor.
///
/// FIXME: could also be a template-id
DeclarationNameInfo MemberNameInfo;

/// The location of the '->' or '.' operator.
SourceLocation OperatorLoc;

// CXXDependentScopeMemberExpr is followed by several trailing objects,
// some of which optional. They are in order:
//
Expand All @@ -3721,8 +3719,16 @@ class CXXDependentScopeMemberExpr final
return CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo;
}

bool hasFirstQualifierFoundInScope() const {
return CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope;
unsigned getNumUnqualifiedLookups() const {
return CXXDependentScopeMemberExprBits.NumUnqualifiedLookups;
}

unsigned numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
return hasQualifier();
}

unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
return getNumUnqualifiedLookups();
}

unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
Expand All @@ -3733,33 +3739,32 @@ class CXXDependentScopeMemberExpr final
return getNumTemplateArgs();
}

unsigned numTrailingObjects(OverloadToken<NamedDecl *>) const {
return hasFirstQualifierFoundInScope();
}

CXXDependentScopeMemberExpr(const ASTContext &Ctx, Expr *Base,
QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
NamedDecl *FirstQualifierFoundInScope,
ArrayRef<DeclAccessPair> UnqualifiedLookups,
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);

CXXDependentScopeMemberExpr(EmptyShell Empty, bool HasTemplateKWAndArgsInfo,
bool HasFirstQualifierFoundInScope);
CXXDependentScopeMemberExpr(EmptyShell Empty, bool HasQualifier,
unsigned NumUnqualifiedLookups,
bool HasTemplateKWAndArgsInfo);

public:
static CXXDependentScopeMemberExpr *
Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
SourceLocation TemplateKWLoc,
ArrayRef<DeclAccessPair> UnqualifiedLookups,
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);

static CXXDependentScopeMemberExpr *
CreateEmpty(const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope);
CreateEmpty(const ASTContext &Ctx, bool HasQualifier,
unsigned NumUnqualifiedLookups, bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs);

/// True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
Expand All @@ -3784,34 +3789,35 @@ class CXXDependentScopeMemberExpr final
bool isArrow() const { return CXXDependentScopeMemberExprBits.IsArrow; }

/// Retrieve the location of the '->' or '.' operator.
SourceLocation getOperatorLoc() const {
return CXXDependentScopeMemberExprBits.OperatorLoc;
SourceLocation getOperatorLoc() const { return OperatorLoc; }

/// Determines whether this member expression had a nested-name-specifier
/// prior to the name of the member, e.g., x->Base::foo.
bool hasQualifier() const {
return CXXDependentScopeMemberExprBits.HasQualifier;
}

/// Retrieve the nested-name-specifier that qualifies the member name.
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
/// If the member name was qualified, retrieves the nested-name-specifier
/// that precedes the member name, with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const {
if (!hasQualifier())
return NestedNameSpecifierLoc();
return *getTrailingObjects<NestedNameSpecifierLoc>();
}

/// Retrieve the nested-name-specifier that qualifies the member
/// name, with source location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
/// If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// NULL.
NestedNameSpecifier *getQualifier() const {
return getQualifierLoc().getNestedNameSpecifier();
}

/// Retrieve the first part of the nested-name-specifier that was
/// found in the scope of the member access expression when the member access
/// was initially parsed.
///
/// This function only returns a useful result when member access expression
/// uses a qualified member name, e.g., "x.Base::f". Here, the declaration
/// returned by this function describes what was found by unqualified name
/// lookup for the identifier "Base" within the scope of the member access
/// expression itself. At template instantiation time, this information is
/// combined with the results of name lookup into the type of the object
/// expression itself (the class type of x).
NamedDecl *getFirstQualifierFoundInScope() const {
if (!hasFirstQualifierFoundInScope())
return nullptr;
return *getTrailingObjects<NamedDecl *>();
/// Retrieve the declarations found by unqualified lookup for the first
/// component name of the nested-name-specifier, if any.
ArrayRef<DeclAccessPair> unqualified_lookups() const {
if (!getNumUnqualifiedLookups())
return std::nullopt;
return {getTrailingObjects<DeclAccessPair>(), getNumUnqualifiedLookups()};
}

/// Retrieve the name of the member that this expression refers to.
Expand Down
15 changes: 8 additions & 7 deletions clang/include/clang/AST/Stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1020,18 +1020,19 @@ class alignas(void *) Stmt {
LLVM_PREFERRED_TYPE(bool)
unsigned IsArrow : 1;

/// True if this member expression used a nested-name-specifier to
/// refer to the member, e.g., "x->Base::f".
LLVM_PREFERRED_TYPE(bool)
unsigned HasQualifier : 1;

/// Whether this member expression has info for explicit template
/// keyword and arguments.
LLVM_PREFERRED_TYPE(bool)
unsigned HasTemplateKWAndArgsInfo : 1;

/// See getFirstQualifierFoundInScope() and the comment listing
/// the trailing objects.
LLVM_PREFERRED_TYPE(bool)
unsigned HasFirstQualifierFoundInScope : 1;

/// The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
/// Number of declarations found by unqualified lookup for the
/// first component name of the nested-name-specifier.
unsigned NumUnqualifiedLookups;
};

class OverloadExprBitfields {
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -2509,6 +2509,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); }
bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
bool isPointerType() const;
bool isSignableType() const;
bool isAnyPointerType() const; // Any C pointer or ObjC object pointer
bool isCountAttributedType() const;
bool isBlockPointerType() const;
Expand Down Expand Up @@ -8004,6 +8005,8 @@ inline bool Type::isAnyPointerType() const {
return isPointerType() || isObjCObjectPointerType();
}

inline bool Type::isSignableType() const { return isPointerType(); }

inline bool Type::isBlockPointerType() const {
return isa<BlockPointerType>(CanonicalType);
}
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/AST/UnresolvedSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ class UnresolvedSetImpl {
decls().push_back(DeclAccessPair::make(D, AS));
}

void addAllDecls(ArrayRef<DeclAccessPair> Other) {
append(iterator(Other.begin()), iterator(Other.end()));
}

/// Replaces the given declaration with the new one, once.
///
/// \return true if the set changed
Expand Down
50 changes: 46 additions & 4 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -2292,6 +2292,36 @@ def CountedBy : DeclOrTypeAttr {
let LangOpts = [COnly];
}

def CountedByOrNull : DeclOrTypeAttr {
let Spellings = [Clang<"counted_by_or_null">];
let Subjects = SubjectList<[Field], ErrorDiag>;
let Args = [ExprArgument<"Count">, IntArgument<"NestedLevel", 1>];
let LateParsed = LateAttrParseExperimentalExt;
let ParseArgumentsAsUnevaluated = 1;
let Documentation = [CountedByDocs];
let LangOpts = [COnly];
}

def SizedBy : DeclOrTypeAttr {
let Spellings = [Clang<"sized_by">];
let Subjects = SubjectList<[Field], ErrorDiag>;
let Args = [ExprArgument<"Size">, IntArgument<"NestedLevel", 1>];
let LateParsed = LateAttrParseExperimentalExt;
let ParseArgumentsAsUnevaluated = 1;
let Documentation = [CountedByDocs];
let LangOpts = [COnly];
}

def SizedByOrNull : DeclOrTypeAttr {
let Spellings = [Clang<"sized_by_or_null">];
let Subjects = SubjectList<[Field], ErrorDiag>;
let Args = [ExprArgument<"Size">, IntArgument<"NestedLevel", 1>];
let LateParsed = LateAttrParseExperimentalExt;
let ParseArgumentsAsUnevaluated = 1;
let Documentation = [CountedByDocs];
let LangOpts = [COnly];
}

// This is a marker used to indicate that an __unsafe_unretained qualifier was
// ignored because ARC is not enabled. The usual representation for this
// qualifier is as an ObjCOwnership attribute with Kind == "none".
Expand Down Expand Up @@ -3660,7 +3690,7 @@ def NoThreadSafetyAnalysis : InheritableAttr {
def GuardedBy : InheritableAttr {
let Spellings = [GNU<"guarded_by">];
let Args = [ExprArgument<"Arg">];
let LateParsed = LateAttrParseStandard;
let LateParsed = LateAttrParseExperimentalExt;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3671,7 +3701,7 @@ def GuardedBy : InheritableAttr {
def PtGuardedBy : InheritableAttr {
let Spellings = [GNU<"pt_guarded_by">];
let Args = [ExprArgument<"Arg">];
let LateParsed = LateAttrParseStandard;
let LateParsed = LateAttrParseExperimentalExt;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3682,7 +3712,7 @@ def PtGuardedBy : InheritableAttr {
def AcquiredAfter : InheritableAttr {
let Spellings = [GNU<"acquired_after">];
let Args = [VariadicExprArgument<"Args">];
let LateParsed = LateAttrParseStandard;
let LateParsed = LateAttrParseExperimentalExt;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand All @@ -3693,7 +3723,7 @@ def AcquiredAfter : InheritableAttr {
def AcquiredBefore : InheritableAttr {
let Spellings = [GNU<"acquired_before">];
let Args = [VariadicExprArgument<"Args">];
let LateParsed = LateAttrParseStandard;
let LateParsed = LateAttrParseExperimentalExt;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
let InheritEvenIfAlreadyPresent = 1;
Expand Down Expand Up @@ -4142,6 +4172,18 @@ def LoopHint : Attr {
let HasCustomParsing = 1;
}

/// The HLSL loop attributes
def HLSLLoopHint: StmtAttr {
/// [unroll(directive)]
/// [loop]
let Spellings = [Microsoft<"unroll">, Microsoft<"loop">];
let Args = [UnsignedArgument<"directive", /*opt*/1>];
let Subjects = SubjectList<[ForStmt, WhileStmt, DoStmt],
ErrorDiag, "'for', 'while', and 'do' statements">;
let LangOpts = [HLSL];
let Documentation = [HLSLLoopHintDocs, HLSLUnrollHintDocs];
}

def CapturedRecord : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
Expand Down
99 changes: 97 additions & 2 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -7343,6 +7343,100 @@ where shaders must be compiled into a library and linked at runtime.
}];
}

def HLSLLoopHintDocs : Documentation {
let Category = DocCatStmt;
let Heading = "[loop]";
let Content = [{
The ``[loop]`` directive allows loop optimization hints to be
specified for the subsequent loop. The directive allows unrolling to
be disabled and is not compatible with [unroll(x)].

Specifying the parameter, ``[loop]``, directs the
unroller to not unroll the loop.

.. code-block:: hlsl

[loop]
for (...) {
...
}

.. code-block:: hlsl

[loop]
while (...) {
...
}

.. code-block:: hlsl

[loop]
do {
...
} while (...)

See `hlsl loop extensions <https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-for>`_
for details.
}];
}

def HLSLUnrollHintDocs : Documentation {
let Category = DocCatStmt;
let Heading = "[unroll(x)], [unroll]";
let Content = [{
Loop unrolling optimization hints can be specified with ``[unroll(x)]``
. The attribute is placed immediately before a for, while,
or do-while.
Specifying the parameter, ``[unroll(_value_)]``, directs the
unroller to unroll the loop ``_value_`` times. Note: [unroll(x)] is not compatible with [loop].

.. code-block:: hlsl

[unroll(4)]
for (...) {
...
}

.. code-block:: hlsl

[unroll]
for (...) {
...
}

.. code-block:: hlsl

[unroll(4)]
while (...) {
...
}

.. code-block:: hlsl

[unroll]
while (...) {
...
}

.. code-block:: hlsl

[unroll(4)]
do {
...
} while (...)

.. code-block:: hlsl

[unroll]
do {
...
} while (...)

See `hlsl loop extensions <https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-for>`_
for details.
}];
}

def ClangRandomizeLayoutDocs : Documentation {
let Category = DocCatDecl;
let Heading = "randomize_layout, no_randomize_layout";
Expand Down Expand Up @@ -7402,7 +7496,8 @@ b for constant buffer views (CBV).

Register space is specified in the format ``space[number]`` and defaults to ``space0`` if omitted.
Here're resource binding examples with and without space:
.. code-block:: c++

.. code-block:: hlsl

RWBuffer<float> Uav : register(u3, space1);
Buffer<float> Buf : register(t1);
Expand All @@ -7420,7 +7515,7 @@ A subcomponent is a register number, which is an integer. A component is in the

Examples:

.. code-block:: c++
.. code-block:: hlsl

cbuffer A {
float3 a : packoffset(c0.y);
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/BuiltinsAArch64.def
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ BUILTIN(__builtin_arm_wfe, "v", "")
BUILTIN(__builtin_arm_wfi, "v", "")
BUILTIN(__builtin_arm_sev, "v", "")
BUILTIN(__builtin_arm_sevl, "v", "")
BUILTIN(__builtin_arm_chkfeat, "WUiWUi", "")

// Like __builtin_trap but provide an 16-bit immediate reason code (which goes into `brk #N`).
BUILTIN(__builtin_arm_trap, "vUIs", "nr")
Expand Down Expand Up @@ -136,6 +137,10 @@ TARGET_BUILTIN(__builtin_arm_st64b, "vv*WUiC*", "n", "ls64")
TARGET_BUILTIN(__builtin_arm_st64bv, "WUiv*WUiC*", "n", "ls64")
TARGET_BUILTIN(__builtin_arm_st64bv0, "WUiv*WUiC*", "n", "ls64")

// Armv9.3-A Guarded Control Stack
TARGET_BUILTIN(__builtin_arm_gcspopm, "WUiWUi", "n", "gcs")
TARGET_BUILTIN(__builtin_arm_gcsss, "vC*vC*", "n", "gcs")

TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
Expand Down Expand Up @@ -292,6 +297,8 @@ TARGET_HEADER_BUILTIN(_CountOneBits64, "UiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGE

TARGET_HEADER_BUILTIN(__prefetch, "vvC*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")

TARGET_HEADER_BUILTIN(__hlt, "UiUi.", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")

#undef BUILTIN
#undef LANGBUILTIN
#undef TARGET_BUILTIN
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enable
CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined.
CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt
CODEGENOPT(HIPCorrectlyRoundedDivSqrt, 1, 1) ///< -fno-hip-fp32-correctly-rounded-divide-sqrt
CODEGENOPT(DisableBlockSignatureString, 1, 0) ///< Set when -fdisable-block-signature-string is enabled.
CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is enabled.
CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get unique names.
CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information.
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,9 @@ def err_drv_negative_columns : Error<
"invalid value '%1' in '%0', value must be 'none' or a positive integer">;
def err_drv_small_columns : Error<
"invalid value '%1' in '%0', value must be '%2' or greater">;
def warn_drv_fraw_string_literals_in_cxx11 : Warning<
"ignoring '-f%select{no-|}0raw-string-literals', which is only valid for C and C++ standards before C++11">,
InGroup<UnusedCommandLineArgument>;

def err_drv_invalid_malign_branch_EQ : Error<
"invalid argument '%0' to -malign-branch=; each element must be one of: %1">;
Expand Down Expand Up @@ -791,6 +794,8 @@ def err_drv_loongarch_wrong_fpu_width : Error<
"wrong fpu width; %select{LSX|LASX}0 depends on 64-bit FPU">;
def err_drv_loongarch_invalid_simd_option_combination : Error<
"invalid option combination; LASX depends on LSX">;
def err_drv_loongarch_invalid_msimd_EQ : Error<
"invalid argument '%0' to -msimd=; must be one of: none, lsx, lasx">;

def err_drv_expand_response_file : Error<
"failed to expand response file: %0">;
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/DiagnosticFrontendKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ def err_module_map_not_found : Error<"module map file '%0' not found">,
def err_missing_module_name : Error<
"no module name provided; specify one with -fmodule-name=">,
DefaultFatal;
def err_file_is_not_module : Error<"file '%0' is not a module file">, DefaultFatal;
def err_missing_module : Error<
"no module named '%0' declared in module map file '%1'">, DefaultFatal;
def err_no_submodule : Error<"no submodule named %0 in module '%1'">;
Expand Down
4 changes: 1 addition & 3 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -895,9 +895,7 @@ def missing_template_arg_list_after_template_kw : Extension<
"keyword">, InGroup<DiagGroup<"missing-template-arg-list-after-template-kw">>,
DefaultError;

def err_missing_dependent_template_keyword : Error<
"use 'template' keyword to treat '%0' as a dependent template name">;
def warn_missing_dependent_template_keyword : ExtWarn<
def ext_missing_dependent_template_keyword : ExtWarn<
"use 'template' keyword to treat '%0' as a dependent template name">;

def ext_extern_template : Extension<
Expand Down
42 changes: 22 additions & 20 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,12 @@ def warn_anyx86_excessive_regsave : Warning<
" with attribute 'no_caller_saved_registers'"
" or be compiled with '-mgeneral-regs-only'">,
InGroup<DiagGroup<"excessive-regsave">>;
def warn_arm_interrupt_calling_convention : Warning<
"call to function without interrupt attribute could clobber interruptee's VFP registers">,
InGroup<Extra>;
def warn_arm_interrupt_vfp_clobber : Warning<
"interrupt service routine with vfp enabled may clobber the "
"interruptee's vfp state">,
InGroup<DiagGroup<"arm-interrupt-vfp-clobber">>;
def err_arm_interrupt_called : Error<
"interrupt service routine cannot be called directly">;
def warn_interrupt_attribute_invalid : Warning<
"%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
"functions that have %select{no parameters|a 'void' return type}1">,
Expand Down Expand Up @@ -6013,7 +6016,7 @@ def note_deleted_assign_field : Note<
"because field %2 is of %select{reference|const-qualified}4 type %3">;

// These should be errors.
def warn_undefined_internal : Warning<
def warn_undefined_internal : ExtWarn<
"%select{function|variable}0 %q1 has internal linkage but is not defined">,
InGroup<DiagGroup<"undefined-internal">>;
def err_undefined_internal_type : Error<
Expand Down Expand Up @@ -6567,28 +6570,28 @@ def warn_superclass_variable_sized_type_not_at_end : Warning<
"field %0 can overwrite instance variable %1 with variable sized type %2"
" in superclass %3">, InGroup<ObjCFlexibleArray>;

def err_flexible_array_count_not_in_same_struct : Error<
"'counted_by' field %0 isn't within the same struct as the flexible array">;
def err_counted_by_attr_not_on_ptr_or_flexible_array_member : Error<
"'counted_by' only applies to pointers or C99 flexible array members">;
def err_count_attr_param_not_in_same_struct : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}1' field %0 isn't within the same struct as the annotated %select{pointer|flexible array}2">;
def err_count_attr_not_on_ptr_or_flexible_array_member : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}0' only applies to pointers%select{ or C99 flexible array members|||}0%select{|; did you mean to use 'counted_by'?}1">;
def err_counted_by_attr_on_array_not_flexible_array_member : Error<
"'counted_by' on arrays only applies to C99 flexible array members">;
def err_counted_by_attr_refer_to_itself : Error<
"'counted_by' cannot refer to the flexible array member %0">;
def err_counted_by_must_be_in_structure : Error<
"field %0 in 'counted_by' not inside structure">;
def err_counted_by_attr_argument_not_integer : Error<
"'counted_by' requires a non-boolean integer type argument">;
def err_counted_by_attr_only_support_simple_decl_reference : Error<
"'counted_by' argument must be a simple declaration reference">;
def err_counted_by_attr_in_union : Error<
"'counted_by' cannot be applied to a union member">;
def err_counted_by_attr_refer_to_union : Error<
"'counted_by' argument cannot refer to a union member">;
def err_count_attr_must_be_in_structure : Error<
"field %0 in '%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}1' not inside structure">;
def err_count_attr_argument_not_integer : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}0' requires a non-boolean integer type argument">;
def err_count_attr_only_support_simple_decl_reference : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}0' argument must be a simple declaration reference">;
def err_count_attr_in_union : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}0' cannot be applied to a union member">;
def err_count_attr_refer_to_union : Error<
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}0' argument cannot refer to a union member">;
def note_flexible_array_counted_by_attr_field : Note<
"field %0 declared here">;
def err_counted_by_attr_pointee_unknown_size : Error<
"'counted_by' %select{cannot|should not}3 be applied to %select{"
"'%select{counted_by|sized_by|counted_by_or_null|sized_by_or_null}4' %select{cannot|should not}3 be applied to %select{"
"a pointer with pointee|" // pointer
"an array with element}0" // array
" of unknown size because %1 is %select{"
Expand Down Expand Up @@ -7696,7 +7699,6 @@ def err_qualified_objc_access : Error<
def ext_freestanding_complex : Extension<
"complex numbers are an extension in a freestanding C99 implementation">;

// FIXME: Remove when we support imaginary.
def err_imaginary_not_supported : Error<"imaginary types are not supported">;

// Obj-c expressions
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 @@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtr
FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination)
FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls)
FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
FEATURE(ptrauth_function_pointer_type_discrimination, LangOpts.PointerAuthFunctionTypeDiscrimination)
EXTENSION(swiftcc,
PP.getTargetInfo().checkCallingConvention(CC_Swift) ==
clang::TargetInfo::CCCR_OK)
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps")
LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers")
LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers")
LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays")
BENIGN_LANGOPT(PointerAuthFunctionTypeDiscrimination, 1, 0,
"Use type discrimination when signing function pointers")

LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
LANGOPT(ExperimentalLateParseAttributes, 1, 0, "experimental late parsing of attributes")
Expand Down Expand Up @@ -465,6 +467,8 @@ LANGOPT(MatrixTypes, 1, 0, "Enable or disable the builtin matrix type")

LANGOPT(CXXAssumptions, 1, 1, "Enable or disable codegen and compile-time checks for C++23's [[assume]] attribute")

LANGOPT(RawStringLiterals, 1, 1, "Enable or disable raw string literals")

ENUM_LANGOPT(StrictFlexArraysLevel, StrictFlexArraysLevelKind, 2,
StrictFlexArraysLevelKind::Default,
"Rely on strict definition of flexible arrays")
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/LangStandard.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ struct LangStandard {
/// hasDigraphs - Language supports digraphs.
bool hasDigraphs() const { return Flags & Digraphs; }

/// hasRawStringLiterals - Language supports R"()" raw string literals.
bool hasRawStringLiterals() const {
// GCC supports raw string literals in C99 and later, but not in C++
// before C++11.
return isCPlusPlus11() || (!isCPlusPlus() && isC99() && isGNUMode());
}

/// isGNUMode - Language includes GNU extensions.
bool isGNUMode() const { return Flags & GNUMode; }

Expand Down
49 changes: 46 additions & 3 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Frontend/OpenMP/OMPGridValues.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/VersionTuple.h"
Expand Down Expand Up @@ -1400,15 +1402,15 @@ class TargetInfo : public TransferrableTargetInfo,
return true;
}

struct BranchProtectionInfo {
class BranchProtectionInfo {
public:
LangOptions::SignReturnAddressScopeKind SignReturnAddr;
LangOptions::SignReturnAddressKeyKind SignKey;
bool BranchTargetEnforcement;
bool BranchProtectionPAuthLR;
bool GuardedControlStack;

BranchProtectionInfo() = default;

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

public:
BranchProtectionInfo()
: SignReturnAddr(LangOptions::SignReturnAddressScopeKind::None),
SignKey(LangOptions::SignReturnAddressKeyKind::AKey),
BranchTargetEnforcement(false), BranchProtectionPAuthLR(false),
GuardedControlStack(false) {}

BranchProtectionInfo(const LangOptions &LangOpts) {
SignReturnAddr =
LangOpts.hasSignReturnAddress()
? (LangOpts.isSignReturnAddressScopeAll()
? LangOptions::SignReturnAddressScopeKind::All
: LangOptions::SignReturnAddressScopeKind::NonLeaf)
: LangOptions::SignReturnAddressScopeKind::None;
SignKey = LangOpts.isSignReturnAddressWithAKey()
? LangOptions::SignReturnAddressKeyKind::AKey
: LangOptions::SignReturnAddressKeyKind::BKey;
BranchTargetEnforcement = LangOpts.BranchTargetEnforcement;
BranchProtectionPAuthLR = LangOpts.BranchProtectionPAuthLR;
GuardedControlStack = LangOpts.GuardedControlStack;
}

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

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

/// Determine if the Architecture in this TargetInfo supports branch
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,11 @@ KEYWORD(_Atomic , KEYALL|KEYNOOPENCL)
KEYWORD(_Bool , KEYNOCXX)
KEYWORD(_Complex , KEYALL)
KEYWORD(_Generic , KEYALL)
// Note, C2y removed support for _Imaginary; we retain it as a keyword because
// 1) it's a reserved identifier, so we're allowed to steal it, 2) there's no
// good way to specify a keyword in earlier but not later language modes within
// this file, 3) this allows us to provide a better diagnostic in case a user
// does use the keyword.
KEYWORD(_Imaginary , KEYALL)
KEYWORD(_Noreturn , KEYALL)
KEYWORD(_Static_assert , KEYALL)
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/CodeGen/CodeGenABITypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ unsigned getLLVMFieldNumber(CodeGenModule &CGM,
/// Return a declaration discriminator for the given global decl.
uint16_t getPointerAuthDeclDiscriminator(CodeGenModule &CGM, GlobalDecl GD);

/// Return a type discriminator for the given function type.
uint16_t getPointerAuthTypeDiscriminator(CodeGenModule &CGM,
QualType FunctionType);

/// Given the language and code-generation options that Clang was configured
/// with, set the default LLVM IR attributes for a function definition.
/// The attributes set here are mostly global target-configuration and
Expand Down
25 changes: 24 additions & 1 deletion clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,7 @@ def shared_libsan : Flag<["-"], "shared-libsan">,
def static_libsan : Flag<["-"], "static-libsan">,
HelpText<"Statically link the sanitizer runtime (Not supported for ASan, TSan or UBSan on darwin)">;
def : Flag<["-"], "shared-libasan">, Alias<shared_libsan>;
def : Flag<["-"], "static-libasan">, Alias<static_libsan>;
def fasm : Flag<["-"], "fasm">, Group<f_Group>;

defm assume_unique_vtables : BoolFOption<"assume-unique-vtables",
Expand Down Expand Up @@ -3477,6 +3478,11 @@ defm objc_avoid_heapify_local_blocks : BoolFOption<"objc-avoid-heapify-local-blo
PosFlag<SetTrue, [], [ClangOption], "Try">,
NegFlag<SetFalse, [], [ClangOption], "Don't try">,
BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>;
defm disable_block_signature_string : BoolFOption<"disable-block-signature-string",
CodeGenOpts<"DisableBlockSignatureString">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption], "Disable">,
NegFlag<SetFalse, [], [ClangOption], "Don't disable">,
BothFlags<[], [CC1Option], " block signature string)">>;

def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>,
Visibility<[ClangOption, FlangOption]>,
Expand Down Expand Up @@ -4228,13 +4234,21 @@ defm ptrauth_vtable_pointer_address_discrimination :
defm ptrauth_vtable_pointer_type_discrimination :
OptInCC1FFlag<"ptrauth-vtable-pointer-type-discrimination", "Enable type discrimination of vtable pointers">;
defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of function pointers in init/fini arrays">;
defm ptrauth_function_pointer_type_discrimination : OptInCC1FFlag<"ptrauth-function-pointer-type-discrimination",
"Enable type discrimination on C function pointers">;
}

def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable matrix data type and related builtin functions">,
MarshallingInfoFlag<LangOpts<"MatrixTypes">>;

defm raw_string_literals : BoolFOption<"raw-string-literals",
LangOpts<"RawStringLiterals">, Default<std#".hasRawStringLiterals()">,
PosFlag<SetTrue, [], [], "Enable">,
NegFlag<SetFalse, [], [], "Disable">,
BothFlags<[], [ClangOption, CC1Option], " raw string literals">>;

def fzero_call_used_regs_EQ
: Joined<["-"], "fzero-call-used-regs=">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
Expand Down Expand Up @@ -4917,6 +4931,9 @@ foreach i = {1-31} in
def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_Group>,
HelpText<"Reserve the x"#i#" register (AArch64/RISC-V only)">;

def mlr_for_calls_only : Flag<["-"], "mlr-for-calls-only">, Group<m_aarch64_Features_Group>,
HelpText<"Do not allocate the LR register for general purpose usage, only for calls. (AArch64 only)">;

foreach i = {8-15,18} in
def fcall_saved_x#i : Flag<["-"], "fcall-saved-x"#i>, Group<m_aarch64_Features_Group>,
HelpText<"Make the x"#i#" register call-saved (AArch64 only)">;
Expand Down Expand Up @@ -5252,6 +5269,9 @@ def mlasx : Flag<["-"], "mlasx">, Group<m_loongarch_Features_Group>,
HelpText<"Enable Loongson Advanced SIMD Extension (LASX).">;
def mno_lasx : Flag<["-"], "mno-lasx">, Group<m_loongarch_Features_Group>,
HelpText<"Disable Loongson Advanced SIMD Extension (LASX).">;
def msimd_EQ : Joined<["-"], "msimd=">, Group<m_loongarch_Features_Group>,
Flags<[TargetSpecific]>,
HelpText<"Select the SIMD extension(s) to be enabled in LoongArch either 'none', 'lsx', 'lasx'.">;
def mnop_mcount : Flag<["-"], "mnop-mcount">, HelpText<"Generate mcount/__fentry__ calls as nops. To activate they need to be patched in.">,
Visibility<[ClangOption, CC1Option]>, Group<m_Group>,
MarshallingInfoFlag<CodeGenOpts<"MNopMCount">>;
Expand Down Expand Up @@ -5716,7 +5736,7 @@ def print_supported_extensions : Flag<["-", "--"], "print-supported-extensions">
def print_enabled_extensions : Flag<["-", "--"], "print-enabled-extensions">,
Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Print the extensions enabled by the given target and -march/-mcpu options."
" (AArch64 only)">,
" (AArch64 and RISC-V only)">,
MarshallingInfoFlag<FrontendOpts<"PrintEnabledExtensions">>;
def : Flag<["-"], "mcpu=help">, Alias<print_supported_cpus>;
def : Flag<["-"], "mtune=help">, Alias<print_supported_cpus>;
Expand Down Expand Up @@ -6667,6 +6687,9 @@ defm stack_arrays : BoolOptionWithoutMarshalling<"f", "stack-arrays",
defm loop_versioning : BoolOptionWithoutMarshalling<"f", "version-loops-for-stride",
PosFlag<SetTrue, [], [ClangOption], "Create unit-strided versions of loops">,
NegFlag<SetFalse, [], [ClangOption], "Do not create unit-strided loops (default)">>;

def fhermetic_module_files : Flag<["-"], "fhermetic-module-files">, Group<f_Group>,
HelpText<"Emit hermetic module files (no nested USE association)">;
} // let Visibility = [FC1Option, FlangOption]

def J : JoinedOrSeparate<["-"], "J">,
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Driver/aarch64-mlr-for-calls-only.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// RUN: %clang --target=aarch64-none-gnu -mlr-for-calls-only -### %s 2> %t
// RUN: FileCheck --check-prefix=CHECK < %t %s
// CHECK: "-target-feature" "+reserve-lr-for-ra"
14 changes: 5 additions & 9 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3368,15 +3368,11 @@ class Parser : public CodeCompletionHandler {
BaseResult ParseBaseSpecifier(Decl *ClassDecl);
AccessSpecifier getAccessSpecifierIfPresent() const;

bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
ParsedType ObjectType,
bool ObjectHadErrors,
SourceLocation TemplateKWLoc,
IdentifierInfo *Name,
SourceLocation NameLoc,
bool EnteringContext,
UnqualifiedId &Id,
bool AssumeTemplateId);
bool ParseUnqualifiedIdTemplateId(
CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors,
SourceLocation TemplateKWLoc, SourceLocation TildeLoc,
IdentifierInfo *Name, SourceLocation NameLoc, bool EnteringContext,
UnqualifiedId &Id, bool AssumeTemplateId);
bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
ParsedType ObjectType,
UnqualifiedId &Result);
Expand Down
12 changes: 10 additions & 2 deletions clang/include/clang/Sema/DeclSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class CXXScopeSpec {
SourceRange Range;
NestedNameSpecifierLocBuilder Builder;
ArrayRef<TemplateParameterList *> TemplateParamLists;
ArrayRef<DeclAccessPair> UnqualifiedLookups;

public:
SourceRange getRange() const { return Range; }
Expand All @@ -91,6 +92,13 @@ class CXXScopeSpec {
return TemplateParamLists;
}

void setUnqualifiedLookups(ArrayRef<DeclAccessPair> Found) {
UnqualifiedLookups = Found;
}
ArrayRef<DeclAccessPair> getUnqualifiedLookups() const {
return UnqualifiedLookups;
}

/// Retrieve the representation of the nested-name-specifier.
NestedNameSpecifier *getScopeRep() const {
return Builder.getRepresentation();
Expand Down Expand Up @@ -269,7 +277,7 @@ class DeclSpec {

enum TSC {
TSC_unspecified,
TSC_imaginary,
TSC_imaginary, // Unsupported
TSC_complex
};

Expand Down Expand Up @@ -875,7 +883,7 @@ class DeclSpec {
}

/// Finish - This does final analysis of the declspec, issuing diagnostics for
/// things like "_Imaginary" (lacking an FP type). After calling this method,
/// things like "_Complex" (lacking an FP type). After calling this method,
/// DeclSpec is guaranteed self-consistent, even if an error occurred.
void Finish(Sema &S, const PrintingPolicy &Policy);

Expand Down
8 changes: 6 additions & 2 deletions clang/include/clang/Sema/Lookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,11 +483,15 @@ class LookupResult {
ResultKind = Found;
}

void addAllDecls(ArrayRef<DeclAccessPair> Other) {
Decls.addAllDecls(Other);
ResultKind = Found;
}

/// Add all the declarations from another set of lookup
/// results.
void addAllDecls(const LookupResult &Other) {
Decls.append(Other.Decls.begin(), Other.Decls.end());
ResultKind = Found;
addAllDecls(Other.Decls.pairs());
}

/// Determine whether no result was found because we could not
Expand Down
65 changes: 28 additions & 37 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2802,7 +2802,8 @@ class Sema final : public SemaBase {
/// (e.g., Base::), perform name lookup for that identifier as a
/// nested-name-specifier within the given scope, and return the result of
/// that name lookup.
NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
bool LookupFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS,
UnresolvedSetImpl &R);

/// Keeps information about an identifier in a nested-name-spec.
///
Expand Down Expand Up @@ -2842,9 +2843,6 @@ class Sema final : public SemaBase {
/// \param EnteringContext If true, enter the context specified by the
/// nested-name-specifier.
/// \param SS Optional nested name specifier preceding the identifier.
/// \param ScopeLookupResult Provides the result of name lookup within the
/// scope of the nested-name-specifier that was computed at template
/// definition time.
/// \param ErrorRecoveryLookup Specifies if the method is called to improve
/// error recovery and what kind of recovery is performed.
/// \param IsCorrectedToColon If not null, suggestion of replace '::' -> ':'
Expand All @@ -2853,11 +2851,6 @@ class Sema final : public SemaBase {
/// not '::'.
/// \param OnlyNamespace If true, only considers namespaces in lookup.
///
/// This routine differs only slightly from ActOnCXXNestedNameSpecifier, in
/// that it contains an extra parameter \p ScopeLookupResult, which provides
/// the result of name lookup within the scope of the nested-name-specifier
/// that was computed at template definition time.
///
/// If ErrorRecoveryLookup is true, then this call is used to improve error
/// recovery. This means that it should not emit diagnostics, it should
/// just return true on failure. It also means it should only return a valid
Expand All @@ -2866,7 +2859,6 @@ class Sema final : public SemaBase {
/// specifier.
bool BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
bool EnteringContext, CXXScopeSpec &SS,
NamedDecl *ScopeLookupResult,
bool ErrorRecoveryLookup,
bool *IsCorrectedToColon = nullptr,
bool OnlyNamespace = false);
Expand Down Expand Up @@ -6341,7 +6333,7 @@ class Sema final : public SemaBase {
enum ExpressionKind {
EK_Decltype,
EK_TemplateArgument,
EK_BoundsAttrArgument,
EK_AttrArgument,
EK_Other
} ExprContext;

Expand Down Expand Up @@ -6454,10 +6446,9 @@ class Sema final : public SemaBase {
return const_cast<Sema *>(this)->parentEvaluationContext();
};

bool isBoundsAttrContext() const {
bool isAttrContext() const {
return ExprEvalContexts.back().ExprContext ==
ExpressionEvaluationContextRecord::ExpressionKind::
EK_BoundsAttrArgument;
ExpressionEvaluationContextRecord::ExpressionKind::EK_AttrArgument;
}

/// Increment when we find a reference; decrement when we find an ignored
Expand Down Expand Up @@ -8567,11 +8558,12 @@ class Sema final : public SemaBase {
const TemplateArgumentListInfo *TemplateArgs,
bool IsDefiniteInstance, const Scope *S);

ExprResult ActOnDependentMemberExpr(
Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OpLoc,
const CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs);
ExprResult
ActOnDependentMemberExpr(Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OpLoc, const CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs);

/// The main callback when the parser finds something like
/// expression . [nested-name-specifier] identifier
Expand Down Expand Up @@ -8627,15 +8619,14 @@ class Sema final : public SemaBase {
ExprResult BuildMemberReferenceExpr(
Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow,
CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs, const Scope *S,
ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);

ExprResult
BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc,
bool IsArrow, const CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
NamedDecl *FirstQualifierInScope, LookupResult &R,
SourceLocation TemplateKWLoc, LookupResult &R,
const TemplateArgumentListInfo *TemplateArgs,
const Scope *S, bool SuppressQualifierCheck = false,
ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
Expand Down Expand Up @@ -11123,15 +11114,14 @@ class Sema final : public SemaBase {
QualType ObjectType, bool EnteringContext,
RequiredTemplateKind RequiredTemplate = SourceLocation(),
AssumedTemplateKind *ATK = nullptr,
bool AllowTypoCorrection = true);
bool AllowTypoCorrection = true, bool MayBeNNS = false);

TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS,
bool hasTemplateKeyword,
const UnqualifiedId &Name,
ParsedType ObjectType, bool EnteringContext,
TemplateTy &Template,
bool &MemberOfUnknownSpecialization,
bool Disambiguation = false);
TemplateNameKind
isTemplateName(Scope *S, CXXScopeSpec &SS, bool hasTemplateKeyword,
const UnqualifiedId &Name, ParsedType ObjectType,
bool EnteringContext, TemplateTy &Template,
bool &MemberOfUnknownSpecialization,
bool Disambiguation = false, bool MayBeNNS = false);

/// Try to resolve an undeclared template name as a type template.
///
Expand Down Expand Up @@ -11460,12 +11450,11 @@ class Sema final : public SemaBase {
/// For example, given "x.MetaFun::template apply", the scope specifier
/// \p SS will be "MetaFun::", \p TemplateKWLoc contains the location
/// of the "template" keyword, and "apply" is the \p Name.
TemplateNameKind ActOnTemplateName(Scope *S, CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
const UnqualifiedId &Name,
ParsedType ObjectType,
bool EnteringContext, TemplateTy &Template,
bool AllowInjectedClassName = false);
TemplateNameKind
ActOnTemplateName(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
const UnqualifiedId &Name, ParsedType ObjectType,
bool EnteringContext, TemplateTy &Template,
bool AllowInjectedClassName = false, bool MayBeNNS = false);

DeclResult ActOnClassTemplateSpecialization(
Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
Expand Down Expand Up @@ -14604,7 +14593,9 @@ class Sema final : public SemaBase {
SourceLocation AttrLoc);

QualType BuildCountAttributedArrayOrPointerType(QualType WrappedTy,
Expr *CountExpr);
Expr *CountExpr,
bool CountInBytes,
bool OrNull);

/// BuildAddressSpaceAttr - Builds a DependentAddressSpaceType if an
/// expression is uninstantiated. If instantiated it will apply the
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Sema/Template.h
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,7 @@ enum class TemplateSubstitutionKind : char {
VarTemplateSpecializationDecl *PrevDecl = nullptr);

Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
Decl *InstantiateTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
ClassTemplatePartialSpecializationDecl *
InstantiateClassTemplatePartialSpecialization(
ClassTemplateDecl *ClassTemplate,
Expand Down
3 changes: 0 additions & 3 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -721,9 +721,6 @@ enum ASTRecordTypes {

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

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

/// Record types used within a source manager block.
Expand Down
6 changes: 0 additions & 6 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -790,11 +790,6 @@ class ASTReader
/// the consumer eagerly.
SmallVector<GlobalDeclID, 16> EagerlyDeserializedDecls;

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

/// The IDs of all tentative definitions stored in the chain.
///
/// Sema keeps track of all tentative definitions in a TU because it has to
Expand Down Expand Up @@ -1505,7 +1500,6 @@ class ASTReader
bool isConsumerInterestedIn(Decl *D);
void PassInterestingDeclsToConsumer();
void PassInterestingDeclToConsumer(Decl *D);
void PassVTableToConsumer(CXXRecordDecl *RD);

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

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

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

void handleVTable(CXXRecordDecl *RD);

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

void InitializeSema(Sema &S) override { SemaPtr = &S; }
void HandleTranslationUnit(ASTContext &Ctx) override;
void HandleVTable(CXXRecordDecl *RD) override { Writer.handleVTable(RD); }
ASTMutationListener *GetASTMutationListener() override;
ASTDeserializationListener *GetASTDeserializationListener() override;
bool hasEmittedPCH() const { return Buffer->IsComplete; }
Expand Down
12 changes: 8 additions & 4 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,7 @@ def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">,

let ParentPackage = Taint in {

def GenericTaintChecker : Checker<"TaintPropagation">,
def TaintPropagationChecker : Checker<"TaintPropagation">, // Modelling checker
HelpText<"Generate taint information used by other checkers">,
CheckerOptions<[
CmdLineOption<String,
Expand All @@ -1080,6 +1080,12 @@ def GenericTaintChecker : Checker<"TaintPropagation">,
"",
InAlpha>,
]>,
Documentation<NotDocumented>,
Hidden;

def GenericTaintChecker : Checker<"GenericTaint">,
HelpText<"Reports potential injection vulnerabilities">,
Dependencies<[TaintPropagationChecker]>,
Documentation<HasDocumentation>;

} // end "alpha.security.taint"
Expand Down Expand Up @@ -1717,9 +1723,7 @@ let ParentPackage = TaintOptIn in {
def TaintedAllocChecker: Checker<"TaintedAlloc">,
HelpText<"Check for memory allocations, where the size parameter "
"might be a tainted (attacker controlled) value.">,
Dependencies<[DynamicMemoryModeling]>,
//FIXME: GenericTaintChecker should be a dependency, but only after it
//is transformed into a modeling checker
Dependencies<[DynamicMemoryModeling, TaintPropagationChecker]>,
Documentation<HasDocumentation>;

} // end "optin.taint"
Expand Down
1 change: 0 additions & 1 deletion clang/include/clang/Support/RISCVVIntrinsicUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,6 @@ class RVVIntrinsic {
bool HasBuiltinAlias, llvm::StringRef ManualCodegen,
const RVVTypes &Types,
const std::vector<int64_t> &IntrinsicTypes,
const std::vector<llvm::StringRef> &RequiredFeatures,
unsigned NF, Policy PolicyAttrs, bool HasFRMRoundModeOp);
~RVVIntrinsic() = default;

Expand Down
20 changes: 10 additions & 10 deletions clang/lib/APINotes/APINotesFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,26 +132,26 @@ using IdentifierDataLayout = llvm::BCRecordLayout<
>;
} // namespace identifier_block

namespace objc_context_block {
namespace context_block {
enum {
OBJC_CONTEXT_ID_DATA = 1,
OBJC_CONTEXT_INFO_DATA = 2,
CONTEXT_ID_DATA = 1,
CONTEXT_INFO_DATA = 2,
};

using ObjCContextIDLayout =
llvm::BCRecordLayout<OBJC_CONTEXT_ID_DATA, // record ID
using ContextIDLayout =
llvm::BCRecordLayout<CONTEXT_ID_DATA, // record ID
llvm::BCVBR<16>, // table offset within the blob (see
// below)
llvm::BCBlob // map from ObjC class names/protocol (as
// IDs) to context IDs
>;

using ObjCContextInfoLayout = llvm::BCRecordLayout<
OBJC_CONTEXT_INFO_DATA, // record ID
llvm::BCVBR<16>, // table offset within the blob (see below)
llvm::BCBlob // map from ObjC context IDs to context information.
using ContextInfoLayout = llvm::BCRecordLayout<
CONTEXT_INFO_DATA, // record ID
llvm::BCVBR<16>, // table offset within the blob (see below)
llvm::BCBlob // map from ObjC context IDs to context information.
>;
} // namespace objc_context_block
} // namespace context_block

namespace objc_property_block {
enum {
Expand Down
93 changes: 46 additions & 47 deletions clang/lib/APINotes/APINotesReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,9 @@ class IdentifierTableInfo {
}
};

/// Used to deserialize the on-disk Objective-C class table.
class ObjCContextIDTableInfo {
/// Used to deserialize the on-disk table of Objective-C classes and C++
/// namespaces.
class ContextIDTableInfo {
public:
using internal_key_type = ContextTableKey;
using external_key_type = internal_key_type;
Expand Down Expand Up @@ -221,9 +222,8 @@ class ObjCContextIDTableInfo {
};

/// Used to deserialize the on-disk Objective-C property table.
class ObjCContextInfoTableInfo
: public VersionedTableInfo<ObjCContextInfoTableInfo, unsigned,
ObjCContextInfo> {
class ContextInfoTableInfo
: public VersionedTableInfo<ContextInfoTableInfo, unsigned, ContextInfo> {
public:
static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
return endian::readNext<uint32_t, llvm::endianness::little>(Data);
Expand All @@ -233,9 +233,9 @@ class ObjCContextInfoTableInfo
return static_cast<size_t>(llvm::hash_value(Key));
}

static ObjCContextInfo readUnversioned(internal_key_type Key,
const uint8_t *&Data) {
ObjCContextInfo Info;
static ContextInfo readUnversioned(internal_key_type Key,
const uint8_t *&Data) {
ContextInfo Info;
ReadCommonTypeInfo(Data, Info);
uint8_t Payload = *Data++;

Expand Down Expand Up @@ -614,17 +614,17 @@ class APINotesReader::Implementation {
/// The identifier table.
std::unique_ptr<SerializedIdentifierTable> IdentifierTable;

using SerializedObjCContextIDTable =
llvm::OnDiskIterableChainedHashTable<ObjCContextIDTableInfo>;
using SerializedContextIDTable =
llvm::OnDiskIterableChainedHashTable<ContextIDTableInfo>;

/// The Objective-C context ID table.
std::unique_ptr<SerializedObjCContextIDTable> ObjCContextIDTable;
/// The Objective-C / C++ context ID table.
std::unique_ptr<SerializedContextIDTable> ContextIDTable;

using SerializedObjCContextInfoTable =
llvm::OnDiskIterableChainedHashTable<ObjCContextInfoTableInfo>;
using SerializedContextInfoTable =
llvm::OnDiskIterableChainedHashTable<ContextInfoTableInfo>;

/// The Objective-C context info table.
std::unique_ptr<SerializedObjCContextInfoTable> ObjCContextInfoTable;
std::unique_ptr<SerializedContextInfoTable> ContextInfoTable;

using SerializedObjCPropertyTable =
llvm::OnDiskIterableChainedHashTable<ObjCPropertyTableInfo>;
Expand Down Expand Up @@ -685,8 +685,8 @@ class APINotesReader::Implementation {
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readIdentifierBlock(llvm::BitstreamCursor &Cursor,
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readObjCContextBlock(llvm::BitstreamCursor &Cursor,
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readContextBlock(llvm::BitstreamCursor &Cursor,
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readObjCPropertyBlock(llvm::BitstreamCursor &Cursor,
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readObjCMethodBlock(llvm::BitstreamCursor &Cursor,
Expand Down Expand Up @@ -906,7 +906,7 @@ bool APINotesReader::Implementation::readIdentifierBlock(
return false;
}

bool APINotesReader::Implementation::readObjCContextBlock(
bool APINotesReader::Implementation::readContextBlock(
llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
if (Cursor.EnterSubBlock(OBJC_CONTEXT_BLOCK_ID))
return true;
Expand Down Expand Up @@ -950,31 +950,30 @@ bool APINotesReader::Implementation::readObjCContextBlock(
}
unsigned Kind = MaybeKind.get();
switch (Kind) {
case objc_context_block::OBJC_CONTEXT_ID_DATA: {
// Already saw Objective-C context ID table.
if (ObjCContextIDTable)
case context_block::CONTEXT_ID_DATA: {
// Already saw Objective-C / C++ context ID table.
if (ContextIDTable)
return true;

uint32_t tableOffset;
objc_context_block::ObjCContextIDLayout::readRecord(Scratch, tableOffset);
context_block::ContextIDLayout::readRecord(Scratch, tableOffset);
auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

ObjCContextIDTable.reset(SerializedObjCContextIDTable::Create(
ContextIDTable.reset(SerializedContextIDTable::Create(
base + tableOffset, base + sizeof(uint32_t), base));
break;
}

case objc_context_block::OBJC_CONTEXT_INFO_DATA: {
// Already saw Objective-C context info table.
if (ObjCContextInfoTable)
case context_block::CONTEXT_INFO_DATA: {
// Already saw Objective-C / C++ context info table.
if (ContextInfoTable)
return true;

uint32_t tableOffset;
objc_context_block::ObjCContextInfoLayout::readRecord(Scratch,
tableOffset);
context_block::ContextInfoLayout::readRecord(Scratch, tableOffset);
auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

ObjCContextInfoTable.reset(SerializedObjCContextInfoTable::Create(
ContextInfoTable.reset(SerializedContextInfoTable::Create(
base + tableOffset, base + sizeof(uint32_t), base));
break;
}
Expand Down Expand Up @@ -1678,7 +1677,7 @@ APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer,

case OBJC_CONTEXT_BLOCK_ID:
if (!HasValidControlBlock ||
Implementation->readObjCContextBlock(Cursor, Scratch)) {
Implementation->readContextBlock(Cursor, Scratch)) {
Failed = true;
return;
}
Expand Down Expand Up @@ -1815,7 +1814,7 @@ APINotesReader::VersionedInfo<T>::VersionedInfo(

auto APINotesReader::lookupObjCClassID(llvm::StringRef Name)
-> std::optional<ContextID> {
if (!Implementation->ObjCContextIDTable)
if (!Implementation->ContextIDTable)
return std::nullopt;

std::optional<IdentifierID> ClassID = Implementation->getIdentifier(Name);
Expand All @@ -1824,33 +1823,33 @@ auto APINotesReader::lookupObjCClassID(llvm::StringRef Name)

// ObjC classes can't be declared in C++ namespaces, so use -1 as the global
// context.
auto KnownID = Implementation->ObjCContextIDTable->find(
auto KnownID = Implementation->ContextIDTable->find(
ContextTableKey(-1, (uint8_t)ContextKind::ObjCClass, *ClassID));
if (KnownID == Implementation->ObjCContextIDTable->end())
if (KnownID == Implementation->ContextIDTable->end())
return std::nullopt;

return ContextID(*KnownID);
}

auto APINotesReader::lookupObjCClassInfo(llvm::StringRef Name)
-> VersionedInfo<ObjCContextInfo> {
if (!Implementation->ObjCContextInfoTable)
-> VersionedInfo<ContextInfo> {
if (!Implementation->ContextInfoTable)
return std::nullopt;

std::optional<ContextID> CtxID = lookupObjCClassID(Name);
if (!CtxID)
return std::nullopt;

auto KnownInfo = Implementation->ObjCContextInfoTable->find(CtxID->Value);
if (KnownInfo == Implementation->ObjCContextInfoTable->end())
auto KnownInfo = Implementation->ContextInfoTable->find(CtxID->Value);
if (KnownInfo == Implementation->ContextInfoTable->end())
return std::nullopt;

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

auto APINotesReader::lookupObjCProtocolID(llvm::StringRef Name)
-> std::optional<ContextID> {
if (!Implementation->ObjCContextIDTable)
if (!Implementation->ContextIDTable)
return std::nullopt;

std::optional<IdentifierID> classID = Implementation->getIdentifier(Name);
Expand All @@ -1859,25 +1858,25 @@ auto APINotesReader::lookupObjCProtocolID(llvm::StringRef Name)

// ObjC classes can't be declared in C++ namespaces, so use -1 as the global
// context.
auto KnownID = Implementation->ObjCContextIDTable->find(
auto KnownID = Implementation->ContextIDTable->find(
ContextTableKey(-1, (uint8_t)ContextKind::ObjCProtocol, *classID));
if (KnownID == Implementation->ObjCContextIDTable->end())
if (KnownID == Implementation->ContextIDTable->end())
return std::nullopt;

return ContextID(*KnownID);
}

auto APINotesReader::lookupObjCProtocolInfo(llvm::StringRef Name)
-> VersionedInfo<ObjCContextInfo> {
if (!Implementation->ObjCContextInfoTable)
-> VersionedInfo<ContextInfo> {
if (!Implementation->ContextInfoTable)
return std::nullopt;

std::optional<ContextID> CtxID = lookupObjCProtocolID(Name);
if (!CtxID)
return std::nullopt;

auto KnownInfo = Implementation->ObjCContextInfoTable->find(CtxID->Value);
if (KnownInfo == Implementation->ObjCContextInfoTable->end())
auto KnownInfo = Implementation->ContextInfoTable->find(CtxID->Value);
if (KnownInfo == Implementation->ContextInfoTable->end())
return std::nullopt;

return {Implementation->SwiftVersion, *KnownInfo};
Expand Down Expand Up @@ -2014,7 +2013,7 @@ auto APINotesReader::lookupTypedef(llvm::StringRef Name,
auto APINotesReader::lookupNamespaceID(
llvm::StringRef Name, std::optional<ContextID> ParentNamespaceID)
-> std::optional<ContextID> {
if (!Implementation->ObjCContextIDTable)
if (!Implementation->ContextIDTable)
return std::nullopt;

std::optional<IdentifierID> NamespaceID = Implementation->getIdentifier(Name);
Expand All @@ -2023,9 +2022,9 @@ auto APINotesReader::lookupNamespaceID(

uint32_t RawParentNamespaceID =
ParentNamespaceID ? ParentNamespaceID->Value : -1;
auto KnownID = Implementation->ObjCContextIDTable->find(
auto KnownID = Implementation->ContextIDTable->find(
{RawParentNamespaceID, (uint8_t)ContextKind::Namespace, *NamespaceID});
if (KnownID == Implementation->ObjCContextIDTable->end())
if (KnownID == Implementation->ContextIDTable->end())
return std::nullopt;

return ContextID(*KnownID);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/APINotes/APINotesTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ LLVM_DUMP_METHOD void CommonTypeInfo::dump(llvm::raw_ostream &OS) const {
OS << '\n';
}

LLVM_DUMP_METHOD void ObjCContextInfo::dump(llvm::raw_ostream &OS) {
LLVM_DUMP_METHOD void ContextInfo::dump(llvm::raw_ostream &OS) {
static_cast<CommonTypeInfo &>(*this).dump(OS);
if (HasDefaultNullability)
OS << "DefaultNullability: " << DefaultNullability << ' ';
Expand Down
Loading