Skip to content

Commit 01f6adc

Browse files
authored
Merge branch 'swift/release/6.2' into lldb/unnamed-bitfields-to-6.2
2 parents ef22585 + 5842d95 commit 01f6adc

File tree

15 files changed

+320
-34
lines changed

15 files changed

+320
-34
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,14 @@ def err_drv_print_header_env_var : Error<
399399
"environment variable CC_PRINT_HEADERS_%select{FORMAT|FILTERING}0 has invalid value %1">;
400400
def err_drv_print_header_env_var_combination : Error<
401401
"unsupported combination: CC_PRINT_HEADERS_FORMAT=%0 and CC_PRINT_HEADERS_FILTERING=%1">;
402-
def err_drv_print_header_env_var_combination_cc1 : Error<
402+
def err_drv_print_header_env_var_invalid_format : Error<
403+
"environment variable CC_PRINT_HEADERS_FORMAT=%0 requires a compatible value for CC_PRINT_HEADERS_FILTERING">;
404+
def err_drv_print_header_cc1_invalid_combination : Error<
403405
"unsupported combination: -header-include-format=%0 and -header-include-filtering=%1">;
406+
def err_drv_print_header_cc1_invalid_filtering : Error<
407+
"-header-include-filtering=%0 requires a compatible value for -header-include-format">;
408+
def err_drv_print_header_cc1_invalid_format : Error<
409+
"-header-include-format=%0 requires a compatible value for -header-include-filtering">;
404410

405411
def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
406412
def warn_drv_optimization_value : Warning<"optimization level '%0' is not supported; using '%1%2' instead">,

clang/include/clang/Basic/HeaderInclude.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,14 @@ enum HeaderIncludeFormatKind { HIFMT_None, HIFMT_Textual, HIFMT_JSON };
2323

2424
/// Whether header information is filtered or not. If HIFIL_Only_Direct_System
2525
/// is used, only information on system headers directly included from
26-
/// non-system headers is emitted.
27-
enum HeaderIncludeFilteringKind { HIFIL_None, HIFIL_Only_Direct_System };
26+
/// non-system files is emitted. The HIFIL_Direct_Per_File filtering shows the
27+
/// direct imports and includes for each non-system source and header file
28+
/// separately.
29+
enum HeaderIncludeFilteringKind {
30+
HIFIL_None,
31+
HIFIL_Only_Direct_System,
32+
HIFIL_Direct_Per_File
33+
};
2834

