343 changes: 336 additions & 7 deletions clang/lib/Driver/Tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3102,15 +3102,23 @@ ParsePICArgs(const ToolChain &ToolChain, const llvm::Triple &Triple,
O.matches(options::OPT_fPIE) || O.matches(options::OPT_fPIC);
} else {
PIE = PIC = false;
if (Triple.isPS4CPU()) {
Arg *ModelArg = Args.getLastArg(options::OPT_mcmodel_EQ);
StringRef Model = ModelArg ? ModelArg->getValue() : "";
if (Model != "kernel") {
PIC = true;
ToolChain.getDriver().Diag(diag::warn_drv_ps4_force_pic)
<< LastPICArg->getSpelling();
}
}
}
}
}

// Introduce a Darwin-specific hack. If the default is PIC, but the
// PIC level would've been set to level 1, force it back to level 2
// PIC instead. This matches the behavior of Darwin GCC (based on
// chandlerc's informal testing in 2012).
if (PIC && ToolChain.getTriple().isOSDarwin())
// Introduce a Darwin and PS4-specific hack. If the default is PIC, but the
// PIC level would've been set to level 1, force it back to level 2 PIC
// instead.
if (PIC && (ToolChain.getTriple().isOSDarwin() || Triple.isPS4CPU()))
IsPICLevelTwo |= ToolChain.isPICDefault();

// This kernel flags are a trump-card: they will disable PIC/PIE
Expand Down Expand Up @@ -3182,6 +3190,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
bool IsWindowsCygnus =
getToolChain().getTriple().isWindowsCygwinEnvironment();
bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
bool IsPS4CPU = getToolChain().getTriple().isPS4CPU();

// Check number of inputs for sanity. We need at least one input.
assert(Inputs.size() >= 1 && "Must have at least one input.");
Expand Down Expand Up @@ -3823,8 +3832,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,

// We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
Args.ClaimAllArgs(options::OPT_g_flags_Group);

// PS4 defaults to no column info
if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
/*Default*/ true))
/*Default=*/ !IsPS4CPU))
CmdArgs.push_back("-dwarf-column-info");

// FIXME: Move backend command line options to the module.
Expand All @@ -3851,7 +3862,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,

// -gdwarf-aranges turns on the emission of the aranges section in the
// backend.
if (Args.hasArg(options::OPT_gdwarf_aranges)) {
// Always enabled on the PS4.
if (Args.hasArg(options::OPT_gdwarf_aranges) || IsPS4CPU) {
CmdArgs.push_back("-backend-option");
CmdArgs.push_back("-generate-arange-section");
}
Expand Down Expand Up @@ -9846,3 +9858,320 @@ void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA,
C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec),
CmdArgs, Inputs));
}

void PS4cpu::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
claimNoWarnArgs(Args);
ArgStringList CmdArgs;

Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);

CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());

const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("ps4-as"));
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}

static void AddPS4ProfileRT(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
false) ||
Args.hasArg(options::OPT_fprofile_generate) ||
Args.hasArg(options::OPT_fprofile_instr_generate) ||
Args.hasArg(options::OPT_fcreate_profile) ||
Args.hasArg(options::OPT_coverage)))
return;

assert(TC.getTriple().isPS4CPU() &&
"Profiling libraries are only implemented for the PS4 CPU");
CmdArgs.push_back("-lclang_rt.profile-x86_64");
}

static void AddPS4SanitizerArgs(const ToolChain &TC, ArgStringList &CmdArgs) {
const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
if (SanArgs.needsUbsanRt()) {
CmdArgs.push_back("-lSceDbgUBSanitizer_stub_weak");
}
if (SanArgs.needsAsanRt()) {
CmdArgs.push_back("-lSceDbgAddressSanitizer_stub_weak");
}
}

