314 changes: 314 additions & 0 deletions clang/lib/Headers/avx10_2_512niintrin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,314 @@
/*===---- avx10_2_512niintrin.h - AVX10.2-512 new instruction intrinsics ---===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
*===-----------------------------------------------------------------------===
*/
#ifndef __IMMINTRIN_H
#error \
"Never use <avx10_2_512niintrin.h> directly; include <immintrin.h> instead."
#endif

#ifdef __SSE2__

#ifndef __AVX10_2_512NIINTRIN_H
#define __AVX10_2_512NIINTRIN_H

#define __DEFAULT_FN_ATTRS \
__attribute__((__always_inline__, __nodebug__, __target__("avx10.2-512"), \
__min_vector_width__(512)))

/* VNNI FP16 */
static __inline__ __m512 __DEFAULT_FN_ATTRS _mm512_dpph_ps(__m512 __W,
__m512h __A,
__m512h __B) {
return (__m512)__builtin_ia32_vdpphps512((__v16sf)__W, (__v32hf)__A,
(__v32hf)__B);
}

static __inline__ __m512 __DEFAULT_FN_ATTRS _mm512_mask_dpph_ps(__m512 __W,
__mmask16 __U,
__m512h __A,
__m512h __B) {
return (__m512)__builtin_ia32_selectps_512(
(__mmask16)__U, (__v16sf)_mm512_dpph_ps(__W, __A, __B), (__v16sf)__W);
}

static __inline__ __m512 __DEFAULT_FN_ATTRS _mm512_maskz_dpph_ps(__mmask16 __U,
__m512 __W,
__m512h __A,
__m512h __B) {
return (__m512)__builtin_ia32_selectps_512(
(__mmask16)__U, (__v16sf)_mm512_dpph_ps(__W, __A, __B),
(__v16sf)_mm512_setzero_ps());
}

/* VMPSADBW */
#define _mm512_mpsadbw_epu8(A, B, imm) \
((__m512i)__builtin_ia32_mpsadbw512((__v64qi)(__m512i)(A), \
(__v64qi)(__m512i)(B), (int)(imm)))

#define _mm512_mask_mpsadbw_epu8(W, U, A, B, imm) \
((__m512i)__builtin_ia32_selectw_512( \
(__mmask32)(U), (__v32hi)_mm512_mpsadbw_epu8((A), (B), (imm)), \
(__v32hi)(__m512i)(W)))

#define _mm512_maskz_mpsadbw_epu8(U, A, B, imm) \
((__m512i)__builtin_ia32_selectw_512( \
(__mmask32)(U), (__v32hi)_mm512_mpsadbw_epu8((A), (B), (imm)), \
(__v32hi)_mm512_setzero_si512()))

