CLANG(1)

πŸ“¦
version 22.1.8 Β· 3 versions
, in fedora 44

πŸ’– CLANG(1) β€” the Clang C, C++, and Objective-C compiler ✨

okay bestie, buckle up, this is the page. this is CLANG(1) from the Clang manual, and it's a big one, so we're doing it in parts. part one starts right here. πŸ’…


🌸 NAME 🌸

clang β€” the Clang C, C++, and Objective-C compiler 🫢


✨ SYNOPSIS ✨

clang [options] filename ...

πŸ¦‹ DESCRIPTION πŸ¦‹

so. clang is a C, C++, and Objective-C compiler and it does literally everything: preprocessing, parsing, optimization, code generation, assembly, and linking. all of it. one girl. πŸ’…

depending on which high-level mode setting you pass, Clang will stop before doing a full link. and like β€” Clang is super integrated, it's giving seamless, but it's still highkey important to actually understand the stages of compilation so you know how to invoke it properly. so here are the stages, in order, no skips:

  • Driver β€” the clang executable is actually just a small driver that controls the overall execution of other tools like the compiler, the assembler, and the linker. typically you don't need to interact with the driver directly, but you transparently use it to run all the other tools. she's the group chat admin fr.
  • Preprocessing β€” this stage handles tokenization of the input source file, macro expansion, #include expansion, and handling of other preprocessor directives. the output of this stage is typically called a ".i" (for C), ".ii" (for C++), ".mi" (for Objective-C), or ".mii" (for Objective-C++) file.
  • Parsing and Semantic Analysis β€” this stage parses the input file, translating preprocessor tokens into a parse tree. once it's in the form of a parse tree, it applies semantic analysis to compute types for expressions as well and determine whether the code is well formed. this stage is responsible for generating most of the compiler warnings as well as parse errors. the output of this stage is an "Abstract Syntax Tree" (AST). πŸ‘‘
  • Code Generation and Optimization β€” this stage translates an AST into low-level intermediate code (known as "LLVM IR") and ultimately to machine code. this phase is responsible for optimizing the generated code and handling target-specific code generation. the output of this stage is typically called a ".s" file or "assembly" file.

Clang also supports the use of an integrated assembler, in which the code generator produces object files directly. this avoids the overhead of generating the ".s" file and of calling the target assembler. efficiency icon behavior, honestly.

  • Assembler β€” this stage runs the target assembler to translate the output of the compiler into a target object file. the output of this stage is typically called a ".o" file or "object" file.
  • Linker β€” this stage runs the target linker to merge multiple object files into an executable or dynamic library. the output of this stage is typically called an "a.out", ".dylib" or ".so" file.

πŸ” Clang Static Analyzer πŸ”

the Clang Static Analyzer is a tool that scans source code to try to find bugs through code analysis. this tool uses many parts of Clang and is built into the same driver. please see https://clang-analyzer.llvm.org for more details on how to use the static analyzer. she's out here finding your bugs before you do 😭


πŸ’… OPTIONS πŸ’…

πŸŽ€ Stage Selection Options πŸŽ€

  • -E β€” run the preprocessor stage. just that. stop there, bestie.
  • -fsyntax-only β€” run the preprocessor, parser and semantic analysis stages.
  • -S β€” run the previous stages as well as LLVM generation and optimization stages and target-specific code generation, producing an assembly file.
  • -c β€” run all of the above, plus the assembler, generating a target ".o" object file.
  • no stage selection option β€” if no stage selection option is specified, all stages above are run, and the linker is run to combine the results into an executable or shared library. the full send. the main character run. πŸƒβ€β™€οΈ

🌈 Language Selection and Mode Options 🌈

  • -x <language> β€” treat subsequent input files as having type language.
  • -std=<standard> β€” specify the language standard to compile for.

