Index: include/clang/Basic/LangOptions.def =================================================================== --- include/clang/Basic/LangOptions.def +++ include/clang/Basic/LangOptions.def @@ -148,6 +148,7 @@ LANGOPT(CharIsSigned , 1, 1, "signed char") LANGOPT(ShortWChar , 1, 0, "unsigned short wchar_t") ENUM_LANGOPT(MSPointerToMemberRepresentationMethod, PragmaMSPointersToMembersKind, 2, PPTMK_BestCase, "member-pointer representation method") +LANGOPT(LongDouble64 , 1, 0, "64-bit long double") LANGOPT(ShortEnums , 1, 0, "short enum types") Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -850,6 +850,10 @@ HelpText<"Force wchar_t to be a short unsigned int">; def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group, Flags<[CC1Option]>, HelpText<"Force wchar_t to be an unsigned int">; +def mlong_double_64 : Flag<["-"], "mlong-double-64">, Group, Flags<[CC1Option]>, + HelpText<"Force long double to be 64 bit">; +def mlong_double_default : Flag<["-"], "mlong-double-default">, Group, Flags<[CC1Option]>, + HelpText<"Force long double to be default width">; def fshow_overloads_EQ : Joined<["-"], "fshow-overloads=">, Group, Flags<[CC1Option]>, HelpText<"Which overload candidates to show when overload resolution fails: " "best|all; defaults to all">; Index: lib/Basic/TargetInfo.cpp =================================================================== --- lib/Basic/TargetInfo.cpp +++ lib/Basic/TargetInfo.cpp @@ -272,6 +272,8 @@ UseBitFieldTypeAlignment = false; if (Opts.ShortWChar) WCharType = UnsignedShort; + if (Opts.LongDouble64) + LongDoubleWidth = LongDoubleAlign = 64; if (Opts.OpenCL) { // OpenCL C requires specific widths for types, irrespective of Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -4168,6 +4168,14 @@ options::OPT_fno_short_wchar)) A->render(Args, CmdArgs); + // -mlong-double-default is default, only pass non-default. + if (Arg *A = Args.getLastArg(options::OPT_mlong_double_64, + options::OPT_mlong_double_default)) { + A->claim(); + if (!A->getOption().matches(options::OPT_mlong_double_default)) + A->render(Args, CmdArgs); + } + // -fno-pascal-strings is default, only pass non-default. if (Args.hasFlag(options::OPT_fpascal_strings, options::OPT_fno_pascal_strings, Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1522,6 +1522,7 @@ Args.getLastArgValue(OPT_fmodule_implementation_of); Opts.NativeHalfType = Opts.NativeHalfType; Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns); + Opts.LongDouble64 = Args.hasArg(OPT_mlong_double_64); if (!Opts.CurrentModule.empty() && !Opts.ImplementationOfModule.empty() && Opts.CurrentModule != Opts.ImplementationOfModule) { Index: test/Driver/clang_f_opts.c =================================================================== --- test/Driver/clang_f_opts.c +++ test/Driver/clang_f_opts.c @@ -390,3 +390,8 @@ // CHECK-WCHAR1-NOT: -fshort-wchar // CHECK-WCHAR2: -fshort-wchar // CHECK-WCHAR2-NOT: -fno-short-wchar + +// RUN: %clang -### -mlong-double-64 -mlong-double-default %s 2>&1 | FileCheck -check-prefix=CHECK-LONG-DOUBLE-64-1 %s +// RUN: %clang -### -mlong-double-default -mlong-double-64 %s 2>&1 | FileCheck -check-prefix=CHECK-LONG-DOUBLE-64-2 %s +// CHECK-LONG-DOUBLE-64-1-NOT: -mlong-double-64 +// CHECK-LONG-DOUBLE-64-2: -mlong-double-64 Index: test/Sema/long-double-64.c =================================================================== --- /dev/null +++ test/Sema/long-double-64.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -fsyntax-only -mlong-double-64 -verify +// expected-no-diagnostics + +int check_long_double_size[sizeof(long double) == 8 ? 1 : -1];