Skip to content

Commit 3c39b85

Browse files
committed
remove ParserConversionAction, add paramter to ParseStringLiteralExpression instead, add conversion to SystemCharset then back to UTF8 to handle escape sequences in system encoding
1 parent b74e511 commit 3c39b85

10 files changed

Lines changed: 71 additions & 24 deletions

File tree

‎clang/include/clang/Basic/TargetInfo.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "llvm/IR/DerivedTypes.h"
3939
#include "llvm/Support/DataTypes.h"
4040
#include "llvm/Support/Error.h"
41+
#include "llvm/Support/TextEncoding.h"
4142
#include "llvm/Support/VersionTuple.h"
4243
#include "llvm/TargetParser/Triple.h"
4344
#include <cassert>
@@ -323,6 +324,8 @@ class TargetInfo : public TransferrableTargetInfo,
323324

324325
virtual ~TargetInfo();
325326

327+
std::unique_ptr<llvm::TextEncodingConverter> TargetStrConverter;
328+
326329
/// Retrieve the target options.
327330
TargetOptions &getTargetOpts() const {
328331
assert(TargetOpts && "Missing target options");

‎clang/include/clang/Lex/TextEncoding.h‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,30 @@
1010
#define LLVM_CLANG_LEX_TEXTENCODING_H
1111

1212
#include "clang/Basic/LangOptions.h"
13+
#include "clang/Basic/TargetInfo.h"
1314
#include "llvm/ADT/StringRef.h"
1415

1516
namespace llvm {
1617
class TextEncodingConverter;
1718
} // namespace llvm
1819

1920
namespace clang {
20-
enum ConversionAction { CA_NoConversion, CA_ToLiteralEncoding };
21+
enum ConversionAction {
22+
CA_NoConversion,
23+
CA_ToSystemEncoding,
24+
CA_ToLiteralEncoding
25+
};
2126

2227
class TextEncoding {
2328
llvm::StringRef LiteralEncoding;
2429
std::unique_ptr<llvm::TextEncodingConverter> ToLiteralEncodingConverter;
30+
std::unique_ptr<llvm::TextEncodingConverter> ToSystemEncodingConverter;
2531

2632
public:
2733
llvm::TextEncodingConverter *getConverter(ConversionAction Action) const;
2834
static std::error_code
29-
setConvertersFromOptions(TextEncoding &TE, const clang::LangOptions &Opts);
35+
setConvertersFromOptions(TextEncoding &TE, const clang::LangOptions &Opts,
36+
clang::TargetInfo &TInfo);
3037

3138
llvm::StringRef getLiteralEncoding() { return LiteralEncoding; }
3239
};

‎clang/include/clang/Parse/Parser.h‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3866,8 +3866,9 @@ class Parser : public CodeCompletionHandler {
38663866
/// associated with the class's definition.
38673867
void PopParsingClass(Sema::ParsingClassState);
38683868

3869-
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral,
3870-
bool Unevaluated);
3869+
ExprResult
3870+
ParseStringLiteralExpression(bool AllowUserDefinedLiteral, bool Unevaluated,
3871+
ConversionAction CA = CA_ToLiteralEncoding);
38713872

38723873
/// This routine is called when the '@' is seen and consumed.
38733874
/// Current token is an Identifier and is not a 'try'. This
@@ -5706,7 +5707,6 @@ class Parser : public CodeCompletionHandler {
57065707
bool Finished;
57075708
};
57085709
ObjCImplParsingDataRAII *CurParsedObjCImpl;
5709-
ConversionAction ParserConversionAction;
57105710

57115711
/// StashAwayMethodOrFunctionBodyTokens - Consume the tokens and store them
57125712
/// for later parsing.

‎clang/lib/Basic/TargetInfo.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
194194
MaxOpenCLWorkGroupSize = 1024;
195195

196196
MaxBitIntWidth.reset();
197+
198+
TargetStrConverter = nullptr;
197199
}
198200

199201
// Out of line virtual dtor for TargetInfo.

‎clang/lib/Frontend/CompilerInstance.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,8 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
561561
if (GetDependencyDirectives)
562562
PP->setDependencyDirectivesGetter(*GetDependencyDirectives);
563563

564-
if (auto EC = TextEncoding::setConvertersFromOptions(PP->getTextEncoding(),
565-
getLangOpts()))
564+
if (auto EC = TextEncoding::setConvertersFromOptions(
565+
PP->getTextEncoding(), getLangOpts(), getTarget()))
566566
PP->getDiagnostics().Report(clang::diag::err_fe_text_encoding_config)
567567
<< PP->getTextEncoding().getLiteralEncoding();
568568
}

‎clang/lib/Lex/TextEncoding.cpp‎

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,55 @@ TextEncoding::getConverter(ConversionAction Action) const {
1717
switch (Action) {
1818
case CA_ToLiteralEncoding:
1919
return ToLiteralEncodingConverter.get();
20+
case CA_ToSystemEncoding:
21+
return ToSystemEncodingConverter.get();
2022
default:
2123
return nullptr;
2224
}
2325
}
2426

