Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ LANGOPT(C2y , 1, 0, "C2y")
LANGOPT(MSVCCompat , 1, 0, "Microsoft Visual C++ full compatibility mode")
LANGOPT(Kernel , 1, 0, "Kernel mode")
LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions")
LANGOPT(ZOSExt , 1, 0, "z/OS extensions")
LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks")
LANGOPT(Borland , 1, 0, "Borland extensions")
LANGOPT(CPlusPlus , 1, 0, "C++")
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ PUNCTUATOR(caretcaret, "^^")
// CHAR8SUPPORT - This is a keyword if 'char8_t' is a built-in type
// KEYFIXEDPOINT - This is a keyword according to the N1169 fixed point
// extension.
// KEYZOS - This is a keyword in C/C++ on z/OS
//
KEYWORD(auto , KEYALL)
KEYWORD(break , KEYALL)
Expand Down Expand Up @@ -725,7 +726,7 @@ KEYWORD(__funcref , KEYALL)

// Microsoft extensions which should be disabled in strict conformance mode
KEYWORD(__ptr64 , KEYMS)
KEYWORD(__ptr32 , KEYMS)
KEYWORD(__ptr32 , KEYMS | KEYZOS)
KEYWORD(__sptr , KEYMS)
KEYWORD(__uptr , KEYMS)
KEYWORD(__w64 , KEYMS)
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -3066,6 +3066,10 @@ dll version.}]>;
def fms_omit_default_lib : Joined<["-"], "fms-omit-default-lib">,
Group<f_Group>, Flags<[]>,
Visibility<[ClangOption, CLOption]>;
def fzos_extensions : Flag<["-"], "fzos-extensions">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Accept some non-standard constructs supported by the z/OS compiler">;
def fno_zos_extensions : Flag<["-"], "fno-zos-extensions">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Do not accept non-standard constructs supported by the z/OS compiler">;
defm delayed_template_parsing : BoolFOption<"delayed-template-parsing",
LangOpts<"DelayedTemplateParsing">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2727,6 +2727,8 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
// <type> ::= U <OpenCL-addrspace>
// <type> ::= U <CUDA-addrspace>

llvm::Triple Triple = getASTContext().getTargetInfo().getTriple();

SmallString<64> ASString;
LangAS AS = Quals.getAddressSpace();

Expand Down Expand Up @@ -2795,7 +2797,11 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
ASString = "ptr32_sptr";
break;
case LangAS::ptr32_uptr:
ASString = "ptr32_uptr";
// For z/OS, there are no special mangling rules applied to the ptr32
// qualifier. Ex: void foo(int * __ptr32 p) -> _Z3f2Pi. The mangling for
// "p" is treated the same as a regular integer pointer.
if (!Triple.isOSzOS())
ASString = "ptr32_uptr";
break;
case LangAS::ptr64:
ASString = "ptr64";
Expand Down
18 changes: 11 additions & 7 deletions clang/lib/Basic/IdentifierTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,14 @@ enum TokenKey : unsigned {
KEYMSCOMPAT = 0x400000,
KEYSYCL = 0x800000,
KEYCUDA = 0x1000000,
KEYHLSL = 0x2000000,
KEYFIXEDPOINT = 0x4000000,
KEYZOS = 0x2000000,
KEYNOZOS = 0x4000000,
KEYHLSL = 0x8000000,
KEYFIXEDPOINT = 0x10000000,
KEYMAX = KEYFIXEDPOINT, // The maximum key
KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX20,
KEYALL = (KEYMAX | (KEYMAX - 1)) & ~KEYNOMS18 &
~KEYNOOPENCL // KEYNOMS18 and KEYNOOPENCL are used to exclude.
KEYALL = (KEYMAX | (KEYMAX - 1)) & ~KEYNOMS18 & ~KEYNOOPENCL &
~KEYNOZOS // KEYNOMS18, KEYNOOPENCL, KEYNOZOS are excluded.
};

/// How a keyword is treated in the selected standard. This enum is ordered
Expand Down Expand Up @@ -199,16 +201,17 @@ static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts,
return LangOpts.isSYCL() ? KS_Enabled : KS_Unknown;
case KEYCUDA:
return LangOpts.CUDA ? KS_Enabled : KS_Unknown;
case KEYZOS:
return LangOpts.ZOSExt ? KS_Enabled : KS_Unknown;
case KEYHLSL:
return LangOpts.HLSL ? KS_Enabled : KS_Unknown;
case KEYNOCXX:
// This is enabled in all non-C++ modes, but might be enabled for other
// reasons as well.
return LangOpts.CPlusPlus ? KS_Unknown : KS_Enabled;
case KEYNOOPENCL:
// The disable behavior for this is handled in getKeywordStatus.
return KS_Unknown;
case KEYNOMS18:
case KEYNOZOS:
// The disable behavior for this is handled in getKeywordStatus.
return KS_Unknown;
case KEYFIXEDPOINT:
Expand All @@ -230,7 +233,8 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts,
if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
!LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015))
return KS_Disabled;