/* VNNI INT8 */
static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpbssd_epi32(__m512i __W,
__m512i __A,
__m512i __B) {
return (__m512i)__builtin_ia32_vpdpbssd512((__v16si)__W, (__v16si)__A,
(__v16si)__B);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_mask_dpbssd_epi32(__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbssd_epi32(__W, __A, __B), (__v16si)__W);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpbssd_epi32(
__mmask16 __U, __m512i __W, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbssd_epi32(__W, __A, __B),
(__v16si)_mm512_setzero_si512());
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpbssds_epi32(__m512i __W,
__m512i __A,
__m512i __B) {
return (__m512i)__builtin_ia32_vpdpbssds512((__v16si)__W, (__v16si)__A,
(__v16si)__B);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_mask_dpbssds_epi32(
__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbssds_epi32(__W, __A, __B), (__v16si)__W);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpbssds_epi32(
__mmask16 __U, __m512i __W, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbssds_epi32(__W, __A, __B),
(__v16si)_mm512_setzero_si512());
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpbsud_epi32(__m512i __W,
__m512i __A,
__m512i __B) {
return (__m512i)__builtin_ia32_vpdpbsud512((__v16si)__W, (__v16si)__A,
(__v16si)__B);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_mask_dpbsud_epi32(__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbsud_epi32(__W, __A, __B), (__v16si)__W);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpbsud_epi32(
__mmask16 __U, __m512i __W, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbsud_epi32(__W, __A, __B),
(__v16si)_mm512_setzero_si512());
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpbsuds_epi32(__m512i __W,
__m512i __A,
__m512i __B) {
return (__m512i)__builtin_ia32_vpdpbsuds512((__v16si)__W, (__v16si)__A,
(__v16si)__B);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_mask_dpbsuds_epi32(
__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbsuds_epi32(__W, __A, __B), (__v16si)__W);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpbsuds_epi32(
__mmask16 __U, __m512i __W, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbsuds_epi32(__W, __A, __B),
(__v16si)_mm512_setzero_si512());
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpbuud_epi32(__m512i __W,
__m512i __A,
__m512i __B) {
return (__m512i)__builtin_ia32_vpdpbuud512((__v16si)__W, (__v16si)__A,
(__v16si)__B);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_mask_dpbuud_epi32(__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbuud_epi32(__W, __A, __B), (__v16si)__W);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpbuud_epi32(
__mmask16 __U, __m512i __W, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbuud_epi32(__W, __A, __B),
(__v16si)_mm512_setzero_si512());
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpbuuds_epi32(__m512i __W,
__m512i __A,
__m512i __B) {
return (__m512i)__builtin_ia32_vpdpbuuds512((__v16si)__W, (__v16si)__A,
(__v16si)__B);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_mask_dpbuuds_epi32(
__m512i __W, __mmask16 __U, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbuuds_epi32(__W, __A, __B), (__v16si)__W);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpbuuds_epi32(
__mmask16 __U, __m512i __W, __m512i __A, __m512i __B) {
return (__m512i)__builtin_ia32_selectd_512(
__U, (__v16si)_mm512_dpbuuds_epi32(__W, __A, __B),
(__v16si)_mm512_setzero_si512());
}

/* VNNI INT16 */
static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpwsud_epi32(__m512i __A,
__m512i __B,
__m512i __C) {
return (__m512i)__builtin_ia32_vpdpwsud512((__v16si)__A, (__v16si)__B,
(__v16si)__C);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_mask_dpwsud_epi32(__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwsud_epi32(__A, __B, __C),
(__v16si)__A);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpwsud_epi32(
__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwsud_epi32(__A, __B, __C),
(__v16si)_mm512_setzero_si512());
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpwsuds_epi32(__m512i __A,
__m512i __B,
__m512i __C) {
return (__m512i)__builtin_ia32_vpdpwsuds512((__v16si)__A, (__v16si)__B,
(__v16si)__C);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_mask_dpwsuds_epi32(
__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwsuds_epi32(__A, __B, __C),
(__v16si)__A);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpwsuds_epi32(
__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwsuds_epi32(__A, __B, __C),
(__v16si)_mm512_setzero_si512());
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpwusd_epi32(__m512i __A,
__m512i __B,
__m512i __C) {
return (__m512i)__builtin_ia32_vpdpwusd512((__v16si)__A, (__v16si)__B,
(__v16si)__C);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_mask_dpwusd_epi32(__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwusd_epi32(__A, __B, __C),
(__v16si)__A);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpwusd_epi32(
__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwusd_epi32(__A, __B, __C),
(__v16si)_mm512_setzero_si512());
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpwusds_epi32(__m512i __A,
__m512i __B,
__m512i __C) {
return (__m512i)__builtin_ia32_vpdpwusds512((__v16si)__A, (__v16si)__B,
(__v16si)__C);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_mask_dpwusds_epi32(
__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwusds_epi32(__A, __B, __C),
(__v16si)__A);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpwusds_epi32(
__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwusds_epi32(__A, __B, __C),
(__v16si)_mm512_setzero_si512());
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpwuud_epi32(__m512i __A,
__m512i __B,
__m512i __C) {
return (__m512i)__builtin_ia32_vpdpwuud512((__v16si)__A, (__v16si)__B,
(__v16si)__C);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_mask_dpwuud_epi32(__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwuud_epi32(__A, __B, __C),
(__v16si)__A);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpwuud_epi32(
__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwuud_epi32(__A, __B, __C),
(__v16si)_mm512_setzero_si512());
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_dpwuuds_epi32(__m512i __A,
__m512i __B,
__m512i __C) {
return (__m512i)__builtin_ia32_vpdpwuuds512((__v16si)__A, (__v16si)__B,
(__v16si)__C);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_mask_dpwuuds_epi32(
__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwuuds_epi32(__A, __B, __C),
(__v16si)__A);
}

static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_maskz_dpwuuds_epi32(
__m512i __A, __mmask16 __U, __m512i __B, __m512i __C) {
return (__m512i)__builtin_ia32_selectd_512(
(__mmask16)__U, (__v16si)_mm512_dpwuuds_epi32(__A, __B, __C),
(__v16si)_mm512_setzero_si512());
}

#undef __DEFAULT_FN_ATTRS

#endif /* __SSE2__ */
#endif /* __AVX10_2_512NIINTRIN_H */
277 changes: 277 additions & 0 deletions clang/lib/Headers/avx10_2minmaxintrin.h

Large diffs are not rendered by default.

2,075 changes: 2,075 additions & 0 deletions clang/lib/Headers/avx10_2niintrin.h

Large diffs are not rendered by default.

113 changes: 36 additions & 77 deletions clang/lib/Headers/avxvnniint16intrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,6 @@
#ifndef __AVXVNNIINT16INTRIN_H
#define __AVXVNNIINT16INTRIN_H

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, __target__("avxvnniint16"), \
__min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, __target__("avxvnniint16"), \
__min_vector_width__(256)))

/// Multiply groups of 2 adjacent pairs of signed 16-bit integers in \a __A with
/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
/// signed 16-bit results. Sum these 2 results with the corresponding
Expand Down Expand Up @@ -53,12 +45,9 @@
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwsud_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpwsud128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpwsud_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpwsud128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 2 adjacent pairs of signed 16-bit integers in \a __A with
/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
Expand Down Expand Up @@ -90,11 +79,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwsud_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpwsud_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpwsud256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}
#define _mm256_dpwsud_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpwsud256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

/// Multiply groups of 2 adjacent pairs of signed 16-bit integers in \a __A with
/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
Expand Down Expand Up @@ -127,12 +114,9 @@ _mm256_dpwsud_epi32(__m256i __W, __m256i __A, __m256i __B) {
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwsuds_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpwsuds128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpwsuds_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpwsuds128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 2 adjacent pairs of signed 16-bit integers in \a __A with
/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
Expand Down Expand Up @@ -165,11 +149,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwsuds_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpwsuds_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpwsuds256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}
#define _mm256_dpwsuds_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpwsuds256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
/// corresponding signed 16-bit integers in \a __B, producing 2 intermediate
Expand Down Expand Up @@ -201,12 +183,9 @@ _mm256_dpwsuds_epi32(__m256i __W, __m256i __A, __m256i __B) {
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwusd_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpwusd128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpwusd_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpwusd128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
/// corresponding signed 16-bit integers in \a __B, producing 2 intermediate
Expand Down Expand Up @@ -238,11 +217,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwusd_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpwusd_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpwusd256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}
#define _mm256_dpwusd_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpwusd256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
/// corresponding signed 16-bit integers in \a __B, producing 2 intermediate
Expand Down Expand Up @@ -275,12 +252,9 @@ _mm256_dpwusd_epi32(__m256i __W, __m256i __A, __m256i __B) {
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwusds_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpwusds128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpwusds_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpwusds128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
/// corresponding signed 16-bit integers in \a __B, producing 2 intermediate
Expand Down Expand Up @@ -313,11 +287,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwusds_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpwusds_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpwusds256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}
#define _mm256_dpwusds_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpwusds256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
Expand Down Expand Up @@ -349,12 +321,9 @@ _mm256_dpwusds_epi32(__m256i __W, __m256i __A, __m256i __B) {
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwuud_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpwuud128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpwuud_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpwuud128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
Expand Down Expand Up @@ -386,11 +355,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwuud_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpwuud_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpwuud256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}
#define _mm256_dpwuud_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpwuud256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
Expand Down Expand Up @@ -423,12 +390,9 @@ _mm256_dpwuud_epi32(__m256i __W, __m256i __A, __m256i __B) {
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwuuds_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpwuuds128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpwuuds_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpwuuds128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 2 adjacent pairs of unsigned 16-bit integers in \a __A with
/// corresponding unsigned 16-bit integers in \a __B, producing 2 intermediate
Expand Down Expand Up @@ -461,13 +425,8 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpwuuds_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpwuuds_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpwuuds256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}

#undef __DEFAULT_FN_ATTRS128
#undef __DEFAULT_FN_ATTRS256
#define _mm256_dpwuuds_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpwuuds256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

#endif // __AVXVNNIINT16INTRIN_H
113 changes: 36 additions & 77 deletions clang/lib/Headers/avxvnniint8intrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@
#ifndef __AVXVNNIINT8INTRIN_H
#define __AVXVNNIINT8INTRIN_H

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, __target__("avxvnniint8"), \
__min_vector_width__(256)))
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, __target__("avxvnniint8"), \
__min_vector_width__(128)))

/// Multiply groups of 4 adjacent pairs of signed 8-bit integers in \a __A with
/// corresponding signed 8-bit integers in \a __B, producing 4 intermediate
/// signed 16-bit results. Sum these 4 results with the corresponding
Expand Down Expand Up @@ -52,12 +44,9 @@
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbssd_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpbssd128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpbssd_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpbssd128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 4 adjacent pairs of signed 8-bit integers in \a __A with
/// corresponding signed 8-bit integers in \a __B, producing 4 intermediate
Expand Down Expand Up @@ -89,11 +78,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbssd_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpbssd_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpbssd256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}
#define _mm256_dpbssd_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpbssd256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

/// Multiply groups of 4 adjacent pairs of signed 8-bit integers in \a __A with
/// corresponding signed 8-bit integers in \a __B, producing 4 intermediate
Expand Down Expand Up @@ -126,12 +113,9 @@ _mm256_dpbssd_epi32(__m256i __W, __m256i __A, __m256i __B) {
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbssds_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpbssds128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpbssds_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpbssds128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 4 adjacent pairs of signed 8-bit integers in \a __A with
/// corresponding signed 8-bit integers in \a __B, producing 4 intermediate
Expand Down Expand Up @@ -164,11 +148,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbssds_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpbssds_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpbssds256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}
#define _mm256_dpbssds_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpbssds256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

/// Multiply groups of 4 adjacent pairs of signed 8-bit integers in \a __A with
/// corresponding unsigned 8-bit integers in \a __B, producing 4 intermediate
Expand Down Expand Up @@ -200,12 +182,9 @@ _mm256_dpbssds_epi32(__m256i __W, __m256i __A, __m256i __B) {
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbsud_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpbsud128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpbsud_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpbsud128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 4 adjacent pairs of signed 8-bit integers in \a __A with
/// corresponding unsigned 8-bit integers in \a __B, producing 4 intermediate
Expand Down Expand Up @@ -237,11 +216,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbsud_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpbsud_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpbsud256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}
#define _mm256_dpbsud_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpbsud256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

/// Multiply groups of 4 adjacent pairs of signed 8-bit integers in \a __A with
/// corresponding unsigned 8-bit integers in \a __B, producing 4 intermediate
Expand Down Expand Up @@ -274,12 +251,9 @@ _mm256_dpbsud_epi32(__m256i __W, __m256i __A, __m256i __B) {
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbsuds_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpbsuds128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpbsuds_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpbsuds128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 4 adjacent pairs of signed 8-bit integers in \a __A with
/// corresponding unsigned 8-bit integers in \a __B, producing 4 intermediate
Expand Down Expand Up @@ -312,11 +286,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbsuds_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpbsuds_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpbsuds256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}
#define _mm256_dpbsuds_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpbsuds256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

/// Multiply groups of 4 adjacent pairs of unsigned 8-bit integers in \a __A with
/// corresponding unsigned 8-bit integers in \a __B, producing 4 intermediate
Expand Down Expand Up @@ -348,12 +320,9 @@ _mm256_dpbsuds_epi32(__m256i __W, __m256i __A, __m256i __B) {
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbuud_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpbuud128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpbuud_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpbuud128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 4 adjacent pairs of unsigned 8-bit integers in \a __A with
/// corresponding unsigned 8-bit integers in \a __B, producing 4 intermediate
Expand Down Expand Up @@ -385,11 +354,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbuud_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpbuud_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpbuud256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}
#define _mm256_dpbuud_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpbuud256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

/// Multiply groups of 4 adjacent pairs of unsigned 8-bit integers in \a __A with
/// corresponding unsigned 8-bit integers in \a __B, producing 4 intermediate
Expand Down Expand Up @@ -422,14 +389,10 @@ _mm256_dpbuud_epi32(__m256i __W, __m256i __A, __m256i __B) {
/// ENDFOR
/// dst[MAX:128] := 0
/// \endcode
static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbuuds_epi32(__m128i __W,
__m128i __A,
__m128i __B) {
return (__m128i)__builtin_ia32_vpdpbuuds128((__v4si)__W, (__v4si)__A,
(__v4si)__B);
}
#define _mm_dpbuuds_epi32(__W, __A, __B) \
((__m128i)__builtin_ia32_vpdpbuuds128((__v4si)(__W), (__v4si)(__A), \
(__v4si)(__B)))

/// Multiply groups of 4 adjacent pairs of signed 8-bit integers in \a __A with
/// corresponding unsigned 8-bit integers in \a __B, producing 4 intermediate
/// signed 16-bit results. Sum these 4 results with the corresponding
/// 32-bit integer in \a __W with signed saturation, and store the packed
Expand Down Expand Up @@ -460,12 +423,8 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_dpbuuds_epi32(__m128i __W,
/// ENDFOR
/// dst[MAX:256] := 0
/// \endcode
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_dpbuuds_epi32(__m256i __W, __m256i __A, __m256i __B) {
return (__m256i)__builtin_ia32_vpdpbuuds256((__v8si)__W, (__v8si)__A,
(__v8si)__B);
}
#undef __DEFAULT_FN_ATTRS128
#undef __DEFAULT_FN_ATTRS256
#define _mm256_dpbuuds_epi32(__W, __A, __B) \
((__m256i)__builtin_ia32_vpdpbuuds256((__v8si)(__W), (__v8si)(__A), \
(__v8si)(__B)))

#endif // __AVXVNNIINT8INTRIN_H
32 changes: 32 additions & 0 deletions clang/lib/Headers/hlsl/hlsl_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,38 @@ float3 lerp(float3, float3, float3);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_lerp)
float4 lerp(float4, float4, float4);

//===----------------------------------------------------------------------===//
// length builtins
//===----------------------------------------------------------------------===//

/// \fn T length(T x)
/// \brief Returns the length of the specified floating-point vector.
/// \param x [in] The vector of floats, or a scalar float.
///
/// Length is based on the following formula: sqrt(x[0]^2 + x[1]^2 + Â…).

_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_length)
half length(half);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_length)
half length(half2);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_length)
half length(half3);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_length)
half length(half4);

