#compdef gcc g++ cc c++ llvm-gcc llvm-g++ clang clang++ -value-,LDFLAGS,-default- -value-,CFLAGS,-default- -value-,CXXFLAGS,-default- -value-,CPPFLAGS,-default-

local curcontext="$curcontext" state line ret=1 expl args args2 march
typeset -A opt_args

if [[ "$service" = -value-* ]]; then
  compset -q
  words=( fake "$words[@]" )
  (( CURRENT++ ))
  if [[ "$service" = *LDFLAGS ]]; then
    args2=( '-R:runtime path:->rundir' )
  else
    args2=()
  fi
else
  args2=( '*:input file:_files -g "*.([cCmisSoak]|cc|cpp|cxx|ii|k[ih])(-.)"' )
fi

args=()
case $MACHTYPE in
m68*)
  args=(
    -m68000 -m68020 -m68020-40 -m68030 -m68040 -m68881
    -mbitfield -mc68000 -mc68020 -mfpa -mnobitfield
    -mrtd -mshort -msoft-float
  )
  ;;
vax)
  args=(
    -mg -mgnu -munix
  )
  ;;
c[1234]*)
  args=(
    -mc1 -mc2 -mc32 -mc34 -mc38
    -margcount -mnoargcount
    -mlong32 -mlong64
    -mvolatile-cache -mvolatile-nocache
  )
  ;;
amd290?0)
  args=(
    -m29000 -m29050 -mbw -mnbw -mdw -mndw
    -mlarge -mnormal -msmall
    -mkernel-registers -mno-reuse-arg-regs
    -mno-stack-check -mno-storem-bug
    -mreuse-arg-regs -msoft-float -mstack-check
    -mstorem-bug -muser-registers
  )
  ;;
arm)
  args=(
    -mapcs -m2 -m3 -m6 -mbsd -mxopen -mno-symrename
  )
  ;;
m88k)
  args=(
    -m88000 -m88100 -m88110 -mbig-pic
    -mcheck-zero-division -mhandle-large-shift
    -midentify-revision -mno-check-zero-division
    -mno-ocs-debug-info -mno-ocs-frame-position
    -mno-optimize-arg-area -mno-serialize-volatile
    -mno-underscores -mocs-debug-info
    -mocs-frame-position -moptimize-arg-area
    -mserialize-volatile -msvr3
    -msvr4 -mtrap-large-shift -muse-div-instruction
    -mversion-03.00 -mwarn-passed-structs
    '-mshort-data--:maximum displacement:'
  )
  ;;
rs6000|powerpc*)
  args=(
    '-mcpu=:CPU type:(rios1 rios2 rsc 501 603 604 power powerpc 403 common)'
    -mpower -mno-power -mpower2 -mno-power2
    -mpowerpc -mno-powerpc
    -mpowerpc-gpopt -mno-powerpc-gpopt
    -mpowerpc-gfxopt -mno-powerpc-gfxopt
    -mnew-mnemonics -mno-new-mnemonics
    -mfull-toc -mminimal-toc -mno-fop-in-toc -mno-sum-in-toc
    -msoft-float -mhard-float -mmultiple -mno-multiple
    -mstring -mno-string -mbit-align -mno-bit-align
    -mstrict-align -mno-strict-align -mrelocatable -mno-relocatable
    -mtoc -mno-toc -mtraceback -mno-traceback
    -mlittle -mlittle-endian -mbig -mbig-endian
    -mcall-aix -mcall-sysv -mprototype
  )
  ;;
romp)
  args=(
    -mcall-lib-mul -mfp-arg-in-fpregs -mfp-arg-in-gregs
    -mfull-fp-blocks -mhc-struct-return -min-line-mul
    -mminimum-fp-blocks -mnohc-struct-return
  )
  ;;
mips*)
  args=(
    '-mcpu=:CPU type:(r2000 r3000 r4000 r4400 r4600 r6000_'
    -mabicalls -membedded-data
    -membedded-pic -mfp32 -mfp64 -mgas -mgp32 -mgp64
    -mgpopt -mhalf-pic -mhard-float -mint64 -mips1
    -mips2 -mips3 -mlong64 -mlong-calls -mmemcpy
    -mmips-as -mmips-tfile -mno-abicalls
    -mno-embedded-data -mno-embedded-pic
    -mno-gpopt -mno-long-calls
    -mno-memcpy -mno-mips-tfile -mno-rnames -mno-stats
    -mrnames -msoft-float
    -m4650 -msingle-float -mmad
    -mstats -EL -EB -nocpp
    '-G:maximum size for small section objects:'
  )
  ;;
