Skip to content

Commit

Permalink
[C++20] [Modules] [Driver] Don't enable -fdelayed-template-parsing by…
Browse files Browse the repository at this point in the history
… default on windows after c++20

There are already 3 issues about the broken state of
-fdelayed-template-parsing and C++20 modules:
- #61068
- #64810
- #65027

The problem is more complex than I thought. I am not sure how to fix it
properly now. Given the complexities and -fdelayed-template-parsing is
actually an extension to support old MS codes, I think it may make sense
to not enable the -fdelayed-template-parsing option by default with
C++20 modules to give more user friendly experience. Users who still want
-fdelayed-template-parsing can specify it explicitly.

Given the discussion in #69551,
we decide to not enable -fdelayed-template-parsing by default on windows
after c++20
  • Loading branch information
ChuanqiXu9 committed Oct 23, 2023
1 parent 12a731b commit 9c0d81e
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 21 deletions.
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ C++ Specific Potentially Breaking Changes
system headers and macros. It will be turned into a hard (non-downgradable)
error in the next Clang release.

- The flag `-fdelayed-template-parsing` won't be enabled by default with C++20
when targetting MSVC to match the behavior of MSVC.
(`MSVC Docs <https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-170>`_)

ABI Changes in This Version
---------------------------
- Following the SystemV ABI for x86-64, ``__int128`` arguments will no longer
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,10 @@ def err_test_module_file_extension_format : Error<
def err_drv_module_output_with_multiple_arch : Error<
"option '-fmodule-output' can't be used with multiple arch options">;

def warn_drv_delayed_template_parsing_after_cxx20 : Warning<
"-fdelayed-template-parsing is deprecated after C++20">,
InGroup<DiagGroup<"delayed-template-parsing-in-cxx20">>;

def err_drv_extract_api_wrong_kind : Error<
"header file '%0' input '%1' does not match the type of prior input "
"in api extraction; use '-x %2' to override">;
Expand Down
54 changes: 33 additions & 21 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3724,20 +3724,10 @@ bool Driver::getDefaultModuleCachePath(SmallVectorImpl<char> &Result) {

static bool RenderModulesOptions(Compilation &C, const Driver &D,
const ArgList &Args, const InputInfo &Input,
const InputInfo &Output, const Arg *Std,
const InputInfo &Output, bool HaveStd20,
ArgStringList &CmdArgs) {
bool IsCXX = types::isCXX(Input.getType());
// FIXME: Find a better way to determine whether the input has standard c++
// modules support by default.
bool HaveStdCXXModules =
IsCXX && Std &&
(Std->containsValue("c++2a") || Std->containsValue("gnu++2a") ||
Std->containsValue("c++20") || Std->containsValue("gnu++20") ||
Std->containsValue("c++2b") || Std->containsValue("gnu++2b") ||
Std->containsValue("c++23") || Std->containsValue("gnu++23") ||
Std->containsValue("c++2c") || Std->containsValue("gnu++2c") ||
Std->containsValue("c++26") || Std->containsValue("gnu++26") ||
Std->containsValue("c++latest") || Std->containsValue("gnu++latest"));
bool HaveStdCXXModules = IsCXX && HaveStd20;
bool HaveModules = HaveStdCXXModules;

// -fmodules enables the use of precompiled modules (off by default).
Expand Down Expand Up @@ -6842,14 +6832,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
(!IsWindowsMSVC || IsMSVC2015Compatible)))
CmdArgs.push_back("-fno-threadsafe-statics");

// -fno-delayed-template-parsing is default, except when targeting MSVC.
// Many old Windows SDK versions require this to parse.
// FIXME: MSVC introduced /Zc:twoPhase- to disable this behavior in their
// compiler. We should be able to disable this by default at some point.
if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
options::OPT_fno_delayed_template_parsing, IsWindowsMSVC))
CmdArgs.push_back("-fdelayed-template-parsing");

// -fgnu-keywords default varies depending on language; only pass if
// specified.
Args.AddLastArg(CmdArgs, options::OPT_fgnu_keywords,
Expand All @@ -6870,8 +6852,38 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,

Args.AddLastArg(CmdArgs, options::OPT_finline_max_stacksize_EQ);

// FIXME: Find a better way to determine whether we are in C++20.
bool HaveCxx20 =
Std &&
(Std->containsValue("c++2a") || Std->containsValue("gnu++2a") ||
Std->containsValue("c++20") || Std->containsValue("gnu++20") ||
Std->containsValue("c++2b") || Std->containsValue("gnu++2b") ||
Std->containsValue("c++23") || Std->containsValue("gnu++23") ||
Std->containsValue("c++2c") || Std->containsValue("gnu++2c") ||
Std->containsValue("c++26") || Std->containsValue("gnu++26") ||
Std->containsValue("c++latest") || Std->containsValue("gnu++latest"));
bool HaveModules =
RenderModulesOptions(C, D, Args, Input, Output, Std, CmdArgs);
RenderModulesOptions(C, D, Args, Input, Output, HaveCxx20, CmdArgs);

// -fdelayed-template-parsing is default when targeting MSVC.
// Many old Windows SDK versions require this to parse.
//
// According to
// https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-170,
// MSVC actually defaults to -fno-delayed-template-parsing (/Zc:twoPhase-
// with MSVC CLI) if using C++20. So we match the behavior with MSVC here to
// not enable -fdelayed-template-parsing by default after C++20.
//
// FIXME: Given -fdelayed-template-parsing is a source of bugs, we should be
// able to disable this by default at some point.
if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
options::OPT_fno_delayed_template_parsing,
IsWindowsMSVC && !HaveCxx20)) {
if (HaveCxx20)
D.Diag(clang::diag::warn_drv_delayed_template_parsing_after_cxx20);

CmdArgs.push_back("-fdelayed-template-parsing");
}

if (Args.hasFlag(options::OPT_fpch_validate_input_files_content,
options::OPT_fno_pch_validate_input_files_content, false))
Expand Down
10 changes: 10 additions & 0 deletions clang/test/Driver/cl-delayed-template-parsing-cxx20.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// RUN: %clang_cl -### -- %s 2>&1 | FileCheck %s --check-prefix=PRE-CXX20
// RUN: %clang_cl -std:c++20 -### -- %s 2>&1 | FileCheck %s
// RUN: %clang_cl -std:c++20 -### -fdelayed-template-parsing -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-EXPLICIT

// PRE-CXX20: -fdelayed-template-parsing

// CHECK-NOT: -fdelayed-template-parsing

// CHECK-EXPLICIT: warning: -fdelayed-template-parsing is deprecated after C++20
// CHECK-EXPLICIT: -fdelayed-template-parsing

0 comments on commit 9c0d81e

Please sign in to comment.