2935
inline HeaderIncludeFormatKind
3036
stringToHeaderIncludeFormatKind(const char *Str) {
@@ -40,6 +46,7 @@ inline bool stringToHeaderIncludeFiltering(const char *Str,
4046
llvm::StringSwitch<std::pair<bool, HeaderIncludeFilteringKind>>(Str)
4147
.Case("none", {true, HIFIL_None})
4248
.Case("only-direct-system", {true, HIFIL_Only_Direct_System})
49+
.Case("direct-per-file", {true, HIFIL_Direct_Per_File})
4350
.Default({false, HIFIL_None});
4451
Kind = P.second;
4552
return P.first;
@@ -64,6 +71,8 @@ headerIncludeFilteringKindToString(HeaderIncludeFilteringKind K) {
6471
return "none";
6572
case HIFIL_Only_Direct_System:
6673
return "only-direct-system";
74+
case HIFIL_Direct_Per_File:
75+
return "direct-per-file";
6776
}
6877
llvm_unreachable("Unknown HeaderIncludeFilteringKind enum");
6978
}

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7586,7 +7586,8 @@ def header_include_format_EQ : Joined<["-"], "header-include-format=">,
75867586
MarshallingInfoEnum<DependencyOutputOpts<"HeaderIncludeFormat">, "HIFMT_Textual">;
75877587
def header_include_filtering_EQ : Joined<["-"], "header-include-filtering=">,
75887588
HelpText<"set the flag that enables filtering header information">,
7589-
Values<"none,only-direct-system">, NormalizedValues<["HIFIL_None", "HIFIL_Only_Direct_System"]>,
7589+
Values<"none,only-direct-system,direct-per-file">,
7590+
NormalizedValues<["HIFIL_None", "HIFIL_Only_Direct_System", "HIFIL_Direct_Per_File"]>,
75907591
MarshallingInfoEnum<DependencyOutputOpts<"HeaderIncludeFiltering">, "HIFIL_None">;
75917592
def show_includes : Flag<["--"], "show-includes">,
75927593
HelpText<"Print cl.exe style /showIncludes to stdout">;

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2541,13 +2541,25 @@ static bool ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
25412541

25422542
// Check for invalid combinations of header-include-format
25432543
// and header-include-filtering.
2544-
if ((Opts.HeaderIncludeFormat == HIFMT_Textual &&
2545-
Opts.HeaderIncludeFiltering != HIFIL_None) ||
2546-
(Opts.HeaderIncludeFormat == HIFMT_JSON &&
2547-
Opts.HeaderIncludeFiltering != HIFIL_Only_Direct_System))
2548-
Diags.Report(diag::err_drv_print_header_env_var_combination_cc1)
2549-
<< Args.getLastArg(OPT_header_include_format_EQ)->getValue()
2550-
<< Args.getLastArg(OPT_header_include_filtering_EQ)->getValue();
2544+
if (Opts.HeaderIncludeFormat == HIFMT_Textual &&
2545+
Opts.HeaderIncludeFiltering != HIFIL_None) {
2546+
if (Args.hasArg(OPT_header_include_format_EQ))
2547+
Diags.Report(diag::err_drv_print_header_cc1_invalid_combination)
2548+
<< headerIncludeFormatKindToString(Opts.HeaderIncludeFormat)
2549+
<< headerIncludeFilteringKindToString(Opts.HeaderIncludeFiltering);
2550+
else
2551+
Diags.Report(diag::err_drv_print_header_cc1_invalid_filtering)
2552+
<< headerIncludeFilteringKindToString(Opts.HeaderIncludeFiltering);
2553+
} else if (Opts.HeaderIncludeFormat == HIFMT_JSON &&
2554+
Opts.HeaderIncludeFiltering == HIFIL_None) {
2555+
if (Args.hasArg(OPT_header_include_filtering_EQ))
2556+
Diags.Report(diag::err_drv_print_header_cc1_invalid_combination)
2557+
<< headerIncludeFormatKindToString(Opts.HeaderIncludeFormat)
2558+
<< headerIncludeFilteringKindToString(Opts.HeaderIncludeFiltering);
2559+
else
2560+
Diags.Report(diag::err_drv_print_header_cc1_invalid_format)
2561+
<< headerIncludeFormatKindToString(Opts.HeaderIncludeFormat);
2562+
}
25512563

25522564
return Diags.getNumErrors() == NumErrorsBefore;
25532565
}

clang/lib/Frontend/HeaderIncludeGen.cpp

Lines changed: 139 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,49 @@ class HeaderIncludesJSONCallback : public PPCallbacks {
106106
void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
107107
SrcMgr::CharacteristicKind FileType) override;
108108
};
109+
110+
/// A callback for emitting direct header and module usage information to a
111+
/// file in JSON. The output format is like HeaderIncludesJSONCallback but has
112+
/// an array of separate entries, one for each non-system source file used in
113+
/// the compilation showing only the direct includes and imports from that file.
114+
class HeaderIncludesDirectPerFileCallback : public PPCallbacks {
115+
SourceManager &SM;
116+
HeaderSearch &HSI;
117+
raw_ostream *OutputFile;
118+
bool OwnsOutputFile;
119+
using DependencyMap = llvm::DenseMap<FileEntryRef, SmallVector<FileEntryRef>>;
120+
DependencyMap Dependencies;
121+
122+
public:
123+
HeaderIncludesDirectPerFileCallback(const Preprocessor *PP,
124+
raw_ostream *OutputFile_,
125+
bool OwnsOutputFile_)
126+
: SM(PP->getSourceManager()), HSI(PP->getHeaderSearchInfo()),
127+
OutputFile(OutputFile_), OwnsOutputFile(OwnsOutputFile_) {}
128+
129+
~HeaderIncludesDirectPerFileCallback() override {
130+
if (OwnsOutputFile)
131+
delete OutputFile;
132+
}
133+
134+
HeaderIncludesDirectPerFileCallback(
135+
const HeaderIncludesDirectPerFileCallback &) = delete;
136+
HeaderIncludesDirectPerFileCallback &
137+
operator=(const HeaderIncludesDirectPerFileCallback &) = delete;
138+
139+
void EndOfMainFile() override;
140+
141+
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
142+
StringRef FileName, bool IsAngled,
143+
CharSourceRange FilenameRange,
144+
OptionalFileEntryRef File, StringRef SearchPath,
145+
StringRef RelativePath, const Module *SuggestedModule,
146+
bool ModuleImported,
147+
SrcMgr::CharacteristicKind FileType) override;
148+
149+
void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
150+
const Module *Imported) override;
151+
};
109152
}
110153

