Skip to content

Commit

Permalink
[Parser] Parse string literal arguments of 'availability', 'external_…
Browse files Browse the repository at this point in the history
…source_symbol' and 'uuid' attributes as unevaluated

This is a complementary to D156237.
These attributes have custom parsing logic.

Reviewed By: cor3ntin

Differential Revision: https://reviews.llvm.org/D159024
  • Loading branch information
s-barannikov committed Aug 30, 2023
1 parent 9b35254 commit a7eaaba
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 38 deletions.
38 changes: 13 additions & 25 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1316,31 +1316,19 @@ void Parser::ParseAvailabilityAttribute(
}
ConsumeToken();
if (Keyword == Ident_message || Keyword == Ident_replacement) {
if (Tok.isNot(tok::string_literal)) {
if (!isTokenStringLiteral()) {
Diag(Tok, diag::err_expected_string_literal)
<< /*Source='availability attribute'*/2;
SkipUntil(tok::r_paren, StopAtSemi);
return;
}
if (Keyword == Ident_message)
MessageExpr = ParseStringLiteralExpression();
else
ReplacementExpr = ParseStringLiteralExpression();
// Also reject wide string literals.
if (StringLiteral *MessageStringLiteral =
cast_or_null<StringLiteral>(MessageExpr.get())) {
if (!MessageStringLiteral->isOrdinary()) {
Diag(MessageStringLiteral->getSourceRange().getBegin(),
diag::err_expected_string_literal)
<< /*Source='availability attribute'*/ 2;
SkipUntil(tok::r_paren, StopAtSemi);
return;
}
}
if (Keyword == Ident_message)
if (Keyword == Ident_message) {
MessageExpr = ParseUnevaluatedStringLiteralExpression();
break;
else
} else {
ReplacementExpr = ParseUnevaluatedStringLiteralExpression();
continue;
}
}

// Special handling of 'NA' only when applied to introduced or
Expand Down Expand Up @@ -1508,7 +1496,7 @@ void Parser::ParseExternalSourceSymbolAttribute(
else
HasDefinedIn = true;

if (Tok.isNot(tok::string_literal)) {
if (!isTokenStringLiteral()) {
Diag(Tok, diag::err_expected_string_literal)
<< /*Source='external_source_symbol attribute'*/ 3
<< /*language | source container | USR*/ (
Expand All @@ -1522,27 +1510,27 @@ void Parser::ParseExternalSourceSymbolAttribute(
if (HadLanguage) {
Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
<< Keyword;
ParseStringLiteralExpression();
ParseUnevaluatedStringLiteralExpression();
continue;
}
Language = ParseStringLiteralExpression();
Language = ParseUnevaluatedStringLiteralExpression();
} else if (Keyword == Ident_USR) {
if (HadUSR) {
Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
<< Keyword;
ParseStringLiteralExpression();
ParseUnevaluatedStringLiteralExpression();
continue;
}
USR = ParseStringLiteralExpression();
USR = ParseUnevaluatedStringLiteralExpression();
} else {
assert(Keyword == Ident_defined_in && "Invalid clause keyword!");
if (HadDefinedIn) {
Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
<< Keyword;
ParseStringLiteralExpression();
ParseUnevaluatedStringLiteralExpression();
continue;
}
DefinedInExpr = ParseStringLiteralExpression();
DefinedInExpr = ParseUnevaluatedStringLiteralExpression();
}
} while (TryConsumeToken(tok::comma));

Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4715,9 +4715,9 @@ void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
}

ArgsVector ArgExprs;
if (Tok.is(tok::string_literal)) {
if (isTokenStringLiteral()) {
// Easy case: uuid("...") -- quoted string.
ExprResult StringResult = ParseStringLiteralExpression();
ExprResult StringResult = ParseUnevaluatedStringLiteralExpression();
if (StringResult.isInvalid())
return;
ArgExprs.push_back(StringResult.get());
Expand Down Expand Up @@ -4772,7 +4772,7 @@ void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
Toks[0].setLiteralData(StrBuffer.data());
Toks[0].setLength(StrBuffer.size());
StringLiteral *UuidString =
cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
cast<StringLiteral>(Actions.ActOnUnevaluatedStringLiteral(Toks).get());
ArgExprs.push_back(UuidString);
}

Expand Down
4 changes: 2 additions & 2 deletions clang/test/Parser/attr-availability-xcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
# error 'availability' attribute is not available
#endif

void f7() __attribute__((availability(macosx,message=L"wide"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
void f7() __attribute__((availability(macosx,message=L"wide"))); // expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}

void f8() __attribute__((availability(macosx,message="a" L"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
void f8() __attribute__((availability(macosx,message="a" L"b"))); // expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}
12 changes: 6 additions & 6 deletions clang/test/Parser/attr-availability.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ void f5(void) __attribute__((availability(macosx,introduced=10.5), availability(

void f6(void) __attribute__((availability(macosx,unavailable,introduced=10.5))); // expected-warning{{'unavailable' availability overrides all other availability information}}

void f7(void) __attribute__((availability(macosx,message=L"wide"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
void f7(void) __attribute__((availability(macosx,message=L"wide"))); // expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}

void f8(void) __attribute__((availability(macosx,message="a" L"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
void f8(void) __attribute__((availability(macosx,message="a" L"b"))); // expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}

void f9(void) __attribute__((availability(macosx,message=u8"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
void f9(void) __attribute__((availability(macosx,message=u8"b"))); // expected-warning {{encoding prefix 'u8' on an unevaluated string literal has no effect}}

void f10(void) __attribute__((availability(macosx,message="a" u8"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
void f10(void) __attribute__((availability(macosx,message="a" u8"b"))); // expected-warning {{encoding prefix 'u8' on an unevaluated string literal has no effect}}

void f11(void) __attribute__((availability(macosx,message=u"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
void f11(void) __attribute__((availability(macosx,message=u"b"))); // expected-warning {{encoding prefix 'u' on an unevaluated string literal has no effect}}

void f12(void) __attribute__((availability(macosx,message="a" u"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
void f12(void) __attribute__((availability(macosx,message="a" u"b"))); // expected-warning {{encoding prefix 'u' on an unevaluated string literal has no effect}}

enum E{
gorf __attribute__((availability(macosx,introduced=8.5, message = 10.0))), // expected-error {{expected string literal for optional message in 'availability' attribute}}
Expand Down
21 changes: 21 additions & 0 deletions clang/test/Parser/attr-external-source-symbol.m
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,27 @@ void f27(void)
void f28(void)
__attribute__((external_source_symbol(USR="")));

void f29(void)
__attribute__((external_source_symbol(language=L"Swift"))); // expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}

void f30(void)
__attribute__((external_source_symbol(language="Swift", language=L"Swift"))); // expected-error {{duplicate 'language' clause in an 'external_source_symbol' attribute}} \
// expected-warning {{encoding prefix 'L' on an unevaluated string literal has no effect}}

void f31(void)
__attribute__((external_source_symbol(USR=u"foo"))); // expected-warning {{encoding prefix 'u' on an unevaluated string literal has no effect}}

void f32(void)
__attribute__((external_source_symbol(USR="foo", USR=u"foo"))); // expected-error {{duplicate 'USR' clause in an 'external_source_symbol' attribute}} \
// expected-warning {{encoding prefix 'u' on an unevaluated string literal has no effect}}

void f33(void)
__attribute__((external_source_symbol(defined_in=U"module"))); // expected-warning {{encoding prefix 'U' on an unevaluated string literal has no effect}}

void f34(void)
__attribute__((external_source_symbol(defined_in="module", defined_in=U"module"))); // expected-error {{duplicate 'defined_in' clause in an 'external_source_symbol' attribute}} \
// expected-warning {{encoding prefix 'U' on an unevaluated string literal has no effect}}

#if __has_attribute(external_source_symbol) != 20230206
# error "invalid __has_attribute version"
#endif
4 changes: 2 additions & 2 deletions clang/test/Parser/ms-square-bracket-attributes.mm
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
)] struct struct_with_uuid_brace;

// uuids must be ascii string literals.
// expected-error@+1 {{uuid attribute contains a malformed GUID}}
// expected-warning@+1 {{encoding prefix 'u8' on an unevaluated string literal has no effect and is incompatible with c++2c}}
[uuid(u8"000000A0-0000-0000-C000-000000000049")] struct struct_with_uuid_u8;
// expected-error@+1 {{uuid attribute contains a malformed GUID}}
// expected-warning@+1 {{encoding prefix 'L' on an unevaluated string literal has no effect and is incompatible with c++2c}}
[uuid(L"000000A0-0000-0000-C000-000000000049")] struct struct_with_uuid_L;

// cl.exe doesn't allow raw string literals in []-style attributes, but does
Expand Down

0 comments on commit a7eaaba

Please sign in to comment.