Skip to content

Commit

Permalink
[C++20][Modules] Quote header unit name in preprocessor output (-E) (l…
Browse files Browse the repository at this point in the history
…lvm#112883)

Summary:
Before this change clang produced output with header unit names that may
conaint path separators, dots and other non-identifier characters. This
diff prints header unit name in quotes and -E output can be compiled
again. Also remove unnecessary space between header unit name and semi.

Test Plan: check-clang
  • Loading branch information
dmpolukhin authored and NoumanAmir657 committed Nov 4, 2024
1 parent 145300e commit f051652
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 6 deletions.
10 changes: 6 additions & 4 deletions clang/lib/Frontend/PrintPreprocessedOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -952,13 +952,15 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
continue;
} else if (Tok.is(tok::annot_header_unit)) {
// This is a header-name that has been (effectively) converted into a
// module-name.
// module-name, print them inside quote.
// FIXME: The module name could contain non-identifier module name
// components. We don't have a good way to round-trip those.
// components and OS specific file paths components. We don't have a good
// way to round-trip those.
Module *M = reinterpret_cast<Module *>(Tok.getAnnotationValue());
std::string Name = M->getFullModuleName();
Callbacks->OS->write(Name.data(), Name.size());
Callbacks->HandleNewlinesInToken(Name.data(), Name.size());
*Callbacks->OS << '"';
Callbacks->OS->write_escaped(Name);
*Callbacks->OS << '"';
} else if (Tok.is(tok::annot_embed)) {
// Manually explode the binary data out to a stream of comma-delimited
// integer values. If the user passed -dE, that is handled by the
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Lex/TokenConcatenation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ static char GetFirstChar(const Preprocessor &PP, const Token &Tok) {
bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok,
const Token &PrevTok,
const Token &Tok) const {
// No space is required between header unit name in quote and semi.
if (PrevTok.is(tok::annot_header_unit) && Tok.is(tok::semi))
return false;

// Conservatively assume that every annotation token that has a printable
// form requires whitespace.
if (PrevTok.isAnnotation())
Expand Down
20 changes: 20 additions & 0 deletions clang/test/Headers/header_unit_preprocessed_output.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: rm -fR %t
// RUN: split-file %s %t
// RUN: cd %t
// RUN: %clang_cc1 -verify -std=c++20 -emit-header-unit -xc++-user-header bz0.h
// RUN: %clang_cc1 -verify -std=c++20 -fmodule-file=bz0.pcm -xc++-user-header bz1.h -E -o bz1.output.h
// RUN: FileCheck %s < bz1.output.h
// RUN: %clang_cc1 -std=c++20 -fmodule-file=bz0.pcm -emit-header-unit -xc++-user-header bz1.output.h

//--- bz0.h
// expected-no-diagnostics
#pragma once

void foo();

//--- bz1.h
// expected-no-diagnostics
import "bz0.h";

// CHECK: # 1 ".{{/|\\\\?}}bz1.h"
// CHECK: import ".{{/|\\\\?}}bz0.h";
4 changes: 2 additions & 2 deletions clang/test/Modules/cxx20-include-translation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,6 @@ export void charlie() {
}

// CHECK: #pragma clang module import ".{{/|\\\\?}}h1.h"
// CHECK: import .{{/|\\\\?}}h2.h
// CHECK: import .{{/|\\\\?}}h3.h
// CHECK: import ".{{/|\\\\?}}h2.h"
// CHECK: import ".{{/|\\\\?}}h3.h"
// CHECK-NOT: #pragma clang module import ".{{/|\\\\?}}h4.h"

0 comments on commit f051652

Please sign in to comment.