2527
std::error_code
2628
TextEncoding::setConvertersFromOptions(TextEncoding &TE,
27-
const clang::LangOptions &Opts) {
29+
const clang::LangOptions &Opts,
30+
clang::TargetInfo &TInfo) {
2831
using namespace llvm;
2932

3033
const char *UTF8 = "UTF-8";
3134
TE.LiteralEncoding =
3235
Opts.LiteralEncoding.empty() ? UTF8 : Opts.LiteralEncoding.c_str();
3336

34-
// Create converter between internal and literal encoding specified
35-
// in fexec-charset option.
36-
if (TE.LiteralEncoding == UTF8)
37+
if (TE.LiteralEncoding != UTF8) {
38+
ErrorOr<TextEncodingConverter> ErrorOrLiteralConverter =
39+
llvm::TextEncodingConverter::create(UTF8, TE.LiteralEncoding);
40+
if (ErrorOrLiteralConverter)
41+
TE.ToLiteralEncodingConverter = std::make_unique<TextEncodingConverter>(
42+
std::move(*ErrorOrLiteralConverter));
43+
else
44+
return ErrorOrLiteralConverter.getError();
45+
}
46+
47+
if (TInfo.getDefaultOrdinaryLiteralEncoding() == UTF8)
3748
return std::error_code();
49+
50+
// Create converter between internal and default ordinary encoding for the
51+
// target
3852
ErrorOr<TextEncodingConverter> ErrorOrConverter =
39-
llvm::TextEncodingConverter::create(UTF8, TE.LiteralEncoding);
53+
llvm::TextEncodingConverter::create(
54+
UTF8, TInfo.getDefaultOrdinaryLiteralEncoding());
55+
if (ErrorOrConverter)
56+
TE.ToSystemEncodingConverter =
57+
std::make_unique<TextEncodingConverter>(std::move(*ErrorOrConverter));
58+
else
59+
return ErrorOrConverter.getError();
60+
61+
ErrorOrConverter = llvm::TextEncodingConverter::create(
62+
TInfo.getDefaultOrdinaryLiteralEncoding(), UTF8);
63+
4064
if (ErrorOrConverter)
41-
TE.ToLiteralEncodingConverter =
65+
TInfo.TargetStrConverter =
4266
std::make_unique<TextEncodingConverter>(std::move(*ErrorOrConverter));
4367
else
4468
return ErrorOrConverter.getError();
69+
4570
return std::error_code();
4671
}

‎clang/lib/Parse/ParseExpr.cpp‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3021,7 +3021,8 @@ ExprResult Parser::ParseUnevaluatedStringLiteralExpression() {
30213021
}
30223022

30233023
ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral,
3024-
bool Unevaluated) {
3024+
bool Unevaluated,
3025+
ConversionAction CA) {
30253026
assert(tokenIsLikeStringLiteral(Tok, getLangOpts()) &&
30263027
"Not a string-literal-like token!");
30273028

@@ -3042,8 +3043,7 @@ ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral,
30423043

30433044
// Pass the set of string tokens, ready for concatenation, to the actions.
30443045
return Actions.ActOnStringLiteral(
3045-
StringToks, AllowUserDefinedLiteral ? getCurScope() : nullptr,
3046-
ParserConversionAction);
3046+
StringToks, AllowUserDefinedLiteral ? getCurScope() : nullptr, CA);
30473047
}
30483048

30493049
ExprResult Parser::ParseGenericSelectionExpression() {

‎clang/lib/Parse/Parser.cpp‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
7070
NumCachedScopes = 0;
7171
CurParsedObjCImpl = nullptr;
7272

73-
ParserConversionAction = CA_ToLiteralEncoding;
74-
7573
// Add #pragma handlers. These are removed and destroyed in the
7674
// destructor.
7775
initializePragmaHandlers();
@@ -1553,12 +1551,12 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
15531551
}
15541552

15551553
ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) {
1556-
SaveAndRestore<ConversionAction> SavedTranslationState(ParserConversionAction,
1557-
CA_NoConversion);
15581554

15591555
ExprResult AsmString;
15601556
if (isTokenStringLiteral()) {
1561-
AsmString = ParseStringLiteralExpression();
1557+
AsmString = ParseStringLiteralExpression(/*AllowUserDefinedLiteral=*/false,
1558+
/*Unevaluated=*/false,
1559+
CA_ToSystemEncoding);
15621560
if (AsmString.isInvalid())
15631561
return AsmString;
15641562

‎clang/lib/Sema/SemaStmtAsm.cpp‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,14 @@ ExprResult Sema::ActOnGCCAsmStmtString(Expr *Expr, bool ForAsmLabel) {
245245
Diag(Expr->getBeginLoc(), diag::err_asm_operand_empty_string)
246246
<< SL->getSourceRange();
247247
}
248+
if (Context.getTargetInfo().TargetStrConverter) {
249+
SmallString<16> ConvertedAsm;
250+
Context.getTargetInfo().TargetStrConverter->convert(SL->getString(),
251+
ConvertedAsm);
252+
return StringLiteral::Create(Context, ConvertedAsm,
253+
StringLiteralKind::Ordinary,
254+
/*Pascal*/ false, {}, SL->getBeginLoc());
255+
}
248256
return SL;
249257
}
250258
if (DiagnoseUnexpandedParameterPack(Expr))

‎clang/test/CodeGen/systemz-charset.c‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,11 @@ const char* preprocessor_concatenation = HELLO_WORLD;
6767
//CHECK: c"\C8\85\93\93\96@\E6\96\99\93\84Z\00"
6868
//CHECK-UTF8: c"Hello World!\00"
6969

70-
void asm_labeled_fn(void) __asm__("asm_sym");
70+
void asm_labeled_fn(void) __asm__("\174asm_sym");
7171
void asm_labeled_fn(void) {}
72-
//CHECK: define{{.*}} void @asm_sym(
73-
//CHECK-UTF8: define{{.*}} void @asm_sym(
72+
//CHECK: define{{.*}}void @"@asm_sym"(
73+
//CHECK-UTF8: define{{.*}}void @"@asm_sym"(
74+
75+
int RC = 25;
76+
asm(" AHI %0,%1\n" : "+r"(RC) : "g"(30) );
77+
`

0 commit comments

Comments
 (0)