static void ConstructPS4LinkJob(const Tool &T, Compilation &C,
const JobAction &JA, const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) {
const toolchains::FreeBSD &ToolChain =
static_cast<const toolchains::FreeBSD &>(T.getToolChain());
const Driver &D = ToolChain.getDriver();
ArgStringList CmdArgs;

// Silence warning for "clang -g foo.o -o foo"
Args.ClaimAllArgs(options::OPT_g_Group);
// and "clang -emit-llvm foo.o -o foo"
Args.ClaimAllArgs(options::OPT_emit_llvm);
// and for "clang -w foo.o -o foo". Other warning options are already
// handled somewhere else.
Args.ClaimAllArgs(options::OPT_w);

if (!D.SysRoot.empty())
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));

if (Args.hasArg(options::OPT_pie))
CmdArgs.push_back("-pie");

if (Args.hasArg(options::OPT_rdynamic))
CmdArgs.push_back("-export-dynamic");
if (Args.hasArg(options::OPT_shared))
CmdArgs.push_back("--oformat=so");

if (Output.isFilename()) {
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
} else {
assert(Output.isNothing() && "Invalid output.");
}

Args.AddAllArgs(CmdArgs, options::OPT_L);
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
Args.AddAllArgs(CmdArgs, options::OPT_e);
Args.AddAllArgs(CmdArgs, options::OPT_s);
Args.AddAllArgs(CmdArgs, options::OPT_t);
Args.AddAllArgs(CmdArgs, options::OPT_r);

if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
CmdArgs.push_back("--no-demangle");

AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);

if (Args.hasArg(options::OPT_pthread)) {
CmdArgs.push_back("-lpthread");
}

AddPS4ProfileRT(ToolChain, Args, CmdArgs);
AddPS4SanitizerArgs(ToolChain, CmdArgs);

const char *Exec = Args.MakeArgString(ToolChain.GetProgramPath("ps4-ld"));

C.addCommand(llvm::make_unique<Command>(JA, T, Exec, CmdArgs, Inputs));
}

static void ConstructGoldLinkJob(const Tool &T, Compilation &C,
const JobAction &JA, const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) {
const toolchains::FreeBSD &ToolChain =
static_cast<const toolchains::FreeBSD &>(T.getToolChain());
const Driver &D = ToolChain.getDriver();
ArgStringList CmdArgs;

// Silence warning for "clang -g foo.o -o foo"
Args.ClaimAllArgs(options::OPT_g_Group);
// and "clang -emit-llvm foo.o -o foo"
Args.ClaimAllArgs(options::OPT_emit_llvm);
// and for "clang -w foo.o -o foo". Other warning options are already
// handled somewhere else.
Args.ClaimAllArgs(options::OPT_w);

if (!D.SysRoot.empty())
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));

if (Args.hasArg(options::OPT_pie))
CmdArgs.push_back("-pie");

if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-Bstatic");
} else {
if (Args.hasArg(options::OPT_rdynamic))
CmdArgs.push_back("-export-dynamic");
CmdArgs.push_back("--eh-frame-hdr");
if (Args.hasArg(options::OPT_shared)) {
CmdArgs.push_back("-Bshareable");
} else {
CmdArgs.push_back("-dynamic-linker");
CmdArgs.push_back("/libexec/ld-elf.so.1");
}
CmdArgs.push_back("--enable-new-dtags");
}

if (Output.isFilename()) {
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
} else {
assert(Output.isNothing() && "Invalid output.");
}

if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
const char *crt1 = NULL;
if (!Args.hasArg(options::OPT_shared)) {
if (Args.hasArg(options::OPT_pg))
crt1 = "gcrt1.o";
else if (Args.hasArg(options::OPT_pie))
crt1 = "Scrt1.o";
else
crt1 = "crt1.o";
}
if (crt1)
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));

CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));

const char *crtbegin = NULL;
if (Args.hasArg(options::OPT_static))
crtbegin = "crtbeginT.o";
else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
crtbegin = "crtbeginS.o";
else
crtbegin = "crtbegin.o";

CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
}

Args.AddAllArgs(CmdArgs, options::OPT_L);

const ToolChain::path_list Paths = ToolChain.getFilePaths();
for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
i != e; ++i)
CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));

Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
Args.AddAllArgs(CmdArgs, options::OPT_e);
Args.AddAllArgs(CmdArgs, options::OPT_s);
Args.AddAllArgs(CmdArgs, options::OPT_t);
Args.AddAllArgs(CmdArgs, options::OPT_r);

