2009-11-17 09:02:29 +03:00
|
|
|
//===--- CompilerInvocation.cpp -------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/Frontend/CompilerInvocation.h"
|
2009-12-01 06:16:53 +03:00
|
|
|
#include "clang/Basic/Diagnostic.h"
|
|
|
|
#include "clang/Basic/Version.h"
|
|
|
|
#include "clang/Driver/Arg.h"
|
|
|
|
#include "clang/Driver/ArgList.h"
|
|
|
|
#include "clang/Driver/CC1Options.h"
|
|
|
|
#include "clang/Driver/DriverDiagnostic.h"
|
|
|
|
#include "clang/Driver/OptTable.h"
|
|
|
|
#include "clang/Driver/Option.h"
|
|
|
|
#include "clang/Frontend/CompilerInvocation.h"
|
|
|
|
#include "clang/Frontend/LangStandard.h"
|
2010-08-19 03:57:17 +04:00
|
|
|
#include "clang/Serialization/ASTReader.h"
|
2009-12-01 06:16:53 +03:00
|
|
|
#include "llvm/ADT/OwningPtr.h"
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2009-11-17 09:02:29 +03:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2009-12-01 06:16:53 +03:00
|
|
|
#include "llvm/ADT/StringSwitch.h"
|
2010-08-30 13:42:39 +04:00
|
|
|
#include "llvm/ADT/Triple.h"
|
2009-11-17 09:02:29 +03:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2009-12-01 06:16:53 +03:00
|
|
|
#include "llvm/System/Host.h"
|
|
|
|
#include "llvm/System/Path.h"
|
2009-11-17 09:02:29 +03:00
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
static const char *getAnalysisName(Analyses Kind) {
|
|
|
|
switch (Kind) {
|
|
|
|
default:
|
2009-12-12 08:05:38 +03:00
|
|
|
llvm_unreachable("Unknown analysis kind!");
|
2009-11-17 09:02:29 +03:00
|
|
|
#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\
|
2009-11-23 01:08:20 +03:00
|
|
|
case NAME: return "-" CMDFLAG;
|
2009-11-17 09:02:29 +03:00
|
|
|
#include "clang/Frontend/Analyses.def"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *getAnalysisStoreName(AnalysisStores Kind) {
|
|
|
|
switch (Kind) {
|
|
|
|
default:
|
2009-12-12 08:05:38 +03:00
|
|
|
llvm_unreachable("Unknown analysis store!");
|
2009-11-17 09:02:29 +03:00
|
|
|
#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) \
|
|
|
|
case NAME##Model: return CMDFLAG;
|
|
|
|
#include "clang/Frontend/Analyses.def"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *getAnalysisConstraintName(AnalysisConstraints Kind) {
|
|
|
|
switch (Kind) {
|
|
|
|
default:
|
2009-12-12 08:05:38 +03:00
|
|
|
llvm_unreachable("Unknown analysis constraints!");
|
2009-11-17 09:02:29 +03:00
|
|
|
#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
|
|
|
|
case NAME##Model: return CMDFLAG;
|
|
|
|
#include "clang/Frontend/Analyses.def"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *getAnalysisDiagClientName(AnalysisDiagClients Kind) {
|
|
|
|
switch (Kind) {
|
|
|
|
default:
|
2009-12-12 08:05:38 +03:00
|
|
|
llvm_unreachable("Unknown analysis client!");
|
2009-11-17 09:02:29 +03:00
|
|
|
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREATE) \
|
|
|
|
case PD_##NAME: return CMDFLAG;
|
|
|
|
#include "clang/Frontend/Analyses.def"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-01 06:16:53 +03:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Serialization (to args)
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-11-17 09:02:29 +03:00
|
|
|
static void AnalyzerOptsToArgs(const AnalyzerOptions &Opts,
|
|
|
|
std::vector<std::string> &Res) {
|
|
|
|
for (unsigned i = 0, e = Opts.AnalysisList.size(); i != e; ++i)
|
|
|
|
Res.push_back(getAnalysisName(Opts.AnalysisList[i]));
|
|
|
|
if (Opts.AnalysisStoreOpt != BasicStoreModel) {
|
|
|
|
Res.push_back("-analyzer-store");
|
|
|
|
Res.push_back(getAnalysisStoreName(Opts.AnalysisStoreOpt));
|
|
|
|
}
|
|
|
|
if (Opts.AnalysisConstraintsOpt != RangeConstraintsModel) {
|
|
|
|
Res.push_back("-analyzer-constraints");
|
|
|
|
Res.push_back(getAnalysisConstraintName(Opts.AnalysisConstraintsOpt));
|
|
|
|
}
|
|
|
|
if (Opts.AnalysisDiagOpt != PD_HTML) {
|
|
|
|
Res.push_back("-analyzer-output");
|
|
|
|
Res.push_back(getAnalysisDiagClientName(Opts.AnalysisDiagOpt));
|
|
|
|
}
|
|
|
|
if (!Opts.AnalyzeSpecificFunction.empty()) {
|
|
|
|
Res.push_back("-analyze-function");
|
|
|
|
Res.push_back(Opts.AnalyzeSpecificFunction);
|
|
|
|
}
|
|
|
|
if (Opts.AnalyzeAll)
|
|
|
|
Res.push_back("-analyzer-opt-analyze-headers");
|
|
|
|
if (Opts.AnalyzerDisplayProgress)
|
|
|
|
Res.push_back("-analyzer-display-progress");
|
2009-12-08 01:06:12 +03:00
|
|
|
if (Opts.AnalyzeNestedBlocks)
|
|
|
|
Res.push_back("-analyzer-opt-analyze-nested-blocks");
|
2010-09-10 04:44:44 +04:00
|
|
|
if (Opts.AnalyzerStats)
|
|
|
|
Res.push_back("-analyzer-stats");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.EagerlyAssume)
|
|
|
|
Res.push_back("-analyzer-eagerly-assume");
|
2009-11-19 08:32:09 +03:00
|
|
|
if (!Opts.PurgeDead)
|
|
|
|
Res.push_back("-analyzer-no-purge-dead");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.TrimGraph)
|
|
|
|
Res.push_back("-trim-egraph");
|
|
|
|
if (Opts.VisualizeEGDot)
|
|
|
|
Res.push_back("-analyzer-viz-egraph-graphviz");
|
|
|
|
if (Opts.VisualizeEGDot)
|
|
|
|
Res.push_back("-analyzer-viz-egraph-ubigraph");
|
|
|
|
if (Opts.EnableExperimentalChecks)
|
|
|
|
Res.push_back("-analyzer-experimental-checks");
|
|
|
|
if (Opts.EnableExperimentalInternalChecks)
|
2009-11-23 01:08:20 +03:00
|
|
|
Res.push_back("-analyzer-experimental-internal-checks");
|
2010-08-07 02:23:07 +04:00
|
|
|
if (Opts.IdempotentOps)
|
|
|
|
Res.push_back("-analyzer-check-idempotent-operations");
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void CodeGenOptsToArgs(const CodeGenOptions &Opts,
|
|
|
|
std::vector<std::string> &Res) {
|
|
|
|
if (Opts.DebugInfo)
|
|
|
|
Res.push_back("-g");
|
|
|
|
if (Opts.DisableLLVMOpts)
|
|
|
|
Res.push_back("-disable-llvm-optzns");
|
|
|
|
if (Opts.DisableRedZone)
|
|
|
|
Res.push_back("-disable-red-zone");
|
2009-12-18 05:43:17 +03:00
|
|
|
if (!Opts.DwarfDebugFlags.empty()) {
|
|
|
|
Res.push_back("-dwarf-debug-flags");
|
|
|
|
Res.push_back(Opts.DwarfDebugFlags);
|
|
|
|
}
|
2009-11-17 09:02:29 +03:00
|
|
|
if (!Opts.MergeAllConstants)
|
|
|
|
Res.push_back("-fno-merge-all-constants");
|
2009-11-20 20:23:30 +03:00
|
|
|
if (Opts.NoCommon)
|
|
|
|
Res.push_back("-fno-common");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.NoImplicitFloat)
|
|
|
|
Res.push_back("-no-implicit-float");
|
2010-07-01 05:31:45 +04:00
|
|
|
if (Opts.OmitLeafFramePointer)
|
|
|
|
Res.push_back("-momit-leaf-frame-pointer");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.OptimizeSize) {
|
|
|
|
assert(Opts.OptimizationLevel == 2 && "Invalid options!");
|
|
|
|
Res.push_back("-Os");
|
2009-11-19 23:54:59 +03:00
|
|
|
} else if (Opts.OptimizationLevel != 0)
|
|
|
|
Res.push_back("-O" + llvm::utostr(Opts.OptimizationLevel));
|
2009-11-29 05:38:34 +03:00
|
|
|
if (!Opts.MainFileName.empty()) {
|
|
|
|
Res.push_back("-main-file-name");
|
|
|
|
Res.push_back(Opts.MainFileName);
|
|
|
|
}
|
2009-11-17 09:02:29 +03:00
|
|
|
// SimplifyLibCalls is only derived.
|
|
|
|
// TimePasses is only derived.
|
|
|
|
// UnitAtATime is unused.
|
|
|
|
// Inlining is only derived.
|
2010-08-08 03:08:14 +04:00
|
|
|
|
|
|
|
// UnrollLoops is derived, but also accepts an option, no
|
|
|
|
// harm in pushing it back here.
|
|
|
|
if (Opts.UnrollLoops)
|
|
|
|
Res.push_back("-funroll-loops");
|
2010-04-13 04:38:24 +04:00
|
|
|
if (Opts.DataSections)
|
|
|
|
Res.push_back("-fdata-sections");
|
|
|
|
if (Opts.FunctionSections)
|
|
|
|
Res.push_back("-ffunction-sections");
|
2009-11-29 10:18:39 +03:00
|
|
|
if (Opts.AsmVerbose)
|
|
|
|
Res.push_back("-masm-verbose");
|
|
|
|
if (!Opts.CodeModel.empty()) {
|
|
|
|
Res.push_back("-mcode-model");
|
|
|
|
Res.push_back(Opts.CodeModel);
|
|
|
|
}
|
2010-03-20 07:15:41 +03:00
|
|
|
if (!Opts.CXAAtExit)
|
|
|
|
Res.push_back("-fno-use-cxa-atexit");
|
|
|
|
if (Opts.CXXCtorDtorAliases)
|
|
|
|
Res.push_back("-mconstructor-aliases");
|
2009-11-29 10:18:39 +03:00
|
|
|
if (!Opts.DebugPass.empty()) {
|
|
|
|
Res.push_back("-mdebug-pass");
|
|
|
|
Res.push_back(Opts.DebugPass);
|
|
|
|
}
|
|
|
|
if (Opts.DisableFPElim)
|
|
|
|
Res.push_back("-mdisable-fp-elim");
|
2009-11-30 11:42:00 +03:00
|
|
|
if (!Opts.FloatABI.empty()) {
|
|
|
|
Res.push_back("-mfloat-abi");
|
|
|
|
Res.push_back(Opts.FloatABI);
|
|
|
|
}
|
2009-11-29 10:18:39 +03:00
|
|
|
if (!Opts.LimitFloatPrecision.empty()) {
|
|
|
|
Res.push_back("-mlimit-float-precision");
|
|
|
|
Res.push_back(Opts.LimitFloatPrecision);
|
|
|
|
}
|
|
|
|
if (Opts.NoZeroInitializedInBSS)
|
|
|
|
Res.push_back("-mno-zero-initialized-bss");
|
2010-04-24 21:56:46 +04:00
|
|
|
switch (Opts.getObjCDispatchMethod()) {
|
|
|
|
case CodeGenOptions::Legacy:
|
|
|
|
break;
|
|
|
|
case CodeGenOptions::Mixed:
|
|
|
|
Res.push_back("-fobjc-dispatch-method=mixed");
|
|
|
|
break;
|
|
|
|
case CodeGenOptions::NonLegacy:
|
|
|
|
Res.push_back("-fobjc-dispatch-method=non-legacy");
|
|
|
|
break;
|
|
|
|
}
|
2010-05-27 09:39:39 +04:00
|
|
|
if (Opts.RelaxAll)
|
|
|
|
Res.push_back("-mrelax-all");
|
2009-11-30 11:42:00 +03:00
|
|
|
if (Opts.SoftFloat)
|
|
|
|
Res.push_back("-msoft-float");
|
2009-11-29 10:18:39 +03:00
|
|
|
if (Opts.UnwindTables)
|
|
|
|
Res.push_back("-munwind-tables");
|
|
|
|
if (Opts.RelocationModel != "pic") {
|
|
|
|
Res.push_back("-mrelocation-model");
|
|
|
|
Res.push_back(Opts.RelocationModel);
|
|
|
|
}
|
2010-02-13 06:50:24 +03:00
|
|
|
if (!Opts.VerifyModule)
|
|
|
|
Res.push_back("-disable-llvm-verifier");
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void DependencyOutputOptsToArgs(const DependencyOutputOptions &Opts,
|
|
|
|
std::vector<std::string> &Res) {
|
|
|
|
if (Opts.IncludeSystemHeaders)
|
|
|
|
Res.push_back("-sys-header-deps");
|
|
|
|
if (Opts.UsePhonyTargets)
|
|
|
|
Res.push_back("-MP");
|
|
|
|
if (!Opts.OutputFile.empty()) {
|
|
|
|
Res.push_back("-dependency-file");
|
|
|
|
Res.push_back(Opts.OutputFile);
|
|
|
|
}
|
|
|
|
for (unsigned i = 0, e = Opts.Targets.size(); i != e; ++i) {
|
|
|
|
Res.push_back("-MT");
|
|
|
|
Res.push_back(Opts.Targets[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DiagnosticOptsToArgs(const DiagnosticOptions &Opts,
|
|
|
|
std::vector<std::string> &Res) {
|
|
|
|
if (Opts.IgnoreWarnings)
|
|
|
|
Res.push_back("-w");
|
|
|
|
if (Opts.NoRewriteMacros)
|
|
|
|
Res.push_back("-Wno-rewrite-macros");
|
|
|
|
if (Opts.Pedantic)
|
|
|
|
Res.push_back("-pedantic");
|
|
|
|
if (Opts.PedanticErrors)
|
|
|
|
Res.push_back("-pedantic-errors");
|
|
|
|
if (!Opts.ShowColumn)
|
|
|
|
Res.push_back("-fno-show-column");
|
|
|
|
if (!Opts.ShowLocation)
|
|
|
|
Res.push_back("-fno-show-source-location");
|
|
|
|
if (!Opts.ShowCarets)
|
|
|
|
Res.push_back("-fno-caret-diagnostics");
|
|
|
|
if (!Opts.ShowFixits)
|
|
|
|
Res.push_back("-fno-diagnostics-fixit-info");
|
|
|
|
if (Opts.ShowSourceRanges)
|
|
|
|
Res.push_back("-fdiagnostics-print-source-range-info");
|
2010-08-20 00:24:43 +04:00
|
|
|
if (Opts.ShowParseableFixits)
|
|
|
|
Res.push_back("-fdiagnostics-parseable-fixits");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.ShowColors)
|
|
|
|
Res.push_back("-fcolor-diagnostics");
|
|
|
|
if (Opts.VerifyDiagnostics)
|
|
|
|
Res.push_back("-verify");
|
|
|
|
if (Opts.ShowOptionNames)
|
|
|
|
Res.push_back("-fdiagnostics-show-option");
|
2010-05-05 01:55:25 +04:00
|
|
|
if (Opts.ShowCategories == 1)
|
|
|
|
Res.push_back("-fdiagnostics-show-category=id");
|
|
|
|
else if (Opts.ShowCategories == 2)
|
|
|
|
Res.push_back("-fdiagnostics-show-category=name");
|
2010-04-08 00:37:06 +04:00
|
|
|
if (Opts.ErrorLimit) {
|
|
|
|
Res.push_back("-ferror-limit");
|
|
|
|
Res.push_back(llvm::utostr(Opts.ErrorLimit));
|
|
|
|
}
|
2010-05-04 21:13:42 +04:00
|
|
|
if (Opts.MacroBacktraceLimit
|
|
|
|
!= DiagnosticOptions::DefaultMacroBacktraceLimit) {
|
|
|
|
Res.push_back("-fmacro-backtrace-limit");
|
|
|
|
Res.push_back(llvm::utostr(Opts.MacroBacktraceLimit));
|
|
|
|
}
|
|
|
|
if (Opts.TemplateBacktraceLimit
|
|
|
|
!= DiagnosticOptions::DefaultTemplateBacktraceLimit) {
|
2010-04-20 11:18:24 +04:00
|
|
|
Res.push_back("-ftemplate-backtrace-limit");
|
|
|
|
Res.push_back(llvm::utostr(Opts.TemplateBacktraceLimit));
|
|
|
|
}
|
|
|
|
|
2010-01-13 06:06:50 +03:00
|
|
|
if (Opts.TabStop != DiagnosticOptions::DefaultTabStop) {
|
2010-01-10 00:54:33 +03:00
|
|
|
Res.push_back("-ftabstop");
|
|
|
|
Res.push_back(llvm::utostr(Opts.TabStop));
|
|
|
|
}
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.MessageLength) {
|
|
|
|
Res.push_back("-fmessage-length");
|
|
|
|
Res.push_back(llvm::utostr(Opts.MessageLength));
|
|
|
|
}
|
|
|
|
if (!Opts.DumpBuildInformation.empty()) {
|
|
|
|
Res.push_back("-dump-build-information");
|
|
|
|
Res.push_back(Opts.DumpBuildInformation);
|
|
|
|
}
|
|
|
|
for (unsigned i = 0, e = Opts.Warnings.size(); i != e; ++i)
|
|
|
|
Res.push_back("-W" + Opts.Warnings[i]);
|
|
|
|
}
|
|
|
|
|
2010-06-08 03:22:09 +04:00
|
|
|
static const char *getInputKindName(InputKind Kind) {
|
2009-11-17 09:02:29 +03:00
|
|
|
switch (Kind) {
|
2010-06-08 03:22:09 +04:00
|
|
|
case IK_None: break;
|
|
|
|
case IK_AST: return "ast";
|
|
|
|
case IK_Asm: return "assembler-with-cpp";
|
|
|
|
case IK_C: return "c";
|
|
|
|
case IK_CXX: return "c++";
|
2010-06-08 03:26:47 +04:00
|
|
|
case IK_LLVM_IR: return "ir";
|
2010-06-08 03:22:09 +04:00
|
|
|
case IK_ObjC: return "objective-c";
|
|
|
|
case IK_ObjCXX: return "objective-c++";
|
|
|
|
case IK_OpenCL: return "cl";
|
|
|
|
case IK_PreprocessedC: return "cpp-output";
|
|
|
|
case IK_PreprocessedCXX: return "c++-cpp-output";
|
|
|
|
case IK_PreprocessedObjC: return "objective-c-cpp-output";
|
|
|
|
case IK_PreprocessedObjCXX:return "objective-c++-cpp-output";
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
|
|
|
|
2009-12-12 08:05:38 +03:00
|
|
|
llvm_unreachable("Unexpected language kind!");
|
2009-11-17 09:02:29 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *getActionName(frontend::ActionKind Kind) {
|
|
|
|
switch (Kind) {
|
|
|
|
case frontend::PluginAction:
|
|
|
|
case frontend::InheritanceView:
|
2009-12-12 08:05:38 +03:00
|
|
|
llvm_unreachable("Invalid kind!");
|
2009-11-17 09:02:29 +03:00
|
|
|
|
|
|
|
case frontend::ASTDump: return "-ast-dump";
|
|
|
|
case frontend::ASTPrint: return "-ast-print";
|
|
|
|
case frontend::ASTPrintXML: return "-ast-print-xml";
|
|
|
|
case frontend::ASTView: return "-ast-view";
|
2010-05-07 19:41:56 +04:00
|
|
|
case frontend::BoostCon: return "-boostcon";
|
2010-08-16 22:17:11 +04:00
|
|
|
case frontend::CreateModule: return "-create-module";
|
2009-11-17 09:02:29 +03:00
|
|
|
case frontend::DumpRawTokens: return "-dump-raw-tokens";
|
|
|
|
case frontend::DumpTokens: return "-dump-tokens";
|
|
|
|
case frontend::EmitAssembly: return "-S";
|
|
|
|
case frontend::EmitBC: return "-emit-llvm-bc";
|
|
|
|
case frontend::EmitHTML: return "-emit-html";
|
|
|
|
case frontend::EmitLLVM: return "-emit-llvm";
|
|
|
|
case frontend::EmitLLVMOnly: return "-emit-llvm-only";
|
2010-05-25 22:41:01 +04:00
|
|
|
case frontend::EmitCodeGenOnly: return "-emit-codegen-only";
|
2010-02-03 04:18:43 +03:00
|
|
|
case frontend::EmitObj: return "-emit-obj";
|
2009-11-17 09:02:29 +03:00
|
|
|
case frontend::FixIt: return "-fixit";
|
|
|
|
case frontend::GeneratePCH: return "-emit-pch";
|
|
|
|
case frontend::GeneratePTH: return "-emit-pth";
|
2010-03-19 22:44:04 +03:00
|
|
|
case frontend::InitOnly: return "-init-only";
|
2009-11-17 09:02:29 +03:00
|
|
|
case frontend::ParseSyntaxOnly: return "-fsyntax-only";
|
|
|
|
case frontend::PrintDeclContext: return "-print-decl-contexts";
|
2010-07-21 00:18:03 +04:00
|
|
|
case frontend::PrintPreamble: return "-print-preamble";
|
2009-11-17 09:02:29 +03:00
|
|
|
case frontend::PrintPreprocessedInput: return "-E";
|
|
|
|
case frontend::RewriteMacros: return "-rewrite-macros";
|
|
|
|
case frontend::RewriteObjC: return "-rewrite-objc";
|
|
|
|
case frontend::RewriteTest: return "-rewrite-test";
|
|
|
|
case frontend::RunAnalysis: return "-analyze";
|
|
|
|
case frontend::RunPreprocessorOnly: return "-Eonly";
|
|
|
|
}
|
|
|
|
|
2009-12-12 08:05:38 +03:00
|
|
|
llvm_unreachable("Unexpected language kind!");
|
2009-11-17 09:02:29 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void FrontendOptsToArgs(const FrontendOptions &Opts,
|
|
|
|
std::vector<std::string> &Res) {
|
|
|
|
if (Opts.DisableFree)
|
|
|
|
Res.push_back("-disable-free");
|
|
|
|
if (Opts.RelocatablePCH)
|
|
|
|
Res.push_back("-relocatable-pch");
|
2010-07-09 04:00:58 +04:00
|
|
|
if (Opts.ChainedPCH)
|
|
|
|
Res.push_back("-chained-pch");
|
2009-12-03 10:01:58 +03:00
|
|
|
if (Opts.ShowHelp)
|
|
|
|
Res.push_back("-help");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.ShowMacrosInCodeCompletion)
|
|
|
|
Res.push_back("-code-completion-macros");
|
2010-05-26 01:41:55 +04:00
|
|
|
if (Opts.ShowCodePatternsInCodeCompletion)
|
|
|
|
Res.push_back("-code-completion-patterns");
|
2010-08-15 10:18:01 +04:00
|
|
|
if (!Opts.ShowGlobalSymbolsInCodeCompletion)
|
|
|
|
Res.push_back("-no-code-completion-globals");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.ShowStats)
|
2009-11-25 13:14:52 +03:00
|
|
|
Res.push_back("-print-stats");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.ShowTimers)
|
|
|
|
Res.push_back("-ftime-report");
|
2009-12-03 10:01:58 +03:00
|
|
|
if (Opts.ShowVersion)
|
|
|
|
Res.push_back("-version");
|
2010-08-13 21:31:00 +04:00
|
|
|
if (Opts.FixWhatYouCan)
|
|
|
|
Res.push_back("-fix-what-you-can");
|
2009-11-17 09:02:29 +03:00
|
|
|
|
|
|
|
bool NeedLang = false;
|
|
|
|
for (unsigned i = 0, e = Opts.Inputs.size(); i != e; ++i)
|
|
|
|
if (FrontendOptions::getInputKindForExtension(Opts.Inputs[i].second) !=
|
|
|
|
Opts.Inputs[i].first)
|
|
|
|
NeedLang = true;
|
|
|
|
if (NeedLang) {
|
|
|
|
Res.push_back("-x");
|
|
|
|
Res.push_back(getInputKindName(Opts.Inputs[0].first));
|
|
|
|
}
|
|
|
|
for (unsigned i = 0, e = Opts.Inputs.size(); i != e; ++i) {
|
|
|
|
assert((!NeedLang || Opts.Inputs[i].first == Opts.Inputs[0].first) &&
|
|
|
|
"Unable to represent this input vector!");
|
|
|
|
Res.push_back(Opts.Inputs[i].second);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Opts.OutputFile.empty()) {
|
|
|
|
Res.push_back("-o");
|
|
|
|
Res.push_back(Opts.OutputFile);
|
|
|
|
}
|
|
|
|
if (!Opts.ViewClassInheritance.empty()) {
|
|
|
|
Res.push_back("-cxx-inheritance-view");
|
|
|
|
Res.push_back(Opts.ViewClassInheritance);
|
|
|
|
}
|
|
|
|
if (!Opts.CodeCompletionAt.FileName.empty()) {
|
|
|
|
Res.push_back("-code-completion-at");
|
|
|
|
Res.push_back(Opts.CodeCompletionAt.FileName + ":" +
|
|
|
|
llvm::utostr(Opts.CodeCompletionAt.Line) + ":" +
|
|
|
|
llvm::utostr(Opts.CodeCompletionAt.Column));
|
|
|
|
}
|
|
|
|
if (Opts.ProgramAction != frontend::InheritanceView &&
|
|
|
|
Opts.ProgramAction != frontend::PluginAction)
|
|
|
|
Res.push_back(getActionName(Opts.ProgramAction));
|
|
|
|
if (!Opts.ActionName.empty()) {
|
|
|
|
Res.push_back("-plugin");
|
|
|
|
Res.push_back(Opts.ActionName);
|
2010-06-16 20:59:23 +04:00
|
|
|
for(unsigned i = 0, e = Opts.PluginArgs.size(); i != e; ++i) {
|
|
|
|
Res.push_back("-plugin-arg-" + Opts.ActionName);
|
|
|
|
Res.push_back(Opts.PluginArgs[i]);
|
|
|
|
}
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
2009-12-03 08:11:05 +03:00
|
|
|
for (unsigned i = 0, e = Opts.Plugins.size(); i != e; ++i) {
|
|
|
|
Res.push_back("-load");
|
|
|
|
Res.push_back(Opts.Plugins[i]);
|
|
|
|
}
|
2010-02-09 22:21:46 +03:00
|
|
|
for (unsigned i = 0, e = Opts.ASTMergeFiles.size(); i != e; ++i) {
|
|
|
|
Res.push_back("-ast-merge");
|
|
|
|
Res.push_back(Opts.ASTMergeFiles[i]);
|
|
|
|
}
|
2010-08-16 22:17:11 +04:00
|
|
|
for (unsigned i = 0, e = Opts.Modules.size(); i != e; ++i) {
|
|
|
|
Res.push_back("-import-module");
|
|
|
|
Res.push_back(Opts.Modules[i]);
|
|
|
|
}
|
2010-04-15 10:09:03 +04:00
|
|
|
for (unsigned i = 0, e = Opts.LLVMArgs.size(); i != e; ++i) {
|
|
|
|
Res.push_back("-mllvm");
|
|
|
|
Res.push_back(Opts.LLVMArgs[i]);
|
|
|
|
}
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
|
|
|
|
std::vector<std::string> &Res) {
|
2009-11-19 08:32:21 +03:00
|
|
|
if (Opts.Sysroot != "/") {
|
2009-11-17 09:02:29 +03:00
|
|
|
Res.push_back("-isysroot");
|
|
|
|
Res.push_back(Opts.Sysroot);
|
|
|
|
}
|
|
|
|
|
2010-09-09 21:38:22 +04:00
|
|
|
for (unsigned i = 0, e = Opts.CXXSystemIncludes.size(); i != e; ++i) {
|
|
|
|
Res.push_back("-cxx-system-include");
|
|
|
|
Res.push_back(Opts.CXXSystemIncludes[i]);
|
|
|
|
}
|
|
|
|
|
2009-11-17 09:02:29 +03:00
|
|
|
/// User specified include entries.
|
|
|
|
for (unsigned i = 0, e = Opts.UserEntries.size(); i != e; ++i) {
|
|
|
|
const HeaderSearchOptions::Entry &E = Opts.UserEntries[i];
|
2009-11-26 05:13:54 +03:00
|
|
|
if (E.IsFramework && (E.Group != frontend::Angled || !E.IsUserSupplied))
|
2010-04-08 02:58:06 +04:00
|
|
|
llvm::report_fatal_error("Invalid option set!");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (E.IsUserSupplied) {
|
|
|
|
if (E.Group == frontend::After) {
|
|
|
|
Res.push_back("-idirafter");
|
|
|
|
} else if (E.Group == frontend::Quoted) {
|
2009-11-26 05:13:54 +03:00
|
|
|
Res.push_back("-iquote");
|
2009-11-17 09:02:29 +03:00
|
|
|
} else if (E.Group == frontend::System) {
|
|
|
|
Res.push_back("-isystem");
|
|
|
|
} else {
|
|
|
|
assert(E.Group == frontend::Angled && "Invalid group!");
|
|
|
|
Res.push_back(E.IsFramework ? "-F" : "-I");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (E.Group != frontend::Angled && E.Group != frontend::System)
|
2010-04-08 02:58:06 +04:00
|
|
|
llvm::report_fatal_error("Invalid option set!");
|
2009-11-17 09:02:29 +03:00
|
|
|
Res.push_back(E.Group == frontend::Angled ? "-iwithprefixbefore" :
|
|
|
|
"-iwithprefix");
|
|
|
|
}
|
|
|
|
Res.push_back(E.Path);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Opts.EnvIncPath.empty()) {
|
|
|
|
// FIXME: Provide an option for this, and move env detection to driver.
|
2010-04-08 02:58:06 +04:00
|
|
|
llvm::report_fatal_error("Not yet implemented!");
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
|
|
|
if (!Opts.CEnvIncPath.empty()) {
|
|
|
|
// FIXME: Provide an option for this, and move env detection to driver.
|
2010-04-08 02:58:06 +04:00
|
|
|
llvm::report_fatal_error("Not yet implemented!");
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
|
|
|
if (!Opts.ObjCEnvIncPath.empty()) {
|
|
|
|
// FIXME: Provide an option for this, and move env detection to driver.
|
2010-04-08 02:58:06 +04:00
|
|
|
llvm::report_fatal_error("Not yet implemented!");
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
|
|
|
if (!Opts.CXXEnvIncPath.empty()) {
|
|
|
|
// FIXME: Provide an option for this, and move env detection to driver.
|
2010-04-08 02:58:06 +04:00
|
|
|
llvm::report_fatal_error("Not yet implemented!");
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
|
|
|
if (!Opts.ObjCXXEnvIncPath.empty()) {
|
|
|
|
// FIXME: Provide an option for this, and move env detection to driver.
|
2010-04-08 02:58:06 +04:00
|
|
|
llvm::report_fatal_error("Not yet implemented!");
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
2009-12-15 03:06:45 +03:00
|
|
|
if (!Opts.ResourceDir.empty()) {
|
|
|
|
Res.push_back("-resource-dir");
|
|
|
|
Res.push_back(Opts.ResourceDir);
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
|
|
|
if (!Opts.UseStandardIncludes)
|
|
|
|
Res.push_back("-nostdinc");
|
2010-03-24 23:13:48 +03:00
|
|
|
if (!Opts.UseStandardCXXIncludes)
|
|
|
|
Res.push_back("-nostdinc++");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.Verbose)
|
|
|
|
Res.push_back("-v");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void LangOptsToArgs(const LangOptions &Opts,
|
|
|
|
std::vector<std::string> &Res) {
|
|
|
|
LangOptions DefaultLangOpts;
|
|
|
|
|
|
|
|
// FIXME: Need to set -std to get all the implicit options.
|
|
|
|
|
|
|
|
// FIXME: We want to only pass options relative to the defaults, which
|
|
|
|
// requires constructing a target. :(
|
|
|
|
//
|
|
|
|
// It would be better to push the all target specific choices into the driver,
|
|
|
|
// so that everything below that was more uniform.
|
|
|
|
|
|
|
|
if (Opts.Trigraphs)
|
|
|
|
Res.push_back("-trigraphs");
|
|
|
|
// Implicit based on the input kind:
|
|
|
|
// AsmPreprocessor, CPlusPlus, ObjC1, ObjC2, OpenCL
|
|
|
|
// Implicit based on the input language standard:
|
|
|
|
// BCPLComment, C99, CPlusPlus0x, Digraphs, GNUInline, ImplicitInt, GNUMode
|
|
|
|
if (Opts.DollarIdents)
|
|
|
|
Res.push_back("-fdollars-in-identifiers");
|
2010-04-18 00:17:31 +04:00
|
|
|
if (Opts.GNUMode && !Opts.GNUKeywords)
|
|
|
|
Res.push_back("-fno-gnu-keywords");
|
|
|
|
if (!Opts.GNUMode && Opts.GNUKeywords)
|
|
|
|
Res.push_back("-fgnu-keywords");
|
2009-11-17 12:15:57 +03:00
|
|
|
if (Opts.Microsoft)
|
2009-12-16 23:10:18 +03:00
|
|
|
Res.push_back("-fms-extensions");
|
2010-09-03 03:59:25 +04:00
|
|
|
if (Opts.Borland)
|
|
|
|
Res.push_back("-fborland-extensions");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.ObjCNonFragileABI)
|
|
|
|
Res.push_back("-fobjc-nonfragile-abi");
|
2010-02-09 22:31:38 +03:00
|
|
|
if (Opts.ObjCNonFragileABI2)
|
|
|
|
Res.push_back("-fobjc-nonfragile-abi2");
|
2009-11-17 09:02:29 +03:00
|
|
|
// NoInline is implicit.
|
|
|
|
if (!Opts.CXXOperatorNames)
|
|
|
|
Res.push_back("-fno-operator-names");
|
|
|
|
if (Opts.PascalStrings)
|
|
|
|
Res.push_back("-fpascal-strings");
|
2009-12-12 04:27:46 +03:00
|
|
|
if (Opts.CatchUndefined)
|
|
|
|
Res.push_back("-fcatch-undefined-behavior");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.WritableStrings)
|
|
|
|
Res.push_back("-fwritable-strings");
|
2010-03-15 13:54:44 +03:00
|
|
|
if (Opts.ConstStrings)
|
|
|
|
Res.push_back("-Wwrite-strings");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (!Opts.LaxVectorConversions)
|
|
|
|
Res.push_back("-fno-lax-vector-conversions");
|
|
|
|
if (Opts.AltiVec)
|
|
|
|
Res.push_back("-faltivec");
|
2009-11-19 23:54:59 +03:00
|
|
|
if (Opts.Exceptions)
|
|
|
|
Res.push_back("-fexceptions");
|
2010-02-10 21:48:44 +03:00
|
|
|
if (Opts.SjLjExceptions)
|
|
|
|
Res.push_back("-fsjlj-exceptions");
|
2009-12-02 21:57:08 +03:00
|
|
|
if (!Opts.RTTI)
|
2009-11-19 08:32:09 +03:00
|
|
|
Res.push_back("-fno-rtti");
|
2009-11-17 10:07:28 +03:00
|
|
|
if (!Opts.NeXTRuntime)
|
|
|
|
Res.push_back("-fgnu-runtime");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.Freestanding)
|
|
|
|
Res.push_back("-ffreestanding");
|
|
|
|
if (Opts.NoBuiltin)
|
|
|
|
Res.push_back("-fno-builtin");
|
2009-12-16 19:59:22 +03:00
|
|
|
if (!Opts.AssumeSaneOperatorNew)
|
|
|
|
Res.push_back("-fno-assume-sane-operator-new");
|
2010-02-07 02:23:06 +03:00
|
|
|
if (!Opts.ThreadsafeStatics)
|
|
|
|
Res.push_back("-fno-threadsafe-statics");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.POSIXThreads)
|
|
|
|
Res.push_back("-pthread");
|
2009-11-17 12:15:57 +03:00
|
|
|
if (Opts.Blocks)
|
2009-11-29 08:52:21 +03:00
|
|
|
Res.push_back("-fblocks");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.EmitAllDecls)
|
|
|
|
Res.push_back("-femit-all-decls");
|
2010-01-08 05:20:44 +03:00
|
|
|
if (Opts.MathErrno)
|
|
|
|
Res.push_back("-fmath-errno");
|
2010-06-27 01:25:03 +04:00
|
|
|
switch (Opts.getSignedOverflowBehavior()) {
|
|
|
|
case LangOptions::SOB_Undefined: break;
|
|
|
|
case LangOptions::SOB_Defined: Res.push_back("-fwrapv"); break;
|
2010-09-17 22:29:54 +04:00
|
|
|
case LangOptions::SOB_Trapping:
|
|
|
|
Res.push_back("-ftrapv"); break;
|
|
|
|
if (!Opts.OverflowHandler.empty()) {
|
|
|
|
Res.push_back("-ftrapv-handler");
|
|
|
|
Res.push_back(Opts.OverflowHandler);
|
|
|
|
}
|
2010-06-27 01:25:03 +04:00
|
|
|
}
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.HeinousExtensions)
|
|
|
|
Res.push_back("-fheinous-gnu-extensions");
|
|
|
|
// Optimize is implicit.
|
|
|
|
// OptimizeSize is implicit.
|
|
|
|
if (Opts.Static)
|
|
|
|
Res.push_back("-static-define");
|
2010-04-15 19:06:22 +04:00
|
|
|
if (Opts.DumpRecordLayouts)
|
|
|
|
Res.push_back("-fdump-record-layouts");
|
2010-04-18 00:15:18 +04:00
|
|
|
if (Opts.DumpVTableLayouts)
|
2010-04-15 19:06:22 +04:00
|
|
|
Res.push_back("-fdump-vtable-layouts");
|
|
|
|
if (Opts.NoBitFieldTypeAlign)
|
|
|
|
Res.push_back("-fno-bitfield-type-alignment");
|
|
|
|
if (Opts.SjLjExceptions)
|
|
|
|
Res.push_back("-fsjlj-exceptions");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.PICLevel) {
|
|
|
|
Res.push_back("-pic-level");
|
|
|
|
Res.push_back(llvm::utostr(Opts.PICLevel));
|
|
|
|
}
|
|
|
|
if (Opts.ObjCGCBitmapPrint)
|
|
|
|
Res.push_back("-print-ivar-layout");
|
2010-04-23 00:26:39 +04:00
|
|
|
if (Opts.NoConstantCFStrings)
|
|
|
|
Res.push_back("-fno-constant-cfstrings");
|
2010-04-09 23:03:51 +04:00
|
|
|
if (!Opts.AccessControl)
|
|
|
|
Res.push_back("-fno-access-control");
|
2009-11-19 23:54:59 +03:00
|
|
|
if (!Opts.CharIsSigned)
|
2009-11-29 08:52:21 +03:00
|
|
|
Res.push_back("-fno-signed-char");
|
2009-11-19 23:54:59 +03:00
|
|
|
if (Opts.ShortWChar)
|
|
|
|
Res.push_back("-fshort-wchar");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (!Opts.ElideConstructors)
|
|
|
|
Res.push_back("-fno-elide-constructors");
|
|
|
|
if (Opts.getGCMode() != LangOptions::NonGC) {
|
|
|
|
if (Opts.getGCMode() == LangOptions::HybridGC) {
|
|
|
|
Res.push_back("-fobjc-gc");
|
|
|
|
} else {
|
|
|
|
assert(Opts.getGCMode() == LangOptions::GCOnly && "Invalid GC mode!");
|
|
|
|
Res.push_back("-fobjc-gc-only");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (Opts.getVisibilityMode() != LangOptions::Default) {
|
|
|
|
Res.push_back("-fvisibility");
|
|
|
|
if (Opts.getVisibilityMode() == LangOptions::Hidden) {
|
2009-11-19 23:54:59 +03:00
|
|
|
Res.push_back("hidden");
|
2009-11-17 09:02:29 +03:00
|
|
|
} else {
|
|
|
|
assert(Opts.getVisibilityMode() == LangOptions::Protected &&
|
|
|
|
"Invalid visibility!");
|
|
|
|
Res.push_back("protected");
|
|
|
|
}
|
|
|
|
}
|
2010-06-15 21:05:35 +04:00
|
|
|
if (Opts.InlineVisibilityHidden)
|
|
|
|
Res.push_back("-fvisibility-inlines-hidden");
|
|
|
|
|
2009-11-17 09:02:29 +03:00
|
|
|
if (Opts.getStackProtectorMode() != 0) {
|
|
|
|
Res.push_back("-stack-protector");
|
|
|
|
Res.push_back(llvm::utostr(Opts.getStackProtectorMode()));
|
|
|
|
}
|
|
|
|
if (Opts.InstantiationDepth != DefaultLangOpts.InstantiationDepth) {
|
|
|
|
Res.push_back("-ftemplate-depth");
|
|
|
|
Res.push_back(llvm::utostr(Opts.InstantiationDepth));
|
|
|
|
}
|
2009-11-29 05:38:47 +03:00
|
|
|
if (!Opts.ObjCConstantStringClass.empty()) {
|
2009-11-17 09:02:29 +03:00
|
|
|
Res.push_back("-fconstant-string-class");
|
|
|
|
Res.push_back(Opts.ObjCConstantStringClass);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void PreprocessorOptsToArgs(const PreprocessorOptions &Opts,
|
|
|
|
std::vector<std::string> &Res) {
|
|
|
|
for (unsigned i = 0, e = Opts.Macros.size(); i != e; ++i)
|
2009-11-26 05:14:07 +03:00
|
|
|
Res.push_back(std::string(Opts.Macros[i].second ? "-U" : "-D") +
|
|
|
|
Opts.Macros[i].first);
|
2009-11-17 09:02:29 +03:00
|
|
|
for (unsigned i = 0, e = Opts.Includes.size(); i != e; ++i) {
|
2009-11-26 05:14:07 +03:00
|
|
|
// FIXME: We need to avoid reincluding the implicit PCH and PTH includes.
|
2009-11-17 09:02:29 +03:00
|
|
|
Res.push_back("-include");
|
|
|
|
Res.push_back(Opts.Includes[i]);
|
|
|
|
}
|
|
|
|
for (unsigned i = 0, e = Opts.MacroIncludes.size(); i != e; ++i) {
|
|
|
|
Res.push_back("-imacros");
|
2009-11-26 05:14:07 +03:00
|
|
|
Res.push_back(Opts.MacroIncludes[i]);
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
|
|
|
if (!Opts.UsePredefines)
|
|
|
|
Res.push_back("-undef");
|
2010-03-19 19:15:56 +03:00
|
|
|
if (Opts.DetailedRecord)
|
|
|
|
Res.push_back("-detailed-preprocessing-record");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (!Opts.ImplicitPCHInclude.empty()) {
|
2009-11-26 05:14:07 +03:00
|
|
|
Res.push_back("-include-pch");
|
2009-11-17 09:02:29 +03:00
|
|
|
Res.push_back(Opts.ImplicitPCHInclude);
|
|
|
|
}
|
|
|
|
if (!Opts.ImplicitPTHInclude.empty()) {
|
2009-11-26 05:14:07 +03:00
|
|
|
Res.push_back("-include-pth");
|
2009-11-17 09:02:29 +03:00
|
|
|
Res.push_back(Opts.ImplicitPTHInclude);
|
|
|
|
}
|
|
|
|
if (!Opts.TokenCache.empty()) {
|
2009-11-26 05:14:07 +03:00
|
|
|
if (Opts.ImplicitPTHInclude.empty()) {
|
|
|
|
Res.push_back("-token-cache");
|
|
|
|
Res.push_back(Opts.TokenCache);
|
|
|
|
} else
|
|
|
|
assert(Opts.ImplicitPTHInclude == Opts.TokenCache &&
|
|
|
|
"Unsupported option combination!");
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
2009-12-03 08:11:16 +03:00
|
|
|
for (unsigned i = 0, e = Opts.RemappedFiles.size(); i != e; ++i) {
|
|
|
|
Res.push_back("-remap-file");
|
|
|
|
Res.push_back(Opts.RemappedFiles[i].first + ";" +
|
|
|
|
Opts.RemappedFiles[i].second);
|
|
|
|
}
|
2009-11-17 09:02:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void PreprocessorOutputOptsToArgs(const PreprocessorOutputOptions &Opts,
|
|
|
|
std::vector<std::string> &Res) {
|
|
|
|
if (!Opts.ShowCPP && !Opts.ShowMacros)
|
2010-04-08 02:58:06 +04:00
|
|
|
llvm::report_fatal_error("Invalid option combination!");
|
2009-11-17 09:02:29 +03:00
|
|
|
|
|
|
|
if (Opts.ShowCPP && Opts.ShowMacros)
|
|
|
|
Res.push_back("-dD");
|
|
|
|
else if (!Opts.ShowCPP && Opts.ShowMacros)
|
|
|
|
Res.push_back("-dM");
|
|
|
|
|
2010-08-25 02:44:13 +04:00
|
|
|
if (Opts.ShowHeaderIncludes)
|
|
|
|
Res.push_back("-H");
|
2009-11-17 09:02:29 +03:00
|
|
|
if (!Opts.ShowLineMarkers)
|
|
|
|
Res.push_back("-P");
|
|
|
|
if (Opts.ShowComments)
|
|
|
|
Res.push_back("-C");
|
|
|
|
if (Opts.ShowMacroComments)
|
|
|
|
Res.push_back("-CC");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void TargetOptsToArgs(const TargetOptions &Opts,
|
|
|
|
std::vector<std::string> &Res) {
|
|
|
|
Res.push_back("-triple");
|
|
|
|
Res.push_back(Opts.Triple);
|
|
|
|
if (!Opts.CPU.empty()) {
|
2009-12-18 09:30:12 +03:00
|
|
|
Res.push_back("-target-cpu");
|
2009-11-17 09:02:29 +03:00
|
|
|
Res.push_back(Opts.CPU);
|
|
|
|
}
|
|
|
|
if (!Opts.ABI.empty()) {
|
|
|
|
Res.push_back("-target-abi");
|
|
|
|
Res.push_back(Opts.ABI);
|
|
|
|
}
|
2010-08-12 03:07:42 +04:00
|
|
|
if (!Opts.LinkerVersion.empty()) {
|
|
|
|
Res.push_back("-target-linker-version");
|
|
|
|
Res.push_back(Opts.LinkerVersion);
|
|
|
|
}
|
2010-08-22 10:43:33 +04:00
|
|
|
if (!Opts.CXXABI.empty()) {
|
|
|
|
Res.push_back("-cxx-abi");
|
|
|
|
Res.push_back(Opts.CXXABI);
|
|
|
|
}
|
2009-11-17 09:02:29 +03:00
|
|
|
for (unsigned i = 0, e = Opts.Features.size(); i != e; ++i) {
|
|
|
|
Res.push_back("-target-feature");
|
|
|
|
Res.push_back(Opts.Features[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CompilerInvocation::toArgs(std::vector<std::string> &Res) {
|
|
|
|
AnalyzerOptsToArgs(getAnalyzerOpts(), Res);
|
|
|
|
CodeGenOptsToArgs(getCodeGenOpts(), Res);
|
|
|
|
DependencyOutputOptsToArgs(getDependencyOutputOpts(), Res);
|
|
|
|
DiagnosticOptsToArgs(getDiagnosticOpts(), Res);
|
|
|
|
FrontendOptsToArgs(getFrontendOpts(), Res);
|
|
|
|
HeaderSearchOptsToArgs(getHeaderSearchOpts(), Res);
|
|
|
|
LangOptsToArgs(getLangOpts(), Res);
|
|
|
|
PreprocessorOptsToArgs(getPreprocessorOpts(), Res);
|
|
|
|
PreprocessorOutputOptsToArgs(getPreprocessorOutputOpts(), Res);
|
|
|
|
TargetOptsToArgs(getTargetOpts(), Res);
|
|
|
|
}
|
2009-12-01 06:16:53 +03:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Deserialization (to args)
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
using namespace clang::driver;
|
|
|
|
using namespace clang::driver::cc1options;
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
|
|
|
|
Diagnostic &Diags) {
|
|
|
|
using namespace cc1options;
|
|
|
|
|
|
|
|
Opts.AnalysisList.clear();
|
|
|
|
#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) \
|
|
|
|
if (Args.hasArg(OPT_analysis_##NAME)) Opts.AnalysisList.push_back(NAME);
|
|
|
|
#include "clang/Frontend/Analyses.def"
|
|
|
|
|
|
|
|
if (Arg *A = Args.getLastArg(OPT_analyzer_store)) {
|
|
|
|
llvm::StringRef Name = A->getValue(Args);
|
|
|
|
AnalysisStores Value = llvm::StringSwitch<AnalysisStores>(Name)
|
|
|
|
#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) \
|
|
|
|
.Case(CMDFLAG, NAME##Model)
|
|
|
|
#include "clang/Frontend/Analyses.def"
|
|
|
|
.Default(NumStores);
|
|
|
|
// FIXME: Error handling.
|
|
|
|
if (Value == NumStores)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
2010-06-10 02:30:54 +04:00
|
|
|
<< A->getAsString(Args) << Name;
|
2009-12-01 06:16:53 +03:00
|
|
|
else
|
|
|
|
Opts.AnalysisStoreOpt = Value;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Arg *A = Args.getLastArg(OPT_analyzer_constraints)) {
|
|
|
|
llvm::StringRef Name = A->getValue(Args);
|
|
|
|
AnalysisConstraints Value = llvm::StringSwitch<AnalysisConstraints>(Name)
|
|
|
|
#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
|
|
|
|
.Case(CMDFLAG, NAME##Model)
|
|
|
|
#include "clang/Frontend/Analyses.def"
|
|
|
|
.Default(NumConstraints);
|
|
|
|
// FIXME: Error handling.
|
|
|
|
if (Value == NumConstraints)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
2010-06-10 02:30:54 +04:00
|
|
|
<< A->getAsString(Args) << Name;
|
2009-12-01 06:16:53 +03:00
|
|
|
else
|
|
|
|
Opts.AnalysisConstraintsOpt = Value;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Arg *A = Args.getLastArg(OPT_analyzer_output)) {
|
|
|
|
llvm::StringRef Name = A->getValue(Args);
|
|
|
|
AnalysisDiagClients Value = llvm::StringSwitch<AnalysisDiagClients>(Name)
|
|
|
|
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) \
|
|
|
|
.Case(CMDFLAG, PD_##NAME)
|
|
|
|
#include "clang/Frontend/Analyses.def"
|
|
|
|
.Default(NUM_ANALYSIS_DIAG_CLIENTS);
|
|
|
|
// FIXME: Error handling.
|
|
|
|
if (Value == NUM_ANALYSIS_DIAG_CLIENTS)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
2010-06-10 02:30:54 +04:00
|
|
|
<< A->getAsString(Args) << Name;
|
2009-12-01 06:16:53 +03:00
|
|
|
else
|
|
|
|
Opts.AnalysisDiagOpt = Value;
|
|
|
|
}
|
|
|
|
|
|
|
|
Opts.VisualizeEGDot = Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
|
|
|
|
Opts.VisualizeEGUbi = Args.hasArg(OPT_analyzer_viz_egraph_ubigraph);
|
|
|
|
Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers);
|
|
|
|
Opts.AnalyzerDisplayProgress = Args.hasArg(OPT_analyzer_display_progress);
|
2009-12-08 01:06:12 +03:00
|
|
|
Opts.AnalyzeNestedBlocks =
|
|
|
|
Args.hasArg(OPT_analyzer_opt_analyze_nested_blocks);
|
2010-09-10 04:44:44 +04:00
|
|
|
Opts.AnalyzerStats = Args.hasArg(OPT_analysis_AnalyzerStats);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.PurgeDead = !Args.hasArg(OPT_analyzer_no_purge_dead);
|
|
|
|
Opts.EagerlyAssume = Args.hasArg(OPT_analyzer_eagerly_assume);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function);
|
2010-08-03 04:09:51 +04:00
|
|
|
Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG);
|
2010-09-30 11:41:24 +04:00
|
|
|
Opts.CFGAddImplicitDtors = Args.hasArg(OPT_analysis_CFGAddImplicitDtors);
|
|
|
|
Opts.CFGAddInitializers = Args.hasArg(OPT_analysis_CFGAddInitializers);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.EnableExperimentalChecks = Args.hasArg(OPT_analyzer_experimental_checks);
|
|
|
|
Opts.EnableExperimentalInternalChecks =
|
|
|
|
Args.hasArg(OPT_analyzer_experimental_internal_checks);
|
|
|
|
Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.MaxNodes = Args.getLastArgIntValue(OPT_analyzer_max_nodes, 150000,Diags);
|
2010-10-19 03:36:05 +04:00
|
|
|
Opts.MaxLoop = Args.getLastArgIntValue(OPT_analyzer_max_loop, 4, Diags);
|
2010-05-06 06:59:29 +04:00
|
|
|
Opts.InlineCall = Args.hasArg(OPT_analyzer_inline_call);
|
2010-08-07 02:23:07 +04:00
|
|
|
Opts.IdempotentOps = Args.hasArg(OPT_analysis_WarnIdempotentOps);
|
2009-12-01 06:16:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
|
|
|
|
Diagnostic &Diags) {
|
|
|
|
using namespace cc1options;
|
|
|
|
// -Os implies -O2
|
|
|
|
if (Args.hasArg(OPT_Os))
|
|
|
|
Opts.OptimizationLevel = 2;
|
|
|
|
else {
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.OptimizationLevel = Args.getLastArgIntValue(OPT_O, 0, Diags);
|
2009-12-01 06:16:53 +03:00
|
|
|
if (Opts.OptimizationLevel > 3) {
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< Args.getLastArg(OPT_O)->getAsString(Args) << Opts.OptimizationLevel;
|
|
|
|
Opts.OptimizationLevel = 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// We must always run at least the always inlining pass.
|
|
|
|
Opts.Inlining = (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining
|
|
|
|
: CodeGenOptions::OnlyAlwaysInlining;
|
|
|
|
|
|
|
|
Opts.DebugInfo = Args.hasArg(OPT_g);
|
2010-09-30 23:05:55 +04:00
|
|
|
Opts.LimitDebugInfo = Args.hasArg(OPT_flimit_debug_info);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns);
|
|
|
|
Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone);
|
2010-10-15 02:36:56 +04:00
|
|
|
Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants);
|
|
|
|
Opts.NoCommon = Args.hasArg(OPT_fno_common);
|
|
|
|
Opts.NoImplicitFloat = Args.hasArg(OPT_no_implicit_float);
|
|
|
|
Opts.OptimizeSize = Args.hasArg(OPT_Os);
|
2010-06-08 03:19:17 +04:00
|
|
|
Opts.SimplifyLibCalls = !(Args.hasArg(OPT_fno_builtin) ||
|
|
|
|
Args.hasArg(OPT_ffreestanding));
|
2010-08-08 03:08:14 +04:00
|
|
|
Opts.UnrollLoops = Args.hasArg(OPT_funroll_loops) ||
|
|
|
|
(Opts.OptimizationLevel > 1 && !Opts.OptimizeSize);
|
2009-12-01 06:16:53 +03:00
|
|
|
|
|
|
|
Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
|
2010-03-20 07:15:41 +03:00
|
|
|
Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit);
|
|
|
|
Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.CodeModel = Args.getLastArgValue(OPT_mcode_model);
|
|
|
|
Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.DisableFPElim = Args.hasArg(OPT_mdisable_fp_elim);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi);
|
2010-08-13 03:36:15 +04:00
|
|
|
Opts.HiddenWeakVTables = Args.hasArg(OPT_fhidden_weak_vtables);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss);
|
2010-05-27 09:39:39 +04:00
|
|
|
Opts.RelaxAll = Args.hasArg(OPT_mrelax_all);
|
2010-07-01 05:31:45 +04:00
|
|
|
Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
|
|
|
|
Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic");
|
2009-12-01 06:16:53 +03:00
|
|
|
|
2010-04-13 04:38:24 +04:00
|
|
|
Opts.FunctionSections = Args.hasArg(OPT_ffunction_sections);
|
|
|
|
Opts.DataSections = Args.hasArg(OPT_fdata_sections);
|
|
|
|
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name);
|
2010-02-13 02:47:27 +03:00
|
|
|
Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
|
2010-04-24 21:56:46 +04:00
|
|
|
|
2010-06-22 04:03:40 +04:00
|
|
|
Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions);
|
|
|
|
|
2010-04-24 21:56:46 +04:00
|
|
|
if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) {
|
|
|
|
llvm::StringRef Name = A->getValue(Args);
|
|
|
|
unsigned Method = llvm::StringSwitch<unsigned>(Name)
|
|
|
|
.Case("legacy", CodeGenOptions::Legacy)
|
|
|
|
.Case("non-legacy", CodeGenOptions::NonLegacy)
|
|
|
|
.Case("mixed", CodeGenOptions::Mixed)
|
|
|
|
.Default(~0U);
|
|
|
|
if (Method == ~0U)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
|
|
|
|
else
|
|
|
|
Opts.ObjCDispatchMethod = Method;
|
|
|
|
}
|
2009-12-01 06:16:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
|
|
|
|
ArgList &Args) {
|
|
|
|
using namespace cc1options;
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file);
|
|
|
|
Opts.Targets = Args.getAllArgValues(OPT_MT);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
|
|
|
|
Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
|
|
|
|
Diagnostic &Diags) {
|
|
|
|
using namespace cc1options;
|
|
|
|
Opts.IgnoreWarnings = Args.hasArg(OPT_w);
|
|
|
|
Opts.NoRewriteMacros = Args.hasArg(OPT_Wno_rewrite_macros);
|
|
|
|
Opts.Pedantic = Args.hasArg(OPT_pedantic);
|
|
|
|
Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors);
|
|
|
|
Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics);
|
|
|
|
Opts.ShowColors = Args.hasArg(OPT_fcolor_diagnostics);
|
|
|
|
Opts.ShowColumn = !Args.hasArg(OPT_fno_show_column);
|
|
|
|
Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info);
|
|
|
|
Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location);
|
|
|
|
Opts.ShowOptionNames = Args.hasArg(OPT_fdiagnostics_show_option);
|
2010-06-11 09:57:47 +04:00
|
|
|
|
|
|
|
llvm::StringRef ShowOverloads =
|
|
|
|
Args.getLastArgValue(OPT_fshow_overloads_EQ, "all");
|
|
|
|
if (ShowOverloads == "best")
|
|
|
|
Opts.ShowOverloads = Diagnostic::Ovl_Best;
|
|
|
|
else if (ShowOverloads == "all")
|
|
|
|
Opts.ShowOverloads = Diagnostic::Ovl_All;
|
|
|
|
else
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< Args.getLastArg(OPT_fshow_overloads_EQ)->getAsString(Args)
|
|
|
|
<< ShowOverloads;
|
|
|
|
|
2010-05-05 01:55:25 +04:00
|
|
|
llvm::StringRef ShowCategory =
|
2010-05-20 20:54:55 +04:00
|
|
|
Args.getLastArgValue(OPT_fdiagnostics_show_category, "none");
|
2010-05-05 01:55:25 +04:00
|
|
|
if (ShowCategory == "none")
|
|
|
|
Opts.ShowCategories = 0;
|
|
|
|
else if (ShowCategory == "id")
|
|
|
|
Opts.ShowCategories = 1;
|
|
|
|
else if (ShowCategory == "name")
|
|
|
|
Opts.ShowCategories = 2;
|
|
|
|
else
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< Args.getLastArg(OPT_fdiagnostics_show_category)->getAsString(Args)
|
|
|
|
<< ShowCategory;
|
|
|
|
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
|
2010-08-20 00:24:43 +04:00
|
|
|
Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.ErrorLimit = Args.getLastArgIntValue(OPT_ferror_limit, 0, Diags);
|
2010-05-04 21:13:42 +04:00
|
|
|
Opts.MacroBacktraceLimit
|
2010-05-20 20:54:55 +04:00
|
|
|
= Args.getLastArgIntValue(OPT_fmacro_backtrace_limit,
|
2010-05-04 21:13:42 +04:00
|
|
|
DiagnosticOptions::DefaultMacroBacktraceLimit, Diags);
|
2010-04-20 11:18:24 +04:00
|
|
|
Opts.TemplateBacktraceLimit
|
2010-05-20 20:54:55 +04:00
|
|
|
= Args.getLastArgIntValue(OPT_ftemplate_backtrace_limit,
|
2010-05-04 21:13:42 +04:00
|
|
|
DiagnosticOptions::DefaultTemplateBacktraceLimit,
|
|
|
|
Diags);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.TabStop = Args.getLastArgIntValue(OPT_ftabstop,
|
2010-01-13 06:06:50 +03:00
|
|
|
DiagnosticOptions::DefaultTabStop, Diags);
|
|
|
|
if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
|
|
|
|
Diags.Report(diag::warn_ignoring_ftabstop_value)
|
|
|
|
<< Opts.TabStop << DiagnosticOptions::DefaultTabStop;
|
|
|
|
Opts.TabStop = DiagnosticOptions::DefaultTabStop;
|
|
|
|
}
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.MessageLength = Args.getLastArgIntValue(OPT_fmessage_length, 0, Diags);
|
|
|
|
Opts.DumpBuildInformation = Args.getLastArgValue(OPT_dump_build_information);
|
|
|
|
Opts.Warnings = Args.getAllArgValues(OPT_W);
|
2009-12-01 06:16:53 +03:00
|
|
|
}
|
|
|
|
|
2010-06-08 03:22:09 +04:00
|
|
|
static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
|
|
|
|
Diagnostic &Diags) {
|
2009-12-01 06:16:53 +03:00
|
|
|
using namespace cc1options;
|
|
|
|
Opts.ProgramAction = frontend::ParseSyntaxOnly;
|
|
|
|
if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
|
|
|
|
switch (A->getOption().getID()) {
|
|
|
|
default:
|
|
|
|
assert(0 && "Invalid option in group!");
|
|
|
|
case OPT_ast_dump:
|
|
|
|
Opts.ProgramAction = frontend::ASTDump; break;
|
|
|
|
case OPT_ast_print:
|
|
|
|
Opts.ProgramAction = frontend::ASTPrint; break;
|
|
|
|
case OPT_ast_print_xml:
|
|
|
|
Opts.ProgramAction = frontend::ASTPrintXML; break;
|
|
|
|
case OPT_ast_view:
|
|
|
|
Opts.ProgramAction = frontend::ASTView; break;
|
2010-05-07 19:41:56 +04:00
|
|
|
case OPT_boostcon:
|
|
|
|
Opts.ProgramAction = frontend::BoostCon; break;
|
2009-12-01 06:16:53 +03:00
|
|
|
case OPT_dump_raw_tokens:
|
|
|
|
Opts.ProgramAction = frontend::DumpRawTokens; break;
|
|
|
|
case OPT_dump_tokens:
|
|
|
|
Opts.ProgramAction = frontend::DumpTokens; break;
|
|
|
|
case OPT_S:
|
|
|
|
Opts.ProgramAction = frontend::EmitAssembly; break;
|
|
|
|
case OPT_emit_llvm_bc:
|
|
|
|
Opts.ProgramAction = frontend::EmitBC; break;
|
|
|
|
case OPT_emit_html:
|
|
|
|
Opts.ProgramAction = frontend::EmitHTML; break;
|
|
|
|
case OPT_emit_llvm:
|
|
|
|
Opts.ProgramAction = frontend::EmitLLVM; break;
|
|
|
|
case OPT_emit_llvm_only:
|
|
|
|
Opts.ProgramAction = frontend::EmitLLVMOnly; break;
|
2010-05-25 22:41:01 +04:00
|
|
|
case OPT_emit_codegen_only:
|
|
|
|
Opts.ProgramAction = frontend::EmitCodeGenOnly; break;
|
2010-02-03 04:18:43 +03:00
|
|
|
case OPT_emit_obj:
|
|
|
|
Opts.ProgramAction = frontend::EmitObj; break;
|
2010-04-24 05:30:46 +04:00
|
|
|
case OPT_fixit_EQ:
|
|
|
|
Opts.FixItSuffix = A->getValue(Args);
|
|
|
|
// fall-through!
|
2009-12-01 06:16:53 +03:00
|
|
|
case OPT_fixit:
|
|
|
|
Opts.ProgramAction = frontend::FixIt; break;
|
|
|
|
case OPT_emit_pch:
|
|
|
|
Opts.ProgramAction = frontend::GeneratePCH; break;
|
|
|
|
case OPT_emit_pth:
|
|
|
|
Opts.ProgramAction = frontend::GeneratePTH; break;
|
2010-03-19 22:44:04 +03:00
|
|
|
case OPT_init_only:
|
|
|
|
Opts.ProgramAction = frontend::InitOnly; break;
|
2009-12-01 06:16:53 +03:00
|
|
|
case OPT_fsyntax_only:
|
|
|
|
Opts.ProgramAction = frontend::ParseSyntaxOnly; break;
|
|
|
|
case OPT_print_decl_contexts:
|
|
|
|
Opts.ProgramAction = frontend::PrintDeclContext; break;
|
2010-07-21 00:18:03 +04:00
|
|
|
case OPT_print_preamble:
|
|
|
|
Opts.ProgramAction = frontend::PrintPreamble; break;
|
2009-12-01 06:16:53 +03:00
|
|
|
case OPT_E:
|
|
|
|
Opts.ProgramAction = frontend::PrintPreprocessedInput; break;
|
|
|
|
case OPT_rewrite_macros:
|
|
|
|
Opts.ProgramAction = frontend::RewriteMacros; break;
|
|
|
|
case OPT_rewrite_objc:
|
|
|
|
Opts.ProgramAction = frontend::RewriteObjC; break;
|
|
|
|
case OPT_rewrite_test:
|
|
|
|
Opts.ProgramAction = frontend::RewriteTest; break;
|
|
|
|
case OPT_analyze:
|
|
|
|
Opts.ProgramAction = frontend::RunAnalysis; break;
|
|
|
|
case OPT_Eonly:
|
|
|
|
Opts.ProgramAction = frontend::RunPreprocessorOnly; break;
|
2010-08-16 22:17:11 +04:00
|
|
|
case OPT_create_module:
|
|
|
|
Opts.ProgramAction = frontend::CreateModule; break;
|
2009-12-01 06:16:53 +03:00
|
|
|
}
|
|
|
|
}
|
2010-06-16 20:59:23 +04:00
|
|
|
|
|
|
|
if (const Arg* A = Args.getLastArg(OPT_plugin)) {
|
|
|
|
Opts.Plugins.push_back(A->getValue(Args,0));
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.ProgramAction = frontend::PluginAction;
|
|
|
|
Opts.ActionName = A->getValue(Args);
|
2010-06-16 20:59:23 +04:00
|
|
|
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_plugin_arg),
|
|
|
|
end = Args.filtered_end(); it != end; ++it) {
|
|
|
|
if ((*it)->getValue(Args, 0) == Opts.ActionName)
|
|
|
|
Opts.PluginArgs.push_back((*it)->getValue(Args, 1));
|
|
|
|
}
|
2009-12-01 06:16:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
|
|
|
|
Opts.CodeCompletionAt =
|
|
|
|
ParsedSourceLocation::FromString(A->getValue(Args));
|
|
|
|
if (Opts.CodeCompletionAt.FileName.empty())
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< A->getAsString(Args) << A->getValue(Args);
|
|
|
|
}
|
|
|
|
Opts.DisableFree = Args.hasArg(OPT_disable_free);
|
|
|
|
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.OutputFile = Args.getLastArgValue(OPT_o);
|
|
|
|
Opts.Plugins = Args.getAllArgValues(OPT_load);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.RelocatablePCH = Args.hasArg(OPT_relocatable_pch);
|
2010-07-09 04:00:58 +04:00
|
|
|
Opts.ChainedPCH = Args.hasArg(OPT_chained_pch);
|
2009-12-03 10:01:58 +03:00
|
|
|
Opts.ShowHelp = Args.hasArg(OPT_help);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.ShowMacrosInCodeCompletion = Args.hasArg(OPT_code_completion_macros);
|
2010-05-26 01:41:55 +04:00
|
|
|
Opts.ShowCodePatternsInCodeCompletion
|
|
|
|
= Args.hasArg(OPT_code_completion_patterns);
|
2010-08-15 10:18:01 +04:00
|
|
|
Opts.ShowGlobalSymbolsInCodeCompletion
|
|
|
|
= !Args.hasArg(OPT_no_code_completion_globals);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.ShowStats = Args.hasArg(OPT_print_stats);
|
|
|
|
Opts.ShowTimers = Args.hasArg(OPT_ftime_report);
|
2009-12-03 10:01:58 +03:00
|
|
|
Opts.ShowVersion = Args.hasArg(OPT_version);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.ViewClassInheritance = Args.getLastArgValue(OPT_cxx_inheritance_view);
|
|
|
|
Opts.ASTMergeFiles = Args.getAllArgValues(OPT_ast_merge);
|
|
|
|
Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm);
|
2010-08-13 21:31:00 +04:00
|
|
|
Opts.FixWhatYouCan = Args.hasArg(OPT_fix_what_you_can);
|
2010-08-16 22:17:11 +04:00
|
|
|
Opts.Modules = Args.getAllArgValues(OPT_import_module);
|
2009-12-01 06:16:53 +03:00
|
|
|
|
2010-06-08 03:22:09 +04:00
|
|
|
InputKind DashX = IK_None;
|
2009-12-01 06:16:53 +03:00
|
|
|
if (const Arg *A = Args.getLastArg(OPT_x)) {
|
2010-06-08 03:22:09 +04:00
|
|
|
DashX = llvm::StringSwitch<InputKind>(A->getValue(Args))
|
|
|
|
.Case("c", IK_C)
|
|
|
|
.Case("cl", IK_OpenCL)
|
|
|
|
.Case("c", IK_C)
|
|
|
|
.Case("cl", IK_OpenCL)
|
|
|
|
.Case("c++", IK_CXX)
|
|
|
|
.Case("objective-c", IK_ObjC)
|
|
|
|
.Case("objective-c++", IK_ObjCXX)
|
|
|
|
.Case("cpp-output", IK_PreprocessedC)
|
|
|
|
.Case("assembler-with-cpp", IK_Asm)
|
|
|
|
.Case("c++-cpp-output", IK_PreprocessedCXX)
|
|
|
|
.Case("objective-c-cpp-output", IK_PreprocessedObjC)
|
|
|
|
.Case("objective-c++-cpp-output", IK_PreprocessedObjCXX)
|
|
|
|
.Case("c-header", IK_C)
|
|
|
|
.Case("objective-c-header", IK_ObjC)
|
|
|
|
.Case("c++-header", IK_CXX)
|
|
|
|
.Case("objective-c++-header", IK_ObjCXX)
|
|
|
|
.Case("ast", IK_AST)
|
2010-06-08 03:26:47 +04:00
|
|
|
.Case("ir", IK_LLVM_IR)
|
2010-06-08 03:22:09 +04:00
|
|
|
.Default(IK_None);
|
|
|
|
if (DashX == IK_None)
|
2009-12-01 06:16:53 +03:00
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< A->getAsString(Args) << A->getValue(Args);
|
|
|
|
}
|
|
|
|
|
|
|
|
// '-' is the default input if none is given.
|
2010-05-20 20:54:55 +04:00
|
|
|
std::vector<std::string> Inputs = Args.getAllArgValues(OPT_INPUT);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.Inputs.clear();
|
|
|
|
if (Inputs.empty())
|
|
|
|
Inputs.push_back("-");
|
|
|
|
for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
|
2010-06-08 03:22:09 +04:00
|
|
|
InputKind IK = DashX;
|
|
|
|
if (IK == IK_None) {
|
2009-12-01 06:16:53 +03:00
|
|
|
IK = FrontendOptions::getInputKindForExtension(
|
|
|
|
llvm::StringRef(Inputs[i]).rsplit('.').second);
|
|
|
|
// FIXME: Remove this hack.
|
|
|
|
if (i == 0)
|
|
|
|
DashX = IK;
|
|
|
|
}
|
|
|
|
Opts.Inputs.push_back(std::make_pair(IK, Inputs[i]));
|
|
|
|
}
|
|
|
|
|
|
|
|
return DashX;
|
|
|
|
}
|
|
|
|
|
2009-12-15 03:06:45 +03:00
|
|
|
std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
|
|
|
|
void *MainAddr) {
|
2009-12-01 06:16:53 +03:00
|
|
|
llvm::sys::Path P = llvm::sys::Path::GetMainExecutable(Argv0, MainAddr);
|
|
|
|
|
|
|
|
if (!P.isEmpty()) {
|
|
|
|
P.eraseComponent(); // Remove /clang from foo/bin/clang
|
|
|
|
P.eraseComponent(); // Remove /bin from foo/bin
|
|
|
|
|
|
|
|
// Get foo/lib/clang/<version>/include
|
|
|
|
P.appendComponent("lib");
|
|
|
|
P.appendComponent("clang");
|
|
|
|
P.appendComponent(CLANG_VERSION_STRING);
|
|
|
|
}
|
|
|
|
|
|
|
|
return P.str();
|
|
|
|
}
|
|
|
|
|
2009-12-13 06:45:58 +03:00
|
|
|
static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
|
2009-12-01 06:16:53 +03:00
|
|
|
using namespace cc1options;
|
2010-09-09 21:38:22 +04:00
|
|
|
Opts.CXXSystemIncludes = Args.getAllArgValues(OPT_cxx_system_include);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.Sysroot = Args.getLastArgValue(OPT_isysroot, "/");
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.Verbose = Args.hasArg(OPT_v);
|
2009-12-13 06:45:58 +03:00
|
|
|
Opts.UseBuiltinIncludes = !Args.hasArg(OPT_nobuiltininc);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.UseStandardIncludes = !Args.hasArg(OPT_nostdinc);
|
2010-03-24 23:13:48 +03:00
|
|
|
Opts.UseStandardCXXIncludes = !Args.hasArg(OPT_nostdincxx);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir);
|
2009-12-01 06:16:53 +03:00
|
|
|
|
|
|
|
// Add -I... and -F... options in order.
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_I, OPT_F),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it)
|
2010-06-12 02:00:13 +04:00
|
|
|
Opts.AddPath((*it)->getValue(Args), frontend::Angled, true,
|
2010-08-25 02:27:37 +04:00
|
|
|
/*IsFramework=*/ (*it)->getOption().matches(OPT_F), true);
|
2009-12-01 06:16:53 +03:00
|
|
|
|
|
|
|
// Add -iprefix/-iwith-prefix/-iwithprefixbefore options.
|
|
|
|
llvm::StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_iprefix, OPT_iwithprefix,
|
|
|
|
OPT_iwithprefixbefore),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
2010-06-12 02:00:13 +04:00
|
|
|
const Arg *A = *it;
|
|
|
|
if (A->getOption().matches(OPT_iprefix))
|
|
|
|
Prefix = A->getValue(Args);
|
|
|
|
else if (A->getOption().matches(OPT_iwithprefix))
|
|
|
|
Opts.AddPath(Prefix.str() + A->getValue(Args),
|
2010-08-25 02:27:37 +04:00
|
|
|
frontend::System, false, false, true);
|
2009-12-01 06:16:53 +03:00
|
|
|
else
|
2010-06-12 02:00:13 +04:00
|
|
|
Opts.AddPath(Prefix.str() + A->getValue(Args),
|
2010-08-25 02:27:37 +04:00
|
|
|
frontend::Angled, false, false, true);
|
2009-12-01 06:16:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_idirafter),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it)
|
2010-08-25 02:27:37 +04:00
|
|
|
Opts.AddPath((*it)->getValue(Args), frontend::After, true, false, true);
|
2009-12-01 06:16:53 +03:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_iquote),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it)
|
2010-08-25 02:27:37 +04:00
|
|
|
Opts.AddPath((*it)->getValue(Args), frontend::Quoted, true, false, true);
|
2010-08-25 01:09:16 +04:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_isystem, OPT_iwithsysroot),
|
2009-12-01 06:16:53 +03:00
|
|
|
ie = Args.filtered_end(); it != ie; ++it)
|
2010-08-25 02:27:37 +04:00
|
|
|
Opts.AddPath((*it)->getValue(Args), frontend::System, true, false,
|
|
|
|
(*it)->getOption().matches(OPT_iwithsysroot));
|
2009-12-01 06:16:53 +03:00
|
|
|
|
|
|
|
// FIXME: Need options for the various environment variables!
|
|
|
|
}
|
|
|
|
|
2010-06-08 03:22:09 +04:00
|
|
|
static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
|
2009-12-01 06:16:53 +03:00
|
|
|
Diagnostic &Diags) {
|
|
|
|
// FIXME: Cleanup per-file based stuff.
|
|
|
|
|
|
|
|
// Set some properties which depend soley on the input kind; it would be nice
|
|
|
|
// to move these to the language standard, and have the driver resolve the
|
|
|
|
// input kind + language standard.
|
2010-06-08 03:22:09 +04:00
|
|
|
if (IK == IK_Asm) {
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.AsmPreprocessor = 1;
|
2010-06-08 03:22:09 +04:00
|
|
|
} else if (IK == IK_ObjC ||
|
|
|
|
IK == IK_ObjCXX ||
|
|
|
|
IK == IK_PreprocessedObjC ||
|
|
|
|
IK == IK_PreprocessedObjCXX) {
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.ObjC1 = Opts.ObjC2 = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
LangStandard::Kind LangStd = LangStandard::lang_unspecified;
|
|
|
|
if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
|
|
|
|
LangStd = llvm::StringSwitch<LangStandard::Kind>(A->getValue(Args))
|
|
|
|
#define LANGSTANDARD(id, name, desc, features) \
|
|
|
|
.Case(name, LangStandard::lang_##id)
|
|
|
|
#include "clang/Frontend/LangStandards.def"
|
|
|
|
.Default(LangStandard::lang_unspecified);
|
|
|
|
if (LangStd == LangStandard::lang_unspecified)
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< A->getAsString(Args) << A->getValue(Args);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LangStd == LangStandard::lang_unspecified) {
|
|
|
|
// Based on the base language, pick one.
|
|
|
|
switch (IK) {
|
2010-06-08 03:22:09 +04:00
|
|
|
case IK_None:
|
|
|
|
case IK_AST:
|
2010-06-08 03:26:47 +04:00
|
|
|
case IK_LLVM_IR:
|
2009-12-01 06:16:53 +03:00
|
|
|
assert(0 && "Invalid input kind!");
|
2010-06-08 03:22:09 +04:00
|
|
|
case IK_OpenCL:
|
2009-12-01 06:16:53 +03:00
|
|
|
LangStd = LangStandard::lang_opencl;
|
|
|
|
break;
|
2010-06-08 03:22:09 +04:00
|
|
|
case IK_Asm:
|
|
|
|
case IK_C:
|
|
|
|
case IK_PreprocessedC:
|
|
|
|
case IK_ObjC:
|
|
|
|
case IK_PreprocessedObjC:
|
2009-12-01 06:16:53 +03:00
|
|
|
LangStd = LangStandard::lang_gnu99;
|
|
|
|
break;
|
2010-06-08 03:22:09 +04:00
|
|
|
case IK_CXX:
|
|
|
|
case IK_PreprocessedCXX:
|
|
|
|
case IK_ObjCXX:
|
|
|
|
case IK_PreprocessedObjCXX:
|
2009-12-01 06:16:53 +03:00
|
|
|
LangStd = LangStandard::lang_gnucxx98;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
|
|
|
|
Opts.BCPLComment = Std.hasBCPLComments();
|
|
|
|
Opts.C99 = Std.isC99();
|
|
|
|
Opts.CPlusPlus = Std.isCPlusPlus();
|
|
|
|
Opts.CPlusPlus0x = Std.isCPlusPlus0x();
|
|
|
|
Opts.Digraphs = Std.hasDigraphs();
|
|
|
|
Opts.GNUMode = Std.isGNUMode();
|
|
|
|
Opts.GNUInline = !Std.isC99();
|
|
|
|
Opts.HexFloats = Std.hasHexFloats();
|
|
|
|
Opts.ImplicitInt = Std.hasImplicitInt();
|
|
|
|
|
|
|
|
// OpenCL has some additional defaults.
|
|
|
|
if (LangStd == LangStandard::lang_opencl) {
|
|
|
|
Opts.OpenCL = 1;
|
|
|
|
Opts.AltiVec = 1;
|
|
|
|
Opts.CXXOperatorNames = 1;
|
|
|
|
Opts.LaxVectorConversions = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// OpenCL and C++ both have bool, true, false keywords.
|
|
|
|
Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
|
|
|
|
|
2010-04-18 00:17:31 +04:00
|
|
|
// We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension
|
|
|
|
// keywords. This behavior is provided by GCC's poorly named '-fasm' flag,
|
|
|
|
// while a subset (the non-C++ GNU keywords) is provided by GCC's
|
|
|
|
// '-fgnu-keywords'. Clang conflates the two for simplicity under the single
|
|
|
|
// name, as it doesn't seem a useful distinction.
|
|
|
|
Opts.GNUKeywords = Args.hasFlag(OPT_fgnu_keywords, OPT_fno_gnu_keywords,
|
|
|
|
Opts.GNUMode);
|
|
|
|
|
2009-12-01 06:16:53 +03:00
|
|
|
if (Opts.CPlusPlus)
|
|
|
|
Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
|
|
|
|
|
|
|
|
if (Args.hasArg(OPT_fobjc_gc_only))
|
|
|
|
Opts.setGCMode(LangOptions::GCOnly);
|
|
|
|
else if (Args.hasArg(OPT_fobjc_gc))
|
|
|
|
Opts.setGCMode(LangOptions::HybridGC);
|
|
|
|
|
|
|
|
if (Args.hasArg(OPT_print_ivar_layout))
|
|
|
|
Opts.ObjCGCBitmapPrint = 1;
|
2010-04-23 00:26:39 +04:00
|
|
|
if (Args.hasArg(OPT_fno_constant_cfstrings))
|
|
|
|
Opts.NoConstantCFStrings = 1;
|
2009-12-01 06:16:53 +03:00
|
|
|
|
|
|
|
if (Args.hasArg(OPT_faltivec))
|
|
|
|
Opts.AltiVec = 1;
|
|
|
|
|
|
|
|
if (Args.hasArg(OPT_pthread))
|
|
|
|
Opts.POSIXThreads = 1;
|
|
|
|
|
2010-05-20 20:54:55 +04:00
|
|
|
llvm::StringRef Vis = Args.getLastArgValue(OPT_fvisibility, "default");
|
2009-12-01 06:16:53 +03:00
|
|
|
if (Vis == "default")
|
|
|
|
Opts.setVisibilityMode(LangOptions::Default);
|
|
|
|
else if (Vis == "hidden")
|
|
|
|
Opts.setVisibilityMode(LangOptions::Hidden);
|
|
|
|
else if (Vis == "protected")
|
|
|
|
Opts.setVisibilityMode(LangOptions::Protected);
|
|
|
|
else
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
|
|
|
|
|
2010-06-15 21:05:35 +04:00
|
|
|
if (Args.hasArg(OPT_fvisibility_inlines_hidden))
|
|
|
|
Opts.InlineVisibilityHidden = 1;
|
2010-06-27 01:25:03 +04:00
|
|
|
|
2010-09-17 22:29:54 +04:00
|
|
|
if (Args.hasArg(OPT_ftrapv)) {
|
2010-06-27 01:25:03 +04:00
|
|
|
Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping);
|
2010-09-17 22:29:54 +04:00
|
|
|
// Set the handler, if one is specified.
|
|
|
|
Opts.OverflowHandler =
|
|
|
|
Args.getLastArgValue(OPT_ftrapv_handler);
|
|
|
|
}
|
2010-06-27 01:25:03 +04:00
|
|
|
else if (Args.hasArg(OPT_fwrapv))
|
|
|
|
Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
|
2009-12-01 06:16:53 +03:00
|
|
|
|
|
|
|
// Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
|
|
|
|
// is specified, or -std is set to a conforming mode.
|
|
|
|
Opts.Trigraphs = !Opts.GNUMode;
|
|
|
|
if (Args.hasArg(OPT_trigraphs))
|
|
|
|
Opts.Trigraphs = 1;
|
|
|
|
|
2009-12-16 23:10:18 +03:00
|
|
|
Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
|
|
|
|
OPT_fno_dollars_in_identifiers,
|
|
|
|
!Opts.AsmPreprocessor);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
|
|
|
|
Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
|
2010-09-03 03:59:25 +04:00
|
|
|
Opts.Borland = Args.hasArg(OPT_fborland_extensions);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
|
2010-03-15 13:54:44 +03:00
|
|
|
Opts.ConstStrings = Args.hasArg(OPT_Wwrite_strings);
|
2009-12-01 06:16:53 +03:00
|
|
|
if (Args.hasArg(OPT_fno_lax_vector_conversions))
|
2010-02-07 02:23:06 +03:00
|
|
|
Opts.LaxVectorConversions = 0;
|
|
|
|
if (Args.hasArg(OPT_fno_threadsafe_statics))
|
2010-02-11 11:02:13 +03:00
|
|
|
Opts.ThreadsafeStatics = 0;
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.Exceptions = Args.hasArg(OPT_fexceptions);
|
2009-12-02 21:57:08 +03:00
|
|
|
Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.Blocks = Args.hasArg(OPT_fblocks);
|
|
|
|
Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
|
|
|
|
Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
|
2010-10-08 04:25:19 +04:00
|
|
|
Opts.ShortEnums = Args.hasArg(OPT_fshort_enums);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
|
|
|
|
Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
|
2009-12-16 19:59:22 +03:00
|
|
|
Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
|
2010-04-09 23:03:51 +04:00
|
|
|
Opts.AccessControl = !Args.hasArg(OPT_fno_access_control);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
|
2010-01-08 05:20:44 +03:00
|
|
|
Opts.MathErrno = Args.hasArg(OPT_fmath_errno);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.InstantiationDepth = Args.getLastArgIntValue(OPT_ftemplate_depth, 1024,
|
2009-12-01 06:16:53 +03:00
|
|
|
Diags);
|
|
|
|
Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.ObjCConstantStringClass =
|
|
|
|
Args.getLastArgValue(OPT_fconstant_string_class);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
|
2010-02-09 22:31:38 +03:00
|
|
|
Opts.ObjCNonFragileABI2 = Args.hasArg(OPT_fobjc_nonfragile_abi2);
|
|
|
|
if (Opts.ObjCNonFragileABI2)
|
|
|
|
Opts.ObjCNonFragileABI = true;
|
2009-12-12 04:27:46 +03:00
|
|
|
Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.PICLevel = Args.getLastArgIntValue(OPT_pic_level, 0, Diags);
|
2010-02-10 21:48:44 +03:00
|
|
|
Opts.SjLjExceptions = Args.hasArg(OPT_fsjlj_exceptions);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.Static = Args.hasArg(OPT_static_define);
|
2010-04-10 23:09:13 +04:00
|
|
|
Opts.DumpRecordLayouts = Args.hasArg(OPT_fdump_record_layouts);
|
2010-04-18 00:15:18 +04:00
|
|
|
Opts.DumpVTableLayouts = Args.hasArg(OPT_fdump_vtable_layouts);
|
2010-07-09 21:35:33 +04:00
|
|
|
Opts.SpellChecking = !Args.hasArg(OPT_fno_spell_checking);
|
2010-04-15 19:06:22 +04:00
|
|
|
Opts.NoBitFieldTypeAlign = Args.hasArg(OPT_fno_bitfield_type_align);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.OptimizeSize = 0;
|
|
|
|
|
|
|
|
// FIXME: Eliminate this dependency.
|
|
|
|
unsigned Opt =
|
2010-05-20 20:54:55 +04:00
|
|
|
Args.hasArg(OPT_Os) ? 2 : Args.getLastArgIntValue(OPT_O, 0, Diags);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.Optimize = Opt != 0;
|
|
|
|
|
|
|
|
// This is the __NO_INLINE__ define, which just depends on things like the
|
|
|
|
// optimization level and -fno-inline, not actually whether the backend has
|
|
|
|
// inlining enabled.
|
|
|
|
//
|
|
|
|
// FIXME: This is affected by other options (-fno-inline).
|
|
|
|
Opts.NoInline = !Opt;
|
|
|
|
|
2010-05-20 20:54:55 +04:00
|
|
|
unsigned SSP = Args.getLastArgIntValue(OPT_stack_protector, 0, Diags);
|
2009-12-01 06:16:53 +03:00
|
|
|
switch (SSP) {
|
|
|
|
default:
|
|
|
|
Diags.Report(diag::err_drv_invalid_value)
|
|
|
|
<< Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
|
|
|
|
break;
|
|
|
|
case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
|
|
|
|
case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
|
|
|
|
case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-03 08:11:16 +03:00
|
|
|
static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
|
|
|
|
Diagnostic &Diags) {
|
2009-12-01 06:16:53 +03:00
|
|
|
using namespace cc1options;
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.ImplicitPCHInclude = Args.getLastArgValue(OPT_include_pch);
|
|
|
|
Opts.ImplicitPTHInclude = Args.getLastArgValue(OPT_include_pth);
|
2009-12-01 06:16:53 +03:00
|
|
|
if (const Arg *A = Args.getLastArg(OPT_token_cache))
|
|
|
|
Opts.TokenCache = A->getValue(Args);
|
|
|
|
else
|
|
|
|
Opts.TokenCache = Opts.ImplicitPTHInclude;
|
|
|
|
Opts.UsePredefines = !Args.hasArg(OPT_undef);
|
2010-03-19 19:15:56 +03:00
|
|
|
Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record);
|
2010-07-27 04:27:13 +04:00
|
|
|
Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch);
|
2010-10-15 00:14:25 +04:00
|
|
|
|
2010-10-15 00:14:18 +04:00
|
|
|
Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls);
|
2010-10-15 00:14:25 +04:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_error_on_deserialized_pch_decl),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
|
|
|
const Arg *A = *it;
|
|
|
|
Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue(Args));
|
|
|
|
}
|
2010-07-27 04:27:13 +04:00
|
|
|
|
Introduce basic support for loading a precompiled preamble while
reparsing an ASTUnit. When saving a preamble, create a buffer larger
than the actual file we're working with but fill everything from the
end of the preamble to the end of the file with spaces (so the lexer
will quickly skip them). When we load the file, create a buffer of the
same size, filling it with the file and then spaces. Then, instruct
the lexer to start lexing after the preamble, therefore continuing the
parse from the spot where the preamble left off.
It's now possible to perform a simple preamble build + parse (+
reparse) with ASTUnit. However, one has to disable a bunch of checking
in the PCH reader to do so. That part isn't committed; it will likely
be handled with some other kind of flag (e.g., -fno-validate-pch).
As part of this, fix some issues with null termination of the memory
buffers created for the preamble; we were trying to explicitly
NULL-terminate them, even though they were also getting implicitly
NULL terminated, leading to excess warnings about NULL characters in
source files.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109445 91177308-0d34-0410-b5e6-96231b3b80d8
2010-07-27 01:36:20 +04:00
|
|
|
if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
|
|
|
|
llvm::StringRef Value(A->getValue(Args));
|
|
|
|
size_t Comma = Value.find(',');
|
|
|
|
unsigned Bytes = 0;
|
|
|
|
unsigned EndOfLine = 0;
|
|
|
|
|
|
|
|
if (Comma == llvm::StringRef::npos ||
|
|
|
|
Value.substr(0, Comma).getAsInteger(10, Bytes) ||
|
|
|
|
Value.substr(Comma + 1).getAsInteger(10, EndOfLine))
|
|
|
|
Diags.Report(diag::err_drv_preamble_format);
|
|
|
|
else {
|
|
|
|
Opts.PrecompiledPreambleBytes.first = Bytes;
|
|
|
|
Opts.PrecompiledPreambleBytes.second = (EndOfLine != 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-01 06:16:53 +03:00
|
|
|
// Add macros from the command line.
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_D, OPT_U),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
2010-06-12 02:00:13 +04:00
|
|
|
if ((*it)->getOption().matches(OPT_D))
|
|
|
|
Opts.addMacroDef((*it)->getValue(Args));
|
2009-12-01 06:16:53 +03:00
|
|
|
else
|
2010-06-12 02:00:13 +04:00
|
|
|
Opts.addMacroUndef((*it)->getValue(Args));
|
2009-12-01 06:16:53 +03:00
|
|
|
}
|
|
|
|
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.MacroIncludes = Args.getAllArgValues(OPT_imacros);
|
2009-12-01 06:16:53 +03:00
|
|
|
|
|
|
|
// Add the ordered list of -includes.
|
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_include, OPT_include_pch,
|
|
|
|
OPT_include_pth),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
2010-06-12 02:00:13 +04:00
|
|
|
const Arg *A = *it;
|
2009-12-01 06:16:53 +03:00
|
|
|
// PCH is handled specially, we need to extra the original include path.
|
2010-06-12 02:00:13 +04:00
|
|
|
if (A->getOption().matches(OPT_include_pch)) {
|
2009-12-01 06:16:53 +03:00
|
|
|
std::string OriginalFile =
|
2010-08-19 03:56:43 +04:00
|
|
|
ASTReader::getOriginalSourceFile(A->getValue(Args), Diags);
|
2009-12-01 06:16:53 +03:00
|
|
|
if (OriginalFile.empty())
|
2009-12-03 12:13:06 +03:00
|
|
|
continue;
|
2009-12-01 06:16:53 +03:00
|
|
|
|
|
|
|
Opts.Includes.push_back(OriginalFile);
|
|
|
|
} else
|
2010-06-12 02:00:13 +04:00
|
|
|
Opts.Includes.push_back(A->getValue(Args));
|
2009-12-01 06:16:53 +03:00
|
|
|
}
|
2009-12-03 08:11:16 +03:00
|
|
|
|
2010-04-14 07:54:58 +04:00
|
|
|
// Include 'altivec.h' if -faltivec option present
|
|
|
|
if (Args.hasArg(OPT_faltivec))
|
|
|
|
Opts.Includes.push_back("altivec.h");
|
|
|
|
|
2009-12-03 08:11:16 +03:00
|
|
|
for (arg_iterator it = Args.filtered_begin(OPT_remap_file),
|
|
|
|
ie = Args.filtered_end(); it != ie; ++it) {
|
2010-06-12 02:00:13 +04:00
|
|
|
const Arg *A = *it;
|
2009-12-03 08:11:16 +03:00
|
|
|
std::pair<llvm::StringRef,llvm::StringRef> Split =
|
2010-06-12 02:00:13 +04:00
|
|
|
llvm::StringRef(A->getValue(Args)).split(';');
|
2009-12-03 08:11:16 +03:00
|
|
|
|
|
|
|
if (Split.second.empty()) {
|
2010-06-12 02:00:13 +04:00
|
|
|
Diags.Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);
|
2009-12-03 08:11:16 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Opts.addRemappedFile(Split.first, Split.second);
|
|
|
|
}
|
2009-12-01 06:16:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
|
|
|
|
ArgList &Args) {
|
|
|
|
using namespace cc1options;
|
|
|
|
Opts.ShowCPP = !Args.hasArg(OPT_dM);
|
|
|
|
Opts.ShowComments = Args.hasArg(OPT_C);
|
2010-08-25 02:44:13 +04:00
|
|
|
Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
|
|
|
|
Opts.ShowLineMarkers = !Args.hasArg(OPT_P);
|
2009-12-01 06:16:53 +03:00
|
|
|
Opts.ShowMacroComments = Args.hasArg(OPT_CC);
|
2010-08-25 02:44:13 +04:00
|
|
|
Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
|
2009-12-01 06:16:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
|
|
|
|
using namespace cc1options;
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.ABI = Args.getLastArgValue(OPT_target_abi);
|
2010-06-11 05:06:47 +04:00
|
|
|
Opts.CXXABI = Args.getLastArgValue(OPT_cxx_abi);
|
2010-05-20 20:54:55 +04:00
|
|
|
Opts.CPU = Args.getLastArgValue(OPT_target_cpu);
|
|
|
|
Opts.Features = Args.getAllArgValues(OPT_target_feature);
|
2010-08-12 03:07:42 +04:00
|
|
|
Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version);
|
2010-08-30 13:42:39 +04:00
|
|
|
Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple));
|
2009-12-01 06:16:53 +03:00
|
|
|
|
|
|
|
// Use the host triple if unspecified.
|
|
|
|
if (Opts.Triple.empty())
|
|
|
|
Opts.Triple = llvm::sys::getHostTriple();
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
|
2010-10-11 13:18:43 +04:00
|
|
|
const char* const *ArgBegin,
|
|
|
|
const char* const *ArgEnd,
|
2009-12-01 06:16:53 +03:00
|
|
|
Diagnostic &Diags) {
|
|
|
|
// Parse the arguments.
|
|
|
|
llvm::OwningPtr<OptTable> Opts(createCC1OptTable());
|
|
|
|
unsigned MissingArgIndex, MissingArgCount;
|
|
|
|
llvm::OwningPtr<InputArgList> Args(
|
|
|
|
Opts->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount));
|
|
|
|
|
|
|
|
// Check for missing argument error.
|
|
|
|
if (MissingArgCount)
|
|
|
|
Diags.Report(diag::err_drv_missing_argument)
|
|
|
|
<< Args->getArgString(MissingArgIndex) << MissingArgCount;
|
|
|
|
|
|
|
|
// Issue errors on unknown arguments.
|
|
|
|
for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
|
|
|
|
ie = Args->filtered_end(); it != ie; ++it)
|
2010-06-12 02:00:13 +04:00
|
|
|
Diags.Report(diag::err_drv_unknown_argument) << (*it)->getAsString(*Args);
|
2009-12-01 06:16:53 +03:00
|
|
|
|
|
|
|
ParseAnalyzerArgs(Res.getAnalyzerOpts(), *Args, Diags);
|
|
|
|
ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, Diags);
|
|
|
|
ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *Args);
|
|
|
|
ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, Diags);
|
2010-06-08 03:22:09 +04:00
|
|
|
InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags);
|
2009-12-13 06:45:58 +03:00
|
|
|
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args);
|
2010-06-08 03:26:47 +04:00
|
|
|
if (DashX != IK_AST && DashX != IK_LLVM_IR)
|
2009-12-01 06:16:53 +03:00
|
|
|
ParseLangArgs(Res.getLangOpts(), *Args, DashX, Diags);
|
2009-12-03 08:11:16 +03:00
|
|
|
ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, Diags);
|
2009-12-01 06:16:53 +03:00
|
|
|
ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args);
|
|
|
|
ParseTargetArgs(Res.getTargetOpts(), *Args);
|
|
|
|
}
|