i[3456]86|x86_64)
  march="native i386 i486 i586 pentium pentium-mmx pentiumpro i686 pentium2 pentium3 pentium3m pentium-m pentium4 pentium4m prescott nocona core2 corei7 corei7-avx core-avx-i core-avx2 atom k6 k6-2 k6-3 athlon athlon-tbird athlon-4 athlon-xp athlon-mp k8 opteron athlon64 athlon-fx k8-sse3 opteron-sse3 athlon64-sse3 amdfam10 barcelona bdver1 bdver2 bdver3 btver1 btver2 winchip-c6 winchip2 c3 c3-2 geode"
  args=(
    '-mtune=-[tune code for CPU type]:CPU type:('"$march"')'
    '-march=-[generate instructions for CPU type]:CPU type:('"generic $march"')'
    -mthreads
    '-mreg-alloc=:default register allocation order:' 

    # arguments with options
    '-mabi=-[Generate code that conforms to the given ABI]:abi:(ms sysv)'
    '-maddress-mode=-[Use given address mode]:address mode:(short long)'
    '-malign-functions=-[Function starts are aligned to this power of 2]: **2 base for function alignment: '
    '-malign-jumps=-[Jump targets are aligned to this power of 2]: **2 base for jump goal alignment: '
    '-malign-loops=-[Loop code aligned to this power of 2]: **2 base for loop alignment: '
    '-masm=-[Use given assembler dialect]:asm dialect:(att intel)'
    '-mbranch-cost=-[Branches are this expensive (1-5, arbitrary units)]:branch cost (1-5): '
    '-mcmodel=-[Use given x86-64 code model]:memory model:(32 small kernel medium large)'
    '-mfpmath=-[Generate floating point mathematics using given instruction set]:FPU type:(387 sse sse,387 both)'
    '-mincoming-stack-boundary=-[Assume incoming stack aligned to this power of 2]:assumed size of boundary: '
    '-mlarge-data-threshold=-[Data greater than given threshold will go into .ldata section in x86-64 medium model]:threshold: '
    '-mpreferred-stack-boundary=-[Attempt to keep stack aligned to this power of 2]:size of boundary: '
    '-mregparm=-[Number of registers used to pass integer arguments]:number of integer argument registers: '
    '-mstringop-strategy=-[Chose strategy to generate stringop using]:stringop strategy:(byte_loop libcall loop rep_4byte rep_8byte rep_byte unrolled_loop)'
    '-mtls-dialect=-[Use given thread-local storage dialect]:TLS dialect:(gnu gnu2)'
    '-mveclibabi=-[Vector library ABI to use]:vector library ABI:(acml svml)'
    
    # arguments without options
    '-m3dnow[Support 3DNow! built-in functions]'
    '-m8bit-idiv[Expand 32bit/64bit integer divide into 8bit unsigned integer divide with run-time check]'
    '-m32[Generate 32bit i386 code]'
    '-m64[Generate 64bit x86-64 code]'
    '-m96bit-long-double[sizeof(long double) is 12]'
    '-m128bit-long-double[sizeof(long double) is 16]'
    '-m80387[Use hardware fp]'
    '-mabm[Support code generation of Advanced Bit Manipulation (ABM) instructions]'
    '-maccumulate-outgoing-args[Reserve space for outgoing arguments in the function prologue]'
    '-madx[Support flag-preserving add-carry instructions]'
    '-maes[Support AES built-in functions and code generation]'
    '-malign-double[Align some doubles on dword boundary]'
    '-malign-stringops[Align destination of the string operations]'
    '-mandroid[Generate code for the Android platform]'
    '-mavx2[Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and AVX2 built-in functions and code generation]'
    '-mavx256-split-unaligned-load[Split 32-byte AVX unaligned load]'
    '-mavx256-split-unaligned-store[Split 32-byte AVX unaligned store]'
    '-mavx[Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2 and AVX built-in functions and code generation]'
    '-mbionic[Use Bionic C library]'
    '-mbmi2[Support BMI2 built-in functions and code generation]'
    '-mbmi[Support BMI built-in functions and code generation]'
    '-mcld[Generate cld instruction in the function prologue]'
    '-mcrc32[Support code generation of crc32 instruction]'
    '-mcx16[Support code generation of cmpxchg16b instruction]'
    '-mdispatch-scheduler[Do dispatch scheduling if processor is bdver1 or bdver2 or bdver3 and Haifa scheduling is selected]'
    '-mf16c[Support F16C built-in functions and code generation]'
    '-mfancy-math-387[Generate sin, cos, sqrt for FPU]'
    '-mfentry[Emit profiling counter call at function entry before prologue]'
    '-mfma4[Support FMA4 built-in functions and code generation ]'
    '-mfma[Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and FMA built-in functions and code generation]'
    '-mforce-drap[Always use Dynamic Realigned Argument Pointer (DRAP) to realign stack]'
    '-mfp-ret-in-387[Return values of functions in FPU registers]'
    '-mfsgsbase[Support FSGSBASE built-in functions and code generation]'
    '-mfxsr[Support FXSAVE and FXRSTOR instructions]'
    '-mglibc[Use GNU C library]'
    '-mhard-float[Use hardware fp]'
    '-mhle[Support Hardware Lock Elision prefixes]'
    '-mieee-fp[Use IEEE math for fp comparisons]'
    '-minline-all-stringops[Inline all known string operations]'
    '-minline-stringops-dynamically[Inline memset/memcpy string operations, but perform inline version only for small blocks]'
    '-mlong-double-64[Use 64-bit long double]'
    '-mlong-double-80[Use 80-bit long double]'
    '-mlwp[Support LWP built-in functions and code generation ]'
    '-mlzcnt[Support LZCNT built-in function and code generation]'
    '-mmmx[Support MMX built-in functions]'
    '-mmovbe[Support code generation of movbe instruction]'
    '-mms-bitfields[Use native (MS) bitfield layout]'
    '-mno-sse4[Do not support SSE4.1 and SSE4.2 built-in functions and code generation]'
    '-momit-leaf-frame-pointer[Omit the frame pointer in leaf functions]'
    '-mpc32[Set 80387 floating-point precision to 32-bit]'
    '-mpc64[Set 80387 floating-point precision to 64-bit]'
    '-mpc80[Set 80387 floating-point precision to 80-bit]'
    '-mpclmul[Support PCLMUL built-in functions and code generation]'
    '-mpopcnt[Support code generation of popcnt instruction]'
    '-mprefer-avx128[Use 128-bit AVX instructions instead of 256-bit AVX instructions in the auto-vectorizer]'
    '-mprfchw[Support PREFETCHW instruction]'
    '-mpush-args[Use push instructions to save outgoing arguments]'
    '-mrdrnd[Support RDRND built-in functions and code generation]'
    '-mrdseed[Support RDSEED instruction]'
    '-mrecip[Generate reciprocals instead of divss and sqrtss]'
    '-mred-zone[Use red-zone in the x86-64 code]'
    '-mrtd[Alternate calling convention]'
    '-mrtm[Support RTM built-in functions and code generation]'
    '-msahf[Support code generation of sahf instruction in 64bit x86-64 code]'
    '-msoft-float[Do not use hardware fp]'
    '-msse2[Support MMX, SSE and SSE2 built-in functions and code generation]'
    '-msse2avx[Encode SSE instructions with VEX prefix]'
    '-msse3[Support MMX, SSE, SSE2 and SSE3 built-in functions and code generation]'
    '-msse4.1[Support MMX, SSE, SSE2, SSE3, SSSE3 and SSE4.1 built-in functions and code generation]'
    '-msse4.2[Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2 built-in functions and code generation]'
    '-msse4[Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2 built-in functions and code generation]'
    '-msse4a[Support MMX, SSE, SSE2, SSE3 and SSE4A built-in functions and code generation]'
    '-msse[Support MMX and SSE built-in functions and code generation]'
    '-msseregparm[Use SSE register passing conventions for SF and DF mode]'
    '-mssse3[Support MMX, SSE, SSE2, SSE3 and SSSE3 built-in functions and code generation]'
    '-mstack-arg-probe[Enable stack probing]'
    '-mstackrealign[Realign stack in prologue]'
    '-mtbm[Support TBM built-in functions and code generation]'
    '-mtls-direct-seg-refs[Use direct references against %gs when accessing tls data]'
    '-muclibc[Use uClibc C library]'
    '-mvect8-ret-in-mem[Return 8-byte vectors in memory]'
    '-mvzeroupper[Generate vzeroupper instruction before a transfer of control flow out of the function]'
    '-mx32[Generate 32bit x86-64 code]'
    '-mxop[Support XOP built-in functions and code generation ]'
    '-mxsave[Support XSAVE and XRSTOR instructions]'
    '-mxsaveopt[Support XSAVEOPT instruction]'
  )
  ;;
hppa*)
  args=(
    -mdisable-fpregs -mdisable-indexing -mfast-indirect-calls
    -mgas -mjump-in-delay -mlong-millicode-calls -mno-disable-fpregs
    -mno-disable-indexing -mno-fast-indirect-calls -mno-gas
    -mno-jump-in-delay -mno-millicode-long-calls
    -mno-portable-runtime -mno-soft-float -msoft-float
    -mpa-risc-1-0 -mpa-risc-1-1 -mportable-runtime
    '-mschedule=:code scheduling constraints:(700 7100 7100LC)'
  )
  ;;
i960)
  args=(
    -m{ka,kb,mc,ca,cf,sa,sb}
    -masm-compat -mclean-linkage
    -mcode-align -mcomplex-addr -mleaf-procedures
    -mic-compat -mic2.0-compat -mic3.0-compat
    -mintel-asm -mno-clean-linkage -mno-code-align
    -mno-complex-addr -mno-leaf-procedures
    -mno-old-align -mno-strict-align -mno-tail-call
    -mnumerics -mold-align -msoft-float -mstrict-align
    -mtail-call
  )
  ;;
sparc)
  args=(
    -mapp-regs -mno-app-regs
    -mfpu -mhard-float
    -mno-fpu -msoft-float
    -mhard-quad-float
    -msoft-quad-float
    -mno-unaligned-doubles
    -munaligned-doubles
    -mfaster-structs -mno-faster-structs
    -mimpure-text
    '-mcpu=:CPU type:(v7 cypress v8 supersparc sparclite f930 f934 hypersparc sparclite86x sparclet tsc701 v9 ultrasparc ultrasparc3)'
    '-mtune=:CPU type:(cypress supersparc hypersparc f930 f934 sparclite86x tsc701 ultrasparc ultrasparc3)'
    -mv8plus -mno-v8plus
    -mvis -mno-vis
    -mlittle-endian
    -m32 -m64
    '-mcmodel=:memory model:(medlow medmid medany embmedany)'
    -mstack-bias -mno-stack-bias
    -mv8
    -mcypress -mepilogue -mflat
    -mno-flat
    -mno-epilogue
    -msparclite -msupersparc
    -mmedlow -mmedany
    -mint32 -mint64 -mlong32 -mlong64
  )
  ;;
alpha*)
  args=(
    -mfp-regs -mno-fp-regs -mno-soft-float
    -msoft-float
  )
  ;;
clipper)
  args=(
    -mc300 -mc400
  )
  ;;
h8/300)
  args=(
    -mrelax -mh
  )
  ;;
esac

if [[ "$service" = clang* ]]; then
    args=(
        $args
        -flto -emit-llvm
        "-Qunused-arguments[don't emit warning for unused driver arguments]"
        --analyze
        -fshow-column -fshow-source-location -fcaret-diagnostics -fdiagnostics-fixit-info
        -fdiagnostics-parseable-fixits -fdiagnostics-print-source-range-info
        -fprint-source-range-info -fdiagnostics-show-option -fmessage-length
    )