supported values for the C language are:

  • c89 β€” ISO C 1990
  • c90 β€” ISO C 1990
  • iso9899:1990 β€” ISO C 1990
  • iso9899:199409 β€” ISO C 1990 with amendment 1
  • gnu89 β€” ISO C 1990 with GNU extensions
  • gnu90 β€” ISO C 1990 with GNU extensions
  • c99 β€” ISO C 1999
  • iso9899:1999 β€” ISO C 1999
  • gnu99 β€” ISO C 1999 with GNU extensions
  • c11 β€” ISO C 2011
  • iso9899:2011 β€” ISO C 2011
  • gnu11 β€” ISO C 2011 with GNU extensions
  • c17 β€” ISO C 2017
  • iso9899:2017 β€” ISO C 2017
  • gnu17 β€” ISO C 2017 with GNU extensions
  • c23 β€” ISO C 2023
  • iso9899:2024 β€” ISO C 2023
  • gnu23 β€” ISO C 2023 with GNU extensions
  • c2y β€” ISO C 202y
  • gnu2y β€” ISO C 202y with GNU extensions
the default C language standard is gnu17, except on PS4, where it is gnu99. πŸ“

supported values for the C++ language are:

  • c++98 β€” ISO C++ 1998 with amendments
  • c++03 β€” ISO C++ 1998 with amendments
  • gnu++98 β€” ISO C++ 1998 with amendments and GNU extensions
  • gnu++03 β€” ISO C++ 1998 with amendments and GNU extensions
  • c++11 β€” ISO C++ 2011 with amendments
  • gnu++11 β€” ISO C++ 2011 with amendments and GNU extensions
  • c++14 β€” ISO C++ 2014 with amendments
  • gnu++14 β€” ISO C++ 2014 with amendments and GNU extensions
  • c++17 β€” ISO C++ 2017 with amendments
  • gnu++17 β€” ISO C++ 2017 with amendments and GNU extensions
  • c++20 β€” ISO C++ 2020 with amendments
  • gnu++20 β€” ISO C++ 2020 with amendments and GNU extensions
  • c++23 β€” ISO C++ 2023 with amendments
  • gnu++23 β€” ISO C++ 2023 with amendments and GNU extensions
  • c++2c β€” Working draft for C++2c
  • gnu++2c β€” Working draft for C++2c with GNU extensions
the default C++ language standard is gnu++17. πŸ’œ

supported values for the OpenCL language are:

  • cl1.0 β€” OpenCL 1.0
  • cl1.1 β€” OpenCL 1.1
  • cl1.2 β€” OpenCL 1.2
  • cl2.0 β€” OpenCL 2.0
the default OpenCL language standard is cl1.0. ✨

supported values for the CUDA language are:

  • cuda β€” NVIDIA CUDA(tm)
  • -stdlib=<library> β€” specify the C++ standard library to use; supported options are libstdc++ and libc++. if not specified, platform default will be used.
  • -rtlib=<library> β€” specify the compiler runtime library to use; supported options are libgcc and compiler-rt. if not specified, platform default will be used.
  • -ansi β€” same as -std=c89. literally just that.
  • -ObjC, -ObjC++ β€” treat source input files as Objective-C and Object-C++ inputs respectively.
  • -trigraphs β€” enable trigraphs.
  • -ffreestanding β€” indicate that the file should be compiled for a freestanding, not a hosted, environment. note that a freestanding build still requires linking against a C Standard Library which supports the freestanding interfaces for the specified language mode and target environment. this includes functions like memcpy, memmove, and memset.
  • -fno-builtin β€” disable special handling and optimizations of well-known library functions, like strlen() and malloc().
  • -fno-builtin-<function> β€” disable special handling and optimizations for the specific library function. for example, -fno-builtin-strlen removes any special handling for the strlen() library function.
  • -fno-builtin-std-<function> β€” disable special handling and optimizations for the specific C++ standard library function in namespace std. for example, -fno-builtin-std-move_if_noexcept removes any special handling for the std::move_if_noexcept() library function.