if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
CmdArgs.push_back("--no-demangle");

AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);

if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
// For PS4, we always want to pass libm, libstdc++ and libkernel
// libraries for both C and C++ compilations.
CmdArgs.push_back("-lkernel");
if (D.CCCIsCXX()) {
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
if (Args.hasArg(options::OPT_pg))
CmdArgs.push_back("-lm_p");
else
CmdArgs.push_back("-lm");
}
// FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
// the default system libraries. Just mimic this for now.
if (Args.hasArg(options::OPT_pg))
CmdArgs.push_back("-lgcc_p");
else
CmdArgs.push_back("-lcompiler_rt");
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-lstdc++");
} else if (Args.hasArg(options::OPT_pg)) {
CmdArgs.push_back("-lgcc_eh_p");
} else {
CmdArgs.push_back("--as-needed");
CmdArgs.push_back("-lstdc++");
CmdArgs.push_back("--no-as-needed");
}

if (Args.hasArg(options::OPT_pthread)) {
if (Args.hasArg(options::OPT_pg))
CmdArgs.push_back("-lpthread_p");
else
CmdArgs.push_back("-lpthread");
}

if (Args.hasArg(options::OPT_pg)) {
if (Args.hasArg(options::OPT_shared))
CmdArgs.push_back("-lc");
else {
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("--start-group");
CmdArgs.push_back("-lc_p");
CmdArgs.push_back("-lpthread_p");
CmdArgs.push_back("--end-group");
} else {
CmdArgs.push_back("-lc_p");
}
}
CmdArgs.push_back("-lgcc_p");
} else {
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("--start-group");
CmdArgs.push_back("-lc");
CmdArgs.push_back("-lpthread");
CmdArgs.push_back("--end-group");
} else {
CmdArgs.push_back("-lc");
}
CmdArgs.push_back("-lcompiler_rt");
}

if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-lstdc++");
} else if (Args.hasArg(options::OPT_pg)) {
CmdArgs.push_back("-lgcc_eh_p");
} else {
CmdArgs.push_back("--as-needed");
CmdArgs.push_back("-lstdc++");
CmdArgs.push_back("--no-as-needed");
}
}

if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nostartfiles)) {
if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
else
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
}

AddPS4ProfileRT(ToolChain, Args, CmdArgs);
AddPS4SanitizerArgs(ToolChain, CmdArgs);

const char *Exec =
#ifdef LLVM_ON_WIN32
Args.MakeArgString(ToolChain.GetProgramPath("ps4-ld.gold.exe"));
#else
Args.MakeArgString(ToolChain.GetProgramPath("ps4-ld"));
#endif

C.addCommand(llvm::make_unique<Command>(JA, T, Exec, CmdArgs, Inputs));
}

void PS4cpu::Link::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
const toolchains::FreeBSD &ToolChain =
static_cast<const toolchains::FreeBSD &>(getToolChain());
const Driver &D = ToolChain.getDriver();
bool PS4Linker;
StringRef LinkerOptName;
if (const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
LinkerOptName = A->getValue();
if (LinkerOptName != "ps4" && LinkerOptName != "gold")
D.Diag(diag::err_drv_unsupported_linker) << LinkerOptName;
}

if (LinkerOptName == "gold")
PS4Linker = false;
else if (LinkerOptName == "ps4")
PS4Linker = true;
else
PS4Linker = !Args.hasArg(options::OPT_shared);

if (PS4Linker)
ConstructPS4LinkJob(*this, C, JA, Output, Inputs, Args, LinkingOutput);
else
ConstructGoldLinkJob(*this, C, JA, Output, Inputs, Args, LinkingOutput);
}
30 changes: 30 additions & 0 deletions clang/lib/Driver/Tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,36 @@ class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
};
} // end namespace Myriad

