OffloadArch was a flat enum that hand-duplicated every AMDGPU and NVPTX
target, plus a few edge cases. This was yet another place that needed
updating every time a new target is added, which should now be avoided.
Replace with a tagged union-like scheme.
Co-authored-by: Claude (Claude-Opus-4.8) <noreply@anthropic.com>
A defaulted copy or move assignment operator for a union is synthesized
with an empty body. `DefineImplicitCopyAssignment` /
`DefineImplicitMoveAssignment` skip union members in the memberwise
loop, and the implied copy of the object representation has no AST
representation, a FIXME that has sat at that skip for a long time. The
operator ends up copying nothing.
Classic CodeGen hides this at ordinary call sites by lowering a trivial
assignment to a memcpy at the call site, so `u1 = u2` works even though
the operator body is a no-op. But when the operator is genuinely called,
through a pointer-to-member for instance, it silently copies nothing.
ClangIR calls the assignment operator at the call site rather than
eliding it, so it hits the empty body directly and drops every union
assignment. The no-op is then deleted at `-O3`. That is the MultiSource
`kc` miscompile, where a `YYSTYPE` union assignment (`*++yyvsp =
yylval`) becomes a no-op.
This implements the FIXME by mirroring the defaulted union copy
constructor (`CGClass.cpp`: "union copy constructor, we must emit a
memcpy") in the AST: when the class is a union,
`DefineImplicit{Copy,Move}Assignment` emits a single whole-object copy
through `buildMemcpyForAssignmentOp`, the helper already used for
trivially-copyable array members, instead of the skipped per-member
assignments. The operator stays trivial (triviality is fixed at
declaration time, before the body is synthesized), so constant
evaluation, which copies trivial unions through its own semantic path
and never executes the body, is unchanged.
Copying the object representation is correct even when a union member is
not trivially copyable, but the synthesized memcpy would then trip
`-Wnontrivial-memcall`. A `void*` cast would drop pointee qualifiers
such as the address space and inject an explicit cast node the source
never wrote. Instead the call keeps its typed union-pointer arguments,
and the union branch in `DefineImplicit{Copy,Move}Assignment` wraps the
build in `IgnoreAllWarningDiagRAII`, a save-and-restore around the
engine's existing ignore-all-warnings state. `CheckMemaccessArguments`
defers the warning and its note through `DiagRuntimeBehavior`, and that
queue flushes after the RAII has restored the previous ignore state, so
`DiagIfReachable` samples that state as it enqueues and drops what is
not error-class. Under `-w` the same queue is discarded before it
flushes, so nothing outside the scoped region changes.
Classic CodeGen now emits the copy when the operator is odr-used, and
ClangIR's union assignment lowers to a real memcpy. On the Sema side,
tests cover the synthesized AST for the implicit-`this` and C++23
explicit-object spellings, the `-Wnontrivial-memcall` suppression, the
preserved address space, the clean `-ast-print` output, and constexpr
active-member copy. The classic and ClangIR lowering is checked across
named, anonymous, and tail-padded unions.
#198918 added a defaulted-union `errorNYI` in ClangIR and deferred this
AST fix to a separate change. This PR makes that fix and drops the
guard, so the now-non-empty body lowers to a `cir.call @memcpy` instead
of erroring. Its own `union-copy-move-assignment.cpp` CIR test, which
expects that call, is the regression check.
This change adds support for lowering floating-point operations with the
fenv attribute set to a call to the corresponding constrained intrinsic
when the operation is lowered to the LLVM dialect.
Generation of operations with the Fenv attribute set will be implemented
in a later change. This only adds support for lowering.
Assisted-by: Cursor / claude-opus-4.8
This PR relocates all `CompilerInstanceWithContext` code to
`DependencyScanningWorker.cpp` and hides them as implementation details,
since no public APIs should use `CompilerInstanceWithContext` directly.
---
<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
This PR implements a streaming stype by-name scanning API. The new API
takes a `DependencyConsumer`, a `DiagnosticsConsumer` and a
`getNextName` lambda. Any diagnositcs flow to the `DependencyConsumer`,
and the results flows to to `DependencyConsumer`. The `getNextName`
lambda is allows the client to stream names into the API, and the API
keeps scanning dependencies for input names until `getNextName` does not
return more names.
rdar://178088113
---
<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
v_cvt_sr_pk_bf16_f32 was gated on bf16-cvt-insts, but that feature is
also present on gfx950 where the (non-sr) v_cvt_pk_bf16_f32 was first
added. The stochastic-rounding v_cvt_sr_pk_bf16_f32 was only added
for gfx1250 and has no gfx950 encoding, so it would mis-select and
later hit the "Invalid opcode" assert. Introduce
cvt-sr-pk-bf16-f32-inst, currently added to gfx13 and 125*
Co-authored-by: Claude (Claude-Opus-4.8)
Currently the ordering of the parameters in `getEndPath` and
`finalizeVisitor` functions does not match the declaration of the
`VisitNode` function. This PR resolves it by reordering the parameters
among these functions to be consistent.
PointerType and VPtrType have hard-coded sizes and alignments of 64/8
bits. On targets with 32-bit pointers (e.g., nvptx, spirv32), this trips
the record layout builder. Any record containing a pointer hit the
insertPadding assertion (offset >= size)
because the pointer was sized at 8 bytes while the following field was
placed at the AST-mandated 4-byte offset.
### Changes:
- CIRGenerator: attaches a CIR-native cir.ptr data-layout entry at
module setup, storing {size-in-bits, abi-align-in-bits} read
from the target DataLayout (only for the default address space).
- CIRTypes: PointerType reads its size/alignment from that entry
(falling back to 64/8 when absent); VPtrType routes through a cir.ptr so
it picks up the same width.
- LowerToLLVM: strips the cir.ptr entry during CIR→LLVM lowering, since
cir.ptr has no meaning in LLVM IR.
- Unit test: checking 4-byte pointer/vptr layout on nvptx, verified
across CIR, CIR→LLVM.
This implements the basics, and leaves NYI in a few places (particularly
those that require cleanup calculations). There IS some additional work
that needs to be done when the ABI work is put in place as well, and the
thunk 'tail' hint isn't implemented either, and is left as a
missing-feature.
This is necessary for compiling the bytecode interpreter in Clang in a
few places during self-build.
This PR extracts out an initializer of `CompilerInstanceWithContext`
that does not depend on any driver code in preperation of moving the
`CompilerInstanceWithContext` into `DependencyScanningWorker.cpp` as an
implementation detail that is not exposed by any APIs.
---
<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
Adds a new `SpacesInBlockComments` clang-format option to control
spacing after `/*` and before `*/` in ordinary block comments.
Supported values:
* Always: formats `/*comment*/` as `/* comment */`
* Never: formats `/* comment */` as `/*comment*/`
* Leave: preserves existing spacing
Documentation comments such as `/** ... */` and `/*! ... */`, and
parameter comments such as `/*Arg=*/`, are left unchanged.
Tests added for all option values, multiline block comments, and
excluded parameter/doc comments.
Addresses #160682
This adds the #cir.fenv attribute to the cir.cmp and cir.vec.cmp and
adds verfiers to enforce that the attribute is only present when the
comparison involves floating-point values.
The cir.vec.cmp operation has an existing folder which is skipped in
this change when the fenv attribute is present. In most circumstance,
this folding could still be done, but the implementation is
intentionally conservative at this point. Proper checking of the
conditions under which folding would be legal will be added later.
The cir.cmp operation does not currently have a folder.
Assisted-by: Cursor / various models
LLVM Memcpy supports copying across address spaces, so we should too. IN
C, this is legal, and there are no associated AST nodes to reasonably
put in a cast, so this patch just legalizes it to match the LLVM
behavior.
Note: I've added a 'CopyTypes' printer/parser as well, because it seems
unfortunate to make EVERY copy have to show all of its types.
Replace manual handling of 2 attributes with
`Sema::mergeDeclAttributes`, which is called during parsing too. Also
propagate attributes not from a previous redeclaration but from a
previous redeclaration outside of the current module. This is done to
avoid double propagation because attributes from a previous decl in the
same module are already handled when a module is built.
Call `ASTDeclReader::attachLatestDecl` after each decl is added to a
redeclaration chain, not once per `ASTReader::loadPendingDeclChain`
call. This is done to maintain correct redeclaration chain for each
`ASTDeclReader::attachPreviousDecl` call because [newly added]
`mergeDeclAttributes` requires a correct redeclaration chain.
Separated `Parser::Initialize` and `Parser::ConsumeToken` so can move
the initialization earlier, into `Parser` constructor. This way
`Parser::Initialize`, `Sema::Initialize`, `ASTReader::InitializeSema` are
executed before deserialization. This specific case is verified by
"Modules/decl-attr-merge-explicit-modules.c".
The change can cause compilation errors for downstream `Parser` clients.
Instead of calling `Parser::Initialize` now you need to call
`Parser::ConsumeToken`.
rdar://175997317
Discovered these just looking around, they are pretty simple/trivial
translations to LLVM-IR intrins, and the infrastructure to do so is
already in place, so this is a bit of simple wiring up!
Implements f/h/hl versions of sin/cos/tan. Also implements base-10
exponent, since it is also trivial.
This commit adds a version of the existing s_buffer_load intrinsic that
more accurately models the memory semantics of the s_buffer_load
instruction, namely that it is, in fact, a memory load.
To preserve the existing behavior that the "nomem" s.buffer.load
intrinsic was using, Clang and MLIR add !invariant.load metadata when
constructing the intrinsic (matching documented requirements on
scalarazable buffer loads) and a late codegen pass adds the metadata
just to be safe.
Tests that were "about" s.buffer.load have been copied to create
versions that use the new intrinsic, as was done for the other
*.ptr.buffer.* operations.
Other tests have been upgraded to use the new intrinsic. This has mainly
resulted in minor instruction ordering changes in prologues, if any
change at all. However, CodeGen/AMDGPU/dagcombine-fma-fmad.ll has seen a
v_fma => v_mad pattern fail to match in one case, I don't know if this
is a real regression.
While I was here, the s_buffer_load => buffer_load fallback has been
updated to preserve cachepolity.
AI disclosure: Primarily AI-written code, but I have at least looked at
and tried to find the worst of the silliness.
---------
Co-authored-by: Codex <codex@openai.com>
This adds the optional #cir.fenv attribute to the cir.cast operation and
updates the verifier to enforce the attribute being present only when
the cast involves floating-point values.
Assisted-by: Cursor / various models
We have a libstdc++ workaround in place to address a hack in libstdc++15
that is used in the definition of `std::format_kind`. GCC accepts the
hack, while Clang does not. libstdc++ was eventually updated to remove
the hack, but we still need the workaround for some versions of
libstdc++15 (see #139560 for more information).
Whether this workaround (and others that address libstdc++ hacks) is
active depends on the value of `__GLIBCXX__`. This stops working if
someone first preprocesses the input (via `-E`) and then attempts to
compile the preprocessed code with Clang (see #160314): since
preprocessing has already happened, `__GLIBCXX__` will be undefined and
the workaround will not be applied.
In case of this particular workaround, this results in `#include
<format>` failing to compile on some versions of libstdc++ if you’re
using separate preprocessing.
To resolve this problem, this patch introduces a new pragma (`#pragma
clang __set_pp_state MACRO_NAME INTEGER`). This is intended as a general
solution to preserving preprocessor state across runs of the
preprocessor.
Currently, the only supported value for `MACRO_NAME`is `__GLIBCXX__`.
When we encounter this form of the pragma, we update
`Preprocessor::CXXStandardLibraryVersion` (we don’t actually define
`__GLIBCXX__` or do anything w/ that macro here). In `-E` mode, the
pragma is retained in the output, and a pragma is emitted for `#define
__GLIBCXX__` if printing macro definitions is disabled.
Things like `#undef __GLIBCXX__` and redefinitions of `__GLIBCXX__` are
deliberately left unhandled (i.e. you get what you get), since users
shouldn’t ever be undefining or redefining this macro anyway (and since
it starts w/ `__`, it would also be UB to do so).
Fixes#160314.
This PR relands #208533 which was reverted in #212832 due to test
failures with iterator-based loops.
Original Change:
#208533 fixes loop variable finalization for OpenMP 6.0
loop-transformations constructs: tile, stripe, reverse, interchange and
fuse to comply with spec requirement page 371, lines 19-21. The spec
requires that "After the execution of the loop-transforming construct,
the loop-iteration variables of any of its transformation-affected loops
have the values that they would have without the loop-transforming
directive".
What's Fixed in This Reland:
The original implementation attempted to finalize all loop variables,
including iterators in range-based for loops (CXXForRangeStmt). This
caused issues because the finalization formula `final_value =
lower_bound + num_iterations * step` only applies to arithmetic types
(integers, floats).
GROMACS uses scoped enums with a boolean underlying type as type-safe
flags (`enum class EmulateGpuNonbonded : bool`), and compares them with
`==` / `!=` / `<`. A scoped enum is not integer-promoted before the
comparison, so the operand reaches `cir.cmp` as a `!cir.bool` (CIR
already
represents a boolean-underlying enum with `!cir.bool`). The `cir.cmp`
operand constraint `CIR_ComparableType` does not list bool, so module
verification fails before the CIR-to-CIR passes with:
```
'cir.cmp' op operand #0 must be comparable type, but got '!cir.bool'
```
Add bool to `CIR_ComparableType` and let the comparison lowering compare
`!cir.bool` the same way it already compares pointers, as an unsigned
`icmp` (`ult` for `<`), which is what classic CodeGen does with these as
`i1`. Plain `bool` comparisons are unchanged, since they still carry the
AST integral promotion and compare as `i32`, and unscoped `enum : bool`
still promotes too.
Six translation units in a minimal GROMACS build hit this
(`taskassignment/decidegpuusage`, `mdrun/runner`, the three `domdec`
topology files, and a gtest-based test), and they compile under
`-fclangir` with the fix. `enum-bool.cpp` covers all six comparison
predicates, and `cmp.cir` gains an unpromoted `!cir.bool` round-trip
next to the existing promoted one. The signature checks in
`enum-bool.cpp` are split into `LLVMCIR` and `OGCG`
because classic codegen marks these `i1` values `zeroext` and CIR does
not, which is call-conv lowering being off in the default pipeline
rather
than anything specific to bool.
As a side effect of my previous refactoring efforts, the method
`ExprEngine::processCFGBlockEntrance` had two very similar parameters: a
`BlockEdge` and a `BlockEntrance` instance.
These are both subclasses of `ProgramPoint`, stored the same data (the
`BlockEntrance` was initialized with data taken from the `BlockEdge`
just before the call) and the `BlockEdge` was almost completely unused
within `processCFGBlockEntrance`.
The only reason for having the `BlockEdge` was that it was stored in the
debug statistic table `blocksExhausted`; so this commit transitions that
simple debug code to use `BlockEntrance` instances instead (which is
also perfectly sufficient for its goals). This allows the removal of the
redundant argument of `processCFGBlockEntrance`.
This prepares the ground for further cleanup in this method.
This adds the #cir.fenv attribute to the CIR_UnaryFPToIntBuiltinOp and
CIR_TernaryFPToFPBuiltinOp base classes, and through them to the
cir.lround, cir.llround, cir.lrint, cir.llrint, and cir.fma operations.
This attribute is still missing from various cast and compare
operations. Those will be added in a follow-up change.
Assisted-by: Cursor / various models
This patch removes the previous implementation of cross; instead, it
adds a new one inside the header files.
Fix: https://github.com/llvm/llvm-project/issues/135425
Assisted by: Claude Opus 4.8
---------
Co-authored-by: Joao Saffran <jderezende@microsoft.com>
This introduces a new CIR attribute that will be used to describe
floating-point environment assumptions and restrictions, allowing for
general modeling of floating-point environment access. A new interface
is also introduced to simplify handling of default settings when the
attribute or one of its optional components is not present.
This patch adds the attribute and interface to FPBinaryOp,
BinaryFPToFPBuiltinOp, and UnaryFPToFPBuiltin. Support for generating
operations with this attribute and lowering them to the LLVM dialect
will be added in a future change.
Assisted-by: Cursor / claude-opus-4.8
A computed `goto *p` placed inside a nested scope -- an if or a loop
body --
made CIRGen produce invalid IR that the region verifier rejected with
"reference to block defined in another region", aborting the compile.
Regular
`goto` avoids this because CIRGen emits a symbolic
`cir.goto` that references no block and is later resolved into a
`cir.br` by
GotoSolver, which runs after FlattenCFG has merged the nested scopes
into one
region. Indirect goto skipped that indirection: `emitIndirectGotoStmt`
built
a real indirect-branch block during CIRGen and branched to it from
inside the
nested region, and `finishIndirectBranch` wired the `cir.indirect_br`
successors at the end of the function -- both while the scopes were
still
separate regions.
This gives indirect goto the same symbolic treatment. A new terminator,
`cir.indirect_goto`, carries the target address and references no
successor,
so it is valid in any region. GotoSolver now rewrites each one into a
`cir.br` to a single shared block holding the `cir.indirect_br` over
every
address-taken label; running after FlattenCFG, it sees all blocks in one
region, so the cross-region branch can no longer occur. GotoSolver
already
collects the address-taken labels -- from `cir.block_address` ops and
from
block-address attributes in global initializers -- so the CIRGen-side
bookkeeping it supersedes (the lazily-built indirect-goto block, the
per-function target list, and the `CIRGenModule` block-address-to-label
map)
is removed.
An indirect goto that branches out of a scope needing cleanup (a VLA
stack
restore, or a non-trivial destructor on the edge) must run that cleanup
on the
branch, which this does not implement. Rather than emit a branch that
silently skips the cleanup, `emitIndirectGotoStmt` reports it with
`errorNYI`.
With the fix, the `evalloop`, `20041214-1`, and `comp-goto-1` programs
in the
LLVM test-suite go from a CIRGen crash to building and running.
We treated line directives as being unevaluated string literal. However
- The standard has no such restriction - or rather the standard has
different, unclear restriction (https://wg21.link/CWG2693)
- Because of Windows paths, it's common for "C:\foo\bar" to be used, and
these should not form escape sequences.
To remain consistent with other implementations, we do not allow `#line
1 <>` at this time. We do however support `#line 1 ""` to avoid a
breaking change.
Fixes a regression introduced by #201413
This patch fixes loop variable finalization for OpenMP 6.0
loop-transformations constructs: `tile`, `stripe`, `reverse`,
`interchange` and `fuse` to comply with spec requirement page 371, lines
19-21. The spec requires that "After the execution of the
loop-transforming construct, the loop-iteration variables of any of its
transformation-affected loops have the values that they would have
without the loop-transforming directive".
`SortIncludes` currently orders includes lexicographically with the
option to ignore case or extension. This adds another option, `Natural`,
that compares embedded runs of digits as numbers rather than sequences
of characters, matching the "natural sort" behaviour found in most file
managers and tools like `sort` when called with the `-V` option.
**Disclaimer**
AI assistance was used in initial exploration and review but the code is
"hand generated".
The UPDATE clause has the same spelling on both of these directives, but
functionally it's two different clauses. Split them into "update", and
"update_depend_objects" to be able to tie their properties to their enum
ids.
This should make it easier to implement auto-generating of clause
properties in the future by avoiding spelling conflicts.
---------
Co-authored-by: Alexey Bataev <a.bataev@outlook.com>
RangedConstraintManager discards a simplified symbol if it reduces to a
concrete integer. This leads to delayed realization that some state
might be infeasible (because the concrete integer does not fit in the
assumed range), which might produce unexpected null pointers on the
following state splits.
PthreadLockChecker has fallen just into this trap. It assumes
`pthread_mutex_lock` is always called in a feasible state, which is was
not true.
In particular, in ZFS the analyzer crashes when runs in CTU mode because
it reaches `pthread_mutex_lock()` in over-constraint state (see the
reduced example in the first commit).
Checkers rely on the invariant that a state split can never result in
both `StateRef`s being null. To fix this violation of the invariant,
this patch helps RangedConstraintManager to realize a state is
infeasible and abort its exploration early so no follow-up state split
produce unexpected null-null pair.
Assisted by Claude Opus 4.8
--
CPP-8665
fixes https://github.com/llvm/llvm-project/issues/212109
From the edits to the release notes:
- On MIPS, a `_Complex` value with an integer element type is now
returned packed
into a single integer register when it fits in one, matching GCC. A
`_Complex char` or
`_Complex short`, and on N32/N64 also a `_Complex int`, is no longer
returned
with one part per register. `-fclang-abi-compat=23` restores the
previous
behavior. (#GH212109)
- On MIPS N32/N64, a `_Complex float` or `_Complex double` argument is
now packed
into integer registers, or onto the stack, once there is no longer room
to give
each of its parts a floating-point register, matching GCC. Clang
previously
always passed the parts separately. `-fclang-abi-compat=23` restores the
previous
behavior. (#GH212109)
This PR adds diagnostics for exact `Where.Parameters` selectors on top
of the existing parsing, serialization, and Sema matching support.
It diagnoses duplicate exact selectors during API notes conversion,
including duplicate `Where.Parameters: []`, while still allowing broad
name-only entries and same-name entries with different selectors.
It also adds reader/Sema support to warn under `-Wapinotes` when an
exact selector in API notes does not match any visible overload. The
reader can now enumerate stored exact selectors for global functions and
C++ methods, and Sema compares those against the selector candidates
derived from the visible overload set.
The diagnostic path follows the same matching policy as Sema, including
the desugared alias fallback, so valid matched selectors do not produce
false warnings.
Tests cover duplicate selector errors, unmatched selector warnings for
globals and C++ methods, broad-plus-exact coexistence, exact notes not
silently applying on mismatch, and no false warnings for matched or
alias-fallback selectors.
Reviewers: @Xazax-hun @j-hui @egorzhdan
---------
Co-authored-by: John Hui <updog@j-hui.com>
1) Mention the limit in the "constexpr evaluation hit maximum step
limit" diagnostic as well
2) Move the "use -fconstexpr-steps" instruction to its own note so we
can reuse it for two different diagnostics
For
```c++
struct S {
constexpr S() {}
};
constexpr S foo[1'500'000] = {};
```
we used to emit
```console
array.cpp:1028:13: error: constexpr variable 'foo' must be initialized by a constant expression
1028 | constexpr S foo[1'500'000] = {};
| ^ ~~
array.cpp:1026:17: note: constexpr evaluation hit maximum step limit; possible infinite loop?
1026 | constexpr S() {}
| ^
array.cpp:1028:31: note: in call to 'S()'
1028 | constexpr S foo[1'500'000] = {};
| ^
```
and now we emit
```console
array.cpp:1028:13: error: constexpr variable 'foo' must be initialized by a constant expression
1028 | constexpr S foo[1'500'000] = {};
| ^ ~~
array.cpp:1026:17: note: constexpr evaluation hit maximum step limit of 1048576; possible infinite loop?
1026 | constexpr S() {}
| ^
array.cpp:1028:31: note: in call to 'S()'
1028 | constexpr S foo[1'500'000] = {};
| ^
array.cpp:1026:17: note: use -fconstexpr-steps= to increase this limit (=0 will remove the limit)
1026 | constexpr S() {}
```
Reverts llvm/llvm-project#196656
The CI does not yet build compiler-rt with SPIR-V support, so
libclang_rt.builtins.bc is absent on that bot. This change made the
missing file a hard error, breaking all libsycl functional tests that
compile with -fsycl.
Re-landing after CI is updated to build compiler-rt for SPIR-V.
Capability attributes on a parameter mean one of two unrelated things:
on a scoped-lockable parameter they describe the locks the passed scope
object holds, while on a function pointer parameter they describe the
requirements of the function called through the pointer. Since #191187
allowed the latter, both of the scoped-lockable code paths have been
misreading function pointer parameters as scope objects.
At a call site, the argument bound to the parameter was translated into
a capability and required to be held, so passing a callback that
requires a capability was reported as a missing lock named after the
callback:
```
void apply(fn_t fn EXCLUSIVE_LOCKS_REQUIRED(mu));
static int my_fn() EXCLUSIVE_LOCKS_REQUIRED(mu);
...
apply(my_fn); // warning: requires holding mutex 'fn'
```
In the callee, the same confusion seeded the parameter's capabilities
into the function's entry lockset, so they were considered held
throughout the body and the calls made through the pointer went
unchecked -- the opposite of what the annotation asks for.
Skip function pointer parameters in both places; their attributes are
already checked at the indirect call sites (by #191187), the same way as
for annotated function pointer variables and fields.
Assisted-by: Claude Opus 5
Store selector name location alongside the existing @-sign and paren locations, exposed via getSelectorLoc(), so tools and diagnostics can reference the name rather than the @selector keyword. While here, rename things to disambiguate locations.
This PR implements compile-time device library linking for SYCL
offloading to SPIR-V targets, using `libclang_rt.builtins.bc` - an
in-tree compiler-rt artifact produced alongside the existing
`libclang_rt.builtins.a` for `SPIRV64`.
## Motivation
SYCL device compilations targeting SPIR-V need access to compiler
builtins (integer arithmetic, floating-point helpers, etc.) at compile
time so the compiler can optimize across user code and builtins, inline
aggressively, and eliminate dead code. This PR lays the foundation by
wiring up the first in-tree device library : `libclang_rt.builtins.bc` -
using the same `-mlink-builtin-bitcode` mechanism already used by
`libclc` and `HIP`.
## Changes
**compiler-rt (compiler-rt/lib/builtins/CMakeLists.txt)**
For the `spirv64` target, after building
`libclang_rt.builtins-spirv64.a`, runs `llvm-link` to merge all bitcode
objects into a single `libclang_rt.builtins.bc`. This file is installed
to `<ResourceDir>/lib/spirv64-unknown-unknown/` alongside the static
archive. The `-mlink-builtin-bitcode` flag requires raw LLVM IR and
cannot unpack a static archive directly, hence the extra step.
**Clang Driver (clang/lib/Driver/ToolChains/SYCL.cpp)**
`SYCLToolChain::getDeviceLibs()` now constructs the path to
`libclang_rt.builtins.bc` under the clang resource directory and returns
it for `-mlink-builtin-bitcode` injection during `spirv64` device
compilation. If the file is absent (e.g. compiler-rt was not built with
spirv64 support), a specific diagnostic is emitted. Linking is
suppressed when `--no-offloadlib` is passed.
**Diagnostics (clang/include/clang/Basic/DiagnosticDriverKinds.td)**
Added `err_drv_no_compiler_rt_builtins_bc`, following the
`err_drv_libclc_not_found` community pattern, with actionable guidance
on how to build compiler-rt with SPIR-V support.
### Test Infrastructure
1. `clang/test/Driver/sycl-device-lib-spirv64.cpp` - new test verifying
-mlink-builtin-bitcode is passed for spirv64, suppressed with
--no-offloadlib, and that a missing .bc produces the correct diagnostic.
2. `clang/test/Driver/Inputs/spirv64-sycl/` - dummy resource-dir fixture
used by driver tests.
3. All existing SYCL driver tests updated to pass -`resource-dir
%S/Inputs/spirv64-sycl `on -fsycl RUN lines, making them independent of
the installed clang resource directory on CI runners.
## Behavior
### Default
```bash
clang -fsycl myprogram.cpp
# Device compilation includes:
# "-mlink-builtin-bitcode" "<ResourceDir>/lib/spirv64-unknown-unknown/libclang_rt.builtins.bc"
```
Automatically links device libraries from `<clang-install>/lib/` during
device compilation.
### Without device libraries
```bash
clang -fsycl --no-offloadlib myprogram.cpp
# -mlink-builtin-bitcode is suppressed
```
Missing .bc (compiler-rt not built with spirv64 support)
```bash
error: no compiler-rt builtins bitcode library '...' found in the clang resource directory;
build compiler-rt with SPIR-V support or pass '--no-offloadlib' to compile without it ```
ExpressionTraits.h defines utilities such as `getTraitName`,
`getTraitSpelling` and an enumeration for expression traits. All other
overloads of these utilities can be found in TypeTraits.h - this patch
combines them to BuiltinTraits.h/cpp.
This is a followup patch for
https://github.com/llvm/llvm-project/pull/201491#discussion_r3460883247
After the parameter declaration of a lambda expression, `Sema` enters
the declaration context of the lambda call operator (in
`ActOnLambdaClosureParameters`), so the lambda specifiers and the
trailing return type are analyzed within that context. Because of this,
predefined expressions such as `__func__` resolve to the lambda call
operator, and not to the possibly enclosing function. (issue #122657)
Added a member to `LambdaScopeInfo` to mark whether or not the compound
statement of the lambda expression has been entered, to be used when
resolving a `PredefinedExpr`
Extracts cache insertion logic from `IsValueInFlagEnum`. This allows us
to drop `mutable` on `FlagBitsCache` while making it reusable as work
list for additional flag_enum diagnostics.