Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1334,6 +1334,10 @@ def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group; def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">, Flags<[CC1Option]>, Group; +def fdigraphs : Flag<["-"], "fdigraphs">, Group, Flags<[CC1Option]>, + HelpText<"Enable alternative token representations '<:', ':>', '<%', '%>', '%:' (default)">; +def fno_digraphs : Flag<["-"], "fno-digraphs">, Group, Flags<[CC1Option]>, + HelpText<"Disallow alternative token representations '<:', ':>', '<%', '%>', '%:'">; def fno_declspec : Flag<["-"], "fno-declspec">, Group, HelpText<"Disallow __declspec as a keyword">, Flags<[CC1Option]>; def fno_dollars_in_identifiers : Flag<["-"], "fno-dollars-in-identifiers">, Group, Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -3970,6 +3970,7 @@ // Forward -f (flag) options which we can pass directly. Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); + Args.AddLastArg(CmdArgs, options::OPT_fdigraphs, options::OPT_fno_digraphs); Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names); Args.AddLastArg(CmdArgs, options::OPT_femulated_tls, options::OPT_fno_emulated_tls); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2080,6 +2080,7 @@ DiagnosticsEngine &Diags) { // FIXME: Cleanup per-file based stuff. LangStandard::Kind LangStd = LangStandard::lang_unspecified; + const Arg *LangStdArg; if (const Arg *A = Args.getLastArg(OPT_std_EQ)) { LangStd = llvm::StringSwitch(A->getValue()) #define LANGSTANDARD(id, name, lang, desc, features) \ @@ -2117,6 +2118,7 @@ } else { // Valid standard, check to make sure language and standard are // compatible. + LangStdArg = A; const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); if (!IsInputCompatibleWithStandard(IK, Std)) { Diags.Report(diag::err_drv_argument_not_allowed_with) @@ -2147,8 +2149,10 @@ Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); } - else + else { LangStd = OpenCLLangStd; + LangStdArg = A; + } } Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header); @@ -2174,6 +2178,16 @@ Opts.GNUKeywords = Args.hasFlag(OPT_fgnu_keywords, OPT_fno_gnu_keywords, Opts.GNUKeywords); + if (const Arg* A = Args.getLastArg(OPT_fdigraphs, OPT_fno_digraphs)) { + // Prevent the user from enabling or disabling digraphs when they are not supported. + if (!Opts.Digraphs && LangStdArg) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getSpelling() << LangStdArg->getAsString(Args); + + if (A->getOption().matches(OPT_fno_digraphs)) + Opts.Digraphs = 0; + } + if (Args.hasArg(OPT_fno_operator_names)) Opts.CXXOperatorNames = 0; Index: test/Lexer/digraph.c =================================================================== --- test/Lexer/digraph.c +++ test/Lexer/digraph.c @@ -1,6 +1,17 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding %s -// expected-no-diagnostics +// RUN: %clang_cc1 -DDIGRAPHS=1 -fsyntax-only -verify -ffreestanding %s +// RUN: %clang_cc1 -DDIGRAPHS=1 -fno-digraphs -fdigraphs -fsyntax-only -verify -ffreestanding %s +// RUN: %clang_cc1 -fno-digraphs -fsyntax-only -verify -ffreestanding %s +// RUN: %clang_cc1 -fdigraphs -fno-digraphs -fsyntax-only -verify -ffreestanding %s + +// RUN: not %clang_cc1 -std=c89 -fdigraphs -fsyntax-only -ffreestanding %s 2>&1 | FileCheck -check-prefix=CHECK1 %s +// RUN: not %clang_cc1 -std=c89 -fno-digraphs -fsyntax-only -ffreestanding %s 2>&1 | FileCheck -check-prefix=CHECK2 %s + +// CHECK1: error: invalid argument '-fdigraphs' not allowed with '-std=c89' +// CHECK2: error: invalid argument '-fno-digraphs' not allowed with '-std=c89' +#if DIGRAPHS + +// expected-no-diagnostics %:include %:ifndef BUFSIZE @@ -14,3 +25,15 @@ d<:len:> = s<:len:>; %> %> +#else + +// expected-error@+1 {{expected identifier or '('}} +%:include +; +// expected-error@+1 {{expected ')'}} expected-note@+1{{to match this '('}} +void copy(char d<::>); + +// expected-error@+1 {{expected function body}} +void copy() <% %> + +#endif