kromanova created this revision.
kromanova added reviewers: filcab, echristo, alexr, probinson.
kromanova added subscribers: silvas, cfe-commits, chapuni, jroelofs, asl, 
pgousseau, gbedwell.
kromanova set the repository for this revision to rL LLVM.

Initial patch for PS4 toolchain was created here: http://reviews.llvm.org/D11279
When this patch was committed in r248546, it caused 2 distinct problems.

(1) Many failures were reported on recently set up PS4 bot. The PS4 driver 
intentionally reported warnings if PS4 SDK was missing. The new buildbot didn't 
have PS4 SDK directory installed. This "combination" caused failures for all 
the tests that had -Werror option.
(2) ps4-linker-win.c failed on all the Windows bots.

This commit was reverted in r248548 to make the bots green again and to decide 
on how to deal with missing PS4 SDK directory issue.

The new patch should take care of both problems mentioned above.
Since review for http://reviews.llvm.org/D11279 was owned by Filipe Cabecinhas 
and already closed, it's probably easier for me to open a new code review. Feel 
free to compare this new patch to the latest patch in D11279.
Here is the summary of the changes:

1.      include/clang/Basic/DiagnosticDriverKinds.td     
Added DefaultIgnore attribute to InvalidOrNonExistentDirectory. 
By default, the PS4 driver won't report a warning about missing PS4 SDK. This 
behavior could be changed if  -Weverything or 
-Winvalid-or-nonexistent-directory options are passed.

2.      Changed 
test/Driver/ps4-linker-non-win.c to use -fuse-ld=gold instead of -linker=gold
test/Driver/ps4-linker-win.c to use -fuse-ld=gold instead of -linker=gold
We do not support "-linker" option anymore. Use "-fuse-ld" instead.

3. test/Driver/ps4-sdk-root.c
Added -Winvalid-or-nonexistent-directory to all the RUN lines to force the 
warning (this is the only test where we want to have the warnings about missing 
PS4 SDK directory enabled).

4.      test/Driver/rtti-options.cpp 
Removed all the changes. No changes are needed, since the warning is not 
reported by default anymore.

Origianal patch extracted by Filipe Cabecinhas, me (Katya Romanova), and Pierre 
Gousseau.






Repository:
  rL LLVM

http://reviews.llvm.org/D13482

Files:
  include/clang/Basic/DiagnosticDriverKinds.td
  include/clang/Basic/DiagnosticGroups.td
  lib/Driver/Driver.cpp
  lib/Driver/ToolChains.cpp
  lib/Driver/ToolChains.h
  lib/Driver/Tools.cpp
  lib/Driver/Tools.h
  lib/Frontend/InitHeaderSearch.cpp
  test/Driver/Inputs/scei-ps4_tree/target/include/.keep
  test/Driver/Inputs/scei-ps4_tree/target/include_common/.keep
  test/Driver/debug-options.c
  test/Driver/ps4-header-search.c
  test/Driver/ps4-linker-non-win.c
  test/Driver/ps4-linker-win.c
  test/Driver/ps4-pic.c
  test/Driver/ps4-sdk-root.c
  test/Driver/stack-protector.c