namespace PS4cpu {
class LLVM_LIBRARY_VISIBILITY Assemble : public Tool {
public:
Assemble(const ToolChain &TC)
: Tool("PS4cpu::Assemble", "assembler", TC, RF_Full) {}

virtual bool hasIntegratedCPP() const { return false; }

virtual void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const;
};

class LLVM_LIBRARY_VISIBILITY Link : public Tool {
public:
Link(const ToolChain &TC) : Tool("PS4cpu::Link", "linker", TC, RF_Full) {}

virtual bool hasIntegratedCPP() const { return false; }
virtual bool isLinkJob() const { return true; }

virtual void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const;
};
} // end namespace PS4cpu

} // end namespace tools
} // end namespace driver
} // end namespace clang
Expand Down
23 changes: 23 additions & 0 deletions clang/lib/Frontend/InitHeaderSearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
case llvm::Triple::OpenBSD:
case llvm::Triple::Bitrig:
case llvm::Triple::NaCl:
case llvm::Triple::PS4:
break;
case llvm::Triple::Win32:
if (triple.getEnvironment() != llvm::Triple::Cygnus)
Expand Down Expand Up @@ -320,6 +321,28 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
case llvm::Triple::RTEMS:
case llvm::Triple::NaCl:
break;
case llvm::Triple::PS4: {
// <isysroot> gets prepended later in AddPath().
std::string BaseSDKPath = "";
if (!HasSysroot) {
const char *envValue = getenv("SCE_PS4_SDK_DIR");
if (envValue)
BaseSDKPath = envValue;
else {
// HSOpts.ResourceDir variable contains the location of Clang's
// resource files.
// Assuming that Clang is configured for PS4 without
// --with-clang-resource-dir option, the location of Clang's resource
// files is <SDK_DIR>/host_tools/lib/clang
SmallString<128> P = StringRef(HSOpts.ResourceDir);
llvm::sys::path::append(P, "../../..");
BaseSDKPath = P.str();
}
}
AddPath(BaseSDKPath + "/target/include", System, false);
if (triple.isPS4CPU())
AddPath(BaseSDKPath + "/target/include_common", System, false);
}
default:
AddPath("/usr/include", ExternCSystem, false);
break;
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

14 changes: 14 additions & 0 deletions clang/test/Driver/debug-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@
// RUN: %clang -### -c -ggdb3 %s -target x86_64-apple-darwin 2>&1 \
// RUN: | FileCheck -check-prefix=G_DARWIN %s

// On the PS4, -g defaults to -gno-column-info, and we always generate the
// arange section.
// RUN: %clang -### -c %s -target x86_64-scei-ps4 2>&1 \
// RUN: | FileCheck -check-prefix=G_PS4 %s
// RUN: %clang -### -c %s -g -target x86_64-scei-ps4 2>&1 \
// RUN: | FileCheck -check-prefix=G_PS4 %s
// RUN: %clang -### -c %s -g -target x86_64-scei-ps4 2>&1 \
// RUN: | FileCheck -check-prefix=NOCI %s
// RUN: %clang -### -c %s -g -gcolumn-info -target x86_64-scei-ps4 2>&1 \
// RUN: | FileCheck -check-prefix=CI %s

// RUN: %clang -### -c -gdwarf-2 %s 2>&1 | FileCheck -check-prefix=G_D2 %s
//
// RUN: %clang -### -c -gfoo %s 2>&1 | FileCheck -check-prefix=G_NO %s
Expand Down Expand Up @@ -86,6 +97,9 @@
// G_DARWIN: "-cc1"
// G_DARWIN: "-gdwarf-2"
//
// G_PS4: "-cc1"
// G_PS4: "-generate-arange-section"
//
// G_D2: "-cc1"
// G_D2: "-gdwarf-2"
//
Expand Down
10 changes: 10 additions & 0 deletions clang/test/Driver/ps4-header-search.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// REQUIRES: x86-registered-target

// RUN: env SCE_PS4_SDK_DIR=%S/Inputs/scei-ps4_tree %clang -target x86_64-scei-ps4 -E -v %s 2>&1 | FileCheck %s --check-prefix=ENVPS4
// ENVPS4: Inputs/scei-ps4_tree/target/include{{$}}
// ENVPS4: Inputs/scei-ps4_tree/target/include_common{{$}}