_HLSL_BUILTIN_ALIAS(__builtin_hlsl_length)
float length(float);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_length)
float length(float2);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_length)
float length(float3);
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_length)
float length(float4);

//===----------------------------------------------------------------------===//
// log builtins
//===----------------------------------------------------------------------===//
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Headers/immintrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,16 @@ _storebe_i64(void * __P, long long __D) {
#include <avx512vlvp2intersectintrin.h>
#endif

#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX10_2__)
#include <avx10_2minmaxintrin.h>
#include <avx10_2niintrin.h>
#endif

#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX10_2_512__)
#include <avx10_2_512minmaxintrin.h>
#include <avx10_2_512niintrin.h>
#endif

#if !defined(__SCE__) || __has_feature(modules) || defined(__ENQCMD__)
#include <enqcmdintrin.h>
#endif
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Lex/PPMacroExpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ void Preprocessor::dumpMacroInfo(const IdentifierInfo *II) {
State ? State->getActiveModuleMacros(*this, II) : std::nullopt)
Active.insert(MM);
llvm::DenseSet<ModuleMacro*> Visited;
llvm::SmallVector<ModuleMacro *, 16> Worklist(Leaf.begin(), Leaf.end());
llvm::SmallVector<ModuleMacro *, 16> Worklist(Leaf);
while (!Worklist.empty()) {
auto *MM = Worklist.pop_back_val();
llvm::errs() << " ModuleMacro " << MM << " "
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {
///
/// HLSL: Parse export function declaration.
///
/// export-function-declaration:
/// export-function-declaration:
/// 'export' function-declaration
///
/// export-declaration-group:
Expand Down Expand Up @@ -1799,7 +1799,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
tok::kw___is_nothrow_constructible,
tok::kw___is_nothrow_convertible,
tok::kw___is_nothrow_destructible,
tok::kw___is_nullptr,
tok::kw___is_object,
tok::kw___is_pod,
tok::kw___is_pointer,
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,6 @@ bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II,
REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable);
REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible);
REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible);
REVERTIBLE_TYPE_TRAIT(__is_nullptr);
REVERTIBLE_TYPE_TRAIT(__is_object);
REVERTIBLE_TYPE_TRAIT(__is_pod);
REVERTIBLE_TYPE_TRAIT(__is_pointer);
Expand Down
126 changes: 126 additions & 0 deletions clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2371,6 +2371,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
ParseOMPEndDeclareTargetDirective(DTCI.Kind, DKind, DTCI.Loc);
return nullptr;
}
case OMPD_assume: {
Diag(Tok, diag::err_omp_unexpected_directive)
<< 1 << getOpenMPDirectiveName(DKind);
break;
}
case OMPD_unknown:
Diag(Tok, diag::err_omp_unknown_directive);
break;
Expand Down Expand Up @@ -2572,6 +2577,70 @@ StmtResult Parser::ParseOpenMPExecutableDirective(
return Directive;
}

StmtResult Parser::ParseOpenMPInformationalDirective(
ParsedStmtContext StmtCtx, OpenMPDirectiveKind DKind, SourceLocation Loc,
bool ReadDirectiveWithinMetadirective) {
assert(isOpenMPInformationalDirective(DKind) &&
"Unexpected directive category");

bool HasAssociatedStatement = true;

SmallVector<OMPClause *, 5> Clauses;
llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1);
DeclarationNameInfo DirName;
unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
ParseScope OMPDirectiveScope(this, ScopeFlags);

Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
Loc);

while (Tok.isNot(tok::annot_pragma_openmp_end)) {
if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
while (Tok.isNot(tok::annot_pragma_openmp_end))
ConsumeAnyToken();
break;
}

OpenMPClauseKind CKind = Tok.isAnnotation()
? OMPC_unknown
: getOpenMPClauseKind(PP.getSpelling(Tok));
Actions.OpenMP().StartOpenMPClause(CKind);
OMPClause *Clause =
ParseOpenMPClause(DKind, CKind, !SeenClauses[unsigned(CKind)]);
SeenClauses[unsigned(CKind)] = true;
if (Clause)
Clauses.push_back(Clause);

if (Tok.is(tok::comma))
ConsumeToken();
Actions.OpenMP().EndOpenMPClause();
}

SourceLocation EndLoc = Tok.getLocation();
ConsumeAnnotationToken();

StmtResult AssociatedStmt;
if (HasAssociatedStatement) {
Actions.OpenMP().ActOnOpenMPRegionStart(DKind, getCurScope());
ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
{
Sema::CompoundScopeRAII Scope(Actions);
AssociatedStmt = ParseStatement();
}
AssociatedStmt =
Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
}

StmtResult Directive = Actions.OpenMP().ActOnOpenMPInformationalDirective(
DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);

Actions.OpenMP().EndOpenMPDSABlock(Directive.get());
OMPDirectiveScope.Exit();

return Directive;
}

