iains created this revision.
Herald added a project: All.
iains added reviewers: rsmith, urnathan, ChuanqiXu.
iains added a subscriber: clang-modules.
iains published this revision for review.
iains added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This is a set of 4 patches that adds the driver-side support for C++20 header 
modules.

We use the same user-facing options as the existing implementation in GCC 
(there seems no engineering reason to deviate from this and it makes things 
easier for users and build system alike).

1/4 - this patch introduces file types for header unit headers to be searched 
for in the user or system paths (or to be given an absolute pathname).
2/4 - adds the -fmoduke-header{.=} command line options
3/4 - is a user-convenience change that allows "foo.h" without complaining 
about C code used in C++ compilations (since we know that the user has already 
specified the intent).
4/4 - adds the -fdirectives-only command that produces pre-processor output 
which retains the macro definitions/undefs that will be present in the built 
header unit.


This adds file types and handling for three input types, representing a C++20
header unit source:

1. When provided with a complete pathname for the header.
2. For a header to be looked up (by the frontend) in the user search paths
3. For a header to be looked up in the system search paths.

We also add a pre-processed file type (although that is a single type, 
regardless
of the original input type).

These types may be specified with -xc++-{user,system,header-unit}-header xxxx.

These types allow us to disambiguate header unit jobs from PCH ones, and thus
we handle these differently from other header jobs in two ways:

1. The job construction is altered to build a C++20 header unit (rather than a 
PCH file, as would be the case for other headers).
2. When the type is "user" or "system" we defer checking for the file until the 
front end is run, since we need to look up the header in the relevant paths 
which are not known at this point.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121588

Files:
  clang/include/clang/Driver/Types.def
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/Types.cpp
  clang/lib/Frontend/FrontendOptions.cpp
  clang/test/Driver/Inputs/header-unit-01.hh
  clang/test/Driver/cxx20-header-units-01.cpp

Index: clang/test/Driver/cxx20-header-units-01.cpp
===================================================================
--- /dev/null
+++ clang/test/Driver/cxx20-header-units-01.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang++ -### -std=c++20 -xc++-user-header foo.h 2>&1 | \
+// RUN:   FileCheck -check-prefix=CHECK-USER %s
+
+// RUN: %clang++ -### -std=c++20 -xc++-system-header vector 2>&1 | \
+// RUN:   FileCheck -check-prefix=CHECK-SYSTEM %s
+
+// RUN: %clang++ -### -std=c++20 -xc++-header-unit-header %S/Inputs/header-unit-01.hh 2>&1 | \
+// RUN:   FileCheck -check-prefix=CHECK-ABS %s -DTDIR=%S/Inputs
+
+// CHECK-USER: "-emit-header-unit"
+// CHECK-USER-SAME: "-o" "foo.pcm"
+// CHECK-USER-SAME: "-x" "c++-user-header" "foo.h"
+// CHECK-SYSTEM: "-emit-header-unit"
+// CHECK-SYSTEM-SAME: "-o" "vector.pcm"
+// CHECK-SYSTEM-SAME: "-x" "c++-system-header" "vector"
+// CHECK-ABS: "-emit-header-unit"
+// CHECK-ABS-SAME: "-o" "header-unit-01.pcm"
+// CHECK-ABS-SAME: "-x" "c++-header-unit-header" "[[TDIR]]/header-unit-01.hh"
Index: clang/lib/Frontend/FrontendOptions.cpp
===================================================================
--- clang/lib/Frontend/FrontendOptions.cpp
+++ clang/lib/Frontend/FrontendOptions.cpp
@@ -27,6 +27,7 @@
       .Cases("C", "cc", "cp", Language::CXX)
       .Cases("cpp", "CPP", "c++", "cxx", "hpp", "hxx", Language::CXX)
       .Case("cppm", Language::CXX)
+      .Case("iih", InputKind(Language::CXX).getPreprocessed())
       .Case("iim", InputKind(Language::CXX).getPreprocessed())
       .Case("cl", Language::OpenCL)
       .Case("clcpp", Language::OpenCLCXX)
Index: clang/lib/Driver/Types.cpp
===================================================================
--- clang/lib/Driver/Types.cpp
+++ clang/lib/Driver/Types.cpp
@@ -65,9 +65,16 @@
   return Id == TY_CXXModule || Id == TY_PP_CXXModule;
 }
 