if (LangOpts.ZOSExt && (Flags & KEYNOZOS))
return KS_Disabled;
KeywordStatus CurStatus = KS_Unknown;

while (Flags != 0) {
Expand Down
40 changes: 39 additions & 1 deletion clang/lib/Basic/Targets/SystemZ.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,30 @@
namespace clang {
namespace targets {

static const unsigned ZOSAddressMap[] = {
0, // Default
0, // opencl_global
0, // opencl_local
0, // opencl_constant
0, // opencl_private
0, // opencl_generic
0, // opencl_global_device
0, // opencl_global_host
0, // cuda_device
0, // cuda_constant
0, // cuda_shared
0, // sycl_global
0, // sycl_global_device
0, // sycl_global_host
0, // sycl_local
0, // sycl_private
0, // ptr32_sptr
1, // ptr32_uptr
0, // ptr64
0, // hlsl_groupshared
0 // wasm_funcref
};

class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {

static const char *const GCCRegNames[];
Expand All @@ -30,6 +54,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
bool HasVector;
bool SoftFloat;
bool UnalignedSymbols;
enum AddrSpace { ptr32 = 1 };

public:
SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
Expand All @@ -49,14 +74,17 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
MinGlobalAlign = 16;
HasUnalignedAccess = true;
if (Triple.isOSzOS()) {
if (Triple.isArch64Bit()) {
AddrSpaceMap = &ZOSAddressMap;
}
TLSSupported = false;
// All vector types are default aligned on an 8-byte boundary, even if the
// vector facility is not available. That is different from Linux.
MaxVectorAlign = 64;
// Compared to Linux/ELF, the data layout differs only in some details:
// - name mangling is GOFF.
// - 32 bit pointers, either as default or special address space
resetDataLayout("E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-"
resetDataLayout("E-m:l-p1:32:32-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-"
"a:8:16-n32:64");
} else {
TLSSupported = true;
Expand Down Expand Up @@ -224,6 +252,16 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(256, 256);
}
uint64_t getPointerWidthV(LangAS AddrSpace) const override {
return (getTriple().isOSzOS() && getTriple().isArch64Bit() &&
getTargetAddressSpace(AddrSpace) == ptr32)
? 32
: PointerWidth;
}

uint64_t getPointerAlignV(LangAS AddrSpace) const override {
return getPointerWidthV(AddrSpace);
}
};
} // namespace targets
} // namespace clang
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7514,6 +7514,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
(C.isForDiagnostics() && !HaveModules))
CmdArgs.push_back("-frewrite-includes");

if (Args.hasFlag(options::OPT_fzos_extensions,
options::OPT_fno_zos_extensions, false))
CmdArgs.push_back("-fzos-extensions");
else if (Args.hasArg(options::OPT_fno_zos_extensions))
CmdArgs.push_back("-fno-zos-extensions");

// Only allow -traditional or -traditional-cpp outside in preprocessing modes.
if (Arg *A = Args.getLastArg(options::OPT_traditional,
options::OPT_traditional_cpp)) {
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3650,6 +3650,11 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
GenerateArg(Consumer, OPT_ftrigraphs);
}

if (T.isOSzOS() && !Opts.ZOSExt)
GenerateArg(Consumer, OPT_fno_zos_extensions);
else if (Opts.ZOSExt)
GenerateArg(Consumer, OPT_fzos_extensions);

if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))
GenerateArg(Consumer, OPT_fblocks);

Expand Down Expand Up @@ -4051,6 +4056,9 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.Trigraphs =
Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);

Opts.ZOSExt =
Args.hasFlag(OPT_fzos_extensions, OPT_fno_zos_extensions, T.isOSzOS());

Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
&& Opts.OpenCLVersion == 200);

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7057,6 +7057,7 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,