/// Parsing of declarative or executable OpenMP directives.
///
/// threadprivate-directive:
Expand Down Expand Up @@ -2920,6 +2989,14 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
<< 1 << getOpenMPDirectiveName(DKind);
SkipUntil(tok::annot_pragma_openmp_end);
break;
case OMPD_assume: {
ConsumeToken();
Directive = ParseOpenMPInformationalDirective(
StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
assert(!Directive.isUnset() &&
"Informational directive remains unprocessed");
return Directive;
}
case OMPD_unknown:
default:
Diag(Tok, diag::err_omp_unknown_directive);
Expand Down Expand Up @@ -3206,6 +3283,9 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_if:
Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
break;
case OMPC_holds:
Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
break;
case OMPC_nowait:
case OMPC_untied:
case OMPC_mergeable:
Expand Down Expand Up @@ -3323,6 +3403,49 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
break;
case OMPC_absent:
case OMPC_contains: {
SourceLocation Loc = ConsumeToken();
SourceLocation LLoc = Tok.getLocation();
SourceLocation RLoc;
llvm::SmallVector<OpenMPDirectiveKind, 4> DKVec;
BalancedDelimiterTracker T(*this, tok::l_paren);
T.consumeOpen();
do {
OpenMPDirectiveKind DK = getOpenMPDirectiveKind(PP.getSpelling(Tok));
if (DK == OMPD_unknown) {
skipUntilPragmaOpenMPEnd(OMPD_assume);
Diag(Tok, diag::err_omp_unexpected_clause)
<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
break;
}
if (isOpenMPExecutableDirective(DK)) {
DKVec.push_back(DK);
ConsumeToken();
} else {
Diag(Tok, diag::err_omp_unexpected_clause)
<< getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
}
} while (TryConsumeToken(tok::comma));
RLoc = Tok.getLocation();
T.consumeClose();
Clause = Actions.OpenMP().ActOnOpenMPDirectivePresenceClause(
CKind, DKVec, Loc, LLoc, RLoc);
break;
}
case OMPC_no_openmp:
case OMPC_no_openmp_routines:
case OMPC_no_parallelism: {
if (!FirstClause) {
Diag(Tok, diag::err_omp_more_one_clause)
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
ErrorFound = true;
}
SourceLocation Loc = ConsumeToken();
Clause = Actions.OpenMP().ActOnOpenMPNullaryAssumptionClause(
CKind, Loc, Tok.getLocation());
break;
}
case OMPC_ompx_attribute:
Clause = ParseOpenMPOMPXAttributesClause(WrongDirective);
break;
Expand Down Expand Up @@ -3408,6 +3531,9 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
/// align-clause
/// 'align' '(' positive-integer-constant ')'
///
/// holds-clause
/// 'holds' '(' expression ')'
///
OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
bool ParseOnly) {
SourceLocation Loc = ConsumeToken();
Expand Down
30 changes: 14 additions & 16 deletions clang/lib/Sema/HLSLExternalSemaSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ struct BuiltinTypeDeclBuilder {
}

BuiltinTypeDeclBuilder &
addMemberVariable(StringRef Name, QualType Type,
addMemberVariable(StringRef Name, QualType Type, llvm::ArrayRef<Attr *> Attrs,
AccessSpecifier Access = AccessSpecifier::AS_private) {
if (Record->isCompleteDefinition())
return *this;
Expand All @@ -96,13 +96,16 @@ struct BuiltinTypeDeclBuilder {
nullptr, false, InClassInitStyle::ICIS_NoInit);
Field->setAccess(Access);
Field->setImplicit(true);
for (Attr *A : Attrs)
Field->addAttr(A);
Record->addDecl(Field);
Fields[Name] = Field;
return *this;
}

BuiltinTypeDeclBuilder &
addHandleMember(AccessSpecifier Access = AccessSpecifier::AS_private) {
addHandleMember(ResourceClass RC, ResourceKind RK, bool IsROV,
AccessSpecifier Access = AccessSpecifier::AS_private) {
if (Record->isCompleteDefinition())
return *this;
QualType Ty = Record->getASTContext().VoidPtrTy;
Expand All @@ -112,17 +115,13 @@ struct BuiltinTypeDeclBuilder {
Ty = Record->getASTContext().getPointerType(
QualType(TTD->getTypeForDecl(), 0));
}
return addMemberVariable("h", Ty, Access);
}

BuiltinTypeDeclBuilder &annotateHLSLResource(ResourceClass RC,
ResourceKind RK, bool IsROV) {
if (Record->isCompleteDefinition())
return *this;
Record->addAttr(
HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC));
Record->addAttr(
HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK, IsROV));
// add handle member
llvm::SmallVector<Attr *, 2> Attrs;
Attr *ResourceClassAttr =
HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC);
Attr *ResourceAttr =
HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK, IsROV);
addMemberVariable("h", Ty, {ResourceClassAttr, ResourceAttr}, Access);
return *this;
}

Expand Down Expand Up @@ -489,9 +488,8 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
ResourceClass RC, ResourceKind RK,
bool IsROV) {
return BuiltinTypeDeclBuilder(Decl)
.addHandleMember()
.addDefaultHandleConstructor(S, RC)
.annotateHLSLResource(RC, RK, IsROV);
.addHandleMember(RC, RK, IsROV)
.addDefaultHandleConstructor(S, RC);
}

void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,13 @@ void Sema::addImplicitTypedef(StringRef Name, QualType T) {
}

void Sema::Initialize() {
// Create BuiltinVaListDecl *before* ExternalSemaSource::InitializeSema(this)
// because during initialization ASTReader can emit globals that require
// name mangling. And the name mangling uses BuiltinVaListDecl.
if (Context.getTargetInfo().hasBuiltinMSVaList())
(void)Context.getBuiltinMSVaListDecl();
(void)Context.getBuiltinVaListDecl();

if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
SC->InitializeSema(*this);

Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1862,7 +1862,7 @@ static bool CheckBuiltinTargetNotInUnsupported(
// Emit an error and return true if the current architecture is not in the list
// of supported architectures.
static bool
CheckBuiltinTargetInSupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall,
CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall,
ArrayRef<llvm::Triple::ArchType> SupportedArchs) {
llvm::Triple::ArchType CurArch =
S.getASTContext().getTargetInfo().getTriple().getArch();
Expand Down Expand Up @@ -2151,7 +2151,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
case Builtin::BI_interlockedbittestandreset_rel:
case Builtin::BI_interlockedbittestandreset_nf:
if (CheckBuiltinTargetInSupported(
*this, BuiltinID, TheCall,
*this, TheCall,
{llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
return ExprError();
break;
Expand All @@ -2164,15 +2164,15 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
case Builtin::BI_interlockedbittestandreset64:
case Builtin::BI_interlockedbittestandset64:
if (CheckBuiltinTargetInSupported(
*this, BuiltinID, TheCall,
*this, TheCall,
{llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
llvm::Triple::aarch64, llvm::Triple::amdgcn}))
return ExprError();
break;

case Builtin::BI__builtin_set_flt_rounds:
if (CheckBuiltinTargetInSupported(
*this, BuiltinID, TheCall,
*this, TheCall,
{llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn}))
return ExprError();
Expand Down
21 changes: 14 additions & 7 deletions clang/lib/Sema/SemaConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,8 @@ DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID,
E->Profile(ID, S.Context, /*Canonical=*/true);
for (const auto &List : MLTAL)
for (const auto &TemplateArg : List.Args)
TemplateArg.Profile(ID, S.Context);
S.Context.getCanonicalTemplateArgument(TemplateArg)
.Profile(ID, S.Context);

// Note that we have to do this with our own collection, because there are
// times where a constraint-expression check can cause us to need to evaluate
Expand Down Expand Up @@ -531,6 +532,10 @@ static ExprResult calculateConstraintSatisfaction(

std::optional<unsigned>
EvaluateFoldExpandedConstraintSize(const CXXFoldExpr *FE) const {

// We should ignore errors in the presence of packs of different size.
Sema::SFINAETrap Trap(S);

Expr *Pattern = FE->getPattern();

SmallVector<UnexpandedParameterPack, 2> Unexpanded;
Expand Down Expand Up @@ -638,8 +643,8 @@ bool Sema::CheckConstraintSatisfaction(
// here.
llvm::SmallVector<TemplateArgument, 4> FlattenedArgs;
for (auto List : TemplateArgsLists)
FlattenedArgs.insert(FlattenedArgs.end(), List.Args.begin(),
List.Args.end());
for (const TemplateArgument &Arg : List.Args)
FlattenedArgs.emplace_back(Context.getCanonicalTemplateArgument(Arg));

llvm::FoldingSetNodeID ID;
ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs);
Expand Down Expand Up @@ -823,6 +828,8 @@ Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
/*RelativeToPrimary=*/true,
/*Pattern=*/nullptr,
/*ForConstraintInstantiation=*/true);
if (TemplateArgs)
MLTAL.replaceInnermostTemplateArguments(FD, *TemplateArgs, /*Final=*/true);
if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
return std::nullopt;

Expand Down Expand Up @@ -1457,8 +1464,8 @@ substituteParameterMappings(Sema &S, NormalizedConstraint &N,
: ArgsAsWritten->arguments().front().getSourceRange().getEnd();
Sema::InstantiatingTemplate Inst(
S, InstLocBegin,
Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept,
{InstLocBegin, InstLocEnd});
Sema::InstantiatingTemplate::ParameterMappingSubstitution{},
Atomic.ConstraintDecl, {InstLocBegin, InstLocEnd});
if (Inst.isInvalid())
return true;
if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs))
Expand All @@ -1476,7 +1483,7 @@ static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N,
const ConceptSpecializationExpr *CSE) {
MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs(
CSE->getNamedConcept(), CSE->getNamedConcept()->getLexicalDeclContext(),
/*Final=*/false, CSE->getTemplateArguments(),
/*Final=*/true, CSE->getTemplateArguments(),
/*RelativeToPrimary=*/true,
/*Pattern=*/nullptr,
/*ForConstraintInstantiation=*/true);
Expand Down Expand Up @@ -1632,7 +1639,7 @@ NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
Kind, std::move(*Sub), FE->getPattern()}};
}

return NormalizedConstraint{new (S.Context) AtomicConstraint(S, E)};
return NormalizedConstraint{new (S.Context) AtomicConstraint(E, D)};
}

bool FoldExpandedConstraint::AreCompatibleForSubsumption(
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8756,7 +8756,8 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
return;
}