fi

local -a languages
languages=(
  c  c-header  cpp-output
  c++  c++-header  c++-cpp-output
  objective-c  objective-c-header  objective-c-cpp-output
  objective-c++ objective-c++-header objective-c++-cpp-output
  assembler  assembler-with-cpp
  ada
  f77  f77-cpp-input f95  f95-cpp-input
  go
  java
)

# generic options (from --help)
args+=(
  -a -C -H -P -s
  '-###[print commands to run this compilation]'
  '-o:output file:_files -g "^*.(c|h|cc|C|cxx)(-.)"'
  '-x[Specify the language of the following input files]:input file language:('"$languages"')'
  '+e-:virtual function definitions in classes:((0\:only\ interface 1\:generate\ code))'
  '-d-:dump:->dump'
  '-g-::debugging information type or level:(0 1 2 3 gdb coff stabs stabs+ dwarf dwarf+ dwarf-2 dwarf-3 dwarf-4 xcoff xcoff+)'
  '-O-::optimization level:((0 1 2 3 g\:optimize\ for\ debugging\ experience s\:optimize\ for\ space fast\:optimize\ for\ speed\ disregarding\ exact\ standards\ compliance))'
  '*-M-::output dependencies:((M\:only\ user\ header\ files MD\:output\ to\ file G\:treat\ missing\ header\ files\ as\ generated))'
  '*-A-:define assertion:'
  '*-D-:define macro:'
  '*-U-:undefine macro:'
  '-E[Preprocess only; do not compile, assemble or link]'
  '-S[Compile only; do not assemble or link]'
  '-c[Compile and assemble, but do not link]'
  '*-Wp,-:preprocessor option:'
  '*-Wl,-:linker option:'
  '*-Xpreprocessor:preprocessor option:'
  '*-Xlinker:linker option:'
  '*-Xassembler:assembler option:'
  '*-u:pretend symbol to be undefined:'
  '*-Wa,-:assembler option:'
  '*-l:library:->library'
  '*-L-:library search path:_files -/'
  '*-I-:header file search path:_files -/'
  '-B-[Add <prefix> to the compiler'\''s search paths]:executable prefix:_files -/'
  '-b:target machine:'
  '-V:specify compiler version:'
  '--version[Display compiler version information]'
  '-print-file-name=-[Display the full path to library <library>]:library:->library'
  '-print-prog-name=-[Display the full path to compiler component <program>]:program:'
  '*-specs=-[Override built-in specs with the contents of <file>]:file:_files'
  '-std=-[Assume that the input sources are for <standard>]:standard:(c90 c89 c99 c11 gnu90 gnu89 gnu99 gnu11 c++98 c++03 gnu++98 gnu++03 c++11 gnu++11 c++1y gnu++1y)'
  '*-include:include file:_files -g \*.h\(-.\)'
  '*-imacros:macro input file:_files -g \*.h\(-.\)'
  '*-idirafter:second include path directory:_files -/'
  '*-iprefix:prefix:_files'
  '*-iwithprefix:second include path directory:_files -/'
  '*-iwithprefixbefore:main include path directory:_files -/'
  '*-isystem:second include path directory (system):_files -/'
  '--sysroot=-[Use <directory> as the root directory for headers and libraries]:directory:_files -/'
  '-pass-exit-codes[Exit with highest error code from a phase]'
  '*--help=-[Display this information]:class:->help'
  '--target-help[Display target specific command line options]'
  '-dumpspecs[Display all of the built in spec strings]'
  '-dumpversion[Display the version of the compiler]'
  '-dumpmachine[Display the compiler'\''s target processor]'
  '-print-search-dirs[Display the directories in the compiler'\''s search path]'
  '-print-libgcc-file-name[Display the name of the compiler'\''s companion library]'
  '-print-multiarch[Display the target'\''s normalized GNU triplet, used as a component in the library path]'
  '-print-multi-directory[Display the root directory for versions of libgcc]'
  '-print-multi-lib[Display the mapping between command line options and multiple library search directories]'
  '-print-multi-os-directory[Display the relative path to OS libraries]'
  '-print-sysroot[Display the target libraries directory]'
  '-print-sysroot-headers-suffix[Display the sysroot suffix used to find headers]'
  '-save-temps[Do not delete intermediate files]'
  '-no-canonical-prefixes[Do not canonicalize paths when building relative prefixes to other gcc components]'
  '-pipe[Use pipes rather than intermediate files]'
  '-pie[Create a position independent executable]'
  '-shared[Create a shared library]'
  '-time[Time the execution of each subprocess]'
)