for C standard library functions that the C++ standard library also provides in namespace std, use -fno-builtin-<function> instead. πŸ’‘
  • -fmath-errno β€” indicate that math functions should be treated as updating errno.
  • -fpascal-strings β€” enable support for Pascal-style strings with "\pfoo".
  • -fms-extensions β€” enable support for Microsoft extensions.
  • -fmsc-version= β€” set _MSC_VER. when on Windows, this defaults to either the same value as the currently installed version of cl.exe, or 1933. not set otherwise.
  • -fborland-extensions β€” enable support for Borland extensions.
  • -fwritable-strings β€” make all string literals default to writable. this disables uniquing of strings and other optimizations.
  • -flax-vector-conversions, -flax-vector-conversions=<kind>, -fno-lax-vector-conversions β€” allow loose type checking rules for implicit vector conversions. possible values of <kind>:
    • none: allow no implicit conversions between vectors
    • integer: allow implicit bitcasts between integer vectors of the same overall bit-width
    • all: allow implicit bitcasts between any vectors of the same overall bit-width
<kind> defaults to integer if unspecified. 🧚
  • -fblocks β€” enable the "Blocks" language feature.
  • -fobjc-abi-version=version β€” select the Objective-C ABI version to use. available versions are 1 (legacy "fragile" ABI), 2 (non-fragile ABI 1), and 3 (non-fragile ABI 2).
  • -fobjc-nonfragile-abi-version=<version> β€” select the Objective-C non-fragile ABI version to use by default. this will only be used as the Objective-C ABI when the non-fragile ABI is enabled (either via -fobjc-nonfragile-abi, or because it is the platform default).
  • -fobjc-nonfragile-abi, -fno-objc-nonfragile-abi β€” enable use of the Objective-C non-fragile ABI. on platforms for which this is the default ABI, it can be disabled with -fno-objc-nonfragile-abi.

πŸ¦„ Target Selection Options πŸ¦„

Clang fully supports cross compilation as an inherent part of its design. depending on how your version of Clang is configured, it may have support for a number of cross compilers, or may only support a native target.

  • -arch <architecture> β€” specify the architecture to build for (Mac OS X specific).
  • -target <architecture> β€” specify the architecture to build for (all platforms).

okay that's part one, and there's more coming, so don't go anywhere πŸ’–

  • -mmacos-version-min=<version> β€” building for macOS? this says what the minimum macOS version your app supports is. like, how far back are we being nice to 🍎
  • -miphoneos-version-min β€” same energy but for iPhone OS: declare the minimum version your app supports. πŸ“±
  • --print-supported-cpus β€” prints out the whole list of supported processors for the target you're aiming at (you set that with --target=<architecture> or -arch <architecture>). if you don't specify a target, it just uses the system default target. lowkey a vibe check for your CPU list πŸ’…
  • -mcpu=?, -mtune=? β€” acts as an alias for --print-supported-cpus. yeah, same thing, different outfit ✨
  • -mcpu=help, -mtune=help β€” also an alias for --print-supported-cpus. three names, one behavior, iconic 🌈
  • -march=<cpu> β€” tells Clang to generate code for a specific processor family member and later. so if you say -march=i486, the compiler is allowed to emit instructions that are valid on i486 and everything after it β€” which means those instructions might not exist on earlier ones. it's giving "we're only supporting the cool kids and up" πŸ‘‘
  • --print-enabled-extensions β€” prints the list of extensions that are enabled for the target you get from combining --target, -march, and -mcpu values. rn this option is only supported on AArch64 and RISC-V, bestie. and on RISC-V it also prints out the ISA string of the enabled extensions. extra credit behavior, we love πŸŽ€
  • --print-supported-extensions β€” prints the list of all extensions supported for every CPU target for an architecture (again, set via --target=<architecture> or -arch <architecture>). no target specified? system default target it is. currently only supported on AArch64 and RISC-V, no cap πŸ¦‹