if (NewVD->isConstexpr() && !T->isDependentType() &&
if (getLangOpts().CPlusPlus && NewVD->isConstexpr() &&
!T->isDependentType() &&
RequireLiteralType(NewVD->getLocation(), T,
diag::err_constexpr_var_non_literal)) {
NewVD->setInvalidDecl();
Expand Down Expand Up @@ -12839,7 +12840,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
InitializationKind Kind = InitializationKind::CreateForInit(
VDecl->getLocation(), DirectInit, Init);
// FIXME: Initialization should not be taking a mutable list of inits.
SmallVector<Expr*, 8> InitsCopy(DeduceInits.begin(), DeduceInits.end());
SmallVector<Expr *, 8> InitsCopy(DeduceInits);
return DeduceTemplateSpecializationFromInitializer(TSI, Entity, Kind,
InitsCopy);
}
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaExceptionSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1431,6 +1431,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
case Stmt::ObjCAutoreleasePoolStmtClass:
case Stmt::ObjCForCollectionStmtClass:
case Stmt::OMPAtomicDirectiveClass:
case Stmt::OMPAssumeDirectiveClass:
case Stmt::OMPBarrierDirectiveClass:
case Stmt::OMPCancelDirectiveClass:
case Stmt::OMPCancellationPointDirectiveClass:
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17008,10 +17008,10 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
if (!isa<ConstantExpr>(E))
E = Result ? ConstantExpr::Create(Context, E, APValue(*Result))
: ConstantExpr::Create(Context, E);

if (Notes.empty())
return E;

// If our only note is the usual "invalid subexpression" note, just point
// the caret at its location rather than producing an essentially
// redundant note.
Expand All @@ -17020,7 +17020,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
DiagLoc = Notes[0].first;
Notes.clear();
}

if (getLangOpts().CPlusPlus) {
if (!Diagnoser.Suppress) {
Diagnoser.diagnoseNotICE(*this, DiagLoc) << E->getSourceRange();
Expand All @@ -17033,7 +17033,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
Diagnoser.diagnoseFold(*this, DiagLoc) << E->getSourceRange();
for (const PartialDiagnosticAt &Note : Notes)
Diag(Note.first, Note.second);

return E;
}

Expand Down
8 changes: 2 additions & 6 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4982,7 +4982,6 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
case UTT_IsArray:
case UTT_IsBoundedArray:
case UTT_IsPointer:
case UTT_IsNullPointer:
case UTT_IsReferenceable:
case UTT_IsLvalueReference:
case UTT_IsRvalueReference:
Expand Down Expand Up @@ -5241,8 +5240,6 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
return T->isIncompleteArrayType();
case UTT_IsPointer:
return T->isAnyPointerType();
case UTT_IsNullPointer:
return T->isNullPtrType();
case UTT_IsLvalueReference:
return T->isLValueReferenceType();
case UTT_IsRvalueReference:
Expand Down Expand Up @@ -9333,14 +9330,13 @@ Sema::BuildExprRequirement(
// be satisfied.
TemplateParameterList *TPL =
ReturnTypeRequirement.getTypeConstraintTemplateParameterList();
QualType MatchedType =
Context.getReferenceQualifiedType(E).getCanonicalType();
QualType MatchedType = Context.getReferenceQualifiedType(E);
llvm::SmallVector<TemplateArgument, 1> Args;
Args.push_back(TemplateArgument(MatchedType));

auto *Param = cast<TemplateTypeParmDecl>(TPL->getParam(0));

MultiLevelTemplateArgumentList MLTAL(Param, Args, /*Final=*/false);
MultiLevelTemplateArgumentList MLTAL(Param, Args, /*Final=*/true);
MLTAL.addOuterRetainedLevels(TPL->getDepth());
const TypeConstraint *TC = Param->getTypeConstraint();
assert(TC && "Type Constraint cannot be null here");
Expand Down
18 changes: 18 additions & 0 deletions clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,24 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
return true;
break;
}
case Builtin::BI__builtin_hlsl_length: {
if (CheckFloatOrHalfRepresentations(&SemaRef, TheCall))
return true;
if (SemaRef.checkArgCount(TheCall, 1))
return true;

ExprResult A = TheCall->getArg(0);
QualType ArgTyA = A.get()->getType();
QualType RetTy;

if (auto *VTy = ArgTyA->getAs<VectorType>())
RetTy = VTy->getElementType();
else
RetTy = TheCall->getArg(0)->getType();

TheCall->setType(RetTy);
break;
}
case Builtin::BI__builtin_hlsl_mad: {
if (SemaRef.checkArgCount(TheCall, 3))
return true;
Expand Down
295 changes: 288 additions & 7 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3563,6 +3563,17 @@ void SemaOpenMP::ActOnOpenMPEndAssumesDirective() {
OMPAssumeScoped.pop_back();
}

StmtResult SemaOpenMP::ActOnOpenMPAssumeDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt,
SourceLocation StartLoc,
SourceLocation EndLoc) {
if (!AStmt)
return StmtError();

return OMPAssumeDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses,
AStmt);
}

OMPRequiresDecl *
SemaOpenMP::CheckOMPRequiresDecl(SourceLocation Loc,
ArrayRef<OMPClause *> ClauseList) {
Expand Down Expand Up @@ -3728,6 +3739,7 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
S->getDirectiveKind() == OMPD_master ||
S->getDirectiveKind() == OMPD_masked ||
S->getDirectiveKind() == OMPD_scope ||
S->getDirectiveKind() == OMPD_assume ||
isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
Visit(S->getAssociatedStmt());
return;
Expand Down Expand Up @@ -4387,6 +4399,7 @@ void SemaOpenMP::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,
case OMPD_unroll:
case OMPD_reverse:
case OMPD_interchange:
case OMPD_assume:
break;
default:
processCapturedRegions(SemaRef, DKind, CurScope,
Expand Down Expand Up @@ -6058,11 +6071,8 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective(
VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();

SmallVector<Expr *, 4> ImplicitFirstprivates(
DSAChecker.getImplicitFirstprivate().begin(),
DSAChecker.getImplicitFirstprivate().end());
SmallVector<Expr *, 4> ImplicitPrivates(
DSAChecker.getImplicitPrivate().begin(),
DSAChecker.getImplicitPrivate().end());
DSAChecker.getImplicitFirstprivate());
SmallVector<Expr *, 4> ImplicitPrivates(DSAChecker.getImplicitPrivate());
const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1;
SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
Expand Down Expand Up @@ -6931,6 +6941,26 @@ SemaOpenMP::DeclGroupPtrTy SemaOpenMP::ActOnOpenMPDeclareSimdDirective(
return DG;
}

StmtResult SemaOpenMP::ActOnOpenMPInformationalDirective(
OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc) {
assert(isOpenMPInformationalDirective(Kind) &&
"Unexpected directive category");

StmtResult Res = StmtError();

switch (Kind) {
case OMPD_assume:
Res = ActOnOpenMPAssumeDirective(Clauses, AStmt, StartLoc, EndLoc);
break;
default:
llvm_unreachable("Unknown OpenMP directive");
}

return Res;
}

static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
QualType NewType) {
assert(NewType->isFunctionProtoType() &&
Expand Down Expand Up @@ -14964,6 +14994,9 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
case OMPC_ompx_dyn_cgroup_mem:
Res = ActOnOpenMPXDynCGroupMemClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
case OMPC_holds:
Res = ActOnOpenMPHoldsClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
case OMPC_grainsize:
case OMPC_num_tasks:
case OMPC_device:
Expand Down Expand Up @@ -20796,6 +20829,203 @@ struct MappableVarListInfo {
};
} // namespace

static DeclRefExpr *buildImplicitMap(Sema &S, QualType BaseType,
DSAStackTy *Stack,
SmallVectorImpl<OMPClause *> &Maps) {

const RecordDecl *RD = BaseType->getAsRecordDecl();
SourceRange Range = RD->getSourceRange();
DeclarationNameInfo ImplicitName;
// Dummy variable _s for Mapper.
VarDecl *VD = buildVarDecl(S, Range.getEnd(), BaseType, "_s");
DeclRefExpr *MapperVarRef =
buildDeclRefExpr(S, VD, BaseType, SourceLocation());

// Create implicit map clause for mapper.
SmallVector<Expr *, 4> SExprs;
for (auto *FD : RD->fields()) {
Expr *BE = S.BuildMemberExpr(
MapperVarRef, /*IsArrow=*/false, Range.getBegin(),
NestedNameSpecifierLoc(), Range.getBegin(), FD,
DeclAccessPair::make(FD, FD->getAccess()),
/*HadMultipleCandidates=*/false,
DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()),
FD->getType(), VK_LValue, OK_Ordinary);
SExprs.push_back(BE);
}
CXXScopeSpec MapperIdScopeSpec;
DeclarationNameInfo MapperId;
OpenMPDirectiveKind DKind = Stack->getCurrentDirective();

OMPClause *MapClause = S.OpenMP().ActOnOpenMPMapClause(
nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec,
MapperId, DKind == OMPD_target_enter_data ? OMPC_MAP_to : OMPC_MAP_tofrom,
/*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), SExprs,
OMPVarListLocTy());
Maps.push_back(MapClause);
return MapperVarRef;
}

static ExprResult buildImplicitMapper(Sema &S, QualType BaseType,
DSAStackTy *Stack) {

// Build impilicit map for mapper
SmallVector<OMPClause *, 4> Maps;
DeclRefExpr *MapperVarRef = buildImplicitMap(S, BaseType, Stack, Maps);

const RecordDecl *RD = BaseType->getAsRecordDecl();
// AST context is RD's ParentASTContext().
ASTContext &Ctx = RD->getParentASTContext();
// DeclContext is RD's DeclContext.
DeclContext *DCT = const_cast<DeclContext *>(RD->getDeclContext());

// Create implicit default mapper for "RD".
DeclarationName MapperId;
auto &DeclNames = Ctx.DeclarationNames;
MapperId = DeclNames.getIdentifier(&Ctx.Idents.get("default"));
auto *DMD = OMPDeclareMapperDecl::Create(Ctx, DCT, SourceLocation(), MapperId,
BaseType, MapperId, Maps, nullptr);
Scope *Scope = S.getScopeForContext(DCT);
if (Scope)
S.PushOnScopeChains(DMD, Scope, /*AddToContext*/ false);
DCT->addDecl(DMD);
DMD->setAccess(clang::AS_none);
auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
VD->setDeclContext(DMD);
VD->setLexicalDeclContext(DMD);
DMD->addDecl(VD);
DMD->setMapperVarRef(MapperVarRef);
FieldDecl *FD = *RD->field_begin();
// create mapper refence.
return DeclRefExpr::Create(Ctx, NestedNameSpecifierLoc{}, FD->getLocation(),
DMD, false, SourceLocation(), BaseType, VK_LValue);
}

// Look up the user-defined mapper given the mapper name and mapper type,
// return true if found one.
static bool hasUserDefinedMapper(Sema &SemaRef, Scope *S,
CXXScopeSpec &MapperIdScopeSpec,
const DeclarationNameInfo &MapperId,
QualType Type) {
// Find all user-defined mappers with the given MapperId.
SmallVector<UnresolvedSet<8>, 4> Lookups;
LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
Lookup.suppressDiagnostics();
while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec,
/*ObjectType=*/QualType())) {
NamedDecl *D = Lookup.getRepresentativeDecl();
while (S && !S->isDeclScope(D))
S = S->getParent();
if (S)
S = S->getParent();
Lookups.emplace_back();
Lookups.back().append(Lookup.begin(), Lookup.end());
Lookup.clear();
}
if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
Type->isInstantiationDependentType() ||
Type->containsUnexpandedParameterPack() ||
filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
return !D->isInvalidDecl() &&
(D->getType()->isDependentType() ||
D->getType()->isInstantiationDependentType() ||
D->getType()->containsUnexpandedParameterPack());
}))
return false;
// Perform argument dependent lookup.
SourceLocation Loc = MapperId.getLoc();
if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
if (filterLookupForUDReductionAndMapper<ValueDecl *>(
Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
if (!D->isInvalidDecl() &&
SemaRef.Context.hasSameType(D->getType(), Type))
return D;
return nullptr;
}))
return true;
// Find the first user-defined mapper with a type derived from the desired
// type.
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
if (!D->isInvalidDecl() &&
SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
!Type.isMoreQualifiedThan(D->getType()))
return D;
return nullptr;
});
if (!VD)
return false;
CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
bool IsAmbiguous = !Paths.isAmbiguous(
SemaRef.Context.getCanonicalType(VD->getType().getUnqualifiedType()));
if (IsAmbiguous)
return false;
if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Type, Paths.front(),
/*DiagID=*/0) != Sema::AR_inaccessible)
return true;
}
return false;
}