# warnings (from --help=warnings), note some -W options are listed by --help=common instead
args+=(
# --help=warnings,^joined
  '-W[This switch is deprecated; use -Wextra instead]'
  '-Wabi-tag[Warn if a subobject has an abi_tag attribute that the complete object type does not have]'
  '-Wabi[Warn about things that will change when compiling with an ABI-compliant compiler]'
  '-Waddress[Warn about suspicious uses of memory addresses]'
  '-Waggregate-return[Warn about returning structures, unions or arrays]'
  '-Waggressive-loop-optimizations[Warn if a loop with constant number of iterations triggers undefined behavior]'
  '-Waliasing[Warn about possible aliasing of dummy arguments]'
  '-Walign-commons[Warn about alignment of COMMON blocks]'
  '-Wall[Enable most warning messages]'
  '-Wampersand[Warn about missing ampersand in continued character constants]'
  '-Warray-bounds[Warn if an array is accessed out of bounds]'
  '-Warray-temporaries[Warn about creation of array temporaries]'
  '-Wassign-intercept[Warn whenever an Objective-C assignment is being intercepted by the garbage collector]'
  '-Wattributes[Warn about inappropriate attribute usage]'
  '-Wbad-function-cast[Warn about casting functions to incompatible types]'
  '-Wbuiltin-macro-redefined[Warn when a built-in preprocessor macro is undefined or redefined]'
  '-Wc++-compat[Warn about C constructs that are not in the common subset of C and C++]'
  '-Wc++0x-compat[Deprecated in favor of -Wc++11-compat]'
  '-Wc++11-compat[Warn about C++ constructs whose meaning differs between ISO C++ 1998 and ISO C++ 2011]'
  '-Wc-binding-type[Warn if the type of a variable might be not interoperable with C]'
  '-Wcast-align[Warn about pointer casts which increase alignment]'
  '-Wcast-qual[Warn about casts which discard qualifiers]'
  '-Wchar-subscripts[Warn about subscripts whose type is "char"]'
  '-Wcharacter-truncation[Warn about truncated character expressions]'
  '-Wclobbered[Warn about variables that might be changed by "longjmp" or "vfork"]'
  '-Wcomment[Warn about possibly nested block comments, and C++ comments spanning more than one physical line]'
  '-Wcomments[Synonym for -Wcomment]'
  '-Wcompare-reals[Warn about equality comparisons involving REAL or COMPLEX expressions]'
  '-Wconversion-extra[Warn about most implicit conversions]'
  '-Wconversion-null[Warn for converting NULL from/to a non-pointer type]'
  '-Wconversion[Warn for implicit type conversions that may change a value]'
  '-Wcoverage-mismatch[Warn in case profiles in -fprofile-use do not match]'
  '-Wcpp[Warn when a #warning directive is encountered]'
  '-Wctor-dtor-privacy[Warn when all constructors and destructors are private]'
  '-Wdeclaration-after-statement[Warn when a declaration is found after a statement]'
  '-Wdelete-non-virtual-dtor[Warn about deleting polymorphic objects with non- virtual destructors]'
  '-Wdeprecated-declarations[Warn about uses of __attribute__((deprecated)) declarations]'
  '-Wdeprecated[Warn if a deprecated compiler feature, class, method, or field is used]'
  '-Wdisabled-optimization[Warn when an optimization pass is disabled]'
  '-Wdiv-by-zero[Warn about compile-time integer division by zero]'
  '-Wdouble-promotion[Warn about implicit conversions from "float" to "double"]'
  '-Weffc++[Warn about violations of Effective C++ style rules]'
  '-Wempty-body[Warn about an empty body in an if or else statement]'
  '-Wendif-labels[Warn about stray tokens after #elif and #endif]'
  '-Wenum-compare[Warn about comparison of different enum types]'
#this still exists but makes completing -Werror= less convenient
  #'-Werror-implicit-function-declaration[This switch is deprecated; use -Werror=implicit-function-declaration instead]'
  '-Wextra[Print extra (possibly unwanted) warnings]'
  '-Wfloat-equal[Warn if testing floating point numbers for equality]'
  '-Wformat-contains-nul[Warn about format strings that contain NUL bytes]'
  '-Wformat-extra-args[Warn if passing too many arguments to a function for its format string]'
  '-Wformat-nonliteral[Warn about format strings that are not literals]'
  '-Wformat-security[Warn about possible security problems with format functions]'
  '-Wformat-y2k[Warn about strftime formats yielding 2-digit years]'
  '-Wformat-zero-length[Warn about zero-length formats]'
  '-Wformat[Warn about printf/scanf/strftime/strfmon format string anomalies]'
  '-Wfree-nonheap-object[Warn when attempting to free a non-heap object]'
  '-Wfunction-elimination[Warn about function call elimination]'
  '-Wignored-qualifiers[Warn whenever type qualifiers are ignored]'
  '-Wimplicit-function-declaration[Warn about implicit function declarations]'
  '-Wimplicit-int[Warn when a declaration does not specify a type]'
  '-Wimplicit-interface[Warn about calls with implicit interface]'
  '-Wimplicit-procedure[Warn about called procedures not explicitly declared]'
  '-Wimplicit[Warn about implicit declarations]'
  '-Winherited-variadic-ctor[Warn about C++11 inheriting constructors when the base has a variadic constructor]'
  '-Winit-self[Warn about variables which are initialized to themselves]'
  '-Winline[Warn when an inlined function cannot be inlined]'
  '-Wint-to-pointer-cast[Warn when there is a cast to a pointer from an integer of a different size]'
  '-Wintrinsic-shadow[Warn if a user-procedure has the same name as an intrinsic]'
  '-Wintrinsics-std[Warn on intrinsics not part of the selected standard]'
  '-Winvalid-memory-model[Warn when an atomic memory model parameter is known to be outside the valid range]'
  '-Winvalid-offsetof[Warn about invalid uses of the "offsetof" macro]'
  '-Winvalid-pch[Warn about PCH files that are found but not used]'
  '-Wjump-misses-init[Warn when a jump misses a variable initialization]'
  '-Wline-truncation[Warn about truncated source lines]'
  '-Wliteral-suffix[Warn when a string or character literal is followed by a ud-suffix which does not begin with an underscore]'
  '-Wlogical-op[Warn when a logical operator is suspiciously always evaluating to true or false]'
  '-Wlong-long[Do not warn about using "long long" when -pedantic]'
  '-Wmain[Warn about suspicious declarations of "main"]'
  '-Wmaybe-uninitialized[Warn about maybe uninitialized automatic variables]'
  '-Wmissing-braces[Warn about possibly missing braces around initializers]'
  '-Wmissing-declarations[Warn about global functions without previous declarations]'
  '-Wmissing-field-initializers[Warn about missing fields in struct initializers]'
  '-Wmissing-include-dirs[Warn about user-specified include directories that do not exist]'
  '-Wmissing-parameter-type[Warn about function parameters declared without a type specifier in K&R-style functions]'
  '-Wmissing-prototypes[Warn about global functions without prototypes]'
  '-Wmudflap[Warn about constructs not instrumented by -fmudflap]'
  '-Wmultichar[Warn about use of multi-character character constants]'
  '-Wnarrowing[Warn about narrowing conversions within { } that are ill-formed in C++11]'
  '-Wnested-externs[Warn about "extern" declarations not at file scope]'
  '-Wnoexcept[Warn when a noexcept expression evaluates to false even though the expression can'\''t actually throw]'
  '-Wnon-template-friend[Warn when non-templatized friend functions are declared within a template]'
  '-Wnon-virtual-dtor[Warn about non-virtual destructors]'
  '-Wnonnull[Warn about NULL being passed to argument slots marked as requiring non-NULL]'
  '-Wold-style-cast[Warn if a C-style cast is used in a program]'
  '-Wold-style-declaration[Warn for obsolescent usage in a declaration]'
  '-Wold-style-definition[Warn if an old-style parameter definition is used]'
  '-Woverflow[Warn about overflow in arithmetic expressions]'
  '-Woverlength-strings[Warn if a string is longer than the maximum portable length specified by the standard]'
  '-Woverloaded-virtual[Warn about overloaded virtual function names]'
  '-Woverride-init[Warn about overriding initializers without side effects]'
  '-Wpacked-bitfield-compat[Warn about packed bit-fields whose offset changed in GCC 4.4]'
  '-Wpacked[Warn when the packed attribute has no effect on struct layout]'
  '-Wpadded[Warn when padding is required to align structure members]'
  '-Wparentheses[Warn about possibly missing parentheses]'
  '-Wpedantic[Issue warnings needed for strict compliance to the standard]'
  '-Wpmf-conversions[Warn when converting the type of pointers to member functions]'
  '-Wpointer-arith[Warn about function pointer arithmetic]'
  '-Wpointer-sign[Warn when a pointer differs in signedness in an assignment]'
  '-Wpointer-to-int-cast[Warn when a pointer is cast to an integer of a different size]'
  '-Wpoison-system-directories[Warn for -I and -L options using system directories if cross compiling]'
  '-Wpragmas[Warn about misuses of pragmas]'
  '-Wproperty-assign-default[Warn if a property for an Objective-C object has no assign semantics specified]'
  '-Wprotocol[Warn if inherited methods are unimplemented]'
  '-Wreal-q-constant[Warn about real-literal-constants with '\''q'\'' exponent-letter]'
  '-Wrealloc-lhs-all[Warn when a left-hand-side variable is reallocated]'
  '-Wrealloc-lhs[Warn when a left-hand-side array variable is reallocated]'
  '-Wredundant-decls[Warn about multiple declarations of the same object]'
  '-Wreorder[Warn when the compiler reorders code]'
  '-Wreturn-local-addr[Warn about returning a pointer/reference to a local or temporary variable]'
  '-Wreturn-type[Warn whenever a function'\''s return type defaults to "int" (C), or about inconsistent return types (C++)]'
  '-Wselector[Warn if a selector has multiple methods]'
  '-Wsequence-point[Warn about possible violations of sequence point rules]'
  '-Wshadow[Warn when one local variable shadows another]'
  '-Wsign-compare[Warn about signed-unsigned comparisons]'
  '-Wsign-promo[Warn when overload promotes from unsigned to signed]'
  '-Wstack-protector[Warn when not issuing stack smashing protection for some reason]'
  '-Wstrict-null-sentinel[Warn about uncasted NULL used as sentinel]'
  '-Wstrict-prototypes[Warn about unprototyped function declarations]'
  '-Wstrict-selector-match[Warn if type signatures of candidate methods do not match exactly]'
  '-Wsuggest-attribute=-[Warn about functions which might be candidates for __attribute__((const))]:const: '
  '-Wsurprising[Warn about "suspicious" constructs]'
  '-Wswitch-default[Warn about enumerated switches missing a "default-" statement]'
  '-Wswitch-enum[Warn about all enumerated switches missing a specific case]'
  '-Wswitch[Warn about enumerated switches, with no default, missing a case]'
  '-Wsync-nand[Warn when __sync_fetch_and_nand and __sync_nand_and_fetch built-in functions are used]'
  '-Wsynth[Deprecated. This switch has no effect]'
  '-Wsystem-headers[Do not suppress warnings from system headers]'
  '-Wtabs[Permit nonconforming uses of the tab character]'
  '-Wtarget-lifetime[Warn if the pointer in a pointer assignment might outlive its target]'
  '-Wtraditional-conversion[Warn of prototypes causing type conversions different from what would happen in the absence of prototype]'
  '-Wtraditional[Warn about features not present in traditional C]'
  '-Wtrampolines[Warn whenever a trampoline is generated]'
  '-Wtrigraphs[Warn if trigraphs are encountered that might affect the meaning of the program]'
  '-Wtype-limits[Warn if a comparison is always true or always false due to the limited range of the data type]'
  '-Wundeclared-selector[Warn about @selector()s without previously declared methods]'
  '-Wundef[Warn if an undefined macro is used in an #if directive]'
  '-Wunderflow[Warn about underflow of numerical constant expressions]'
  '-Wuninitialized[Warn about uninitialized automatic variables]'
  '-Wunknown-pragmas[Warn about unrecognized pragmas]'
  '-Wunsafe-loop-optimizations[Warn if the loop cannot be optimized due to nontrivial assumptions]'
  '-Wunsuffixed-float-constants[Warn about unsuffixed float constants]'
  '-Wunused-but-set-parameter[Warn when a function parameter is only set, otherwise unused]'
  '-Wunused-but-set-variable[Warn when a variable is only set, otherwise unused]'
  '-Wunused-dummy-argument[Warn about unused dummy arguments]'
  '-Wunused-function[Warn when a function is unused]'
  '-Wunused-label[Warn when a label is unused]'
  '-Wunused-local-typedefs[Warn when typedefs locally defined in a function are not used]'
  '-Wunused-macros[Warn about macros defined in the main file that are not used]'
  '-Wunused-parameter[Warn when a function parameter is unused]'
  '-Wunused-result[Warn if a caller of a function, marked with attribute warn_unused_result, does not use its return value]'
  '-Wunused-value[Warn when an expression value is unused]'
  '-Wunused-variable[Warn when a variable is unused]'
  '-Wunused[Enable all -Wunused- warnings]'
  '-Wuseless-cast[Warn about useless casts]'
  '-Wvarargs[Warn about questionable usage of the macros used to retrieve variable arguments]'
  '-Wvariadic-macros[Warn about using variadic macros]'
  '-Wvector-operation-performance[Warn when a vector operation is compiled outside the SIMD]'
  '-Wvirtual-move-assign[Warn if a virtual base has a non-trivial move assignment operator]'
  '-Wvla[Warn if a variable length array is used]'
  '-Wvolatile-register-var[Warn when a register variable is declared volatile]'
  '-Wwrite-strings[In C++, nonzero means warn about deprecated conversion from string literals to '\''char *'\''. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard]'
  '-Wzero-as-null-pointer-constant[Warn when a literal '\''0'\'' is used as null pointer]'
  '-frequire-return-statement[Functions which return values must end with return statements]'