111154
static void PrintHeaderInfo(raw_ostream *OutputFile, StringRef Filename,
@@ -192,14 +235,21 @@ void clang::AttachHeaderIncludeGen(Preprocessor &PP,
192235
MSStyle));
193236
break;
194237
}
195-
case HIFMT_JSON: {
196-
assert(DepOpts.HeaderIncludeFiltering == HIFIL_Only_Direct_System &&
197-
"only-direct-system is the only option for filtering");
198-
PP.addPPCallbacks(std::make_unique<HeaderIncludesJSONCallback>(
199-
&PP, OutputFile, OwnsOutputFile));
238+
case HIFMT_JSON:
239+
switch (DepOpts.HeaderIncludeFiltering) {
240+
default:
241+
llvm_unreachable("Unknown HeaderIncludeFilteringKind enum");
242+
case HIFIL_Only_Direct_System:
243+
PP.addPPCallbacks(std::make_unique<HeaderIncludesJSONCallback>(
244+
&PP, OutputFile, OwnsOutputFile));
245+
break;
246+
case HIFIL_Direct_Per_File:
247+
PP.addPPCallbacks(std::make_unique<HeaderIncludesDirectPerFileCallback>(
248+
&PP, OutputFile, OwnsOutputFile));
249+
break;
250+
}
200251
break;
201252
}
202-
}
203253
}
204254

205255
void HeaderIncludesCallback::FileChanged(SourceLocation Loc,
@@ -260,8 +310,11 @@ void HeaderIncludesCallback::FileSkipped(const FileEntryRef &SkippedFile, const
260310

261311
void HeaderIncludesJSONCallback::EndOfMainFile() {
262312
OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getMainFileID());
263-
SmallString<256> MainFile(FE->getName());
264-
SM.getFileManager().makeAbsolutePath(MainFile);
313+
SmallString<256> MainFile;
314+
if (FE) {
315+
MainFile += FE->getName();
316+
SM.getFileManager().makeAbsolutePath(MainFile);
317+
}
265318

266319
std::string Str;
267320
llvm::raw_string_ostream OS(Str);
@@ -319,3 +372,81 @@ void HeaderIncludesJSONCallback::FileSkipped(
319372

320373
IncludedHeaders.push_back(SkippedFile.getName().str());
321374
}
375+
376+
void HeaderIncludesDirectPerFileCallback::EndOfMainFile() {
377+
if (Dependencies.empty())
378+
return;
379+
380+
// Sort the files so that the output does not depend on the DenseMap order.
381+
SmallVector<FileEntryRef> SourceFiles;
382+
for (auto F = Dependencies.begin(), FEnd = Dependencies.end(); F != FEnd;
383+
++F) {
384+
SourceFiles.push_back(F->first);
385+
}
386+
llvm::sort(SourceFiles, [](const FileEntryRef &LHS, const FileEntryRef &RHS) {
387+
return LHS.getUID() < RHS.getUID();
388+
});
389+
390+
std::string Str;
391+
llvm::raw_string_ostream OS(Str);
392+
llvm::json::OStream JOS(OS);
393+
JOS.array([&] {
394+
for (auto S = SourceFiles.begin(), SE = SourceFiles.end(); S != SE; ++S) {
395+
JOS.object([&] {
396+
SmallVector<FileEntryRef> &Deps = Dependencies[*S];
397+
JOS.attribute("source", S->getName().str());
398+
JOS.attributeArray("includes", [&] {
399+
for (unsigned I = 0, N = Deps.size(); I != N; ++I)
400+
JOS.value(Deps[I].getName().str());
401+
});
402+
});
403+
}
404+
});
405+
OS << "\n";
406+
407+
if (OutputFile->get_kind() == raw_ostream::OStreamKind::OK_FDStream) {
408+
llvm::raw_fd_ostream *FDS = static_cast<llvm::raw_fd_ostream *>(OutputFile);
409+
if (auto L = FDS->lock())
410+
*OutputFile << Str;
411+
} else
412+
*OutputFile << Str;
413+
}
414+
415+
void HeaderIncludesDirectPerFileCallback::InclusionDirective(
416+
SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
417+
bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File,
418+
StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule,
419+
bool ModuleImported, SrcMgr::CharacteristicKind FileType) {
420+
if (!File)
421+
return;
422+
423+
SourceLocation Loc = SM.getExpansionLoc(HashLoc);
424+
if (SM.isInSystemHeader(Loc))
425+
return;
426+
OptionalFileEntryRef FromFile = SM.getFileEntryRefForID(SM.getFileID(Loc));
427+
if (!FromFile)
428+
return;
429+
430+
Dependencies[*FromFile].push_back(*File);
431+
}
432+
433+
void HeaderIncludesDirectPerFileCallback::moduleImport(SourceLocation ImportLoc,
434+
ModuleIdPath Path,
435+
const Module *Imported) {
436+
if (!Imported)
437+
return;
438+
439+
SourceLocation Loc = SM.getExpansionLoc(ImportLoc);
440+
if (SM.isInSystemHeader(Loc))
441+
return;
442+
OptionalFileEntryRef FromFile = SM.getFileEntryRefForID(SM.getFileID(Loc));
443+
if (!FromFile)
444+
return;
445+
446+
OptionalFileEntryRef ModuleMapFile =
447+
HSI.getModuleMap().getModuleMapFileForUniquing(Imported);
448+
if (!ModuleMapFile)
449+
return;
450+
451+
Dependencies[*FromFile].push_back(*ModuleMapFile);
452+
}

clang/lib/Headers/float.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,10 @@
1717
/* On various platforms, fall back to the system's float.h, which might have
1818
* additional definitions and/or implementation-defined values.
1919
*/
20-
#if (defined(__APPLE__) || defined(__MINGW32__) || defined(_MSC_VER) || \
21-
defined(_AIX) || defined(__musl__)) && \
20+
#if (defined(__MINGW32__) || defined(_MSC_VER) || defined(_AIX) || \
21+
defined(__musl__)) && \
2222
__STDC_HOSTED__ && __has_include_next(<float.h>)
2323