Index: test/Driver/stack-protector.c
===================================================================
--- test/Driver/stack-protector.c
+++ test/Driver/stack-protector.c
@@ -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"
Index: test/Driver/ps4-sdk-root.c
===================================================================
--- test/Driver/ps4-sdk-root.c
+++ test/Driver/ps4-sdk-root.c
@@ -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 -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### -c -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
+// RUN: env SCE_PS4_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -S -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
+// RUN: env SCE_PS4_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -E -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
+// RUN: env SCE_PS4_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -emit-ast -nostdinc -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
+
+// RUN: env SCE_PS4_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -c --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
+// RUN: env SCE_PS4_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -S --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
+// RUN: env SCE_PS4_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -E --sysroot=foo/ -target x86_64-scei-ps4 %s 2>&1 | FileCheck -check-prefix=NO-WARN %s
+// RUN: env SCE_PS4_SDK_DIR=.. %clang -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### --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 -Winvalid-or-nonexistent-directory -### -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 -Winvalid-or-nonexistent-directory -### -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:}}
Index: test/Driver/ps4-pic.c
===================================================================
--- test/Driver/ps4-pic.c
+++ test/Driver/ps4-pic.c
@@ -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
Index: test/Driver/ps4-linker-win.c
===================================================================
--- test/Driver/ps4-linker-win.c
+++ test/Driver/ps4-linker-win.c
@@ -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 -fuse-ld=gold, or -shared with no -fuse-ld 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 -fuse-ld=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 -fuse-ld=ps4 -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-PS4-LINKER %s
+// RUN: env "PATH=%T" %clang -target x86_64-scei-ps4  %s -shared \
+// RUN:     -fuse-ld=ps4 -### 2>&1 | FileCheck --check-prefix=CHECK-PS4-LINKER %s
+
+// CHECK-PS4-GOLD: ps4-ld.gold.exe
+// CHECK-PS4-LINKER: ps4-ld.exe
Index: test/Driver/ps4-linker-non-win.c
===================================================================
--- test/Driver/ps4-linker-non-win.c
+++ test/Driver/ps4-linker-non-win.c
@@ -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 -fuse-ld=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 -fuse-ld=ps4 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-PS4-LINKER %s
+// RUN: env "PATH=%T" %clang -### -target x86_64-scei-ps4  %s -shared \
+// RUN:     -fuse-ld=ps4 2>&1 | FileCheck --check-prefix=CHECK-PS4-LINKER %s
+
+// CHECK-PS4-LINKER: ps4-ld
Index: test/Driver/ps4-header-search.c
===================================================================
--- test/Driver/ps4-header-search.c
+++ test/Driver/ps4-header-search.c
@@ -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{{$}}
Index: test/Driver/debug-options.c
===================================================================
--- test/Driver/debug-options.c
+++ test/Driver/debug-options.c
@@ -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
@@ -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"
 //
Index: lib/Frontend/InitHeaderSearch.cpp
===================================================================
--- lib/Frontend/InitHeaderSearch.cpp
+++ lib/Frontend/InitHeaderSearch.cpp
@@ -215,6 +215,7 @@
     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)
@@ -318,6 +319,28 @@
   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;
Index: lib/Driver/Tools.h
===================================================================
--- lib/Driver/Tools.h
+++ lib/Driver/Tools.h
@@ -828,6 +828,36 @@
 };
 } // 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
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -3072,15 +3072,23 @@
             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
@@ -3152,6 +3160,7 @@
   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.");
@@ -3791,8 +3800,10 @@
 
   // 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.
@@ -3819,7 +3830,8 @@
 
   // -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");
   }
@@ -9845,3 +9857,320 @@
   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);
+}
Index: lib/Driver/ToolChains.h
===================================================================
--- lib/Driver/ToolChains.h
+++ lib/Driver/ToolChains.h
@@ -1002,6 +1002,27 @@
                              llvm::opt::ArgStringList &CC1Args) const override;
 };
 
+class LLVM_LIBRARY_VISIBILITY PS4CPU : public Generic_ELF {
+public:
+  PS4CPU(const Driver &D, const llvm::Triple &Triple,
+         const llvm::opt::ArgList &Args);
+
+  bool IsMathErrnoDefault() const override { return false; }
+  bool IsObjCNonFragileABIDefault() const override { return true; }
+  bool HasNativeLLVMSupport() const override;
+  bool isPICDefault() const override;
+
+  unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
+    return 2; // SSPStrong
+  }
+
+  SanitizerMask getSupportedSanitizers() const override;
+
+protected:
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
+};
+
 } // end namespace toolchains
 } // end namespace driver
 } // end namespace clang
Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp
+++ lib/Driver/ToolChains.cpp
@@ -4065,3 +4065,69 @@
                          options::OPT_fno_use_init_array, true))
     CC1Args.push_back("-fuse-init-array");
 }