✨ Code Generation Options ✨

  • -O0, -O1, -O2, -O3, -Ofast, -Os, -Oz, -Og, -O, -O4 β€” pick your optimization level, queen. here's the tea:
    • -O0 β€” means "no optimization": this level compiles the fastest and generates the most debuggable code. raw, unfiltered, honest πŸ’€
    • -O1 β€” somewhere between -O0 and -O2. the middle child 🫢
    • -O2 β€” a moderate level of optimization which enables most optimizations. the reliable bestie ✨
    • -O3 β€” like -O2, except it also enables optimizations that take longer to perform or that may generate larger code (all in an attempt to make the program run faster). go big or go home πŸ”₯
    • -Ofast β€” enables all the optimizations from -O3 plus other aggressive optimizations that may violate strict compliance with language standards. this is deprecated in Clang 19 and a warning gets emitted saying you should use -O3 together with -ffast-math instead if the non-standard math behavior is actually what you wanted. there's no timeline yet for removal; the whole point is to discourage -Ofast because it's genuinely surprising that an optimization flag changes the observable behavior of correct code. > bestie, that's not a vibe, that's a jumpscare 😭
    • -Os β€” like -O2 with extra optimizations to reduce code size. small and mighty πŸ“
    • -Oz β€” like -Os (and therefore like -O2), but it reduces code size even further. microscopic, adorable 🌸
    • -Og β€” similar to -O1, but with slightly reduced optimization and better variable visibility. the same optimizations run as at -O1, but the -fextend-variable-liveness flag is also set, which tries to prevent optimizations from reducing the liveness of your variables β€” so they're actually available when you're debugging. debugging queen behavior πŸ‘‘
    • -O β€” equivalent to -O1. the lazy girl's -O1 πŸ’…
    • -O4 and higher β€” currently equivalent to -O3. go off, but it's the same thing 🌈
  • -g, -gline-tables-only, -gmodules β€” these control debug information output. heads up: Clang debug info works best at -O0. and when you pass more than one option starting with -g, the last one wins. so order matters, bestie:
    • -g β€” generate debug information. plain and simple πŸŽ€
    • -gline-tables-only β€” generates only line table debug information. this allows for symbolicated backtraces with inlining information, but it does not include any info about variables, their locations, or their types. it's giving "here's where we are, don't ask about the locals" πŸ™ˆ
    • -gmodules β€” generates debug information that contains external references to types defined in Clang modules or precompiled headers, instead of emitting redundant debug type information into every single object file. this option transparently switches the Clang module format to object file containers that hold the Clang module together with the debug information. when compiling a program that uses Clang modules or precompiled headers, this option produces complete debug info with faster compile times and much smaller object files. obsessed. ✨
do not use this option when building static libraries for distribution to other machines, because the debug info will contain references to the module cache on the machine where the library's object files were built. that's a "works on my machine" trap, fr fr πŸ’€
  • -fstandalone-debug, -fno-standalone-debug β€” Clang does a bunch of optimizations to shrink the debug information in the binary. they work on the assumption that debug type info can be spread out across multiple compilation units. for example, Clang won't emit type definitions for types that aren't needed by a module and could just be replaced with a forward declaration. and further, Clang will only emit type info for a dynamic C++ class in the module that contains the vtable for that class.

the -fstandalone-debug option turns all those optimizations off. this is useful when you're working with 3rd-party libraries that don't come with debug information. this is the default on Darwin. note that Clang will never emit type information for types that aren't referenced at all by the program. πŸ¦‹

  • -feliminate-unused-debug-types β€” by default, Clang doesn't emit type info for types that are defined but not used in a program. if you want to retain the debug info for those unused types, use the negation -fno-eliminate-unused-debug-types. the way that unused types deserve representation too πŸ’œ
  • -fexceptions β€” allows exceptions to be thrown through Clang-compiled stack frames (on many targets this enables unwind information for functions that might have an exception thrown through them). for most targets, this is enabled by default for C++. so it's already slaying unless you turned it off 🌈
  • -ftrapv β€” generates code to catch integer overflow errors. signed integer overflow is undefined in C. with this flag, extra code is generated to detect that and abort when it happens. > it's not a fix, it's a tripwire β€” it detects and aborts, bestie 🚨
  • -fvisibility β€” this flag sets the default visibility level. that's it, that's the whole job πŸ‘‘
  • -fcommon, -fno-common β€” this flag specifies that variables without initializers get common linkage. you can turn that off with -fno-common. two flags, one toggle πŸ’…
  • -ftls-model=<model> β€” sets the default thread-local storage (TLS) model to use for thread-local variables. the valid values are: "global-dynamic", "local-dynamic", "initial-exec" and "local-exec". the default is "global-dynamic". you can override the default model with the tls_model attribute. and the compiler will try to choose a more efficient model if it can, because it's thoughtful like that ✨
  • -flto, -flto=full, -flto=thin, -emit-llvm β€” generates output files in LLVM formats, suitable for link time optimization. when used with -S this generates LLVM intermediate language assembly files; otherwise it generates LLVM bitcode format object files (which may be passed to the linker depending on the stage selection options). 🧚

