DiagnosticsEngine &Diags;
+ enum DriverMode {
+ GCCMode,
+ GXXMode,
+ CPPMode
+ } Mode;
+
public:
// Diag - Forwarding function for diagnostics.
DiagnosticBuilder Diag(unsigned DiagID) const {
InputList;
/// Whether the driver should follow g++ like behavior.
- unsigned CCCIsCXX : 1;
+ bool CCCIsCXX() const { return Mode == GXXMode; }
/// Whether the driver is just the preprocessor.
- unsigned CCCIsCPP : 1;
+ bool CCCIsCPP() const { return Mode == CPPMode; }
/// Echo commands while executing (in -v style).
unsigned CCCEcho : 1;
/// @name Driver Steps
/// @{
+ /// ParseDriverMode - Look for and handle the driver mode option in Args.
+ void ParseDriverMode(ArrayRef<const char *> Args);
+
/// ParseArgStrings - Parse the given list of strings into an
/// ArgList.
llvm::opt::InputArgList *ParseArgStrings(ArrayRef<const char *> Args);
Group<ccc_Group>, HelpText<"DEBUG/DEVELOPMENT OPTIONS">;
class CCCDriverOpt : Group<ccc_driver_Group>, Flags<[DriverOption, HelpHidden]>;
-def ccc_cxx : Flag<["-"], "ccc-cxx">, CCCDriverOpt,
- HelpText<"Act as a C++ driver">;
+def driver_mode : Joined<["--"], "driver-mode=">, CCCDriverOpt,
+ HelpText<"Set the driver mode to either 'gcc', 'g++' or 'cpp'">;
def ccc_echo : Flag<["-"], "ccc-echo">, CCCDriverOpt,
HelpText<"Echo commands before running them">;
def ccc_gcc_name : Separate<["-"], "ccc-gcc-name">, CCCDriverOpt,
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
DefaultImageName(DefaultImageName),
DriverTitle("clang LLVM compiler"),
CCPrintOptionsFilename(0), CCPrintHeadersFilename(0),
- CCLogDiagnosticsFilename(0), CCCIsCXX(false),
- CCCIsCPP(false),CCCEcho(false), CCCPrintBindings(false),
+ CCLogDiagnosticsFilename(0), Mode(GCCMode),
+ CCCEcho(false), CCCPrintBindings(false),
CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false),
CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true),
CCCUsePCH(true), SuppressMissingInputWarning(false) {
delete I->second;
}
+void Driver::ParseDriverMode(ArrayRef<const char *> Args) {
+ const std::string OptName =
+ getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
+
+ for (size_t I = 0, E = Args.size(); I != E; ++I) {
+ const StringRef Arg = Args[I];
+ if (!Arg.startswith(OptName))
+ continue;
+
+ const StringRef Value = Arg.drop_front(OptName.size());
+ const unsigned M = llvm::StringSwitch<unsigned>(Value)
+ .Case("gcc", GCCMode)
+ .Case("g++", GXXMode)
+ .Case("cpp", CPPMode)
+ .Default(~0U);
+
+ if (M != ~0U)
+ Mode = static_cast<DriverMode>(M);
+ else
+ Diag(diag::err_drv_unsupported_option_argument) << OptName << Value;
+ }
+}
+
InputArgList *Driver::ParseArgStrings(ArrayRef<const char *> ArgList) {
llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
unsigned MissingArgIndex, MissingArgCount;
phases::ID FinalPhase;
// -{E,M,MM} only run the preprocessor.
- if (CCCIsCPP ||
+ if (CCCIsCPP() ||
(PhaseArg = DAL.getLastArg(options::OPT_E)) ||
(PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM))) {
FinalPhase = phases::Preprocess;
}
}
+ // We look for the driver mode option early, because the mode can affect
+ // how other options are parsed.
+ ParseDriverMode(ArgList.slice(1));
+
// FIXME: What are we going to do with -V and -b?
// FIXME: This stuff needs to go into the Compilation, not the driver.
CCCPrintOptions = Args->hasArg(options::OPT_ccc_print_options);
CCCPrintActions = Args->hasArg(options::OPT_ccc_print_phases);
CCCPrintBindings = Args->hasArg(options::OPT_ccc_print_bindings);
- CCCIsCXX = Args->hasArg(options::OPT_ccc_cxx) || CCCIsCXX;
CCCEcho = Args->hasArg(options::OPT_ccc_echo);
if (const Arg *A = Args->getLastArg(options::OPT_ccc_gcc_name))
CCCGenericGCCName = A->getValue();
"crash backtrace, preprocessed source, and associated run script.";
// Suppress driver output and emit preprocessor output to temp file.
- CCCIsCPP = true;
+ Mode = CPPMode;
CCGenDiagnostics = true;
C.getArgs().AddFlagArg(0, Opts->getOption(options::OPT_frewrite_includes));
//
// Otherwise emit an error but still use a valid type to avoid
// spurious errors (e.g., no inputs).
- if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP)
+ if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP())
Diag(clang::diag::err_drv_unknown_stdin_type);
Ty = types::TY_C;
} else {
Ty = TC.LookupTypeForExtension(Ext + 1);
if (Ty == types::TY_INVALID) {
- if (CCCIsCPP)
+ if (CCCIsCPP())
Ty = types::TY_C;
else
Ty = types::TY_Object;
// If the driver is invoked as C++ compiler (like clang++ or c++) it
// should autodetect some input files as C++ for g++ compatibility.
- if (CCCIsCXX) {
+ if (CCCIsCXX()) {
types::ID OldTy = Ty;
Ty = types::lookupCXXTypeForCType(Ty);
}
}
}
- if (CCCIsCPP && Inputs.empty()) {
+ if (CCCIsCPP() && Inputs.empty()) {
// If called as standalone preprocessor, stdin is processed
// if no other input is present.
unsigned Index = Args.getBaseArgs().MakeIndex("-");
// Special case when final phase determined by binary name, rather than
// by a command-line argument with a corresponding Arg.
- if (CCCIsCPP)
+ if (CCCIsCPP())
Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
<< InputArg->getAsString(Args)
<< getPhaseName(InitialPhase);
// Claim -### here.
(void) C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
+ // Claim --driver-mode, it was handled earlier.
+ (void) C.getArgs().hasArg(options::OPT_driver_mode);
+
for (ArgList::const_iterator it = C.getArgs().begin(), ie = C.getArgs().end();
it != ie; ++it) {
Arg *A = *it;
/// arguments that is shared with gcc.
static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
- if (!Args.hasArg(options::OPT_E) && !D.CCCIsCPP)
+ if (!Args.hasArg(options::OPT_E) && !D.CCCIsCPP())
D.Diag(diag::err_drv_argument_only_allowed_with)
<< A->getAsString(Args) << "-E";
}
const char *GCCName;
if (!customGCCName.empty())
GCCName = customGCCName.c_str();
- else if (D.CCCIsCXX) {
+ else if (D.CCCIsCXX()) {
GCCName = "g++";
} else
GCCName = "gcc";
// Libraries
//----------------------------------------------------------------------------
if (incStdLib && incDefLibs) {
- if (D.CCCIsCXX) {
+ if (D.CCCIsCXX()) {
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
CmdArgs.push_back("-lm");
}
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
- if (getToolChain().getDriver().CCCIsCXX)
+ if (getToolChain().getDriver().CCCIsCXX())
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
// link_ssp spec is empty.
CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o"));
CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
}
- if (getToolChain().getDriver().CCCIsCXX)
+ if (getToolChain().getDriver().CCCIsCXX())
CmdArgs.push_back(Args.MakeArgString(LibPath + "cxa_finalize.o"));
}
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
- if (getToolChain().getDriver().CCCIsCXX)
+ if (getToolChain().getDriver().CCCIsCXX())
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
CmdArgs.push_back("-lgcc_s");
if (!Args.hasArg(options::OPT_shared)) {
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
- if (D.CCCIsCXX) {
+ if (D.CCCIsCXX()) {
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
if (Args.hasArg(options::OPT_pg))
CmdArgs.push_back("-lm_p");
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
- if (D.CCCIsCXX) {
+ if (D.CCCIsCXX()) {
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
if (Args.hasArg(options::OPT_pg))
CmdArgs.push_back("-lm_p");
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
- if (D.CCCIsCXX) {
+ if (D.CCCIsCXX()) {
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
if (Args.hasArg(options::OPT_pg))
CmdArgs.push_back("-lm_p");
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
- if (D.CCCIsCXX) {
+ if (D.CCCIsCXX()) {
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
CmdArgs.push_back("-lm");
}
bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;
bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
Args.hasArg(options::OPT_static);
- if (!D.CCCIsCXX)
+ if (!D.CCCIsCXX())
CmdArgs.push_back("-lgcc");
if (StaticLibgcc || isAndroid) {
- if (D.CCCIsCXX)
+ if (D.CCCIsCXX())
CmdArgs.push_back("-lgcc");
} else {
- if (!D.CCCIsCXX)
+ if (!D.CCCIsCXX())
CmdArgs.push_back("--as-needed");
CmdArgs.push_back("-lgcc_s");
- if (!D.CCCIsCXX)
+ if (!D.CCCIsCXX())
CmdArgs.push_back("--no-as-needed");
}
if (StaticLibgcc && !isAndroid)
CmdArgs.push_back("-lgcc_eh");
- else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX)
+ else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
CmdArgs.push_back("-lgcc");
// According to Android ABI, we have to link with libdl if we are
// Call these before we add the C++ ABI library.
if (Sanitize.needsUbsanRt())
- addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX,
+ addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX(),
Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
Sanitize.needsMsanRt() || Sanitize.needsLsanRt());
if (Sanitize.needsAsanRt())
// The profile runtime also needs access to system libraries.
addProfileRTLinux(getToolChain(), Args, CmdArgs);
- if (D.CCCIsCXX &&
+ if (D.CCCIsCXX() &&
!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
- if (D.CCCIsCXX) {
+ if (D.CCCIsCXX()) {
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
CmdArgs.push_back("-lm");
}
}
}
- if (D.CCCIsCXX) {
+ if (D.CCCIsCXX()) {
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
CmdArgs.push_back("-lm");
}
-// REQUIRES: shell
-// RUN: ln -sf %clang %T/clang-cpp
-
// PR13529: Don't crash.
-// RUN: %T/clang-cpp -lfoo -M %s 2>&1 | FileCheck --check-prefix=CHECK-PR13529 %s
+// RUN: %clang_cpp -lfoo -M %s 2>&1 | FileCheck --check-prefix=CHECK-PR13529 %s
// CHECK-PR13529: warning: -lfoo: 'linker' input unused in cpp mode
// CHECK001: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include"
// CHECK001-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin{{/|\\}}hexagon-as"
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: %clangxx -### -target hexagon-unknown-elf \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK002 %s
// CHECK004-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include"
// CHECK004-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin{{/|\\}}hexagon-as"
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: %clangxx -### -target hexagon-unknown-elf \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -nostdlibinc \
// RUN: %s 2>&1 \
// CHECK005-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include"
// CHECK005-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin{{/|\\}}hexagon-as"
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: %clangxx -### -target hexagon-unknown-elf \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -nostdinc++ \
// RUN: %s 2>&1 \
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Defaults for C++
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: %clangxx -### -target hexagon-unknown-elf \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK012 %s
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// -nostdlib, -nostartfiles, -nodefaultlibs
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: %clangxx -### -target hexagon-unknown-elf \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -nostdlib \
// RUN: %s 2>&1 \
// CHECK017-NOT: "--end-group"
// CHECK017-NOT: fini.o
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: %clangxx -### -target hexagon-unknown-elf \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -nostartfiles \
// RUN: %s 2>&1 \
// CHECK018: "--end-group"
// CHECK018-NOT: fini.o
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: %clangxx -### -target hexagon-unknown-elf \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -nodefaultlibs \
// RUN: %s 2>&1 \
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Other args to pass to linker
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-elf \
+// RUN: %clangxx -### -target hexagon-unknown-elf \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -s \
// RUN: -Tbss 0xdead -Tdata 0xbeef -Ttext 0xcafe \
// CHECK001: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include"
// CHECK001-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin{{/|\\}}hexagon-as"
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-linux \
+// RUN: %clangxx -### -target hexagon-unknown-linux \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK002 %s
// CHECK004-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include"
// CHECK004-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin{{/|\\}}hexagon-as"
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-linux \
+// RUN: %clangxx -### -target hexagon-unknown-linux \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -nostdlibinc \
// RUN: %s 2>&1 \
// CHECK005-NOT: "-internal-externc-isystem" "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/hexagon/include"
// CHECK005-NEXT: "{{.*}}/Inputs/hexagon_tree/qc/bin/../../gnu/bin{{/|\\}}hexagon-as"
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-linux \
+// RUN: %clangxx -### -target hexagon-unknown-linux \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -nostdinc++ \
// RUN: %s 2>&1 \
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Defaults for C++
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-linux \
+// RUN: %clangxx -### -target hexagon-unknown-linux \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK012 %s
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// -nostdlib, -nostartfiles, -nodefaultlibs
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-linux \
+// RUN: %clangxx -### -target hexagon-unknown-linux \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -nostdlib \
// RUN: %s 2>&1 \
// CHECK017-NOT: "--end-group"
// CHECK017-NOT: fini.o
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-linux \
+// RUN: %clangxx -### -target hexagon-unknown-linux \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -nostartfiles \
// RUN: %s 2>&1 \
// CHECK018: "--end-group"
// CHECK018-NOT: fini.o
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-linux \
+// RUN: %clangxx -### -target hexagon-unknown-linux \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -nodefaultlibs \
// RUN: %s 2>&1 \
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Other args to pass to linker
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// RUN: %clang -ccc-cxx -x c++ -### -target hexagon-unknown-linux \
+// RUN: %clangxx -### -target hexagon-unknown-linux \
// RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
// RUN: -s \
// RUN: -Tbss 0xdead -Tdata 0xbeef -Ttext 0xcafe \
// RUN: %clang --help | FileCheck %s -check-prefix=HELP
// HELP: isystem
// HELP-NOT: ast-dump
-// HELP-NOT: ccc-cxx
+// HELP-NOT: driver-mode
// RUN: %clang --help-hidden | FileCheck %s -check-prefix=HELP-HIDDEN
-// HELP-HIDDEN: ccc-cxx
+// HELP-HIDDEN: driver-mode
// RUN: %clang -dumpversion | FileCheck %s -check-prefix=DUMPVERSION
// DUMPVERSION: 4.2.1
config.substitutions.append( ('%clang_cc1', '%s -cc1 -internal-isystem %s'
% (config.clang,
getClangBuiltinIncludeDir(config.clang))) )
+config.substitutions.append( ('%clang_cpp', ' ' + config.clang +
+ ' --driver-mode=cpp '))
config.substitutions.append( ('%clangxx', ' ' + config.clang +
- ' -ccc-cxx '))
+ ' --driver-mode=g++ '))
config.substitutions.append( ('%clang', ' ' + config.clang + ' ') )
config.substitutions.append( ('%test_debuginfo', ' ' + config.llvm_src_root + '/utils/test_debuginfo.pl ') )
config.substitutions.append(
(' %clang-cc1 ',
"""*** invalid substitution, use '%clang_cc1'. ***""") )
+config.substitutions.append(
+ (' %clang-cpp ',
+ """*** invalid substitution, use '%clang_cpp'. ***""") )
###
// is gets added via -target as implicit first argument.
static const struct {
const char *Suffix;
- bool IsCXX;
- bool IsCPP;
+ const char *ModeFlag;
} suffixes [] = {
- { "clang", false, false },
- { "clang++", true, false },
- { "clang-c++", true, false },
- { "clang-cc", false, false },
- { "clang-cpp", false, true },
- { "clang-g++", true, false },
- { "clang-gcc", false, false },
- { "cc", false, false },
- { "cpp", false, true },
- { "++", true, false },
+ { "clang", 0 },
+ { "clang++", "--driver-mode=g++" },
+ { "clang-c++", "--driver-mode=g++" },
+ { "clang-cc", 0 },
+ { "clang-cpp", "--driver-mode=cpp" },
+ { "clang-g++", "--driver-mode=g++" },
+ { "clang-gcc", 0 },
+ { "cc", 0 },
+ { "cpp", "--driver-mode=cpp" },
+ { "++", "--driver-mode=g++" },
};
std::string ProgName(llvm::sys::path::stem(ArgVector[0]));
StringRef ProgNameRef(ProgName);
for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
if (ProgNameRef.endswith(suffixes[i].Suffix)) {
FoundMatch = true;
- if (suffixes[i].IsCXX)
- TheDriver.CCCIsCXX = true;
- if (suffixes[i].IsCPP)
- TheDriver.CCCIsCPP = true;
+ SmallVectorImpl<const char *>::iterator it = ArgVector.begin();
+ if (it != ArgVector.end())
+ ++it;
+ if (suffixes[i].ModeFlag)
+ ArgVector.insert(it, suffixes[i].ModeFlag);
break;
}
}