// RUN: %clang -isysroot %S/Inputs/scei-ps4_tree -target x86_64-scei-ps4 -E -v %s 2>&1 | FileCheck %s --check-prefix=SYSROOTPS4
// SYSROOTPS4: "{{[^"]*}}clang{{[^"]*}}"
// SYSROOTPS4: Inputs/scei-ps4_tree/target/include{{$}}
// SYSROOTPS4: Inputs/scei-ps4_tree/target/include_common{{$}}
18 changes: 18 additions & 0 deletions clang/test/Driver/ps4-linker-non-win.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// UNSUPPORTED: system-windows
// REQUIRES: x86-registered-target

// RUN: touch %T/ps4-ld

// RUN: env "PATH=%T" %clang -### -target x86_64-scei-ps4 %s -linker=gold 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s
// RUN: env "PATH=%T" %clang -### -target x86_64-scei-ps4 %s -shared 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s

// RUN: env "PATH=%T" %clang -### -target x86_64-scei-ps4 %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s
// RUN: env "PATH=%T" %clang -### -target x86_64-scei-ps4 %s -linker=ps4 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s
// RUN: env "PATH=%T" %clang -### -target x86_64-scei-ps4 %s -shared \
// RUN: -linker=ps4 2>&1 | FileCheck --check-prefix=CHECK-PS4-LINKER %s

// CHECK-PS4-LINKER: ps4-ld
26 changes: 26 additions & 0 deletions clang/test/Driver/ps4-linker-win.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// The full path to the gold linker was not found on Windows because the
// driver fails to add an .exe extension to the name.
// We check that gold linker's full name (with an extension) is specified
// on the command line if -linker=gold, or -shared with no -linker option
// are passed. Otherwise, we check that the PS4's linker's full name is
// specified.

// REQUIRES: system-windows, x86-registered-target

// RUN: touch %T/ps4-ld.exe
// RUN: touch %T/ps4-ld.gold.exe

// RUN: env "PATH=%T" %clang -target x86_64-scei-ps4 %s -linker=gold -### 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-GOLD %s
// RUN: env "PATH=%T" %clang -target x86_64-scei-ps4 %s -shared -### 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-GOLD %s

// RUN: env "PATH=%T" %clang -target x86_64-scei-ps4 %s -### 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s
// RUN: env "PATH=%T" %clang -target x86_64-scei-ps4 %s -linker=ps4 -### 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-PS4-LINKER %s
// RUN: env "PATH=%T" %clang -target x86_64-scei-ps4 %s -shared \
// RUN: -linker=ps4 -### 2>&1 | FileCheck --check-prefix=CHECK-PS4-LINKER %s

// CHECK-PS4-GOLD: ps4-ld.gold.exe
// CHECK-PS4-LINKER: ps4-ld.exe
106 changes: 106 additions & 0 deletions clang/test/Driver/ps4-pic.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// REQUIRES: x86-registered-target

// Test the driver's control over the PIC behavior for PS4 compiler.
// These consist of tests of the relocation model flags and the
// pic level flags passed to CC1.
//
// CHECK-NO-PIC: "-mrelocation-model" "static"
// CHECK-NO-PIC-NOT: "-pic-level"
// CHECK-NO-PIC-NOT: "-pie-level"
//
// CHECK-DYNAMIC-NO-PIC2: unsupported option '-mdynamic-no-pic'
// CHECK-DYNAMIC-NO-PIC2: "-mrelocation-model" "dynamic-no-pic"
//
// CHECK-PIC2: "-mrelocation-model" "pic"
// CHECK-PIC2: "-pic-level" "2"
//
// CHECK-PIE2: "-mrelocation-model" "pic"
// CHECK-PIE2: "-pie-level" "2"
//
// CHECK-NOPIC-IGNORED: using '-fPIC'
// CHECK-NOPIC-IGNORED: "-mrelocation-model" "pic"
// CHECK-NOPIC-IGNORED: "-pic-level" "2"
//
// CHECK-DIAG-PIC: option '-fno-PIC' was ignored by the PS4 toolchain, using '-fPIC'
// CHECK-DIAG-PIE: option '-fno-PIE' was ignored by the PS4 toolchain, using '-fPIC'
// CHECK-DIAG-pic: option '-fno-pic' was ignored by the PS4 toolchain, using '-fPIC'
// CHECK-DIAG-pie: option '-fno-pie' was ignored by the PS4 toolchain, using '-fPIC'
//
// CHECK-STATIC-ERR: unsupported option '-static' for target 'PS4'

