Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -769,6 +769,4 @@ def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">, HelpText<"The string to embed in the Dwarf debug AT_producer record.">; -def defsym : Separate<["-"], "defsym">, - HelpText<"Define a value for a symbol">; } // let Flags = [CC1AsOption] Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -543,6 +543,8 @@ def dM : Flag<["-"], "dM">, Group, Flags<[CC1Option]>, HelpText<"Print macro definitions in -E mode instead of normal output">; def dead__strip : Flag<["-"], "dead_strip">; +def defsym : Separate<["-"], "defsym">, Group, Flags<[CC1Option, CC1AsOption]>, + HelpText<"Define an assembly-time variable with the given name and value">; def dependency_file : Separate<["-"], "dependency-file">, Flags<[CC1Option]>, HelpText<"Filename (or -) to write dependency output to">; def dependency_dot : Separate<["-"], "dependency-dot">, Flags<[CC1Option]>, Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -113,6 +113,24 @@ } } +// Validate the value to a -defsym option +static bool validateDefsym(const char *S, const Driver &D) { + auto Pair = StringRef(S).split('='); + auto Sym = Pair.first; + auto SVal = Pair.second; + + if (Sym.empty() || SVal.empty()) { + D.Diag(diag::err_drv_defsym_invalid_format) << S; + return false; + } + int64_t IVal; + if (SVal.getAsInteger(0, IVal)) { + D.Diag(diag::err_drv_defsym_invalid_symval) << SVal; + return false; + } + return true; +} + /// Apply \a Work on the current tool chain \a RegularToolChain and any other /// offloading tool chain that is associated with the current action \a JA. static void @@ -1728,6 +1746,21 @@ // arg after parsing the '-I' arg. bool TakeNextArg = false; + // Handle the top-level implementation of the integrated assembler + // -defsym option + for (const Arg *A : Args.filtered(options::OPT_defsym)) { + A->claim(); + if (A->getNumValues() != 1) { + D.Diag(diag::err_drv_defsym_invalid_format) << A->getAsString(Args); + break; + } + const char *S = A->getValue(0); + if (validateDefsym(S, D)) { + CmdArgs.push_back("-defsym"); + CmdArgs.push_back(S); + } + } + // When using an integrated assembler, translate -Wa, and -Xassembler // options. bool CompressDebugSections = false; @@ -1843,21 +1876,10 @@ break; } const char *S = A->getValue(1); - auto Pair = StringRef(S).split('='); - auto Sym = Pair.first; - auto SVal = Pair.second; - - if (Sym.empty() || SVal.empty()) { - D.Diag(diag::err_drv_defsym_invalid_format) << S; - break; + if (validateDefsym(S, D)) { + CmdArgs.push_back(Value.data()); + TakeNextArg = true; } - int64_t IVal; - if (SVal.getAsInteger(0, IVal)) { - D.Diag(diag::err_drv_defsym_invalid_symval) << SVal; - break; - } - CmdArgs.push_back(Value.data()); - TakeNextArg = true; } else { D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Value; Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2500,6 +2500,12 @@ Success = false; } + // Issue warning for integrated assembler -defsym option + for (const Arg *A : Args.filtered(options::OPT_defsym)) { + A->claim(); + Diags.Report(diag::warn_drv_unused_argument) << A->getAsString(Args); + } + // Issue errors on unknown arguments. for (const Arg *A : Args.filtered(OPT_UNKNOWN)) { Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args); Index: test/Driver/defsym.c =================================================================== --- /dev/null +++ test/Driver/defsym.c @@ -0,0 +1,13 @@ +// RUN: not %clang -c -o /dev/null %s \ +// RUN: -defsym \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR +// CHECK-DEFSYM-ERR: error: argument to '-defsym' is missing (expected 1 value) + +// RUN: %clang -c -o /dev/null %s \ +// RUN: -defsym bar=1 \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-WARN +// CHECK-DEFSYM-WARN: warning: argument unused during compilation: '-defsym bar=1' + +int foo(void) { + return 0; +} Index: test/Driver/defsym.s =================================================================== --- test/Driver/defsym.s +++ test/Driver/defsym.s @@ -1,37 +1,73 @@ // RUN: %clang -### -c -integrated-as %s \ // RUN: -Wa,-defsym,abc=5 -Wa,-defsym,xyz=0xa \ // RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM1 +// RUN: %clang -### -c -integrated-as %s \ +// RUN: -defsym abc=5 -defsym xyz=0xa \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM1 // RUN: %clang -### -c -no-integrated-as -target x86_64-unknown-unknown %s \ // RUN: -Wa,-defsym,abc=5 -Wa,-defsym,xyz=0xa \ // RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM1 +// RUN: %clang -### -c -no-integrated-as -target x86_64-unknown-unknown %s \ +// RUN: -defsym abc=5 -defsym xyz=0xa \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-UNUSED // CHECK-DEFSYM1: "-defsym" // CHECK-DEFSYM1: "abc=5" // CHECK-DEFSYM1: "-defsym" // CHECK-DEFSYM1: "xyz=0xa" +// CHECK-UNUSED: warning: argument unused during compilation: '-defsym abc=5' [-Wunused-command-line-argument] +// CHECK-UNUSED: warning: argument unused during compilation: '-defsym xyz=0xa' [-Wunused-command-line-argument] // RUN: not %clang -c -integrated-as -o /dev/null %s \ // RUN: -Wa,-defsym,abc= \ // RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR1 +// RUN: not %clang -c -integrated-as -o /dev/null %s \ +// RUN: -defsym abc= \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR1 // CHECK-DEFSYM-ERR1: error: defsym must be of the form: sym=value: abc= // RUN: not %clang -c -integrated-as -o /dev/null %s \ -// RUN: -Wa,-defsym,=123 \ +// RUN: -Wa,-defsym,abc \ // RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR2 -// CHECK-DEFSYM-ERR2: error: defsym must be of the form: sym=value: =123 +// RUN: not %clang -c -integrated-as -o /dev/null %s \ +// RUN: -defsym abc \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR2 +// CHECK-DEFSYM-ERR2: error: defsym must be of the form: sym=value: abc // RUN: not %clang -c -integrated-as -o /dev/null %s \ -// RUN: -Wa,-defsym,abc=1a2b3c \ +// RUN: -Wa,-defsym,=123 \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR3 +// RUN: not %clang -c -integrated-as -o /dev/null %s \ +// RUN: -defsym =123 \ // RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR3 -// CHECK-DEFSYM-ERR3: error: Value is not an integer: 1a2b3c +// CHECK-DEFSYM-ERR3: error: defsym must be of the form: sym=value: =123 // RUN: not %clang -c -integrated-as -o /dev/null %s \ -// RUN: -Wa,-defsym \ +// RUN: -Wa,-defsym,123 \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR4 +// RUN: not %clang -c -integrated-as -o /dev/null %s \ +// RUN: -defsym 123 \ // RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR4 +// CHECK-DEFSYM-ERR4: error: defsym must be of the form: sym=value: 123 // RUN: not %clang -c -integrated-as -o /dev/null %s \ +// RUN: -Wa,-defsym,abc=1a2b3c \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR5 +// RUN: not %clang -c -integrated-as -o /dev/null %s \ +// RUN: -defsym abc=1a2b3c \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR5 +// CHECK-DEFSYM-ERR5: error: Value is not an integer: 1a2b3c + +// RUN: not %clang -c -integrated-as -o /dev/null %s \ +// RUN: -Wa,-defsym \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR6 +// RUN: not %clang -c -integrated-as -o /dev/null %s \ // RUN: -Wa,-defsym, \ -// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR4 +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR6 +// CHECK-DEFSYM-ERR6: error: defsym must be of the form: sym=value: -defsym -// CHECK-DEFSYM-ERR4: error: defsym must be of the form: sym=value: -defsym +// RUN: not %clang -c -integrated-as -o /dev/null %s \ +// RUN: -defsym \ +// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-DEFSYM-ERR7 +// CHECK-DEFSYM-ERR7: error: argument to '-defsym' is missing (expected 1 value) \ No newline at end of file