diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def --- a/clang/include/clang/Driver/Types.def +++ b/clang/include/clang/Driver/Types.def @@ -64,7 +64,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) @@ -89,6 +93,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) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2219,6 +2219,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; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4609,6 +4609,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(JA)) { diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp --- a/clang/lib/Driver/Types.cpp +++ b/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) diff --git a/clang/lib/Frontend/FrontendOptions.cpp b/clang/lib/Frontend/FrontendOptions.cpp --- a/clang/lib/Frontend/FrontendOptions.cpp +++ b/clang/lib/Frontend/FrontendOptions.cpp @@ -27,7 +27,7 @@ .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 diff --git a/clang/test/Driver/cxx20-header-units-01.cpp b/clang/test/Driver/cxx20-header-units-01.cpp new file mode 100644 --- /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"