static bool isImplicitMapperNeeded(Sema &S, DSAStackTy *Stack,
QualType CanonType, const Expr *E) {

// DFS over data members in structures/classes.
SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(1,
{CanonType, nullptr});
llvm::DenseMap<const Type *, bool> Visited;
SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(1, {nullptr, 1});
while (!Types.empty()) {
auto [BaseType, CurFD] = Types.pop_back_val();
while (ParentChain.back().second == 0)
ParentChain.pop_back();
--ParentChain.back().second;
if (BaseType.isNull())
continue;
// Only structs/classes are allowed to have mappers.
const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
if (!RD)
continue;
auto It = Visited.find(BaseType.getTypePtr());
if (It == Visited.end()) {
// Try to find the associated user-defined mapper.
CXXScopeSpec MapperIdScopeSpec;
DeclarationNameInfo DefaultMapperId;
DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
&S.Context.Idents.get("default")));
DefaultMapperId.setLoc(E->getExprLoc());
bool HasUDMapper =
hasUserDefinedMapper(S, Stack->getCurScope(), MapperIdScopeSpec,
DefaultMapperId, BaseType);
It = Visited.try_emplace(BaseType.getTypePtr(), HasUDMapper).first;
}
// Found default mapper.
if (It->second)
return true;
// Check for the "default" mapper for data members.
bool FirstIter = true;
for (FieldDecl *FD : RD->fields()) {
if (!FD)
continue;
QualType FieldTy = FD->getType();
if (FieldTy.isNull() ||
!(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
continue;
if (FirstIter) {
FirstIter = false;
ParentChain.emplace_back(CurFD, 1);
} else {
++ParentChain.back().second;
}
Types.emplace_back(FieldTy, FD);
}
}
return false;
}

// Check the validity of the provided variable list for the provided clause kind
// \a CKind. In the check process the valid expressions, mappable expression
// components, variables, and user-defined mappers are extracted and used to
Expand Down Expand Up @@ -21095,6 +21325,24 @@ static void checkMappableExpressionList(
Type.getCanonicalType(), UnresolvedMapper);
if (ER.isInvalid())
continue;
if (!ER.get() && isa<ArraySectionExpr>(VE)) {
// Create implicit mapper as needed.
QualType BaseType = VE->getType().getCanonicalType();
if (BaseType->isSpecificBuiltinType(BuiltinType::ArraySection)) {
const auto *OASE = cast<ArraySectionExpr>(VE->IgnoreParenImpCasts());
QualType BType = ArraySectionExpr::getBaseOriginalType(OASE->getBase());
QualType ElemType;
if (const auto *ATy = BType->getAsArrayTypeUnsafe())
ElemType = ATy->getElementType();
else
ElemType = BType->getPointeeType();
BaseType = ElemType.getCanonicalType();
}
if (BaseType->getAsRecordDecl() &&
isImplicitMapperNeeded(SemaRef, DSAS, BaseType, VE)) {
ER = buildImplicitMapper(SemaRef, BaseType, DSAS);
}
}
MVLI.UDMapperList.push_back(ER.get());

// Save the current expression.
Expand Down Expand Up @@ -21522,8 +21770,7 @@ SemaOpenMP::DeclGroupPtrTy SemaOpenMP::ActOnOpenMPDeclareMapperDirective(
}
// Build expressions for implicit maps of data members with 'default'
// mappers.
SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
Clauses.end());
SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses);
if (getLangOpts().OpenMP >= 50)
processImplicitMapsWithDefaultMappers(SemaRef, DSAStack,
ClausesWithImplicit);
Expand Down Expand Up @@ -23126,6 +23373,40 @@ OMPClause *SemaOpenMP::ActOnOpenMPXBareClause(SourceLocation StartLoc,
return new (getASTContext()) OMPXBareClause(StartLoc, EndLoc);
}

OMPClause *SemaOpenMP::ActOnOpenMPHoldsClause(Expr *E, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
return new (getASTContext()) OMPHoldsClause(E, StartLoc, LParenLoc, EndLoc);
}

OMPClause *SemaOpenMP::ActOnOpenMPDirectivePresenceClause(
OpenMPClauseKind CK, llvm::ArrayRef<OpenMPDirectiveKind> DKVec,
SourceLocation Loc, SourceLocation LLoc, SourceLocation RLoc) {
switch (CK) {
case OMPC_absent:
return OMPAbsentClause::Create(getASTContext(), DKVec, Loc, LLoc, RLoc);
case OMPC_contains:
return OMPContainsClause::Create(getASTContext(), DKVec, Loc, LLoc, RLoc);
default:
llvm_unreachable("Unexpected OpenMP clause");
}
}

OMPClause *SemaOpenMP::ActOnOpenMPNullaryAssumptionClause(OpenMPClauseKind CK,
SourceLocation Loc,
SourceLocation RLoc) {
switch (CK) {
case OMPC_no_openmp:
return new (getASTContext()) OMPNoOpenMPClause(Loc, RLoc);
case OMPC_no_openmp_routines:
return new (getASTContext()) OMPNoOpenMPRoutinesClause(Loc, RLoc);
case OMPC_no_parallelism:
return new (getASTContext()) OMPNoParallelismClause(Loc, RLoc);
default:
llvm_unreachable("Unexpected OpenMP clause");
}
}