# --help=warnings,joined
  '-Wlarger-than=-[Warn if an object is larger than <number> bytes]:number: '
  '-Wnormalized=-[Warn about non-normalised Unicode strings]:normalization:((id\:allow\ some\ non-nfc\ characters\ that\ are\ valid\ identifiers nfc\:only\ allow\ NFC nfkc\:only\ allow\ NFKC none\:allow\ any\ normalization)): '
  '-Wstack-usage=-[Warn if stack usage might be larger than specified amount]:stack usage: '
  '-Wstrict-aliasing=-[Warn about code which might break strict aliasing rules]:level of checking (higher is more accurate):(1 2 3)'
  '-Wstrict-overflow=-[Warn about optimizations that assume that signed overflow is undefined]:level of checking (higher finds more cases):(1 2 3 4 5)'
# -W options from --help=common
  '-Werror=-[Treat specified warning as error (or all if none specified)]:warning:->werror'
  '-Wfatal-errors[Exit on the first error occurred]'
  '-Wframe-larger-than=-[Warn if a function'\'\''s stack frame requires more than <number> bytes]:number: '
)
# optimizers (from --help=optimizers), except for -O
args+=(
# --help=optimizers,^joined
  '-faggressive-loop-optimizations[Aggressively optimize loops using language constraints]'
  '-falign-functions=-[Align the start of functions]:function alignment'
  '-falign-jumps=-[Align labels which are only reached by jumping]:jump alignment'
  '-falign-labels=-[Align all labels]:label alignment'
  '-falign-loops=-[Align the start of loops]:loop alignment'
  '-fasynchronous-unwind-tables[Generate unwind tables that are exact at each instruction boundary]'
  '-fbranch-count-reg[Replace add, compare, branch with branch on count register]'
  '-fbranch-probabilities[Use profiling information for branch probabilities]'
  '-fbranch-target-load-optimize2[Perform branch target load optimization after prologue / epilogue threading]'
  '-fbranch-target-load-optimize[Perform branch target load optimization before prologue / epilogue threading]'
  '-fbtr-bb-exclusive[Restrict target load migration not to re-use registers in any basic block]'
  '-fcaller-saves[Save registers around function calls]'
  '-fcombine-stack-adjustments[Looks for opportunities to reduce stack adjustments and stack references]'
  '-fcommon[Do not put uninitialized globals in the common section]'
  '-fcompare-elim[Perform comparison elimination after register allocation has finished]'
  '-fconserve-stack[Do not perform optimizations increasing noticeably stack usage]'
  '-fcprop-registers[Perform a register copy-propagation optimization pass]'
  '-fcrossjumping[Perform cross-jumping optimization]'
  '-fcse-follow-jumps[When running CSE, follow jumps to their targets]'
  '-fcx-fortran-rules[Complex multiplication and division follow Fortran rules]'
  '-fcx-limited-range[Omit range reduction step when performing complex division]'
  '-fdata-sections[Place data items into their own section]'
  '-fdce[Use the RTL dead code elimination pass]'
  '-fdefer-pop[Defer popping functions args from stack until later]'
  '-fdelayed-branch[Attempt to fill delay slots of branch instructions]'
  '-fdelete-null-pointer-checks[Delete useless null pointer checks]'
  '-fdevirtualize[Try to convert virtual calls to direct ones]'
  '-fdse[Use the RTL dead store elimination pass]'
  '-fearly-inlining[Perform early inlining]'
  '-fexceptions[Enable exception handling]'
  '-fexpensive-optimizations[Perform a number of minor, expensive optimizations]'
  '-ffinite-math-only[Assume no NaNs or infinities are generated]'
  '-ffloat-store[Don'\''t allocate floats and doubles in extended- precision registers]'
  '-fforward-propagate[Perform a forward propagation pass on RTL]'
  '-fgcse-after-reload[Perform global common subexpression elimination after register allocation has finished]'
  '-fgcse-las[Perform redundant load after store elimination in global common subexpression elimination]'
  '-fgcse-lm[Perform enhanced load motion during global common subexpression elimination]'
  '-fgcse-sm[Perform store motion after global common subexpression elimination]'
  '-fgcse[Perform global common subexpression elimination]'
  '-fgraphite-identity[Enable Graphite Identity transformation]'
  '-fguess-branch-probability[Enable guessing of branch probabilities]'
  '-fhandle-exceptions[This switch lacks documentation]'
  '-fhoist-adjacent-loads[Enable hoisting adjacent loads to encourage generating conditional move instructions]'
  '-fif-conversion2[Perform conversion of conditional jumps to conditional execution]'
  '-fif-conversion[Perform conversion of conditional jumps to branchless equivalents]'
  '-finline-atomics[Inline __atomic operations when a lock free instruction sequence is available]'
  '-finline-functions-called-once[Integrate functions only required by their single caller]'
  '-finline-functions[Integrate functions not declared "inline" into their callers when profitable]'
  '-finline-small-functions[Integrate functions into their callers when code size is known not to grow]'
  '-finline[Enable inlining of function declared "inline", disabling disables all inlining]'
  '-fipa-cp-clone[Perform cloning to make Interprocedural constant propagation stronger]'
  '-fipa-cp[Perform Interprocedural constant propagation]'
  '-fipa-profile[Perform interprocedural profile propagation]'
  '-fipa-pta[Perform interprocedural points-to analysis]'
  '-fipa-pure-const[Discover pure and const functions]'
  '-fipa-reference[Discover readonly and non addressable static variables]'
  '-fipa-sra[Perform interprocedural reduction of aggregates]'
  '-fira-hoist-pressure[Use IRA based register pressure calculation in RTL hoist optimizations]'
  '-fivopts[Optimize induction variables on trees]'
  '-fjump-tables[Use jump tables for sufficiently large switch statements]'
  '-floop-block[Enable Loop Blocking transformation]'
  '-floop-interchange[Enable Loop Interchange transformation]'
  '-floop-nest-optimize[Enable the ISL based loop nest optimizer]'
  '-floop-parallelize-all[Mark all loops as parallel]'
  '-floop-strip-mine[Enable Loop Strip Mining transformation]'
  '-fmath-errno[Set errno after built-in math functions]'
  '-fmerge-all-constants[Attempt to merge identical constants and constant variables]'
  '-fmerge-constants[Attempt to merge identical constants across compilation units]'
  '-fmodulo-sched[Perform SMS based modulo scheduling before the first scheduling pass]'
  '-fmove-loop-invariants[Move loop invariant computations out of loops]'
  '-fno-threadsafe-statics[Do not generate thread-safe code for initializing local statics]'
  '-fnon-call-exceptions[Support synchronous non-call exceptions]'
  '-fnothrow-opt[Treat a throw() exception specification as noexcept to improve code size]'
  '-fomit-frame-pointer[When possible do not generate stack frames]'
  '-fopt-info[Enable all optimization info dumps on stderr]'
  '-foptimize-register-move[Do the full register move optimization pass]'
  '-foptimize-sibling-calls[Optimize sibling and tail recursive calls]'
  '-foptimize-strlen[Enable string length optimizations on trees]'
  '-fpack-struct[Pack structure members together without holes]'
  '-fpeel-loops[Perform loop peeling]'
  '-fpeephole2[Enable an RTL peephole pass before sched2]'
  '-fpeephole[Enable machine specific peephole optimizations]'
  '-fpredictive-commoning[Run predictive commoning optimization]'
  '-fprefetch-loop-arrays[Generate prefetch instructions, if available, for arrays in loops]'
  '-freg-struct-return[Return small aggregates in registers]'
  '-fregmove[Enables a register move optimization]'
  '-frename-registers[Perform a register renaming optimization pass]'
  '-freorder-blocks-and-partition[Reorder basic blocks and partition into hot and cold sections]'
  '-freorder-blocks[Reorder basic blocks to improve code placement]'
  '-freorder-functions[Reorder functions to improve code placement]'
  '-frerun-cse-after-loop[Add a common subexpression elimination pass after loop optimizations]'
  '-freschedule-modulo-scheduled-loops[Enable/Disable the traditional scheduling in loops that already passed modulo scheduling]'
  '-frounding-math[Disable optimizations that assume default FP rounding behavior]'
  '-frtti[Generate run time type descriptor information]'
  '-fsched-critical-path-heuristic[Enable the critical path heuristic in the scheduler]'
  '-fsched-dep-count-heuristic[Enable the dependent count heuristic in the scheduler]'
  '-fsched-group-heuristic[Enable the group heuristic in the scheduler]'
  '-fsched-interblock[Enable scheduling across basic blocks]'
  '-fsched-last-insn-heuristic[Enable the last instruction heuristic in the scheduler]'
  '-fsched-pressure[Enable register pressure sensitive insn scheduling]'
  '-fsched-rank-heuristic[Enable the rank heuristic in the scheduler]'
  '-fsched-spec-insn-heuristic[Enable the speculative instruction heuristic in the scheduler]'
  '-fsched-spec-load-dangerous[Allow speculative motion of more loads]'
  '-fsched-spec-load[Allow speculative motion of some loads]'
  '-fsched-spec[Allow speculative motion of non-loads]'
  '-fsched2-use-superblocks[If scheduling post reload, do superblock scheduling]'
  '-fschedule-insns2[Reschedule instructions after register allocation]'
  '-fschedule-insns[Reschedule instructions before register allocation]'
  '-fsection-anchors[Access data in the same section from shared anchor points]'
  '-fsel-sched-pipelining-outer-loops[Perform software pipelining of outer loops during selective scheduling]'
  '-fsel-sched-pipelining[Perform software pipelining of inner loops during selective scheduling]'
  '-fsel-sched-reschedule-pipelined[Reschedule pipelined regions without pipelining]'
  '-fselective-scheduling2[Run selective scheduling after reload]'
  '-fselective-scheduling[Schedule instructions using selective scheduling algorithm]'
  '-fshort-double[Use the same size for double as for float]'
  '-fshort-enums[Use the narrowest integer type possible for enumeration types]'
  '-fshort-wchar[Force the underlying type for "wchar_t" to be "unsigned short"]'
  '-fshrink-wrap[Emit function prologues only before parts of the function that need it, rather than at the top of the function]'
  '-fsignaling-nans[Disable optimizations observable by IEEE signaling NaNs]'
  '-fsigned-zeros[Disable floating point optimizations that ignore the IEEE signedness of zero]'
  '-fsingle-precision-constant[Convert floating point constants to single precision constants]'
  '-fsplit-ivs-in-unroller[Split lifetimes of induction variables when loops are unrolled]'
  '-fsplit-wide-types[Split wide types into independent registers]'
  '-fstrict-aliasing[Assume strict aliasing rules apply]'
  '-fstrict-enums[Assume that values of enumeration type are always within the minimum range of that type]'
  '-fthread-jumps[Perform jump threading optimizations]'
  '-ftoplevel-reorder[Reorder top level functions, variables, and asms]'
  '-ftrapping-math[Assume floating-point operations can trap]'
  '-ftrapv[Trap for signed overflow in addition, subtraction and multiplication]'
  '-ftree-bit-ccp[Enable SSA-BIT-CCP optimization on trees]'
  '-ftree-builtin-call-dce[Enable conditional dead code elimination for builtin calls]'
  '-ftree-ccp[Enable SSA-CCP optimization on trees]'
  '-ftree-ch[Enable loop header copying on trees]'
  '-ftree-coalesce-inlined-vars[Enable coalescing of copy-related user variables that are inlined]'
  '-ftree-coalesce-vars[Enable coalescing of all copy-related user variables]'
  '-ftree-copy-prop[Enable copy propagation on trees]'
  '-ftree-copyrename[Replace SSA temporaries with better names in copies]'
  '-ftree-cselim[Transform condition stores into unconditional ones]'
  '-ftree-dce[Enable SSA dead code elimination optimization on trees]'
  '-ftree-dominator-opts[Enable dominator optimizations]'
  '-ftree-dse[Enable dead store elimination]'
  '-ftree-forwprop[Enable forward propagation on trees]'
  '-ftree-fre[Enable Full Redundancy Elimination (FRE) on trees]'
  '-ftree-loop-distribute-patterns[Enable loop distribution for patterns transformed into a library call]'
  '-ftree-loop-distribution[Enable loop distribution on trees]'
  '-ftree-loop-if-convert-stores[Also if-convert conditional jumps containing memory writes]'
  '-ftree-loop-if-convert[Convert conditional jumps in innermost loops to branchless equivalents]'
  '-ftree-loop-im[Enable loop invariant motion on trees]'
  '-ftree-loop-ivcanon[Create canonical induction variables in loops]'
  '-ftree-loop-optimize[Enable loop optimizations on tree level]'
  '-ftree-lrs[Perform live range splitting during the SSA- >normal pass]'
  '-ftree-partial-pre[In SSA-PRE optimization on trees, enable partial- partial redundancy elimination]'
  '-ftree-phiprop[Enable hoisting loads from conditional pointers]'
  '-ftree-pre[Enable SSA-PRE optimization on trees]'
  '-ftree-pta[Perform function-local points-to analysis on trees]'
  '-ftree-reassoc[Enable reassociation on tree level]'
  '-ftree-scev-cprop[Enable copy propagation of scalar-evolution information]'
  '-ftree-sink[Enable SSA code sinking on trees]'
  '-ftree-slp-vectorize[Enable basic block vectorization (SLP) on trees]'
  '-ftree-slsr[Perform straight-line strength reduction]'
  '-ftree-sra[Perform scalar replacement of aggregates]'
  '-ftree-switch-conversion[Perform conversions of switch initializations]'
  '-ftree-tail-merge[Enable tail merging on trees]'
  '-ftree-ter[Replace temporary expressions in the SSA->normal pass]'
  '-ftree-vect-loop-version[Enable loop versioning when doing loop vectorization on trees]'
  '-ftree-vectorize[Enable loop vectorization on trees]'
  '-ftree-vrp[Perform Value Range Propagation on trees]'
  '-funit-at-a-time[Compile whole compilation unit at a time]'
  '-funroll-all-loops[Perform loop unrolling for all loops]'
  '-funroll-loops[Perform loop unrolling when iteration count is known]'
  '-funsafe-loop-optimizations[Allow loop optimizations to assume that the loops behave in normal way]'
  '-funsafe-math-optimizations[Allow math optimizations that may violate IEEE or ISO standards]'
  '-funswitch-loops[Perform loop unswitching]'
  '-funwind-tables[Just generate unwind tables for exception handling]'
  '-fvar-tracking-assignments-toggle[Toggle -fvar-tracking-assignments]'
  '-fvar-tracking-assignments[Perform variable tracking by annotating assignments]'
  '-fvar-tracking-uninit[Perform variable tracking and also tag variables that are uninitialized]'
  '-fvar-tracking[Perform variable tracking]'
  '-fvariable-expansion-in-unroller[Apply variable expansion when loops are unrolled]'
  '-fvect-cost-model[Enable use of cost model in vectorization]'
  '-fvpt[Use expression value profiles in optimizations]'
  '-fweb[Construct webs and split unrelated uses of single variable]'
  '-fwhole-program[Perform whole program optimizations]'
  '-fwrapv[Assume signed arithmetic overflow wraps around]'