+
+PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+    : Generic_ELF(D, Triple, Args) {
+  if (Args.hasArg(options::OPT_static))
+    D.Diag(diag::err_drv_unsupported_opt_for_target) << "-static" << "PS4";
+
+  // Determine where to find the PS4 libraries. We use SCE_PS4_SDK_DIR
+  // if it exists; otherwise use the driver's installation path, which
+  // should be <SDK_DIR>/host_tools/bin.
+  const char *EnvValue = getenv("SCE_PS4_SDK_DIR");
+  if (EnvValue && !llvm::sys::fs::exists(EnvValue))
+    getDriver().Diag(clang::diag::warn_drv_ps4_sdk_dir) << EnvValue;
+
+  std::string PS4SDKDir = (EnvValue ? EnvValue : getDriver().Dir + "/../..");
+
+  // Report a warning if we can't find the include or lib directories from
+  // the SDK.
+  // If -isysroot was passed, use that as the SDK base path.
+  std::string PrefixDir;
+  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+    PrefixDir = A->getValue();
+    if (!llvm::sys::fs::exists(PrefixDir))
+      getDriver().Diag(clang::diag::warn_missing_sysroot) << PrefixDir;
+  } else
+    PrefixDir = PS4SDKDir;
+
+  std::string PS4SDKIncludeDir = PrefixDir + "/target/include";
+  if (!Args.hasArg(options::OPT_nostdinc) &&
+      !Args.hasArg(options::OPT_nostdlibinc) &&
+      !Args.hasArg(options::OPT_isysroot) &&
+      !Args.hasArg(options::OPT__sysroot_EQ) &&
+      !llvm::sys::fs::exists(PS4SDKIncludeDir)) {
+    getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
+        << "PS4 system headers" << PS4SDKIncludeDir;
+  }
+
+  std::string PS4SDKLibDir = PS4SDKDir + "/target/lib";
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs) &&
+      !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) &&
+      !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) &&
+      !Args.hasArg(options::OPT_emit_ast) &&
+      !llvm::sys::fs::exists(PS4SDKLibDir)) {
+    getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected)
+        << "PS4 system libraries" << PS4SDKLibDir;
+    return;
+  }
+  getFilePaths().push_back(PS4SDKLibDir);
+}
+
+Tool *PS4CPU::buildAssembler() const {
+  return new tools::PS4cpu::Assemble(*this);
+}
+
+Tool *PS4CPU::buildLinker() const { return new tools::PS4cpu::Link(*this); }
+
+bool PS4CPU::isPICDefault() const { return true; }
+
+bool PS4CPU::HasNativeLLVMSupport() const { return true; }
+
+SanitizerMask PS4CPU::getSupportedSanitizers() const {
+  SanitizerMask Res = ToolChain::getSupportedSanitizers();
+  Res |= SanitizerKind::Address;
+  Res |= SanitizerKind::Vptr;
+  return Res;
+}
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -2254,6 +2254,9 @@
     case llvm::Triple::CUDA:
       TC = new toolchains::CudaToolChain(*this, Target, Args);
       break;
+    case llvm::Triple::PS4:
+      TC = new toolchains::PS4CPU(*this, Target, Args);
+      break;
     default:
       // Of these targets, Hexagon is the only one that might have
       // an OS of Linux, in which case it got handled above already.
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -821,3 +821,7 @@
 
 // A warning group for things that will change semantics in the future.
 def FutureCompat : DiagGroup<"future-compat">;
+
+def InvalidOrNonExistentDirectory : DiagGroup<"invalid-or-nonexistent-directory">;
+
+def OptionIgnored : DiagGroup<"option-ignored">;
Index: include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- include/clang/Basic/DiagnosticDriverKinds.td
+++ include/clang/Basic/DiagnosticDriverKinds.td
@@ -194,4 +194,18 @@
 def warn_target_unsupported_nanlegacy : Warning<
   "ignoring '-mnan=legacy' option because the '%0' architecture does not support it">,
   InGroup<UnsupportedNan>;
+
+def warn_drv_unable_to_find_directory_expected : Warning<
+  "unable to find %0 directory, expected to be in '%1'">,
+  InGroup<InvalidOrNonExistentDirectory>, DefaultIgnore;
+
+def warn_drv_ps4_force_pic : Warning<
+  "option '%0' was ignored by the PS4 toolchain, using '-fPIC'">,
+  InGroup<OptionIgnored>;
+
+def warn_drv_ps4_sdk_dir : Warning<
+  "environment variable SCE_PS4_SDK_DIR is set, but points to invalid or nonexistent directory '%0'">,
+  InGroup<InvalidOrNonExistentDirectory>;
+
+def err_drv_unsupported_linker : Error<"unsupported value '%0' for -linker option">;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to