ExprResult SemaOpenMP::ActOnOMPArraySectionExpr(
Expr *Base, SourceLocation LBLoc, Expr *LowerBound,
SourceLocation ColonLocFirst, SourceLocation ColonLocSecond, Expr *Length,
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16125,7 +16125,7 @@ ExprResult Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
// Replace the resulting type information before rebuilding the generic
// selection expression.
ArrayRef<Expr *> A = GSE->getAssocExprs();
SmallVector<Expr *, 4> AssocExprs(A.begin(), A.end());
SmallVector<Expr *, 4> AssocExprs(A);
unsigned ResultIdx = GSE->getResultIndex();
AssocExprs[ResultIdx] = SubExpr.get();

Expand Down
18 changes: 9 additions & 9 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3334,8 +3334,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,

// Only substitute for the innermost template argument list.
MultiLevelTemplateArgumentList TemplateArgLists;
TemplateArgLists.addOuterTemplateArguments(Template, CanonicalConverted,
/*Final=*/false);
TemplateArgLists.addOuterTemplateArguments(Template, SugaredConverted,
/*Final=*/true);
TemplateArgLists.addOuterRetainedLevels(
AliasTemplate->getTemplateParameters()->getDepth());

Expand Down Expand Up @@ -4202,7 +4202,7 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
TemplateDeductionInfo Info(FailedCandidates.getLocation());

if (TemplateDeductionResult Result =
DeduceTemplateArguments(Partial, CanonicalConverted, Info);
DeduceTemplateArguments(Partial, SugaredConverted, Info);
Result != TemplateDeductionResult::Success) {
// Store the failed-deduction information for use in diagnostics, later.
// TODO: Actually use the failed-deduction info?
Expand All @@ -4213,7 +4213,7 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
} else {
Matched.push_back(PartialSpecMatchResult());
Matched.back().Partial = Partial;
Matched.back().Args = Info.takeCanonical();
Matched.back().Args = Info.takeSugared();
}
}

Expand Down Expand Up @@ -4358,13 +4358,13 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,

auto *CSD = ImplicitConceptSpecializationDecl::Create(
Context, NamedConcept->getDeclContext(), NamedConcept->getLocation(),
CanonicalConverted);
SugaredConverted);
ConstraintSatisfaction Satisfaction;
bool AreArgsDependent =
TemplateSpecializationType::anyDependentTemplateArguments(
*TemplateArgs, CanonicalConverted);
MultiLevelTemplateArgumentList MLTAL(NamedConcept, CanonicalConverted,
/*Final=*/false);
*TemplateArgs, SugaredConverted);
MultiLevelTemplateArgumentList MLTAL(NamedConcept, SugaredConverted,
/*Final=*/true);
LocalInstantiationScope Scope(*this);

EnterExpressionEvaluationContext EECtx{
Expand Down Expand Up @@ -5582,7 +5582,7 @@ bool Sema::CheckTemplateArgumentList(
CXXThisScopeRAII(*this, RD, ThisQuals, RD != nullptr);

MultiLevelTemplateArgumentList MLTAL = getTemplateInstantiationArgs(
Template, NewContext, /*Final=*/false, CanonicalConverted,
Template, NewContext, /*Final=*/true, SugaredConverted,
/*RelativeToPrimary=*/true,
/*Pattern=*/nullptr,
/*ForConceptInstantiation=*/true);
Expand Down
103 changes: 40 additions & 63 deletions clang/lib/Sema/SemaTemplateDeduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,6 @@ static TemplateDeductionResult DeduceNonTypeTemplateArgument(
const NonTypeTemplateParmDecl *NTTP, ValueDecl *D, QualType T,
TemplateDeductionInfo &Info,
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
D = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
TemplateArgument New(D, T);
return DeduceNonTypeTemplateArgument(
S, TemplateParams, NTTP, DeducedTemplateArgument(New), T, Info, Deduced);
Expand Down Expand Up @@ -1380,11 +1379,6 @@ static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex) {
return false;
}

static CXXRecordDecl *getCanonicalRD(QualType T) {
return cast<CXXRecordDecl>(
T->castAs<RecordType>()->getDecl()->getCanonicalDecl());
}

/// Attempt to deduce the template arguments by checking the base types
/// according to (C++20 [temp.deduct.call] p4b3.
///
Expand Down Expand Up @@ -1439,7 +1433,7 @@ DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD,
for (const auto &Base : RD->bases()) {
QualType T = Base.getType();
assert(T->isRecordType() && "Base class that isn't a record?");
if (Visited.insert(::getCanonicalRD(T)).second)
if (Visited.insert(T->getAsCXXRecordDecl()).second)
ToVisit.push_back(T);
}
};
Expand All @@ -1460,7 +1454,7 @@ DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD,

// If this was a successful deduction, add it to the list of matches,
// otherwise we need to continue searching its bases.
const CXXRecordDecl *RD = ::getCanonicalRD(NextT);
const CXXRecordDecl *RD = NextT->getAsCXXRecordDecl();
if (BaseResult == TemplateDeductionResult::Success)
Matches.insert({RD, DeducedCopy});
else
Expand All @@ -1481,7 +1475,7 @@ DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD,
// We can give up once we have a single item (or have run out of things to
// search) since cyclical inheritance isn't valid.
while (Matches.size() > 1 && !ToVisit.empty()) {
const CXXRecordDecl *RD = ::getCanonicalRD(ToVisit.pop_back_val());
const CXXRecordDecl *RD = ToVisit.pop_back_val()->getAsCXXRecordDecl();
Matches.erase(RD);

// Always add all bases, since the inheritance tree can contain
Expand Down Expand Up @@ -2030,15 +2024,16 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
if (!S.isCompleteType(Info.getLocation(), A))
return Result;

if (getCanonicalRD(A)->isInvalidDecl())
const CXXRecordDecl *RD = A->getAsCXXRecordDecl();
if (RD->isInvalidDecl())
return Result;

// Reset the incorrectly deduced argument from above.
Deduced = DeducedOrig;

// Check bases according to C++14 [temp.deduct.call] p4b3:
auto BaseResult = DeduceTemplateBases(S, getCanonicalRD(A),
TemplateParams, P, Info, Deduced);
auto BaseResult =
DeduceTemplateBases(S, RD, TemplateParams, P, Info, Deduced);
return BaseResult != TemplateDeductionResult::Invalid ? BaseResult
: Result;
}
Expand Down Expand Up @@ -3083,7 +3078,7 @@ CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template,
// If we don't need to replace the deduced template arguments,
// we can add them immediately as the inner-most argument list.
if (!DeducedArgsNeedReplacement(Template))
Innermost = CanonicalDeducedArgs;
Innermost = SugaredDeducedArgs;

MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs(
Template, Template->getDeclContext(), /*Final=*/false, Innermost,
Expand All @@ -3095,7 +3090,7 @@ CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template,
// not class-scope explicit specialization, so replace with Deduced Args
// instead of adding to inner-most.
if (!Innermost)
MLTAL.replaceInnermostTemplateArguments(Template, CanonicalDeducedArgs);
MLTAL.replaceInnermostTemplateArguments(Template, SugaredDeducedArgs);

if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints, MLTAL,
Info.getLocation(),
Expand Down Expand Up @@ -3369,9 +3364,7 @@ Sema::DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
// Use the InjectedClassNameType.
PType = Context.getTypeDeclType(CTD->getTemplatedDecl());
} else if (const auto *AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(TD)) {
PType = AliasTemplate->getTemplatedDecl()
->getUnderlyingType()
.getCanonicalType();
PType = AliasTemplate->getTemplatedDecl()->getUnderlyingType();
} else {
assert(false && "Expected a class or alias template");
}
Expand Down Expand Up @@ -3505,15 +3498,15 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
// the explicit template arguments. They'll be used as part of deduction
// for this template parameter pack.
unsigned PartiallySubstitutedPackIndex = -1u;
if (!CanonicalBuilder.empty()) {
const TemplateArgument &Arg = CanonicalBuilder.back();
if (!SugaredBuilder.empty()) {
const TemplateArgument &Arg = SugaredBuilder.back();
if (Arg.getKind() == TemplateArgument::Pack) {
auto *Param = TemplateParams->getParam(CanonicalBuilder.size() - 1);
auto *Param = TemplateParams->getParam(SugaredBuilder.size() - 1);
// If this is a fully-saturated fixed-size pack, it should be
// fully-substituted, not partially-substituted.
std::optional<unsigned> Expansions = getExpandedPackSize(Param);
if (!Expansions || Arg.pack_size() < *Expansions) {
PartiallySubstitutedPackIndex = CanonicalBuilder.size() - 1;
PartiallySubstitutedPackIndex = SugaredBuilder.size() - 1;
CurrentInstantiationScope->SetPartiallySubstitutedPack(
Param, Arg.pack_begin(), Arg.pack_size());
}
Expand Down Expand Up @@ -3890,8 +3883,8 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
if (!Specialization || Specialization->isInvalidDecl())
return TemplateDeductionResult::SubstitutionFailure;

assert(Specialization->getPrimaryTemplate()->getCanonicalDecl() ==
FunctionTemplate->getCanonicalDecl());
assert(isSameDeclaration(Specialization->getPrimaryTemplate(),
FunctionTemplate));

// If the template argument list is owned by the function template
// specialization, release it.
Expand Down Expand Up @@ -3920,13 +3913,13 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
(CanonicalBuilder.size() ==
FunctionTemplate->getTemplateParameters()->size())) {
if (CheckInstantiatedFunctionTemplateConstraints(
Info.getLocation(), Specialization, CanonicalBuilder,
Info.getLocation(), Specialization, SugaredBuilder,
Info.AssociatedConstraintsSatisfaction))
return TemplateDeductionResult::MiscellaneousDeductionFailure;

if (!Info.AssociatedConstraintsSatisfaction.IsSatisfied) {
Info.reset(Info.takeSugared(),
TemplateArgumentList::CreateCopy(Context, CanonicalBuilder));
Info.reset(TemplateArgumentList::CreateCopy(Context, SugaredBuilder),
Info.takeCanonical());
return TemplateDeductionResult::ConstraintsNotSatisfied;
}
}
Expand Down Expand Up @@ -4736,8 +4729,7 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
// types, template argument deduction fails.
if (!ArgFunctionType.isNull()) {
if (IsAddressOfFunction ? !isSameOrCompatibleFunctionType(
Context.getCanonicalType(SpecializationType),
Context.getCanonicalType(ArgFunctionType))
SpecializationType, ArgFunctionType)
: !Context.hasSameFunctionTypeIgnoringExceptionSpec(
SpecializationType, ArgFunctionType)) {
Info.FirstArg = TemplateArgument(SpecializationType);
Expand All @@ -4751,19 +4743,17 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(

TemplateDeductionResult Sema::DeduceTemplateArguments(
FunctionTemplateDecl *ConversionTemplate, QualType ObjectType,
Expr::Classification ObjectClassification, QualType ToType,
Expr::Classification ObjectClassification, QualType A,
CXXConversionDecl *&Specialization, TemplateDeductionInfo &Info) {
if (ConversionTemplate->isInvalidDecl())
return TemplateDeductionResult::Invalid;

CXXConversionDecl *ConversionGeneric
= cast<CXXConversionDecl>(ConversionTemplate->getTemplatedDecl());

QualType FromType = ConversionGeneric->getConversionType();

// Canonicalize the types for deduction.
QualType P = Context.getCanonicalType(FromType);
QualType A = Context.getCanonicalType(ToType);
QualType P = ConversionGeneric->getConversionType();
bool IsReferenceP = P->isReferenceType();
bool IsReferenceA = A->isReferenceType();

// C++0x [temp.deduct.conv]p2:
// If P is a reference type, the type referred to by P is used for
Expand All @@ -4779,7 +4769,7 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
// We work around a defect in the standard here: cv-qualifiers are also
// removed from P and A in this case, unless P was a reference type. This
// seems to mostly match what other compilers are doing.
if (!FromType->getAs<ReferenceType>()) {
if (!IsReferenceP) {
A = A.getUnqualifiedType();
P = P.getUnqualifiedType();
}
Expand Down Expand Up @@ -4835,7 +4825,7 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
// - If the original A is a reference type, A can be more
// cv-qualified than the deduced A (i.e., the type referred to
// by the reference)
if (ToType->isReferenceType())
if (IsReferenceA)
TDF |= TDF_ArgWithReferenceType;
// - The deduced A can be another pointer or pointer to member
// type that can be converted to A via a qualification
Expand Down Expand Up @@ -5003,8 +4993,8 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
/*PartialTemplateArgs=*/false,
SugaredConverted, CanonicalConverted))
return true;
MultiLevelTemplateArgumentList MLTAL(Concept, CanonicalConverted,
/*Final=*/false);
MultiLevelTemplateArgumentList MLTAL(Concept, SugaredConverted,
/*Final=*/true);
// Build up an EvaluationContext with an ImplicitConceptSpecializationDecl so
// that the template arguments of the constraint can be preserved. For
// example:
Expand All @@ -5018,7 +5008,7 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
S, Sema::ExpressionEvaluationContext::Unevaluated,
ImplicitConceptSpecializationDecl::Create(
S.getASTContext(), Concept->getDeclContext(), Concept->getLocation(),
CanonicalConverted));
SugaredConverted));
if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()},
MLTAL, TypeLoc.getLocalSourceRange(),
Satisfaction))
Expand Down Expand Up @@ -5736,17 +5726,6 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
return AtLeastAsConstrained1 ? FT1 : FT2;
}