24-
/* Prior to Apple's 10.7 SDK, float.h SDK header used to apply an extra level
25-
* of #include_next<float.h> to keep Metrowerks compilers happy. Avoid this
26-
* extra indirection.
27-
*/
28-
#ifdef __APPLE__
29-
#define _FLOAT_H_
30-
#endif
31-
3224
# include_next <float.h>
3325

3426
/* Undefine anything that we'll be redefining below. */
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// RUN: %clang_cc1 -header-include-format=json -header-include-filtering=only-direct-system -header-include-file %t.txt -emit-module -x c -fmodules -fmodule-name=X %s -o /dev/null
2+
module X {}
Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,33 @@
11
// RUN: %clang_cc1 -E -header-include-format=json -header-include-filtering=only-direct-system -header-include-file %t.txt -I %S/Inputs/print-header-json -isystem %S/Inputs/print-header-json/system %s
22
// RUN: cat %t.txt | FileCheck %s --check-prefix=SUPPORTED
3+
34
// RUN: not %clang_cc1 -E -header-include-format=textual -header-include-filtering=only-direct-system -header-include-file %t.txt -I %S/Inputs/print-header-json -isystem %S/Inputs/print-header-json/system %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED0
45
// RUN: not %clang_cc1 -E -header-include-format=json -header-include-filtering=none -header-include-file %t.txt -I %S/Inputs/print-header-json -isystem %S/Inputs/print-header-json/system %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED1
5-
// RUN: rm %t.txt
6-
// RUN: env CC_PRINT_HEADERS_FORMAT=json CC_PRINT_HEADERS_FILTERING=only-direct-system CC_PRINT_HEADERS_FILE=%t.txt %clang -fsyntax-only -I %S/Inputs/print-header-json -isystem %S/Inputs/print-header-json/system %s -o /dev/null
76
// RUN: env CC_PRINT_HEADERS_FORMAT=textual CC_PRINT_HEADERS_FILTERING=only-direct-system CC_PRINT_HEADERS_FILE=%t.txt not %clang -fsyntax-only -I %S/Inputs/print-header-json -isystem %S/Inputs/print-header-json/system %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED2
87
// RUN: env CC_PRINT_HEADERS_FORMAT=json CC_PRINT_HEADERS_FILTERING=none CC_PRINT_HEADERS_FILE=%t.txt not %clang -fsyntax-only -I %S/Inputs/print-header-json -isystem %S/Inputs/print-header-json/system %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED3
8+
// RUN: env CC_PRINT_HEADERS_FORMAT=json CC_PRINT_HEADERS_FILE=%t.txt not %clang -fsyntax-only -I %S/Inputs/print-header-json -isystem %S/Inputs/print-header-json/system %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED4
9+
// RUN: not %clang_cc1 -E -header-include-filtering=only-direct-system -header-include-file %t.txt -I %S/Inputs/print-header-json -isystem %S/Inputs/print-header-json/system %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED5
10+
// RUN: not %clang_cc1 -E -header-include-format=json -header-include-file %t.txt -I %S/Inputs/print-header-json -isystem %S/Inputs/print-header-json/system %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNSUPPORTED6
11+
12+
// RUN: rm %t.txt
13+
// RUN: env CC_PRINT_HEADERS_FORMAT=json CC_PRINT_HEADERS_FILTERING=only-direct-system CC_PRINT_HEADERS_FILE=%t.txt %clang -fsyntax-only -I %S/Inputs/print-header-json -isystem %S/Inputs/print-header-json/system %s -o /dev/null
914
// RUN: cat %t.txt | FileCheck %s --check-prefix=SUPPORTED
1015

