212 lines · python
1# ===----------------------------------------------------------------------===##2#3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4# See https://llvm.org/LICENSE.txt for license information.5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6#7# ===----------------------------------------------------------------------===##8 9# Test that headers are not tripped up by the surrounding code defining various10# alphabetic macros. Also ensure that we don't swallow the definition of user11# provided macros (in other words, ensure that we push/pop correctly everywhere).12 13# This test fails with MSVC headers, with Clang 20 (and early 21 versions);14# the headers end up pulling in Clang intrinsics headers, which in 20.x and15# early 21.x versions use unreserved identifiers,16# see https://github.com/llvm/llvm-project/issues/161808.17#18# UNSUPPORTED: clang-20 && msvc19 20# RUN: %{python} %s %{libcxx-dir}/utils21# END.22 23import sys24 25sys.path.append(sys.argv[1])26from libcxx.header_information import (27 lit_header_restrictions,28 lit_header_undeprecations,29 public_headers,30)31 32for header in public_headers:33 print(34 f"""\35//--- {header}.compile.pass.cpp36{lit_header_restrictions.get(header, '')}37{lit_header_undeprecations.get(header, '')}38 39// This is required to detect the platform we're building for below.40#include <__config>41 42#define SYSTEM_RESERVED_NAME This name should not be used in libc++43 44// libc++ does not use single-letter names as a matter of principle.45// But Windows' own <wchar.h>, <math.h>, and <exception> use many of these46// (at least C,E,F,I,M,N,P,S,X,Y,Z) as uglified function parameter names,47// so don't define these on Windows.48//49#ifndef _WIN3250#define _A SYSTEM_RESERVED_NAME51#define _B SYSTEM_RESERVED_NAME52#define _C SYSTEM_RESERVED_NAME53#define _D SYSTEM_RESERVED_NAME54#define _E SYSTEM_RESERVED_NAME55#define _F SYSTEM_RESERVED_NAME56#define _G SYSTEM_RESERVED_NAME57#define _H SYSTEM_RESERVED_NAME58#define _I SYSTEM_RESERVED_NAME59#define _J SYSTEM_RESERVED_NAME60#define _K SYSTEM_RESERVED_NAME61#define _L SYSTEM_RESERVED_NAME62#define _M SYSTEM_RESERVED_NAME63#define _N SYSTEM_RESERVED_NAME64#define _O SYSTEM_RESERVED_NAME65#define _P SYSTEM_RESERVED_NAME66#define _Q SYSTEM_RESERVED_NAME67#define _R SYSTEM_RESERVED_NAME68#define _S SYSTEM_RESERVED_NAME69#define _T SYSTEM_RESERVED_NAME70#define _U SYSTEM_RESERVED_NAME71#define _V SYSTEM_RESERVED_NAME72#define _W SYSTEM_RESERVED_NAME73#define _X SYSTEM_RESERVED_NAME74#define _Y SYSTEM_RESERVED_NAME75#define _Z SYSTEM_RESERVED_NAME76#endif77 78// FreeBSD's <sys/types.h> uses _M79//80#ifdef __FreeBSD__81# undef _M82#endif83 84// Test that libc++ doesn't use names that collide with FreeBSD system macros.85// newlib and picolibc also define these macros86#if !defined(__FreeBSD__) && !_LIBCPP_LIBC_NEWLIB87# define __null_sentinel SYSTEM_RESERVED_NAME88# define __generic SYSTEM_RESERVED_NAME89#endif90 91// tchar.h defines these macros on Windows92#ifndef _WIN3293# define _UI SYSTEM_RESERVED_NAME94# define _PUC SYSTEM_RESERVED_NAME95# define _CPUC SYSTEM_RESERVED_NAME96# define _PC SYSTEM_RESERVED_NAME97# define _CRPC SYSTEM_RESERVED_NAME98# define _CPC SYSTEM_RESERVED_NAME99#endif100 101// yvals.h on MINGW defines this macro102#ifndef _WIN32103# define _C2 SYSTEM_RESERVED_NAME104#endif105 106// Test that libc++ doesn't use names that collide with Win32 API macros.107// Obviously we can only define these on non-Windows platforms.108#ifndef _WIN32109# define __allocator SYSTEM_RESERVED_NAME110# define __bound SYSTEM_RESERVED_NAME111# define __deallocate SYSTEM_RESERVED_NAME112# define __deref SYSTEM_RESERVED_NAME113# define __format_string SYSTEM_RESERVED_NAME114# define __full SYSTEM_RESERVED_NAME115# define __in SYSTEM_RESERVED_NAME116# define __inout SYSTEM_RESERVED_NAME117# define __nz SYSTEM_RESERVED_NAME118# define __out SYSTEM_RESERVED_NAME119# define __part SYSTEM_RESERVED_NAME120# define __post SYSTEM_RESERVED_NAME121# define __pre SYSTEM_RESERVED_NAME122#endif123 124// Newlib & picolibc use __input as a parameter name of a64l & l64a125#if !_LIBCPP_LIBC_NEWLIB126# define __input SYSTEM_RESERVED_NAME127#endif128#define __output SYSTEM_RESERVED_NAME129 130#define __acquire SYSTEM_RESERVED_NAME131#define __release SYSTEM_RESERVED_NAME132 133// Android and FreeBSD use this for __attribute__((__unused__))134#if !defined(__FreeBSD__) && !defined(__ANDROID__)135#define __unused SYSTEM_RESERVED_NAME136#endif137 138// These names are not reserved, so the user can macro-define them.139// These are intended to find improperly _Uglified template parameters.140#define A SYSTEM_RESERVED_NAME141#define Arg SYSTEM_RESERVED_NAME142#define Args SYSTEM_RESERVED_NAME143#define As SYSTEM_RESERVED_NAME144#define B SYSTEM_RESERVED_NAME145#define Bs SYSTEM_RESERVED_NAME146#define C SYSTEM_RESERVED_NAME147#define Cp SYSTEM_RESERVED_NAME148#define Cs SYSTEM_RESERVED_NAME149// Windows setjmp.h contains a struct member named 'D' on ARM/AArch64.150#ifndef _WIN32151# define D SYSTEM_RESERVED_NAME152#endif153#define Dp SYSTEM_RESERVED_NAME154#define Ds SYSTEM_RESERVED_NAME155#define E SYSTEM_RESERVED_NAME156#define Ep SYSTEM_RESERVED_NAME157#define Es SYSTEM_RESERVED_NAME158#define N SYSTEM_RESERVED_NAME159#define Np SYSTEM_RESERVED_NAME160#define Ns SYSTEM_RESERVED_NAME161#define R SYSTEM_RESERVED_NAME162#define Rp SYSTEM_RESERVED_NAME163#define Rs SYSTEM_RESERVED_NAME164#define T SYSTEM_RESERVED_NAME165#define Tp SYSTEM_RESERVED_NAME166#define Ts SYSTEM_RESERVED_NAME167#define Type SYSTEM_RESERVED_NAME168#define Types SYSTEM_RESERVED_NAME169#define U SYSTEM_RESERVED_NAME170#define Up SYSTEM_RESERVED_NAME171#define Us SYSTEM_RESERVED_NAME172#define V SYSTEM_RESERVED_NAME173#define Vp SYSTEM_RESERVED_NAME174#define Vs SYSTEM_RESERVED_NAME175#define X SYSTEM_RESERVED_NAME176#define Xp SYSTEM_RESERVED_NAME177#define Xs SYSTEM_RESERVED_NAME178 179// The classic Windows min/max macros180#define min SYSTEM_RESERVED_NAME181#define max SYSTEM_RESERVED_NAME182 183// Test to make sure curses has no conflicting macros with the standard library184#define move SYSTEM_RESERVED_NAME185#define erase SYSTEM_RESERVED_NAME186#define refresh SYSTEM_RESERVED_NAME187 188// Dinkumware libc ctype.h uses these definitions189#define _XA SYSTEM_RESERVED_NAME190#define _XS SYSTEM_RESERVED_NAME191#define _BB SYSTEM_RESERVED_NAME192#define _CN SYSTEM_RESERVED_NAME193#define _DI SYSTEM_RESERVED_NAME194#define _LO SYSTEM_RESERVED_NAME195#define _PU SYSTEM_RESERVED_NAME196#define _SP SYSTEM_RESERVED_NAME197#define _UP SYSTEM_RESERVED_NAME198#define _XD SYSTEM_RESERVED_NAME199 200#include <{header}>201 202// Make sure we don't swallow the definition of the macros we push/pop203#define STRINGIFY_IMPL(x) #x204#define STRINGIFY(x) STRINGIFY_IMPL(x)205static_assert(__builtin_strcmp(STRINGIFY(min), STRINGIFY(SYSTEM_RESERVED_NAME)) == 0, "");206static_assert(__builtin_strcmp(STRINGIFY(max), STRINGIFY(SYSTEM_RESERVED_NAME)) == 0, "");207static_assert(__builtin_strcmp(STRINGIFY(move), STRINGIFY(SYSTEM_RESERVED_NAME)) == 0, "");208static_assert(__builtin_strcmp(STRINGIFY(erase), STRINGIFY(SYSTEM_RESERVED_NAME)) == 0, "");209static_assert(__builtin_strcmp(STRINGIFY(refresh), STRINGIFY(SYSTEM_RESERVED_NAME)) == 0, "");210"""211 )212