# --help=optimizers,joined
  '-fpack-struct=-[Set initial maximum structure member alignment]:alignment: '
)

# other common options, gcc --help=warnings --help=optimizers --help=common|sed 1,/language-independent/d
args+=(
# | grep -v ::
  '--debug[This switch lacks documentation]'
  '--dump[This switch lacks documentation]'
  '--dumpbase[This switch lacks documentation]'
  '--dumpdir[This switch lacks documentation]'
  '--help[Display this information]'
  '--no-warnings[This switch lacks documentation]'
  '--optimize[This switch lacks documentation]'
  '--output[This switch lacks documentation]'
  '--param[Set parameter <param> to value.  See manpage for a complete list of parameters]:name=value'
  '--pedantic-errors[This switch lacks documentation]'
  '--pedantic[This switch lacks documentation]'
  '--profile[This switch lacks documentation]'
  '--verbose[This switch lacks documentation]'
  '--version[This switch lacks documentation]'
  '-aux-info[Emit declaration information into <file>]:file:_files'
  '-dumpbase[Set the file basename to be used for dumps]'
  '-dumpdir[Set the directory name to be used for dumps]'
  '-fPIC[Generate position-independent code if possible (large mode)]'
  '-fPIE[Generate position-independent code for executables if possible (large mode)]'
  '-fassociative-math[Allow optimization for floating-point arithmetic which may change the result of the operation due to rounding]'
  '-fauto-inc-dec[Generate auto-inc/dec instructions]'
  '-fbounds-check[Generate code to check bounds before indexing arrays]'
  '-fcall-saved--[Mark <register> as being preserved across functions]:register'
  '-fcall-used--[Mark <register> as being corrupted by function calls]:register'
  '-fcheck-data-deps[Compare the results of several data dependence analyzers]'
  '-fcompare-debug-second[Run only the second compilation of -fcompare-debug]'
  '-fcompare-debug=[Compile with and without e.g. -gtoggle, and compare the final-insns dump]:opts:' #TODO: complete gcc options here
  '-fdbg-cnt-list[List all available debugging counters with their limits and counts]'
  '-fdbg-cnt=[,<counter>-<limit>,...) Set the debug counter limit]:counter\:limit,...: ' #TODO: gcc -fdbg-cnt-list -x c /dev/null -o /dev/null -c
  '-fdebug-types-section[Output .debug_types section when using DWARF v4 debuginfo]'
  '-fdelete-dead-exceptions[Delete dead instructions that may throw exceptions]'
  '-fdiagnostics-show-caret[Show the source line with a caret indicating the column]'
  '-fdiagnostics-show-location=-[How often to emit source location at the beginning of line-wrapped diagnostics]:source location:(once every-line)'
  '-fdiagnostics-show-option[Amend appropriate diagnostic messages with the command line option that controls them]'
  #not meant for end users
  #'-fdisable--pass=[disables an optimization pass]:range1+range2: '
  #'-fdisable-[disables an optimization pass]'
  #'-fenable--pass=[enables an optimization pass]:range1+range2: '
  #'-fenable-[enables an optimization pass]'
  #'-fdump-<type>[Dump various compiler internals to a file]'
  '-fdump-final-insns=-[Dump to filename the insns at the end of translation]:filename:_files'
  '-fdump-go-spec=-[Write all declarations to file as Go code]:filename:_files'
  '-fdump-noaddr[Suppress output of addresses in debugging dumps]'
  '-fdump-passes[Dump optimization passes]'
  '-fdump-unnumbered-links[Suppress output of previous and next insn numbers in debugging dumps]'
  '-fdump-unnumbered[Suppress output of instruction numbers, line number notes and addresses in debugging dumps]'
  '-fdwarf2-cfi-asm[Enable CFI tables via GAS assembler directives]'
  '-feliminate-dwarf2-dups[Perform DWARF2 duplicate elimination]'
  '-feliminate-unused-debug-symbols[Perform unused type elimination in debug info]'
  '-feliminate-unused-debug-types[Perform unused type elimination in debug info]'
  '-femit-class-debug-always[Do not suppress C++ class debug information]'
  '-fexcess-precision=-[Specify handling of excess floating-point precision]:precision handling:(fast standard)'
  '-ffast-math[Sets -fno-math-errno, -funsafe-math-optimizations, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans and -fcx-limited-range]'
  '-ffat-lto-objects[Output lto objects containing both the intermediate language and binary output]'
  '-ffixed--[Mark <register> as being unavailable to the compiler]:register'
  '-ffunction-cse[Allow function addresses to be held in registers]'
  '-ffunction-sections[Place each function into its own section]'
  '-fgnu-tm[Enable support for GNU transactional memory]'
  '-fgraphite[Enable in and out of Graphite representation]'
  '-fident[Process #ident directives]'
  '-findirect-inlining[Perform indirect inlining]'
  '-finhibit-size-directive[Do not generate .size directives]'
  '-finline-limit=[Limit the size of inlined functions to <number>]:number: '
  '-finstrument-functions[Instrument function entry and exit with profiling calls]'
  '-fira-loop-pressure[Use IRA based register pressure calculation in RTL loop optimizations]'
  '-fira-share-save-slots[Share slots for saving different hard registers]'
  '-fira-share-spill-slots[Share stack slots for spilled pseudo-registers]'
  '-fira-verbose=[Control IRA'\''s level of diagnostic messages]:verbosity: '
  '-fkeep-inline-functions[Generate code for functions even if they are fully inlined]'
  '-fkeep-static-consts[Emit static const variables even if they are not used]'
  '-fleading-underscore[Give external symbols a leading underscore]'
  '-flto-compression-level=[Use zlib compression level <number> for IL]:compression level: '
  '-flto-partition=[Partition symbols and vars at linktime based on object files they originate from]:partitioning algorithm:(1to1 balanced max)'
  '-flto-report[Report various link-time optimization statistics]'
  '-flto[Enable link-time optimization]'
  '-fmax-errors=-[Maximum number of errors to report]:errors: '
  '-fmem-report-wpa[Report on permanent memory allocation in WPA only]'
  '-fmem-report[Report on permanent memory allocation]'
  '-fmerge-debug-strings[Attempt to merge identical debug strings across compilation units]'
  '-fmessage-length=-[Limit diagnostics to <number> characters per line.  0 suppresses line-wrapping]:length: '
  '-fmodulo-sched-allow-regmoves[Perform SMS based modulo scheduling with register moves allowed]'
  '-fopt-info-type=-[Dump compiler optimization details]:filename:_files'
  '-fopt-info[Dump compiler optimization details]'
  '-fpartial-inlining[Perform partial inlining]'
  '-fpcc-struct-return[Return small aggregates in memory, not registers]'
  '-fpic[Generate position-independent code if possible (small mode)]'
  '-fpie[Generate position-independent code for executables if possible (small mode)]'
  '-fplugin-arg--[Specify argument <key>=<value> for plugin <name>]:-fplugin-arg-name-key=value: ' #TODO
  '-fpost-ipa-mem-report[Report on memory allocation before interprocedural optimization]'
  '-fpre-ipa-mem-report[Report on memory allocation before interprocedural optimization]'
  '-fprofile-arcs[Insert arc-based program profiling code]'
  '-fprofile-correction[Enable correction of flow inconsistent profile data input]'
  '-fprofile-generate[Enable common options for generating profile info for profile feedback directed optimizations]'
  '-fprofile-report[Report on consistency of profile]'
  '-fprofile-use[Enable common options for performing profile feedback directed optimizations]'
  '-fprofile-values[Insert code to profile values of expressions]'
  '-fprofile[Enable basic program profiling code]'
  '-frandom-seed=-[Use <string> as random seed]:seed: '
  '-freciprocal-math[Same as -fassociative-math for expressions which include division]'
  '-frecord-gcc-switches[Record gcc command line switches in the object file]'
  '-free[Turn on Redundant Extensions Elimination pass]'
  '-fsanitize=-[Enable AddressSanitizer, a memory error detector]:style:(address thread)'
  '-fsched-stalled-insns-dep=-[Set dependence distance checking in premature scheduling of queued insns]:instructions: '
  '-fsched-stalled-insns=-[Set number of queued insns that can be prematurely scheduled]:instructions: '
  '-fsched-verbose=-[Set the verbosity level of the scheduler]:verbosity: '
  '-fshow-column[Show column numbers in diagnostics, when available]'
  '-fsplit-stack[Generate discontiguous stack frames]'
  '-fstack-check=-[Insert stack checking code into the program.  -fstack-check=specific if to argument given]:type:(none generic specific)'
  '-fstack-limit-register=-[Trap if the stack goes past <register>]:register: '
  '-fstack-limit-symbol=-[Trap if the stack goes past symbol <name>]:name: '
  '-fno-stack-limit'
  '-fstack-protector-all[Use a stack protection method for every function]'
  '-fstack-protector[Use propolice as a stack protection method]'
  '-fstack-usage[Output stack usage information on a per-function basis]'
  '-fstrict-overflow[Treat signed overflow as undefined]'
  '-fstrict-volatile-bitfields[Force bitfield accesses to match their type width]'
  '-fsync-libcalls[Implement __atomic operations via libcalls to legacy __sync functions]'
  '-fsyntax-only[Check for syntax errors, then stop]'
  '-ftest-coverage[Create data files needed by "gcov"]'
  '-ftime-report[Report the time taken by each compiler pass]'
  '-ftls-model=-[Set the default thread-local storage code generation model]:TLS model:(global-dynamic local-dynamic initial-exec local-exec)'
  '-ftracer[Perform superblock formation via tail duplication]'
  '-ftree-loop-linear[Enable loop interchange transforms.  Same as  -floop-interchange]'
  '-fuse-ld=[Use the specified linker instead of the default linker]:linker:(bfd gold)'
  '-fuse-linker-plugin[Use linker plugin during link-time optimization]'
  '-fverbose-asm[Add extra commentary to assembler output]'
  '-fvisibility=[Set the default symbol visibility]:visibility:(default internal hidden protected)'
  '-fzero-initialized-in-bss[Put zero initialized data in the bss section]'
  '-gno-pubnames[Don'\''t generate DWARF pubnames and pubtypes sections]'
  '-gno-record-gcc-switches[Don'\''t record gcc command line switches in DWARF DW_AT_producer]'
  '-gno-split-dwarf[Don'\''t generate debug information in separate .dwo files]'
  '-gno-strict-dwarf[Emit DWARF additions beyond selected version]'
  '-gpubnames[Generate DWARF pubnames and pubtypes sections]'
  '-grecord-gcc-switches[Record gcc command line switches in DWARF DW_AT_producer]'
  '-gsplit-dwarf[Generate debug information in separate .dwo files]'
  '-gstrict-dwarf[Don'\''t emit DWARF additions beyond selected version]'
  '-gtoggle[Toggle debug information generation]'
  '-gvms[Generate debug information in VMS format]'
  '-imultiarch[Set <dir> to be the multiarch include subdirectory]:directory:_files -/' #XXX not in manpage
  '-iplugindir=[Set <dir> to be the default plugin directory]:directory:_files -/'
  '(-pg)-p[Enable function profiling for prof]'
  '(-p)-pg[Enable function profiling for gprof]'
  '-pedantic-errors[Like -pedantic but issue them as errors]'
  '-pedantic[Issue all mandatory diagnostics in the C standard]'
  '-quiet[Do not display functions compiled or elapsed time]'
  '-v[Enable verbose output]'
  '-version[Display the compiler'\''s version]'
  '-w[Suppress warnings]'