// Add address space to type based on its attributes.
LangAS ASIdx = LangAS::Default;
llvm::Triple Triple = S.Context.getTargetInfo().getTriple();
uint64_t PtrWidth =
S.Context.getTargetInfo().getPointerWidth(LangAS::Default);
if (PtrWidth == 32) {
Expand All @@ -7065,7 +7066,7 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
else if (Attrs[attr::UPtr])
ASIdx = LangAS::ptr32_uptr;
} else if (PtrWidth == 64 && Attrs[attr::Ptr32]) {
if (Attrs[attr::UPtr])
if (Triple.isOSzOS() || Attrs[attr::UPtr])
ASIdx = LangAS::ptr32_uptr;
else
ASIdx = LangAS::ptr32_sptr;
Expand Down
53 changes: 53 additions & 0 deletions clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-definitions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// RUN: %clang_cc1 -triple s390x-ibm-zos -emit-llvm < %s | FileCheck %s --check-prefix=PTR32-ZOS
// RUN: %clang_cc1 -triple s390x-ibm-linux -fzos-extensions -emit-llvm < %s | FileCheck %s --check-prefix=PTR32-LINUX
// RUN: %clang_cc1 -triple s390x-linux-gnu -fzos-extensions -emit-llvm < %s | FileCheck %s --check-prefix=PTR32-LINUX

void ptr32_declarations() {
// PTR32-ZOS-LABEL: @ptr32_declarations()
// PTR32-LINUX-LABEL: @ptr32_declarations()

// PTR32-ZOS: %p1 = alloca ptr addrspace(1), align 4
// PTR32-LINUX-NOT: %p1 = alloca i8 addrspace(1)*, align 4
// PTR32-LINUX: %p1 = alloca ptr, align 8
char * __ptr32 p1;

// PTR32-ZOS: %p2 = alloca ptr, align 8
// PTR32-LINUX-NOT: %p2 = alloca ptr addrspace(1), align 8
// PTR32-LINUX: %p2 = alloca ptr, align 8
char * __ptr32 *p2;

// PTR32-ZOS: %p3 = alloca ptr addrspace(1), align 4
// PTR32-LINUX-NOT: %p3 = alloca i8* addrspace(1)*, align 4
// PTR32-LINUX: %p3 = alloca ptr, align 8
char ** __ptr32 p3;

// PTR32-ZOS: %p4 = alloca ptr, align 8
// PTR32-LINUX-NOT: %p4 = alloca ptr addrspace(1), align 8
// PTR32-LINUX: %p4 = alloca ptr, align 8
char ** __ptr32 *p4;

// PTR32-ZOS: %p5 = alloca ptr, align 8
// PTR32-LINUX-NOT: %p5 = alloca ptr addrspace(1), align 8
// PTR32-LINUX: %p5 = alloca ptr, align 8
char *** __ptr32 *p5;

// PTR32-ZOS: %p6 = alloca ptr, align 8
// PTR32-LINUX: %p6 = alloca ptr, align 8
char **p6;

// PTR32-ZOS: %p7 = alloca ptr addrspace(1), align 4
// PTR32-LINUX-NOT: %p7 = alloca i8 addrspace(1)* addrspace(1)*, align 4
// PTR32-LINUX: %p7 = alloca ptr, align 8
char * __ptr32 * __ptr32 p7;

// PTR32-ZOS: %p8 = alloca ptr addrspace(1), align 4
// PTR32-LINUX-NOT: %p8 = alloca i8* addrspace(1)* addrspace(1)*, align 4
// PTR32-LINUX: %p8 = alloca ptr, align 8
char ** __ptr32 * __ptr32 p8;

// PTR32-ZOS: %p9 = alloca ptr, align 8
// PTR32-LINUX-NOT: %p9 = alloca i8* addrspace(1)* addrspace(1)**, align 8
// PTR32-LINUX: %p9 = alloca ptr, align 8
char ** __ptr32 * __ptr32 *p9;

}
84 changes: 84 additions & 0 deletions clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-malloc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// RUN: %clang -target s390x-ibm-zos -emit-llvm -S -O2 %s -o - | FileCheck %s --check-prefix=X64
#include <stddef.h>
void *__malloc31(size_t);

int test_1() {
// X64-LABEL: define {{.*}} i32 @test_1()
// X64: ret i32 135
int *__ptr32 a;
int *b;
int i;
int sum1, sum2, sum3;

a = (int *__ptr32)__malloc31(sizeof(int) * 10);

b = a;
sum1 = 0;
for (i = 0; i < 10; ++i) {
a[i] = i;
sum1 += i;
}

sum2 = 0;
for (i = 0; i < 10; ++i) {
sum2 += a[i];
}
sum3 = 0;
for (i = 0; i < 10; ++i) {
sum3 += b[i];
}

return (sum1 + sum2 + sum3);
}

int test_2() {
// X64-LABEL: define {{.*}} i32 @test_2()
// X64: ret i32 4
int *a = (int *)__malloc31(sizeof(int));
int *__ptr32 b;

*a = 99;
b = a;
*b = 44;

// Test should return 4
return (*b - 40);
}

int test_3() {
// X64-LABEL: define {{.*}} i32 @test_3()
// X64: ret i32 4
int *a = (int *)__malloc31(sizeof(int));
int *__ptr32 b;

*a = 99;
b = a;

// Test should return 4
return (*b - 95);
}

int test_4() {
// X64-LABEL: define {{.*}} i32 @test_4()
// X64: ret i32 1
int *a = (int *)__malloc31(sizeof(int));
float *d = (float *)__malloc31(sizeof(float));

int *__ptr32 b;
int *c;

float *__ptr32 e;
float *f;

*a = 0;
*d = 0.0;

b = a;
c = a;
e = d;
f = d;

// Test should return 1
return (b == c && e == f);
}

Loading