// RUN: %clang -c %s -target x86_64-scei-ps4 -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIC2
// RUN: %clang -c %s -target x86_64-scei-ps4 -fpic -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIC2
// RUN: %clang -c %s -target x86_64-scei-ps4 -fPIC -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIC2
// RUN: %clang -c %s -target x86_64-scei-ps4 -fpie -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
// RUN: %clang -c %s -target x86_64-scei-ps4 -fPIE -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
// RUN: %clang -c %s -target x86_64-scei-ps4 -fpic -fno-pic -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
// RUN: %clang -c %s -target x86_64-scei-ps4 -fPIC -fno-PIC -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
// RUN: %clang -c %s -target x86_64-scei-ps4 -fpic -fno-PIC -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
// RUN: %clang -c %s -target x86_64-scei-ps4 -fPIC -fno-pic -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
// RUN: %clang -c %s -target x86_64-scei-ps4 -fpie -fno-pie -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
// RUN: %clang -c %s -target x86_64-scei-ps4 -fPIE -fno-PIE -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
// RUN: %clang -c %s -target x86_64-scei-ps4 -fpie -fno-PIE -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
// RUN: %clang -c %s -target x86_64-scei-ps4 -fPIE -fno-pie -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
// RUN: %clang -c %s -target x86_64-scei-ps4 -fpie -fno-pic -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
// RUN: %clang -c %s -target x86_64-scei-ps4 -fpic -fno-pie -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
// RUN: %clang -c %s -target x86_64-scei-ps4 -fpic -fPIC -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIC2
// RUN: %clang -c %s -target x86_64-scei-ps4 -fPIC -fpic -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIC2
// RUN: %clang -c %s -target x86_64-scei-ps4 -fpic -fPIE -fpie -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
// RUN: %clang -c %s -target x86_64-scei-ps4 -fpie -fPIC -fPIE -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIE2
//
// Defaults change for PS4.
// RUN: %clang -c %s -target x86_64-scei-ps4 -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIC2
// RUN: %clang -c %s -target x86_64-scei-ps4 -fno-pic -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
// RUN: %clang -c %s -target x86_64-scei-ps4 -fno-PIC -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIC-IGNORED
//
// Disregard any of the PIC-specific flags if we have a trump-card flag.
// RUN: %clang -c %s -target x86_64-scei-ps4 -mkernel -fPIC -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC
// RUN: %clang -c %s -target x86_64-scei-ps4 -mdynamic-no-pic -fPIC -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-DYNAMIC-NO-PIC2
//
// -static not supported at all.
// RUN: %clang -c %s -target x86_64-scei-ps4 -static -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-STATIC-ERR
//
// -fno-PIC etc. is obeyed if -mcmodel=kernel is also present.
// RUN: %clang -c %s -target x86_64-scei-ps4 -mcmodel=kernel -fno-PIC -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC
// RUN: %clang -c %s -target x86_64-scei-ps4 -mcmodel=kernel -fno-PIE -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC
// RUN: %clang -c %s -target x86_64-scei-ps4 -mcmodel=kernel -fno-pic -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC
// RUN: %clang -c %s -target x86_64-scei-ps4 -mcmodel=kernel -fno-pie -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC
//
// Verify that we reflect the option the user specified, when we ignore it.
// RUN: %clang -c %s -target x86_64-scei-ps4 -fno-PIC -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-DIAG-PIC
// RUN: %clang -c %s -target x86_64-scei-ps4 -fno-PIE -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-DIAG-PIE
// RUN: %clang -c %s -target x86_64-scei-ps4 -fno-pic -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-DIAG-pic
// RUN: %clang -c %s -target x86_64-scei-ps4 -fno-pie -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-DIAG-pie
48 changes: 48 additions & 0 deletions clang/test/Driver/ps4-sdk-root.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// REQUIRES: x86-registered-target