# | grep ::
  '-fabi-version=-[Use version <n> of the C++ ABI (default: 2)]:ABI version:(1 2 3 4 5 6)'
  '-fdebug-prefix-map=-[Map one directory name to another in debug information]:/old/dir=/new/dir:->dirtodir'
  '-ffp-contract=-[Perform floating- point expression contraction (default: fast)]:style:(on off fast)'
  '-finstrument-functions-exclude-file-list=-[Do not instrument functions listed in files]:comma-separated file list:->commafiles'
  '-finstrument-functions-exclude-function-list=-[Do not instrument listed functions]:comma-separated list of syms: '
  '-fira-algorithm=-[Set the used IRA algorithm]:algorithm:(priority CB)'
  '-fira-region=-[Set regions for IRA]:region:(all mixed one)'
  '-fplugin=-[Specify a plugin to load]:plugin: ' # TODO: complete plugins?
  '-fprofile-dir=-[Set the top-level directory for storing the profile data]:profile directory:_files -/'
  '-fstack-reuse=-[Set stack reuse level for local variables]:reuse-level:(all named_vars none)'
  '-ftree-parallelize-loops=-[Enable automatic parallelization of loops]:threads: '
)

# How to mostly autogenerate the above stuff:
# joinhelplines() { sed '$!N;s/^\(  -.*\)\n  \s*\([^-]\)/\1 \2/;P;D' }
# gcc-x86() { gcc --help=target,\^undocumented | joinhelplines | joinhelplines }
# compdef _gnu_generic gcc-x86
# printf '%s\n' ${(onq-)_args_cache_gcc_x86}
_arguments -C -M 'L:|-{fWm}no-=-{fWm} r:|[_-]=* r:|=*' \
  "$args[@]" \
  "$args2[@]" && ret=0