the default for -flto is "full", where the LLVM bitcode is suitable for monolithic Link Time Optimization (LTO), meaning the linker merges all such modules into a single combined module for optimization. with "thin", ThinLTO compilation is invoked instead. skinny legend behavior 🌸

Note:

on Darwin, when using -flto along with -g and compiling and linking in separate steps, you also need to pass -Wl,-object_path_lto,<lto-filename>.o at the linking step, to instruct the ld64 linker not to delete the temporary object file generated during Link Time Optimization. (this flag is automatically passed to the linker by Clang if compilation and linking are done in a single step.) this is what lets you debug the executable as well as generate the .dSYM bundle using dsymutil(1). don't skip this step or you'll be sad 😭

πŸš— Driver Options πŸš—

  • -### β€” print (but do not run) the commands that would run for this compilation. it's the "show me your outfit" of compiler flags πŸ‘—
  • --help β€” display available options. the classic πŸŽ€
  • -Qunused-arguments β€” do not emit any warnings for unused driver arguments. silence, but make it intentional 🀫
  • -Wa,<args> β€” pass the comma separated arguments in args to the assembler.
  • -Wl,<args> β€” pass the comma separated arguments in args to the linker.
  • -Wp,<args> β€” pass the comma separated arguments in args to the preprocessor.
  • -Xanalyzer <arg> β€” pass arg to the static analyzer.
  • -Xassembler <arg> β€” pass arg to the assembler.
  • -Xlinker <arg> β€” pass arg to the linker.
  • -Xpreprocessor <arg> β€” pass arg to the preprocessor.
  • -o <file> β€” write output to file. the main character output slot πŸ’…
  • -print-file-name=<file> β€” print the full library path of file. πŸ—ΊοΈ
  • -print-libgcc-file-name β€” print the library path for the currently used compiler runtime library ("libgcc.a" or "libclang_rt.builtins.*.a"). πŸ”
  • -print-prog-name=<name> β€” print the full program path of name. πŸ“
  • -print-search-dirs β€” print the paths used for finding libraries and programs. the map of where everything lives 🧭
  • -save-temps β€” save intermediate compilation results. receipts, but for your build πŸ’Ύ
  • -save-stats, -save-stats=cwd, -save-stats=obj β€” save internal code generation (LLVM) statistics to a file in the current directory (-save-stats / "-save-stats=cwd") or in the directory of the output file ("-save-stats=obj"). πŸ“Š

you can also use environment variables to control the statistics reporting. setting CC_PRINT_INTERNAL_STAT to 1 enables the feature, and the report goes to stdout in JSON format.

setting CC_PRINT_INTERNAL_STAT_FILE to a file path makes it report statistics to the given file, in the JSON format.

note that -save-stats takes precedence over CC_PRINT_INTERNAL_STAT and CC_PRINT_INTERNAL_STAT_FILE. flag wins, always ✨
  • -integrated-as, -no-integrated-as β€” used to enable and disable, respectively, the use of the integrated assembler. whether the integrated assembler is on by default is target dependent. iykyk πŸ¦‹
  • -time β€” time individual commands. stopwatch era ⏱️
  • -ftime-report β€” print a timing summary of each stage of compilation. the full breakdown, no crumbs left 🌈
  • -v β€” show commands to run and use verbose output. tell me everything, bestie πŸ‘‘

