No mixing annotations and attributes.
This commit is contained in:
@@ -1802,6 +1802,8 @@ def err_expansion_statements_disabled : Error<
|
||||
"'template for' statements are not enabled; use '-fexpansion-statements'">;
|
||||
def err_annotation_with_using : Error<
|
||||
"annotations are not permitted following an attribute-using-prefix">;
|
||||
def err_mixed_attributes_and_annotations : Error<
|
||||
"attribute specifier cannot contain both attributes and annotations">;
|
||||
def warn_meant_parenthesize_reflection : Warning<
|
||||
"'%0' binds to reflection operand">, InGroup<ReflexingParse>;
|
||||
def err_splice_template_argument : Error<
|
||||
|
||||
@@ -4792,6 +4792,9 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
|
||||
checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin);
|
||||
ConsumeBracket();
|
||||
|
||||
bool AllowAnnotations = getLangOpts().AnnotationAttributes &&
|
||||
Tok.is(tok::equal);
|
||||
|
||||
SourceLocation CommonScopeLoc;
|
||||
IdentifierInfo *CommonScopeName = nullptr;
|
||||
if (Tok.is(tok::kw_using)) {
|
||||
@@ -4830,15 +4833,23 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
|
||||
SourceLocation ScopeLoc, AttrLoc;
|
||||
IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr;
|
||||
|
||||
if (Tok.is(tok::equal) && getLangOpts().AnnotationAttributes) {
|
||||
// This is a C++2c annotation.
|
||||
if (CommonScopeName) {
|
||||
Diag(Tok.getLocation(), diag::err_annotation_with_using);
|
||||
SkipUntil(tok::r_square, tok::colon, tok::r_splice, StopBeforeMatch);
|
||||
if (AllowAnnotations) {
|
||||
if (Tok.is(tok::equal)) {
|
||||
// This is a C++2c annotation.
|
||||
if (CommonScopeName) {
|
||||
Diag(Tok.getLocation(), diag::err_annotation_with_using);
|
||||
SkipUntil(tok::r_square, tok::colon, tok::r_splice, StopBeforeMatch);
|
||||
} else {
|
||||
ParseAnnotationSpecifier(Attrs, EndLoc);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
ParseAnnotationSpecifier(Attrs, EndLoc);
|
||||
Diag(Tok.getLocation(), diag::err_mixed_attributes_and_annotations);
|
||||
SkipUntil(tok::r_square, tok::colon, tok::r_splice, StopBeforeMatch);
|
||||
}
|
||||
continue;
|
||||
} else if (Tok.is(tok::equal)) {
|
||||
Diag(Tok.getLocation(), diag::err_mixed_attributes_and_annotations);
|
||||
SkipUntil(tok::r_square, tok::colon, tok::r_splice, StopBeforeMatch);
|
||||
}
|
||||
|
||||
AttrName = TryParseCXX11AttributeIdentifier(
|
||||
|
||||
@@ -20,14 +20,14 @@ namespace basic_parsing {
|
||||
|
||||
consteval int fn() { return 1; }
|
||||
|
||||
[[maybe_unused, =42, =basic_parsing::fn(), maybe_unused]]
|
||||
[[=42, =basic_parsing::fn()]]
|
||||
void annFn();
|
||||
|
||||
struct [[maybe_unused, =42, =basic_parsing::fn(), maybe_unused]] S;
|
||||
struct [[=42, =basic_parsing::fn()]] S;
|
||||
|
||||
template <typename>
|
||||
struct [[maybe_unused, =42, =basic_parsing::fn(), maybe_unused]] TCls;
|
||||
struct [[=42, =basic_parsing::fn()]] TCls;
|
||||
|
||||
namespace [[maybe_unused, =42, =basic_parsing::fn(), maybe_unused]] NS {};
|
||||
namespace [[=42, =basic_parsing::fn()]] NS {};
|
||||
|
||||
} // namespace basic_parsing
|
||||
|
||||
@@ -43,11 +43,11 @@ static_assert(annotations_of(^^NS).size() == 0);
|
||||
// =============
|
||||
|
||||
namespace non_dependent {
|
||||
[[maybe_unused, =1, =1, =2, =1.0f]] void fn();
|
||||
struct [[maybe_unused, =3, =3, =4, =2.0f]] S;
|
||||
template <typename> struct [[maybe_unused, =5, =5, =6, =3.0f]] TCls {};
|
||||
template <typename> [[maybe_unused, =5, =5, =6, =3.0f]] void TFn();
|
||||
namespace [[maybe_unused, =7, =7, =8, =4.0f]] NS {}
|
||||
[[=1, =1, =2, =1.0f]] void fn();
|
||||
struct [[=3, =3, =4, =2.0f]] S;
|
||||
template <typename> struct [[=5, =5, =6, =3.0f]] TCls {};
|
||||
template <typename> [[=5, =5, =6, =3.0f]] void TFn();
|
||||
namespace [[=7, =7, =8, =4.0f]] NS {}
|
||||
|
||||
static_assert((annotations_of(^^fn) |
|
||||
std::views::transform(std::meta::constant_of) |
|
||||
@@ -153,7 +153,7 @@ template <std::meta::info R>
|
||||
struct TCls {};
|
||||
|
||||
template <std::meta::info R> requires (is_function(R))
|
||||
struct [[=int(annotations_of(R).size()), maybe_unused]] TCls<R> {};
|
||||
struct [[=int(annotations_of(R).size())]] TCls<R> {};
|
||||
|
||||
static_assert(annotations_of(^^TCls<^^::>).size() == 0);
|
||||
static_assert(annotation_of_type<int>(^^TCls<^^fn>) == 3);
|
||||
|
||||
Reference in New Issue
Block a user