/// Determine if the two templates are equivalent.
static bool isSameTemplate(TemplateDecl *T1, TemplateDecl *T2) {
if (T1 == T2)
return true;

if (!T1 || !T2)
return false;

return T1->getCanonicalDecl() == T2->getCanonicalDecl();
}

UnresolvedSetIterator Sema::getMostSpecialized(
UnresolvedSetIterator SpecBegin, UnresolvedSetIterator SpecEnd,
TemplateSpecCandidateSet &FailedCandidates,
Expand Down Expand Up @@ -5774,9 +5753,9 @@ UnresolvedSetIterator Sema::getMostSpecialized(
FunctionTemplateDecl *Challenger
= cast<FunctionDecl>(*I)->getPrimaryTemplate();
assert(Challenger && "Not a function template specialization?");
if (isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger, Loc,
TPOC_Other, 0),
Challenger)) {
if (declaresSameEntity(getMoreSpecializedTemplate(BestTemplate, Challenger,
Loc, TPOC_Other, 0),
Challenger)) {
Best = I;
BestTemplate = Challenger;
}
Expand All @@ -5789,9 +5768,9 @@ UnresolvedSetIterator Sema::getMostSpecialized(
FunctionTemplateDecl *Challenger
= cast<FunctionDecl>(*I)->getPrimaryTemplate();
if (I != Best &&
!isSameTemplate(getMoreSpecializedTemplate(BestTemplate, Challenger,
Loc, TPOC_Other, 0),
BestTemplate)) {
!declaresSameEntity(getMoreSpecializedTemplate(BestTemplate, Challenger,
Loc, TPOC_Other, 0),
BestTemplate)) {
Ambiguous = true;
break;
}
Expand Down Expand Up @@ -6116,11 +6095,10 @@ Sema::getMoreSpecializedPartialSpecialization(
"the partial specializations being compared should specialize"
" the same template.");
TemplateName Name(PS1->getSpecializedTemplate());
TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name);
QualType PT1 = Context.getTemplateSpecializationType(
CanonTemplate, PS1->getTemplateArgs().asArray());
Name, PS1->getTemplateArgs().asArray());
QualType PT2 = Context.getTemplateSpecializationType(
CanonTemplate, PS2->getTemplateArgs().asArray());
Name, PS2->getTemplateArgs().asArray());

TemplateDeductionInfo Info(Loc);
return getMoreSpecialized(*this, PT1, PT2, PS1, PS2, Info);
Expand All @@ -6129,12 +6107,11 @@ Sema::getMoreSpecializedPartialSpecialization(
bool Sema::isMoreSpecializedThanPrimary(
VarTemplatePartialSpecializationDecl *Spec, TemplateDeductionInfo &Info) {
VarTemplateDecl *Primary = Spec->getSpecializedTemplate();
TemplateName CanonTemplate =
Context.getCanonicalTemplateName(TemplateName(Primary));
TemplateName Name(Primary);
QualType PrimaryT = Context.getTemplateSpecializationType(
CanonTemplate, Primary->getInjectedTemplateArgs());
Name, Primary->getInjectedTemplateArgs());
QualType PartialT = Context.getTemplateSpecializationType(
CanonTemplate, Spec->getTemplateArgs().asArray());
Name, Spec->getTemplateArgs().asArray());

VarTemplatePartialSpecializationDecl *MaybeSpec =
getMoreSpecialized(*this, PartialT, PrimaryT, Spec, Primary, Info);
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaTemplateInstantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1447,7 +1447,8 @@ namespace {
}

void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> NewDecls) {
if (Old->isParameterPack()) {
if (Old->isParameterPack() &&
(NewDecls.size() != 1 || !NewDecls.front()->isParameterPack())) {
SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Old);
for (auto *New : NewDecls)
SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(
Expand Down
Loading