πŸ’… Diagnostics Options πŸ’…

  • -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 β€” okay so these are the glow-up knobs for how Clang talks to you about diagnostics, aka your errors and warnings. Want more info? The Clang User's Manual has the full tea, bestie. ✨

🌸 Preprocessor Options 🌸

  • -D<macroname>=<value> β€” sneaks an implicit #define into the predefines buffer, which gets read before your source file even starts getting preprocessed. πŸŽ€
  • -U<macroname> β€” the opposite vibe: drops an implicit #undef into the predefines buffer, also read before your source file gets preprocessed. πŸ’…
  • -include <filename> β€” adds an implicit #include into the predefines buffer, read before the source file is preprocessed. Sneaky but iconic. πŸ¦‹
  • -I<directory> β€” adds that directory to the search path for include files. 🌈
  • -F<directory> β€” adds that directory to the search path for framework include files. πŸ“
  • -nostdinc β€” do not go looking in the standard system directories or the compiler builtin directories for include files. None of them. Periodt. πŸ’€
  • -nostdlibinc β€” skips the standard system directories for include files, but does still search the compiler builtin include directories. Half yes, half no, iykyk. ✨
  • -nobuiltininc β€” doesn't search clang's builtin directory for include files. πŸ™ˆ
  • -nostdinc++ β€” doesn't search the system C++ standard library directory for include files. πŸ‘‘
  • -fkeep-system-includes β€” okay this one only works with -E, no exceptions. Instead of copying the preprocessed content of "system" headers into the output, it keeps the #include directive right where it is. This can massively cut down the volume of text -E spits out, which is genuinely so helpful when you're trying to cook up a "small" reproduceable test case. 🫢
⚠️ But bestie, listen β€” this option does not guarantee reproduceability. Not even a little. If the including source defines preprocessor symbols that influence how the system headers behave (think _XOPEN_SOURCE), then running -E will remove that definition, and that can genuinely change the semantics of the included header. Also, if you're using a different version of the system headers β€” especially a different version of the STL β€” the behavior may come out different too. So always verify the preprocessed file by compiling it separately. No skipping this step, fr fr. 😭

🌟 ENVIRONMENT 🌟

  • TMPDIR, TEMP, TMP β€” these three get checked, in order, to figure out where to write the temporary files used while compiling. First one that answers wins. πŸŽ€
  • CPATH β€” specifies extra (non-system) header search paths for finding included header files. These get searched after the paths you gave with -I<directory>, but before any system header search paths. Paths are separated by the same platform dependent delimiter used in the PATH environment variable. And here's the detail people miss: empty entries in that delimited list β€” including ones at the very beginning or the very end β€” are treated as specifying the compiler's current working directory. πŸ‘€
  • C_INCLUDE_PATH, OBJC_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJCPLUS_INCLUDE_PATH β€” these specify extra system header file search paths, used when processing the corresponding language. Search paths are delimited the same way as for the CPATH environment variable. 🌈
  • MACOSX_DEPLOYMENT_TARGET β€” if -mmacos-version-min isn't specified, the default deployment target gets read from this environment variable instead. Heads up: this option only affects Darwin targets. πŸ“

πŸ’€ BUGS πŸ’€

Found a bug? Say it with your chest β€” go to https://github.com/llvm/llvm-project/issues/. And like, most bug reports should include preprocessed source files (use the -E option, bestie), the full output of the compiler, and info to reproduce. Give them everything so they can actually help you. 🫢


πŸ‘‘ SEE ALSO πŸ‘‘

as(1), ld(1)


✨ Author ✨

Maintained by the Clang / LLVM Team (http://clang.llvm.org)


2007-2026, The Clang Team


And that's the whole page, bestie β€” copyright's sitting at 2007-2026, The Clang Team, and this edition is dated Jul 16, 2026. Go compile something iconic. Slay. πŸ’…βœ¨πŸŽ€

πŸ“¦ where this page comes from