+static bool isPreprocessedHeaderUnitType(ID Id) {
+  return Id == TY_CXXSHeader || Id == TY_CXXUHeader || Id == TY_CXXHUHeader ||
+         Id == TY_PP_CXXHeaderUnit;
+}
+
 types::ID types::getPrecompiledType(ID Id) {
   if (isPreprocessedModuleType(Id))
     return TY_ModuleFile;
+  if (isPreprocessedHeaderUnitType(Id))
+    return TY_HeaderUnit;
   if (onlyPrecompileType(Id))
     return TY_PCH;
   return TY_INVALID;
@@ -139,6 +146,10 @@
   case TY_CLHeader:
   case TY_ObjCHeader: case TY_PP_ObjCHeader:
   case TY_CXXHeader: case TY_PP_CXXHeader:
+  case TY_CXXSHeader:
+  case TY_CXXUHeader:
+  case TY_CXXHUHeader:
+  case TY_PP_CXXHeaderUnit:
   case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
   case TY_CXXModule: case TY_PP_CXXModule:
   case TY_AST: case TY_ModuleFile: case TY_PCH:
@@ -210,6 +221,10 @@
   case TY_CXX: case TY_PP_CXX:
   case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
   case TY_CXXHeader: case TY_PP_CXXHeader:
+  case TY_CXXSHeader:
+  case TY_CXXUHeader:
+  case TY_CXXHUHeader:
+  case TY_PP_CXXHeaderUnit:
   case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
   case TY_CXXModule: case TY_PP_CXXModule:
   case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE:
@@ -323,6 +338,7 @@
            .Case("hpp", TY_CXXHeader)
            .Case("hxx", TY_CXXHeader)
            .Case("iim", TY_PP_CXXModule)
+           .Case("iih", TY_PP_CXXHeaderUnit)
            .Case("lib", TY_Object)
            .Case("mii", TY_PP_ObjCXX)
            .Case("obj", TY_Object)
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -4607,6 +4607,8 @@
       CmdArgs.push_back(IsHeaderModulePrecompile
                             ? "-emit-header-module"
                             : "-emit-module-interface");
+    else if (JA.getType() == types::TY_HeaderUnit)
+      CmdArgs.push_back("-emit-header-unit");
     else
       CmdArgs.push_back("-emit-pch");
   } else if (isa<VerifyPCHJobAction>(JA)) {
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -2209,6 +2209,11 @@
   if (Value == "-")
     return true;
 
+  // If it's a header to be found in the system or user search path, then defer
+  // complaints about its absence until those searches can be done.
+  if (Ty == types::TY_CXXSHeader || Ty == types::TY_CXXUHeader)
+    return true;
+
   if (getVFS().exists(Value))
     return true;
 
Index: clang/include/clang/Driver/Types.def
===================================================================
--- clang/include/clang/Driver/Types.def
+++ clang/include/clang/Driver/Types.def
@@ -63,7 +63,11 @@
 TYPE("objective-c-header",       ObjCHeader,   PP_ObjCHeader,   "h",      phases::Preprocess, phases::Precompile)
 TYPE("c++-header-cpp-output",    PP_CXXHeader, INVALID,         "ii",     phases::Precompile)
 TYPE("c++-header",               CXXHeader,    PP_CXXHeader,    "hh",     phases::Preprocess, phases::Precompile)
-TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID, "mii",  phases::Precompile)
+TYPE("c++-header-unit-cpp-output", PP_CXXHeaderUnit,INVALID,    "iih",    phases::Precompile)
+TYPE("c++-header-unit-header",   CXXHUHeader,  PP_CXXHeaderUnit,"hh",     phases::Preprocess, phases::Precompile)
+TYPE("c++-system-header",        CXXSHeader,   PP_CXXHeaderUnit,"hh",     phases::Preprocess, phases::Precompile)
+TYPE("c++-user-header",          CXXUHeader,   PP_CXXHeaderUnit,"hh",     phases::Preprocess, phases::Precompile)
+TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID,"mii",   phases::Precompile)
 TYPE("objective-c++-header",     ObjCXXHeader, PP_ObjCXXHeader, "h",      phases::Preprocess, phases::Precompile)
 TYPE("c++-module",               CXXModule,    PP_CXXModule,    "cppm",   phases::Preprocess, phases::Precompile, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
 TYPE("c++-module-cpp-output",    PP_CXXModule, INVALID,         "iim",    phases::Precompile, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
@@ -88,6 +92,7 @@
 TYPE("ifs",                      IFS,          INVALID,         "ifs",    phases::IfsMerge)
 TYPE("ifs-cpp",                  IFS_CPP,      INVALID,         "ifs",    phases::Compile, phases::IfsMerge)
 TYPE("pcm",                      ModuleFile,   INVALID,         "pcm",    phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("header-unit",              HeaderUnit,   INVALID,         "pcm",    phases::Compile, phases::Backend, phases::Assemble, phases::Link)
 TYPE("plist",                    Plist,        INVALID,         "plist",  phases::Compile, phases::Backend, phases::Assemble, phases::Link)
 TYPE("rewritten-objc",           RewrittenObjC,INVALID,         "cpp",    phases::Compile, phases::Backend, phases::Assemble, phases::Link)
 TYPE("rewritten-legacy-objc",    RewrittenLegacyObjC,INVALID,   "cpp",    phases::Compile, phases::Backend, phases::Assemble, phases::Link)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to