16+
// RUN: rm %t.txt
17+
// RUN: env CC_PRINT_HEADERS_FORMAT=json CC_PRINT_HEADERS_FILTERING=direct-per-file CC_PRINT_HEADERS_FILE=%t.txt %clang -fsyntax-only -I %S/Inputs/print-header-json -isystem %S/Inputs/print-header-json/system %s -o /dev/null
18+
// RUN: cat %t.txt | FileCheck %s --check-prefix=SUPPORTED_PERFILE
19+
1120
#include "system0.h"
1221
#include "header0.h"
1322
#include "system2.h"
1423

1524
// SUPPORTED: {"source":"{{[^,]*}}print-header-json.c","includes":["{{[^,]*}}system0.h","{{[^,]*}}system3.h","{{[^,]*}}system2.h"]}
25+
// SUPPORTED_PERFILE: [{"source":"{{[^,]*}}print-header-json.c","includes":["{{[^,]*}}system0.h","{{[^,]*}}header0.h","{{[^,]*}}system2.h"]},{"source":"{{[^,]*}}header0.h","includes":["{{[^,]*}}system3.h","{{[^,]*}}header1.h","{{[^,]*}}header2.h"]}]
1626

1727
// UNSUPPORTED0: error: unsupported combination: -header-include-format=textual and -header-include-filtering=only-direct-system
1828
// UNSUPPORTED1: error: unsupported combination: -header-include-format=json and -header-include-filtering=none
1929
// UNSUPPORTED2: error: unsupported combination: CC_PRINT_HEADERS_FORMAT=textual and CC_PRINT_HEADERS_FILTERING=only-direct-system
2030
// UNSUPPORTED3: error: unsupported combination: CC_PRINT_HEADERS_FORMAT=json and CC_PRINT_HEADERS_FILTERING=none
31+
// UNSUPPORTED4: error: environment variable CC_PRINT_HEADERS_FORMAT=json requires a compatible value for CC_PRINT_HEADERS_FILTERING
32+
// UNSUPPORTED5: error: -header-include-filtering=only-direct-system requires a compatible value for -header-include-format
33+
// UNSUPPORTED6: error: -header-include-format=json requires a compatible value for -header-include-filtering

clang/tools/driver/driver.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ static bool SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) {
167167
}
168168

169169
const char *FilteringStr = ::getenv("CC_PRINT_HEADERS_FILTERING");
170+
if (!FilteringStr) {
171+
TheDriver.Diag(clang::diag::err_drv_print_header_env_var_invalid_format)
172+
<< EnvVar;
173+
return false;
174+
}
170175
HeaderIncludeFilteringKind Filtering;
171176
if (!stringToHeaderIncludeFiltering(FilteringStr, Filtering)) {
172177
TheDriver.Diag(clang::diag::err_drv_print_header_env_var)
@@ -177,7 +182,7 @@ static bool SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) {
177182
if ((TheDriver.CCPrintHeadersFormat == HIFMT_Textual &&
178183
Filtering != HIFIL_None) ||
179184
(TheDriver.CCPrintHeadersFormat == HIFMT_JSON &&
180-
Filtering != HIFIL_Only_Direct_System)) {
185+
Filtering == HIFIL_None)) {
181186
TheDriver.Diag(clang::diag::err_drv_print_header_env_var_combination)
182187
<< EnvVar << FilteringStr;
183188
return false;

0 commit comments

Comments
 (0)