// Check that ps4-clang doesn't report a warning message when locating
// system header files (either by looking at the value of SCE_PS4_SDK_DIR
// or relative to the location of the compiler driver), if "-nostdinc",
// "--sysroot" or "-isysroot" option is specified on the command line.
// Otherwise, check that ps4-clang reports a warning.

// Check that clang doesn't report a warning message when locating
// system libraries (either by looking at the value of SCE_PS4_SDK_DIR
// or relative to the location of the compiler driver), if "-c", "-S", "-E",
// "--sysroot", "-nostdlib" or "-nodefaultlibs" option is specified on
// the command line.
// Otherwise, check that ps4-clang reports a warning.

// setting up SCE_PS4_SDK_DIR to existing location, which is not a PS4 SDK.
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=WARN-SYS-LIBS -check-prefix=NO-WARN %s

// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -c -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -S -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -E -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -emit-ast -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=WARN-SYS-LIBS -check-prefix=NO-WARN %s

// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -c -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -S -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -E -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -emit-ast -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s

// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -c --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -S --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -E --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -emit-ast --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s

// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -c -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -S -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -E -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -emit-ast -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### --sysroot=foo/ -isysroot foo -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-ISYSROOT -check-prefix=NO-WARN %s

// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -nostdlib -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s
// RUN: env SCE_PS4_SDK_DIR=.. %clang -### -nodefaultlibs -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=WARN-SYS-HEADERS -check-prefix=NO-WARN %s

// NO-WARN-NOT: {{warning:|error:}}
// WARN-SYS-HEADERS: warning: unable to find PS4 system headers directory
// WARN-ISYSROOT: warning: no such sysroot directory: 'foo'
// WARN-SYS-LIBS: warning: unable to find PS4 system libraries directory
// NO-WARN-NOT: {{warning:|error:}}
3 changes: 2 additions & 1 deletion clang/test/Driver/rtti-options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
// RUN: %clang -x c++ -### -c -target x86_64-unknown-unknown -fexceptions %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s

// -frtti + exceptions
// RUN: %clang -### -c -target x86_64-scei-ps4 -fcxx-exceptions -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s
// ps4 needs -nostdinc due to having warnings if the SDK is not installed
// RUN: %clang -### -c -nostdinc -target x86_64-scei-ps4 -fcxx-exceptions -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s
// RUN: %clang -### -c -target x86_64-unknown-unknown -fcxx-exceptions -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s

// -f{no-,}rtti/default
Expand Down
9 changes: 9 additions & 0 deletions clang/test/Driver/stack-protector.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,12 @@
// RUN: %clang -fstack-protector-all -### %s 2>&1 | FileCheck %s -check-prefix=SSP-ALL
// SSP-ALL: "-stack-protector" "3"
// SSP-ALL-NOT: "-stack-protector-buffer-size"

// RUN: %clang -target x86_64-scei-ps4 -### %s 2>&1 | FileCheck %s -check-prefix=SSP-PS4
// RUN: %clang -target x86_64-scei-ps4 -fstack-protector -### %s 2>&1 | FileCheck %s -check-prefix=SSP-PS4
// SSP-PS4: "-stack-protector" "2"
// SSP-PS4-NOT: "-stack-protector-buffer-size"

// RUN: %clang -target x86_64-scei-ps4 -fstack-protector --param ssp-buffer-size=16 -### %s 2>&1 | FileCheck %s -check-prefix=SSP-PS4-BUF
// SSP-PS4-BUF: "-stack-protector" "2"
// SSP-PS4-BUF: "-stack-protector-buffer-size" "16"