[clang] 5c6a146 - [C++20][Modules][Driver][HU 1/N] Initial handling for -xc++-{system,user}-header.

Iain Sandoe via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 22 01:25:34 PDT 2022


Author: Iain Sandoe
Date: 2022-04-22T09:24:29+01:00
New Revision: 5c6a14649843ccd2c50ed9e2fcacaa8ebd820ae8

URL: https://github.com/llvm/llvm-project/commit/5c6a14649843ccd2c50ed9e2fcacaa8ebd820ae8
DIFF: https://github.com/llvm/llvm-project/commit/5c6a14649843ccd2c50ed9e2fcacaa8ebd820ae8.diff

LOG: [C++20][Modules][Driver][HU 1/N] Initial handling for -xc++-{system,user}-header.

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.

Differential Revision: https://reviews.llvm.org/D121588

Added: 
    clang/test/Driver/Inputs/header-unit-01.hh
    clang/test/Driver/cxx20-header-units-01.cpp

Modified: 
    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

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def
index 94041b183add2..0cf265e05fedc 100644
--- a/clang/include/clang/Driver/Types.def
+++ b/clang/include/clang/Driver/Types.def
@@ -64,7 +64,11 @@ TYPE("objective-c-header-cpp-output", PP_ObjCHeader, INVALID,   "mi",     phases
 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)
@@ -89,6 +93,7 @@ TYPE("ast",                      AST,          INVALID,         "ast",    phases
 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)

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 1c5fb22026e26..6fa95a8834a2c 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2219,6 +2219,11 @@ bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value,
   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;
 

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c37394318dbff..28910d4bd4321 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4609,6 +4609,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
       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)) {

diff  --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index befdc50faa9c5..1115e8c7710cf 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -65,9 +65,16 @@ static bool isPreprocessedModuleType(ID Id) {
   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 @@ bool types::isAcceptedByClang(ID Id) {
   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 @@ bool types::isCXX(ID Id) {
   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 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) {
            .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)

diff  --git a/clang/lib/Frontend/FrontendOptions.cpp b/clang/lib/Frontend/FrontendOptions.cpp
index 37ac428a80033..a7bdae343a944 100644
--- a/clang/lib/Frontend/FrontendOptions.cpp
+++ b/clang/lib/Frontend/FrontendOptions.cpp
@@ -27,7 +27,7 @@ InputKind FrontendOptions::getInputKindForExtension(StringRef Extension) {
       .Cases("C", "cc", "cp", Language::CXX)
       .Cases("cpp", "CPP", "c++", "cxx", "hpp", "hxx", Language::CXX)
       .Case("cppm", Language::CXX)
-      .Case("iim", InputKind(Language::CXX).getPreprocessed())
+      .Cases("iim", "iih", InputKind(Language::CXX).getPreprocessed())
       .Case("cl", Language::OpenCL)
       .Case("clcpp", Language::OpenCLCXX)
       .Cases("cu", "cuh", Language::CUDA)

diff  --git a/clang/test/Driver/Inputs/header-unit-01.hh b/clang/test/Driver/Inputs/header-unit-01.hh
new file mode 100644
index 0000000000000..e69de29bb2d1d

diff  --git a/clang/test/Driver/cxx20-header-units-01.cpp b/clang/test/Driver/cxx20-header-units-01.cpp
new file mode 100644
index 0000000000000..d4c3a02d4867d
--- /dev/null
+++ b/clang/test/Driver/cxx20-header-units-01.cpp
@@ -0,0 +1,19 @@
+// 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 \
+// RUN:   -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"


        


More information about the cfe-commits mailing list