//===--- Options.cpp - clang-cc Option Handling ---------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // This file contains "pure" option handling, it is only responsible for turning // the options into internal *Option classes, but shouldn't have any other // logic. #include "Options.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Frontend/AnalysisConsumer.h" #include "clang/CodeGen/CodeGenOptions.h" #include "clang/Frontend/DependencyOutputOptions.h" #include "clang/Frontend/DiagnosticOptions.h" #include "clang/Frontend/FrontendOptions.h" #include "clang/Frontend/HeaderSearchOptions.h" #include "clang/Frontend/LangStandard.h" #include "clang/Frontend/PCHReader.h" #include "clang/Frontend/PreprocessorOptions.h" #include "clang/Frontend/PreprocessorOutputOptions.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/RegistryParser.h" #include "llvm/System/Host.h" #include using namespace clang; //===----------------------------------------------------------------------===// // Analyzer Options //===----------------------------------------------------------------------===// namespace analyzeroptions { static llvm::cl::list AnalysisList(llvm::cl::desc("Source Code Analysis - Checks and Analyses"), llvm::cl::values( #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\ clEnumValN(NAME, CMDFLAG, DESC), #include "clang/Frontend/Analyses.def" clEnumValEnd)); static llvm::cl::opt AnalysisStoreOpt("analyzer-store", llvm::cl::desc("Source Code Analysis - Abstract Memory Store Models"), llvm::cl::init(BasicStoreModel), llvm::cl::values( #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)\ clEnumValN(NAME##Model, CMDFLAG, DESC), #include "clang/Frontend/Analyses.def" clEnumValEnd)); static llvm::cl::opt AnalysisConstraintsOpt("analyzer-constraints", llvm::cl::desc("Source Code Analysis - Symbolic Constraint Engines"), llvm::cl::init(RangeConstraintsModel), llvm::cl::values( #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)\ clEnumValN(NAME##Model, CMDFLAG, DESC), #include "clang/Frontend/Analyses.def" clEnumValEnd)); static llvm::cl::opt AnalysisDiagOpt("analyzer-output", llvm::cl::desc("Source Code Analysis - Output Options"), llvm::cl::init(PD_HTML), llvm::cl::values( #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREATE)\ clEnumValN(PD_##NAME, CMDFLAG, DESC), #include "clang/Frontend/Analyses.def" clEnumValEnd)); static llvm::cl::opt AnalyzeAll("analyzer-opt-analyze-headers", llvm::cl::desc("Force the static analyzer to analyze " "functions defined in header files")); static llvm::cl::opt AnalyzerDisplayProgress("analyzer-display-progress", llvm::cl::desc("Emit verbose output about the analyzer's progress")); static llvm::cl::opt AnalyzerExperimentalChecks("analyzer-experimental-checks", llvm::cl::desc("Use experimental path-sensitive checks")); static llvm::cl::opt AnalyzerExperimentalInternalChecks("analyzer-experimental-internal-checks", llvm::cl::desc("Use new default path-sensitive checks currently in testing")); static llvm::cl::opt AnalyzeSpecificFunction("analyze-function", llvm::cl::desc("Run analysis on specific function")); static llvm::cl::opt EagerlyAssume("analyzer-eagerly-assume", llvm::cl::desc("Eagerly assume the truth/falseness of some " "symbolic constraints")); static llvm::cl::opt NoPurgeDead("analyzer-no-purge-dead", llvm::cl::desc("Don't remove dead symbols, bindings, and constraints before" " processing a statement")); static llvm::cl::opt TrimGraph("trim-egraph", llvm::cl::desc("Only show error-related paths in the analysis graph")); static llvm::cl::opt VisualizeEGDot("analyzer-viz-egraph-graphviz", llvm::cl::desc("Display exploded graph using GraphViz")); static llvm::cl::opt VisualizeEGUbi("analyzer-viz-egraph-ubigraph", llvm::cl::desc("Display exploded graph using Ubigraph")); } //===----------------------------------------------------------------------===// // Code Generation Options //===----------------------------------------------------------------------===// namespace codegenoptions { static llvm::cl::opt DisableLLVMOptimizations("disable-llvm-optzns", llvm::cl::desc("Don't run LLVM optimization passes")); static llvm::cl::opt DisableRedZone("disable-red-zone", llvm::cl::desc("Do not emit code that uses the red zone.")); static llvm::cl::opt GenerateDebugInfo("g", llvm::cl::desc("Generate source level debug information")); static llvm::cl::opt MAsmVerbose("masm-verbose", llvm::cl::desc("Generate verbose assembly output")); static llvm::cl::opt MCodeModel("mcode-model", llvm::cl::desc("The code model to use")); static llvm::cl::opt MDebugPass("mdebu-pass", llvm::cl::desc("Output additional debug information")); static llvm::cl::opt MDisableFPElim("mdisable-fp-elim", llvm::cl::desc("Disable frame pointer elimination optimization")); static llvm::cl::opt MFloatABI("mfloat-abi", llvm::cl::desc("The float ABI to use")); static llvm::cl::opt MLimitFloatPrecision("mlimit-float-precision", llvm::cl::desc("Limit float precision to the given value")); static llvm::cl::opt MNoZeroInitializedInBSS("mno-zero-initialized-in-bss", llvm::cl::desc("Do not put zero initialized data in the BSS")); static llvm::cl::opt MSoftFloat("msoft-float", llvm::cl::desc("Use software floating point")); static llvm::cl::opt MRelocationModel("mrelocation-model", llvm::cl::desc("The relocation model to use"), llvm::cl::init("pic")); static llvm::cl::opt MUnwindTables("munwind-tables", llvm::cl::desc("Generate unwinding tables for all functions")); static llvm::cl::opt MainFileName("main-file-name", llvm::cl::desc("Main file name to use for debug info")); static llvm::cl::opt NoCommon("fno-common", llvm::cl::desc("Compile common globals like normal definitions"), llvm::cl::ValueDisallowed); static llvm::cl::opt NoImplicitFloat("no-implicit-float", llvm::cl::desc("Don't generate implicit floating point instructions (x86-only)")); static llvm::cl::opt NoMergeConstants("fno-merge-all-constants", llvm::cl::desc("Disallow merging of constants.")); // It might be nice to add bounds to the CommandLine library directly. struct OptLevelParser : public llvm::cl::parser { bool parse(llvm::cl::Option &O, llvm::StringRef ArgName, llvm::StringRef Arg, unsigned &Val) { if (llvm::cl::parser::parse(O, ArgName, Arg, Val)) return true; if (Val > 3) return O.error("'" + Arg + "' invalid optimization level!"); return false; } }; static llvm::cl::opt OptLevel("O", llvm::cl::Prefix, llvm::cl::desc("Optimization level")); static llvm::cl::opt OptSize("Os", llvm::cl::desc("Optimize for size")); } //===----------------------------------------------------------------------===// // Dependency Output Options //===----------------------------------------------------------------------===// namespace dependencyoutputoptions { static llvm::cl::opt DependencyFile("dependency-file", llvm::cl::desc("Filename (or -) to write dependency output to")); static llvm::cl::opt DependenciesIncludeSystemHeaders("sys-header-deps", llvm::cl::desc("Include system headers in dependency output")); static llvm::cl::list DependencyTargets("MT", llvm::cl::desc("Specify target for dependency")); static llvm::cl::opt PhonyDependencyTarget("MP", llvm::cl::desc("Create phony target for each dependency " "(other than main file)")); } //===----------------------------------------------------------------------===// // Diagnostic Options //===----------------------------------------------------------------------===// namespace diagnosticoptions { static llvm::cl::opt DumpBuildInformation("dump-build-information", llvm::cl::value_desc("filename"), llvm::cl::desc("output a dump of some build information to a file")); static llvm::cl::opt NoShowColumn("fno-show-column", llvm::cl::desc("Do not include column number on diagnostics")); static llvm::cl::opt NoShowLocation("fno-show-source-location", llvm::cl::desc("Do not include source location information with" " diagnostics")); static llvm::cl::opt NoCaretDiagnostics("fno-caret-diagnostics", llvm::cl::desc("Do not include source line and caret with" " diagnostics")); static llvm::cl::opt NoDiagnosticsFixIt("fno-diagnostics-fixit-info", llvm::cl::desc("Do not include fixit information in" " diagnostics")); static llvm::cl::opt OptNoWarnings("w"); static llvm::cl::opt OptPedantic("pedantic"); static llvm::cl::opt OptPedanticErrors("pedantic-errors"); // This gets all -W options, including -Werror, -W[no-]system-headers, etc. The // driver has stripped off -Wa,foo etc. The driver has also translated -W to // -Wextra, so we don't need to worry about it. static llvm::cl::list OptWarnings("W", llvm::cl::Prefix, llvm::cl::ValueOptional); static llvm::cl::opt PrintSourceRangeInfo("fdiagnostics-print-source-range-info", llvm::cl::desc("Print source range spans in numeric form")); static llvm::cl::opt PrintDiagnosticOption("fdiagnostics-show-option", llvm::cl::desc("Print diagnostic name with mappable diagnostics")); static llvm::cl::opt MessageLength("fmessage-length", llvm::cl::desc("Format message diagnostics so that they fit " "within N columns or fewer, when possible."), llvm::cl::value_desc("N")); static llvm::cl::opt PrintColorDiagnostic("fcolor-diagnostics", llvm::cl::desc("Use colors in diagnostics")); static llvm::cl::opt SilenceRewriteMacroWarning("Wno-rewrite-macros", llvm::cl::desc("Silence ObjC rewriting warnings")); static llvm::cl::opt VerifyDiagnostics("verify", llvm::cl::desc("Verify emitted diagnostics and warnings")); } //===----------------------------------------------------------------------===// // Frontend Options //===----------------------------------------------------------------------===// namespace frontendoptions { using namespace clang::frontend; static llvm::cl::opt CodeCompletionAt("code-completion-at", llvm::cl::value_desc("file:line:column"), llvm::cl::desc("Dump code-completion information at a location")); static llvm::cl::opt NoCodeCompletionDebugPrinter("no-code-completion-debug-printer", llvm::cl::desc("Don't the \"debug\" code-completion print")); static llvm::cl::opt CodeCompletionWantsMacros("code-completion-macros", llvm::cl::desc("Include macros in code-completion results")); static llvm::cl::opt DisableFree("disable-free", llvm::cl::desc("Disable freeing of memory on exit")); static llvm::cl::opt EmptyInputOnly("empty-input-only", llvm::cl::desc("Force running on an empty input file")); static llvm::cl::opt InputType("x", llvm::cl::desc("Input language type"), llvm::cl::init(FrontendOptions::IK_None), llvm::cl::values(clEnumValN(FrontendOptions::IK_C, "c", "C"), clEnumValN(FrontendOptions::IK_OpenCL, "cl", "OpenCL C"), clEnumValN(FrontendOptions::IK_CXX, "c++", "C++"), clEnumValN(FrontendOptions::IK_ObjC, "objective-c", "Objective C"), clEnumValN(FrontendOptions::IK_ObjCXX, "objective-c++", "Objective C++"), clEnumValN(FrontendOptions::IK_PreprocessedC, "cpp-output", "Preprocessed C"), clEnumValN(FrontendOptions::IK_Asm, "assembler-with-cpp", "Assembly Source Codde"), clEnumValN(FrontendOptions::IK_PreprocessedCXX, "c++-cpp-output", "Preprocessed C++"), clEnumValN(FrontendOptions::IK_PreprocessedObjC, "objective-c-cpp-output", "Preprocessed Objective C"), clEnumValN(FrontendOptions::IK_PreprocessedObjCXX, "objective-c++-cpp-output", "Preprocessed Objective C++"), clEnumValN(FrontendOptions::IK_C, "c-header", "C header"), clEnumValN(FrontendOptions::IK_ObjC, "objective-c-header", "Objective-C header"), clEnumValN(FrontendOptions::IK_CXX, "c++-header", "C++ header"), clEnumValN(FrontendOptions::IK_ObjCXX, "objective-c++-header", "Objective-C++ header"), clEnumValN(FrontendOptions::IK_AST, "ast", "Clang AST"), clEnumValEnd)); static llvm::cl::list InputFilenames(llvm::cl::Positional, llvm::cl::desc("")); static llvm::cl::opt InheritanceViewCls("cxx-inheritance-view", llvm::cl::value_desc("class name"), llvm::cl::desc("View C++ inheritance for a specified class")); static llvm::cl::list FixItAtLocations("fixit-at", llvm::cl::value_desc("source-location"), llvm::cl::desc("Perform Fix-It modifications at the given source location")); static llvm::cl::opt OutputFile("o", llvm::cl::value_desc("path"), llvm::cl::desc("Specify output file")); static llvm::cl::opt PluginActionName("plugin", llvm::cl::desc("Use the named plugin action " "(use \"help\" to list available options)")); static llvm::cl::opt ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore, llvm::cl::init(ParseSyntaxOnly), llvm::cl::values( clEnumValN(RunPreprocessorOnly, "Eonly", "Just run preprocessor, no output (for timings)"), clEnumValN(PrintPreprocessedInput, "E", "Run preprocessor, emit preprocessed file"), clEnumValN(DumpRawTokens, "dump-raw-tokens", "Lex file in raw mode and dump raw tokens"), clEnumValN(RunAnalysis, "analyze", "Run static analysis engine"), clEnumValN(DumpTokens, "dump-tokens", "Run preprocessor, dump internal rep of tokens"), clEnumValN(ParseNoop, "parse-noop", "Run parser with noop callbacks (for timings)"), clEnumValN(ParseSyntaxOnly, "fsyntax-only", "Run parser and perform semantic analysis"), clEnumValN(FixIt, "fixit", "Apply fix-it advice to the input source"), clEnumValN(ParsePrintCallbacks, "parse-print-callbacks", "Run parser and print each callback invoked"), clEnumValN(EmitHTML, "emit-html", "Output input source as HTML"), clEnumValN(ASTPrint, "ast-print", "Build ASTs and then pretty-print them"), clEnumValN(ASTPrintXML, "ast-print-xml", "Build ASTs and then print them in XML format"), clEnumValN(ASTDump, "ast-dump", "Build ASTs and then debug dump them"), clEnumValN(ASTView, "ast-view", "Build ASTs and view them with GraphViz"), clEnumValN(PrintDeclContext, "print-decl-contexts", "Print DeclContexts and their Decls"), clEnumValN(DumpRecordLayouts, "dump-record-layouts", "Dump record layout information"), clEnumValN(GeneratePTH, "emit-pth", "Generate pre-tokenized header file"), clEnumValN(GeneratePCH, "emit-pch", "Generate pre-compiled header file"), clEnumValN(EmitAssembly, "S", "Emit native assembly code"), clEnumValN(EmitLLVM, "emit-llvm", "Build ASTs then convert to LLVM, emit .ll file"), clEnumValN(EmitBC, "emit-llvm-bc", "Build ASTs then convert to LLVM, emit .bc file"), clEnumValN(EmitLLVMOnly, "emit-llvm-only", "Build ASTs and convert to LLVM, discarding output"), clEnumValN(RewriteTest, "rewrite-test", "Rewriter playground"), clEnumValN(RewriteObjC, "rewrite-objc", "Rewrite ObjC into C (code rewriter example)"), clEnumValN(RewriteMacros, "rewrite-macros", "Expand macros without full preprocessing"), clEnumValN(RewriteBlocks, "rewrite-blocks", "Rewrite Blocks to C"), clEnumValEnd)); static llvm::cl::opt RelocatablePCH("relocatable-pch", llvm::cl::desc("Whether to build a relocatable precompiled " "header")); static llvm::cl::opt Stats("print-stats", llvm::cl::desc("Print performance metrics and statistics")); static llvm::cl::opt TimeReport("ftime-report", llvm::cl::desc("Print the amount of time each " "phase of compilation takes")); } //===----------------------------------------------------------------------===// // Language Options //===----------------------------------------------------------------------===// namespace langoptions { using namespace clang::frontend; static llvm::cl::opt NoBuiltin("fno-builtin", llvm::cl::desc("Disable implicit builtin knowledge of functions")); static llvm::cl::opt AltiVec("faltivec", llvm::cl::desc("Enable AltiVec vector initializer syntax")); static llvm::cl::opt AccessControl("faccess-control", llvm::cl::desc("Enable C++ access control")); static llvm::cl::opt NoSignedChar("fno-signed-char", llvm::cl::desc("Char is unsigned")); static llvm::cl::opt DollarsInIdents("fdollars-in-identifiers", llvm::cl::desc("Allow '$' in identifiers")); static llvm::cl::opt EmitAllDecls("femit-all-decls", llvm::cl::desc("Emit all declarations, even if unused")); static llvm::cl::opt EnableBlocks("fblocks", llvm::cl::desc("enable the 'blocks' language feature")); static llvm::cl::opt EnableHeinousExtensions("fheinous-gnu-extensions", llvm::cl::desc("enable GNU extensions that you really really shouldn't use"), llvm::cl::ValueDisallowed, llvm::cl::Hidden); static llvm::cl::opt Exceptions("fexceptions", llvm::cl::desc("Enable support for exception handling")); static llvm::cl::opt Freestanding("ffreestanding", llvm::cl::desc("Assert that the compilation takes place in a " "freestanding environment")); static llvm::cl::opt GNURuntime("fgnu-runtime", llvm::cl::desc("Generate output compatible with the standard GNU " "Objective-C runtime")); static llvm::cl::opt LangStd("std", llvm::cl::desc("Language standard to compile for"), llvm::cl::init(LangStandard::lang_unspecified), llvm::cl::values( #define LANGSTANDARD(id, name, desc, features) \ clEnumValN(LangStandard::lang_##id, name, desc), #include "clang/Frontend/LangStandards.def" clEnumValEnd)); static llvm::cl::opt MSExtensions("fms-extensions", llvm::cl::desc("Accept some non-standard constructs used in " "Microsoft header files ")); static llvm::cl::opt NoMathErrno("fno-math-errno", llvm::cl::desc("Don't require math functions to respect errno")); static llvm::cl::opt NoElideConstructors("fno-elide-constructors", llvm::cl::desc("Disable C++ copy constructor elision")); static llvm::cl::opt NoLaxVectorConversions("fno-lax-vector-conversions", llvm::cl::desc("Disallow implicit conversions between " "vectors with a different number of " "elements or different element types")); static llvm::cl::opt NoOperatorNames("fno-operator-names", llvm::cl::desc("Do not treat C++ operator name keywords as " "synonyms for operators")); static llvm::cl::opt ObjCConstantStringClass("fconstant-string-class", llvm::cl::value_desc("class name"), llvm::cl::desc("Specify the class to use for constant " "Objective-C string objects.")); static llvm::cl::opt ObjCEnableGC("fobjc-gc", llvm::cl::desc("Enable Objective-C garbage collection")); static llvm::cl::opt ObjCExclusiveGC("fobjc-gc-only", llvm::cl::desc("Use GC exclusively for Objective-C related " "memory management")); static llvm::cl::opt ObjCEnableGCBitmapPrint("print-ivar-layout", llvm::cl::desc("Enable Objective-C Ivar layout bitmap print trace")); static llvm::cl::opt ObjCNonFragileABI("fobjc-nonfragile-abi", llvm::cl::desc("enable objective-c's nonfragile abi")); static llvm::cl::opt OverflowChecking("ftrapv", llvm::cl::desc("Trap on integer overflow")); static llvm::cl::opt PICLevel("pic-level", llvm::cl::desc("Value for __PIC__")); static llvm::cl::opt PThread("pthread", llvm::cl::desc("Support POSIX threads in generated code")); static llvm::cl::opt PascalStrings("fpascal-strings", llvm::cl::desc("Recognize and construct Pascal-style " "string literals")); static llvm::cl::opt NoRtti("fno-rtti", llvm::cl::desc("Disable generation of rtti information")); static llvm::cl::opt ShortWChar("fshort-wchar", llvm::cl::desc("Force wchar_t to be a short unsigned int")); static llvm::cl::opt StaticDefine("static-define", llvm::cl::desc("Should __STATIC__ be defined")); static llvm::cl::opt StackProtector("stack-protector", llvm::cl::desc("Enable stack protectors")); static llvm::cl::opt SymbolVisibility("fvisibility", llvm::cl::desc("Set the default symbol visibility:"), llvm::cl::init(LangOptions::Default), llvm::cl::values(clEnumValN(LangOptions::Default, "default", "Use default symbol visibility"), clEnumValN(LangOptions::Hidden, "hidden", "Use hidden symbol visibility"), clEnumValN(LangOptions::Protected,"protected", "Use protected symbol visibility"), clEnumValEnd)); static llvm::cl::opt TemplateDepth("ftemplate-depth", llvm::cl::desc("Maximum depth of recursive template " "instantiation")); static llvm::cl::opt Trigraphs("trigraphs", llvm::cl::desc("Process trigraph sequences")); static llvm::cl::opt WritableStrings("fwritable-strings", llvm::cl::desc("Store string literals as writable data")); } //===----------------------------------------------------------------------===// // General Preprocessor Options //===----------------------------------------------------------------------===// namespace preprocessoroptions { static llvm::cl::list D_macros("D", llvm::cl::value_desc("macro"), llvm::cl::Prefix, llvm::cl::desc("Predefine the specified macro")); static llvm::cl::list ImplicitIncludes("include", llvm::cl::value_desc("file"), llvm::cl::desc("Include file before parsing")); static llvm::cl::list ImplicitMacroIncludes("imacros", llvm::cl::value_desc("file"), llvm::cl::desc("Include macros from file before parsing")); static llvm::cl::opt ImplicitIncludePCH("include-pch", llvm::cl::value_desc("file"), llvm::cl::desc("Include precompiled header file")); static llvm::cl::opt ImplicitIncludePTH("include-pth", llvm::cl::value_desc("file"), llvm::cl::desc("Include file before parsing")); static llvm::cl::opt TokenCache("token-cache", llvm::cl::value_desc("path"), llvm::cl::desc("Use specified token cache file")); static llvm::cl::list U_macros("U", llvm::cl::value_desc("macro"), llvm::cl::Prefix, llvm::cl::desc("Undefine the specified macro")); static llvm::cl::opt UndefMacros("undef", llvm::cl::value_desc("macro"), llvm::cl::desc("undef all system defines")); } //===----------------------------------------------------------------------===// // Header Search Options //===----------------------------------------------------------------------===// namespace headersearchoptions { static llvm::cl::opt nostdinc("nostdinc", llvm::cl::desc("Disable standard #include directories")); static llvm::cl::opt nobuiltininc("nobuiltininc", llvm::cl::desc("Disable builtin #include directories")); // Various command line options. These four add directories to each chain. static llvm::cl::list F_dirs("F", llvm::cl::value_desc("directory"), llvm::cl::Prefix, llvm::cl::desc("Add directory to framework include search path")); static llvm::cl::list I_dirs("I", llvm::cl::value_desc("directory"), llvm::cl::Prefix, llvm::cl::desc("Add directory to include search path")); static llvm::cl::list idirafter_dirs("idirafter", llvm::cl::value_desc("directory"), llvm::cl::Prefix, llvm::cl::desc("Add directory to AFTER include search path")); static llvm::cl::list iquote_dirs("iquote", llvm::cl::value_desc("directory"), llvm::cl::Prefix, llvm::cl::desc("Add directory to QUOTE include search path")); static llvm::cl::list isystem_dirs("isystem", llvm::cl::value_desc("directory"), llvm::cl::Prefix, llvm::cl::desc("Add directory to SYSTEM include search path")); // These handle -iprefix/-iwithprefix/-iwithprefixbefore. static llvm::cl::list iprefix_vals("iprefix", llvm::cl::value_desc("prefix"), llvm::cl::Prefix, llvm::cl::desc("Set the -iwithprefix/-iwithprefixbefore prefix")); static llvm::cl::list iwithprefix_vals("iwithprefix", llvm::cl::value_desc("dir"), llvm::cl::Prefix, llvm::cl::desc("Set directory to SYSTEM include search path with prefix")); static llvm::cl::list iwithprefixbefore_vals("iwithprefixbefore", llvm::cl::value_desc("dir"), llvm::cl::Prefix, llvm::cl::desc("Set directory to include search path with prefix")); static llvm::cl::opt isysroot("isysroot", llvm::cl::value_desc("dir"), llvm::cl::desc("Set the system root directory (usually /)")); static llvm::cl::opt Verbose("v", llvm::cl::desc("Enable verbose output")); } //===----------------------------------------------------------------------===// // Preprocessed Output Options //===----------------------------------------------------------------------===// namespace preprocessoroutputoptions { static llvm::cl::opt DisableLineMarkers("P", llvm::cl::desc("Disable linemarker output in -E mode")); static llvm::cl::opt EnableCommentOutput("C", llvm::cl::desc("Enable comment output in -E mode")); static llvm::cl::opt EnableMacroCommentOutput("CC", llvm::cl::desc("Enable comment output in -E mode, " "even from macro expansions")); static llvm::cl::opt DumpMacros("dM", llvm::cl::desc("Print macro definitions in -E mode instead of" " normal output")); static llvm::cl::opt DumpDefines("dD", llvm::cl::desc("Print macro definitions in -E mode in " "addition to normal output")); } //===----------------------------------------------------------------------===// // Target Options //===----------------------------------------------------------------------===// namespace targetoptions { static llvm::cl::opt TargetABI("target-abi", llvm::cl::desc("Target a particular ABI type")); static llvm::cl::opt TargetCPU("mcpu", llvm::cl::desc("Target a specific cpu type ('-mcpu help' for details)")); static llvm::cl::list TargetFeatures("target-feature", llvm::cl::desc("Target specific attributes")); static llvm::cl::opt TargetTriple("triple", llvm::cl::desc("Specify target triple (e.g. i686-apple-darwin9)")); } //===----------------------------------------------------------------------===// // Option Object Construction //===----------------------------------------------------------------------===// void clang::InitializeAnalyzerOptions(AnalyzerOptions &Opts) { using namespace analyzeroptions; Opts.AnalysisList = AnalysisList; Opts.AnalysisStoreOpt = AnalysisStoreOpt; Opts.AnalysisConstraintsOpt = AnalysisConstraintsOpt; Opts.AnalysisDiagOpt = AnalysisDiagOpt; Opts.VisualizeEGDot = VisualizeEGDot; Opts.VisualizeEGUbi = VisualizeEGUbi; Opts.AnalyzeAll = AnalyzeAll; Opts.AnalyzerDisplayProgress = AnalyzerDisplayProgress; Opts.PurgeDead = !NoPurgeDead; Opts.EagerlyAssume = EagerlyAssume; Opts.AnalyzeSpecificFunction = AnalyzeSpecificFunction; Opts.EnableExperimentalChecks = AnalyzerExperimentalChecks; Opts.EnableExperimentalInternalChecks = AnalyzerExperimentalInternalChecks; Opts.TrimGraph = TrimGraph; } void clang::InitializeCodeGenOptions(CodeGenOptions &Opts, const LangOptions &Lang) { using namespace codegenoptions; // -Os implies -O2 unsigned Opt = OptLevel.getPosition() ? OptLevel : 0; Opts.OptimizationLevel = OptSize ? 2 : Opt; // We must always run at least the always inlining pass. Opts.Inlining = (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining : CodeGenOptions::OnlyAlwaysInlining; Opts.DebugInfo = GenerateDebugInfo; Opts.DisableLLVMOpts = DisableLLVMOptimizations; Opts.DisableRedZone = DisableRedZone; Opts.MergeAllConstants = !NoMergeConstants; Opts.NoCommon = NoCommon; Opts.NoImplicitFloat = NoImplicitFloat; Opts.OptimizeSize = OptSize; Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !OptSize); // LLVM Code Generator options. Opts.AsmVerbose = MAsmVerbose; Opts.CodeModel = MCodeModel; Opts.DebugPass = MDebugPass; Opts.DisableFPElim = MDisableFPElim; Opts.FloatABI = MFloatABI; Opts.LimitFloatPrecision = MLimitFloatPrecision; Opts.NoZeroInitializedInBSS = MNoZeroInitializedInBSS; Opts.SoftFloat = MSoftFloat; Opts.RelocationModel = MRelocationModel; Opts.UnwindTables = MUnwindTables; #ifdef NDEBUG Opts.VerifyModule = 0; #endif if (MainFileName.getPosition()) Opts.MainFileName = MainFileName; } void clang::InitializeDependencyOutputOptions(DependencyOutputOptions &Opts) { using namespace dependencyoutputoptions; Opts.OutputFile = DependencyFile; Opts.Targets = DependencyTargets; Opts.IncludeSystemHeaders = DependenciesIncludeSystemHeaders; Opts.UsePhonyTargets = PhonyDependencyTarget; } void clang::InitializeDiagnosticOptions(DiagnosticOptions &Opts) { using namespace diagnosticoptions; Opts.Warnings = OptWarnings; Opts.DumpBuildInformation = DumpBuildInformation; Opts.IgnoreWarnings = OptNoWarnings; Opts.MessageLength = MessageLength; Opts.NoRewriteMacros = SilenceRewriteMacroWarning; Opts.Pedantic = OptPedantic; Opts.PedanticErrors = OptPedanticErrors; Opts.ShowCarets = !NoCaretDiagnostics; Opts.ShowColors = PrintColorDiagnostic; Opts.ShowColumn = !NoShowColumn; Opts.ShowFixits = !NoDiagnosticsFixIt; Opts.ShowLocation = !NoShowLocation; Opts.ShowOptionNames = PrintDiagnosticOption; Opts.ShowSourceRanges = PrintSourceRangeInfo; Opts.VerifyDiagnostics = VerifyDiagnostics; } void clang::InitializeFrontendOptions(FrontendOptions &Opts) { using namespace frontendoptions; Opts.ProgramAction = ProgAction; Opts.ActionName = PluginActionName; Opts.CodeCompletionAt = CodeCompletionAt; Opts.DebugCodeCompletionPrinter = !NoCodeCompletionDebugPrinter; Opts.DisableFree = DisableFree; Opts.EmptyInputOnly = EmptyInputOnly; Opts.FixItLocations = FixItAtLocations; Opts.OutputFile = OutputFile; Opts.RelocatablePCH = RelocatablePCH; Opts.ShowMacrosInCodeCompletion = CodeCompletionWantsMacros; Opts.ShowStats = Stats; Opts.ShowTimers = TimeReport; Opts.ViewClassInheritance = InheritanceViewCls; // Enforce certain program action implications. if (!Opts.ActionName.empty()) Opts.ProgramAction = frontend::PluginAction; if (!Opts.ViewClassInheritance.empty()) Opts.ProgramAction = frontend::InheritanceView; if (!Opts.FixItLocations.empty()) Opts.ProgramAction = frontend::FixIt; // '-' is the default input if none is given. if (InputFilenames.empty()) { FrontendOptions::InputKind IK = InputType; if (IK == FrontendOptions::IK_None) IK = FrontendOptions::IK_C; Opts.Inputs.push_back(std::make_pair(IK, "-")); } else { for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) { FrontendOptions::InputKind IK = InputType; llvm::StringRef Ext = llvm::StringRef(InputFilenames[i]).rsplit('.').second; if (IK == FrontendOptions::IK_None) IK = FrontendOptions::getInputKindForExtension(Ext); Opts.Inputs.push_back(std::make_pair(IK, InputFilenames[i])); } } } void clang::InitializeHeaderSearchOptions(HeaderSearchOptions &Opts, llvm::StringRef BuiltinIncludePath) { using namespace headersearchoptions; if (isysroot.getPosition()) Opts.Sysroot = isysroot; Opts.Verbose = Verbose; // Handle -I... and -F... options, walking the lists in parallel. unsigned Iidx = 0, Fidx = 0; while (Iidx < I_dirs.size() && Fidx < F_dirs.size()) { if (I_dirs.getPosition(Iidx) < F_dirs.getPosition(Fidx)) { Opts.AddPath(I_dirs[Iidx], frontend::Angled, true, false); ++Iidx; } else { Opts.AddPath(F_dirs[Fidx], frontend::Angled, true, true); ++Fidx; } } // Consume what's left from whatever list was longer. for (; Iidx != I_dirs.size(); ++Iidx) Opts.AddPath(I_dirs[Iidx], frontend::Angled, true, false); for (; Fidx != F_dirs.size(); ++Fidx) Opts.AddPath(F_dirs[Fidx], frontend::Angled, true, true); // Handle -idirafter... options. for (unsigned i = 0, e = idirafter_dirs.size(); i != e; ++i) Opts.AddPath(idirafter_dirs[i], frontend::After, true, false); // Handle -iquote... options. for (unsigned i = 0, e = iquote_dirs.size(); i != e; ++i) Opts.AddPath(iquote_dirs[i], frontend::Quoted, true, false); // Handle -isystem... options. for (unsigned i = 0, e = isystem_dirs.size(); i != e; ++i) Opts.AddPath(isystem_dirs[i], frontend::System, true, false); // Walk the -iprefix/-iwithprefix/-iwithprefixbefore argument lists in // parallel, processing the values in order of occurance to get the right // prefixes. { std::string Prefix = ""; // FIXME: this isn't the correct default prefix. unsigned iprefix_idx = 0; unsigned iwithprefix_idx = 0; unsigned iwithprefixbefore_idx = 0; bool iprefix_done = iprefix_vals.empty(); bool iwithprefix_done = iwithprefix_vals.empty(); bool iwithprefixbefore_done = iwithprefixbefore_vals.empty(); while (!iprefix_done || !iwithprefix_done || !iwithprefixbefore_done) { if (!iprefix_done && (iwithprefix_done || iprefix_vals.getPosition(iprefix_idx) < iwithprefix_vals.getPosition(iwithprefix_idx)) && (iwithprefixbefore_done || iprefix_vals.getPosition(iprefix_idx) < iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) { Prefix = iprefix_vals[iprefix_idx]; ++iprefix_idx; iprefix_done = iprefix_idx == iprefix_vals.size(); } else if (!iwithprefix_done && (iwithprefixbefore_done || iwithprefix_vals.getPosition(iwithprefix_idx) < iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) { Opts.AddPath(Prefix+iwithprefix_vals[iwithprefix_idx], frontend::System, false, false); ++iwithprefix_idx; iwithprefix_done = iwithprefix_idx == iwithprefix_vals.size(); } else { Opts.AddPath(Prefix+iwithprefixbefore_vals[iwithprefixbefore_idx], frontend::Angled, false, false); ++iwithprefixbefore_idx; iwithprefixbefore_done = iwithprefixbefore_idx == iwithprefixbefore_vals.size(); } } } // Add CPATH environment paths. if (const char *Env = getenv("CPATH")) Opts.EnvIncPath = Env; // Add language specific environment paths. if (const char *Env = getenv("OBJCPLUS_INCLUDE_PATH")) Opts.ObjCXXEnvIncPath = Env; if (const char *Env = getenv("CPLUS_INCLUDE_PATH")) Opts.CXXEnvIncPath = Env; if (const char *Env = getenv("OBJC_INCLUDE_PATH")) Opts.CEnvIncPath = Env; if (const char *Env = getenv("C_INCLUDE_PATH")) Opts.CEnvIncPath = Env; if (!nobuiltininc) Opts.BuiltinIncludePath = BuiltinIncludePath; Opts.UseStandardIncludes = !nostdinc; } void clang::InitializePreprocessorOptions(PreprocessorOptions &Opts) { using namespace preprocessoroptions; Opts.ImplicitPCHInclude = ImplicitIncludePCH; Opts.ImplicitPTHInclude = ImplicitIncludePTH; // Select the token cache file, we don't support more than one currently so we // can't have both an implicit-pth and a token cache file. if (TokenCache.getPosition() && ImplicitIncludePTH.getPosition()) { // FIXME: Don't fail like this. fprintf(stderr, "error: cannot use both -token-cache and -include-pth " "options\n"); exit(1); } if (TokenCache.getPosition()) Opts.TokenCache = TokenCache; else Opts.TokenCache = ImplicitIncludePTH; // Use predefines? Opts.UsePredefines = !UndefMacros; // Add macros from the command line. unsigned d = 0, D = D_macros.size(); unsigned u = 0, U = U_macros.size(); while (d < D || u < U) { if (u == U || (d < D && D_macros.getPosition(d) < U_macros.getPosition(u))) Opts.addMacroDef(D_macros[d++]); else Opts.addMacroUndef(U_macros[u++]); } // If -imacros are specified, include them now. These are processed before // any -include directives. for (unsigned i = 0, e = ImplicitMacroIncludes.size(); i != e; ++i) Opts.MacroIncludes.push_back(ImplicitMacroIncludes[i]); // Add the ordered list of -includes, sorting in the implicit include options // at the appropriate location. llvm::SmallVector, 8> OrderedPaths; std::string OriginalFile; if (!ImplicitIncludePTH.empty()) OrderedPaths.push_back(std::make_pair(ImplicitIncludePTH.getPosition(), &ImplicitIncludePTH)); if (!ImplicitIncludePCH.empty()) { OriginalFile = PCHReader::getOriginalSourceFile(ImplicitIncludePCH); // FIXME: Don't fail like this. if (OriginalFile.empty()) exit(1); OrderedPaths.push_back(std::make_pair(ImplicitIncludePCH.getPosition(), &OriginalFile)); } for (unsigned i = 0, e = ImplicitIncludes.size(); i != e; ++i) OrderedPaths.push_back(std::make_pair(ImplicitIncludes.getPosition(i), &ImplicitIncludes[i])); llvm::array_pod_sort(OrderedPaths.begin(), OrderedPaths.end()); for (unsigned i = 0, e = OrderedPaths.size(); i != e; ++i) Opts.Includes.push_back(*OrderedPaths[i].second); } void clang::InitializeLangOptions(LangOptions &Options, FrontendOptions::InputKind IK) { using namespace langoptions; // 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. if (IK == FrontendOptions::IK_Asm) { Options.AsmPreprocessor = 1; } else if (IK == FrontendOptions::IK_ObjC || IK == FrontendOptions::IK_ObjCXX || IK == FrontendOptions::IK_PreprocessedObjC || IK == FrontendOptions::IK_PreprocessedObjCXX) { Options.ObjC1 = Options.ObjC2 = 1; } if (LangStd == LangStandard::lang_unspecified) { // Based on the base language, pick one. switch (IK) { case FrontendOptions::IK_None: case FrontendOptions::IK_AST: assert(0 && "Invalid input kind!"); case FrontendOptions::IK_OpenCL: LangStd = LangStandard::lang_opencl; break; case FrontendOptions::IK_Asm: case FrontendOptions::IK_C: case FrontendOptions::IK_PreprocessedC: case FrontendOptions::IK_ObjC: case FrontendOptions::IK_PreprocessedObjC: LangStd = LangStandard::lang_gnu99; break; case FrontendOptions::IK_CXX: case FrontendOptions::IK_PreprocessedCXX: case FrontendOptions::IK_ObjCXX: case FrontendOptions::IK_PreprocessedObjCXX: LangStd = LangStandard::lang_gnucxx98; break; } } const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); Options.BCPLComment = Std.hasBCPLComments(); Options.C99 = Std.isC99(); Options.CPlusPlus = Std.isCPlusPlus(); Options.CPlusPlus0x = Std.isCPlusPlus0x(); Options.Digraphs = Std.hasDigraphs(); Options.GNUInline = !Std.isC99(); Options.GNUMode = Std.isGNUMode(); Options.HexFloats = Std.hasHexFloats(); Options.ImplicitInt = Std.hasImplicitInt(); // OpenCL has some additional defaults. if (LangStd == LangStandard::lang_opencl) { Options.OpenCL = 1; Options.AltiVec = 1; Options.CXXOperatorNames = 1; Options.LaxVectorConversions = 1; } // OpenCL and C++ both have bool, true, false keywords. Options.Bool = Options.OpenCL || Options.CPlusPlus; if (Options.CPlusPlus) Options.CXXOperatorNames = !NoOperatorNames; if (ObjCExclusiveGC) Options.setGCMode(LangOptions::GCOnly); else if (ObjCEnableGC) Options.setGCMode(LangOptions::HybridGC); if (ObjCEnableGCBitmapPrint) Options.ObjCGCBitmapPrint = 1; if (AltiVec) Options.AltiVec = 1; if (PThread) Options.POSIXThreads = 1; Options.setVisibilityMode(SymbolVisibility); Options.OverflowChecking = OverflowChecking; // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs // is specified, or -std is set to a conforming mode. Options.Trigraphs = !Options.GNUMode; if (Trigraphs.getPosition()) Options.Trigraphs = Trigraphs; // Command line option wins if specified. // Default to not accepting '$' in identifiers when preprocessing assembler. Options.DollarIdents = !Options.AsmPreprocessor; if (DollarsInIdents.getPosition()) // Explicit setting overrides default. Options.DollarIdents = DollarsInIdents; if (PascalStrings.getPosition()) Options.PascalStrings = PascalStrings; if (MSExtensions.getPosition()) Options.Microsoft = MSExtensions; Options.WritableStrings = WritableStrings; if (NoLaxVectorConversions.getPosition()) Options.LaxVectorConversions = 0; Options.Exceptions = Exceptions; Options.Rtti = !NoRtti; Options.Blocks = EnableBlocks; Options.CharIsSigned = !NoSignedChar; if (ShortWChar.getPosition()) Options.ShortWChar = ShortWChar; Options.NoBuiltin = NoBuiltin; if (Freestanding) Options.Freestanding = Options.NoBuiltin = 1; if (EnableHeinousExtensions) Options.HeinousExtensions = 1; if (AccessControl) Options.AccessControl = 1; Options.ElideConstructors = !NoElideConstructors; Options.MathErrno = !NoMathErrno; if (TemplateDepth.getPosition()) Options.InstantiationDepth = TemplateDepth; // Override the default runtime if the user requested it. if (GNURuntime) Options.NeXTRuntime = 0; if (!ObjCConstantStringClass.empty()) Options.ObjCConstantStringClass = ObjCConstantStringClass; if (ObjCNonFragileABI) Options.ObjCNonFragileABI = 1; if (EmitAllDecls) Options.EmitAllDecls = 1; // The __OPTIMIZE_SIZE__ define is tied to -Oz, which we don't support. unsigned Opt = codegenoptions::OptLevel.getPosition() ? codegenoptions::OptLevel : 0; Options.OptimizeSize = 0; Options.Optimize = codegenoptions::OptSize || Opt; assert(PICLevel <= 2 && "Invalid value for -pic-level"); Options.PICLevel = PICLevel; // 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). Options.NoInline = !Opt; Options.Static = StaticDefine; if (StackProtector.getPosition()) { switch (StackProtector) { default: assert(0 && "Invalid value for -stack-protector"); case 0: Options.setStackProtectorMode(LangOptions::SSPOff); break; case 1: Options.setStackProtectorMode(LangOptions::SSPOn); break; case 2: Options.setStackProtectorMode(LangOptions::SSPReq); break; } } } void clang::InitializePreprocessorOutputOptions(PreprocessorOutputOptions &Opts) { using namespace preprocessoroutputoptions; Opts.ShowCPP = !DumpMacros; Opts.ShowMacros = DumpMacros || DumpDefines; Opts.ShowLineMarkers = !DisableLineMarkers; Opts.ShowComments = EnableCommentOutput; Opts.ShowMacroComments = EnableMacroCommentOutput; } void clang::InitializeTargetOptions(TargetOptions &Opts) { using namespace targetoptions; Opts.ABI = TargetABI; Opts.CPU = TargetCPU; Opts.Triple = TargetTriple; Opts.Features = TargetFeatures; // Use the host triple if unspecified. if (Opts.Triple.empty()) Opts.Triple = llvm::sys::getHostTriple(); }