case "$state" in
dump)
  _values -s '' 'dump information' \
    'M[only macro definitions]' \
    'N[macro names]' \
    'D[macro definitions and normal output]' \
    'y[debugging information during parsing]' \
    'r[after RTL generation]' \
    'x[only generate RTL]' \
    'j[after jump optimization]' \
    's[after CSE]' \
    'L[after loop optimization]' \
    't[after second CSE pass]' \
    'f[after flow analysis]' \
    'c[after instruction combination]' \
    'S[after first instruction scheduling pass]' \
    'l[after local register allocation]' \
    'g[after global register allocation]' \
    'R[after second instruction scheduling pass]' \
    'J[after last jump optimization]' \
    'd[after delayed branch scheduling]' \
    'k[after conversion from registers to stack]' \
    'a[all dumps]' \
    'm[print memory usage statistics]' \
    'p[annotate assembler output]' && ret=0
  ;;
library)
  _wanted libraries expl library \
      compadd - ${^=LD_LIBRARY_PATH:-/usr/lib /usr/local/lib}/lib*.(a|so*)(:t:fr:s/lib//) && ret=0
  ;;
rundir)
  compset -P '*:'
  compset -S ':*'
  _files -/ -S/ -r '\n\t\- /:' "$@" && ret=0
  ;;
help)
  _values -s , 'help' \
    optimizers warnings target params common \
    c c++ objc objc++ lto ada adascil adawhy fortran go java \
    {\^,}undocumented {\^,}joined {\^,}separate \
  && ret=0
  ;;
dirtodir)
  compset -P '*='
  _files -/ && ret=0
  ;;
commafiles)
  compset -P '*,'
  _files && ret=0
  ;;
esac

return ret

