//===--------------------------------------------------------------------===//
// C99 6.9: External Definitions.
+ struct ParsedAttributesWithRange : ParsedAttributes {
+ ParsedAttributesWithRange(AttributeFactory &factory)
+ : ParsedAttributes(factory) {}
+
+ void clear() {
+ ParsedAttributes::clear();
+ Range = SourceRange();
+ }
+
+ SourceRange Range;
+ };
+ struct ParsedAttributesViewWithRange : ParsedAttributesView {
+ ParsedAttributesViewWithRange() : ParsedAttributesView() {}
+ void clearListOnly() {
+ ParsedAttributesView::clearListOnly();
+ Range = SourceRange();
+ }
+
+ SourceRange Range;
+ };
+
DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
ParsingDeclSpec *DS = nullptr);
bool isDeclarationAfterDeclarator();
D.takeAttributes(attrs, endLoc);
}
}
-
- /// Parses GNU-style attributes and returns them without source range
- /// information.
- ///
- /// This API is discouraged. Use the version that takes a
- /// ParsedAttributesWithRange instead.
- bool MaybeParseGNUAttributes(ParsedAttributes &Attrs,
- SourceLocation *EndLoc = nullptr,
+ bool MaybeParseGNUAttributes(ParsedAttributes &attrs,
+ SourceLocation *endLoc = nullptr,
LateParsedAttrList *LateAttrs = nullptr) {
if (Tok.is(tok::kw___attribute)) {
- ParsedAttributesWithRange AttrsWithRange(AttrFactory);
- ParseGNUAttributes(Attrs, EndLoc, LateAttrs);
- Attrs.takeAllFrom(AttrsWithRange);
+ ParseGNUAttributes(attrs, endLoc, LateAttrs);
return true;
}
return false;
}
-
- bool MaybeParseGNUAttributes(ParsedAttributesWithRange &Attrs,
- SourceLocation *EndLoc = nullptr,
- LateParsedAttrList *LateAttrs = nullptr) {
- if (Tok.is(tok::kw___attribute)) {
- ParseGNUAttributes(Attrs, EndLoc, LateAttrs);
- return true;
- }
- return false;
- }
-
- /// Parses GNU-style attributes and returns them without source range
- /// information.
- ///
- /// This API is discouraged. Use the version that takes a
- /// ParsedAttributesWithRange instead.
- void ParseGNUAttributes(ParsedAttributes &Attrs,
- SourceLocation *EndLoc = nullptr,
- LateParsedAttrList *LateAttrs = nullptr,
- Declarator *D = nullptr) {
- ParsedAttributesWithRange AttrsWithRange(AttrFactory);
- ParseGNUAttributes(AttrsWithRange, EndLoc, LateAttrs, D);
- Attrs.takeAllFrom(AttrsWithRange);
- }
-
- void ParseGNUAttributes(ParsedAttributesWithRange &Attrs,
- SourceLocation *EndLoc = nullptr,
+ void ParseGNUAttributes(ParsedAttributes &attrs,
+ SourceLocation *endLoc = nullptr,
LateParsedAttrList *LateAttrs = nullptr,
Declarator *D = nullptr);
void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
mutable AttributePool pool;
};
-struct ParsedAttributesWithRange : ParsedAttributes {
- ParsedAttributesWithRange(AttributeFactory &factory)
- : ParsedAttributes(factory) {}
-
- void clear() {
- ParsedAttributes::clear();
- Range = SourceRange();
- }
-
- SourceRange Range;
-};
-struct ParsedAttributesViewWithRange : ParsedAttributesView {
- ParsedAttributesViewWithRange() : ParsedAttributesView() {}
- void clearListOnly() {
- ParsedAttributesView::clearListOnly();
- Range = SourceRange();
- }
-
- SourceRange Range;
-};
-
/// These constants match the enumerated choices of
/// err_attribute_argument_n_type and err_attribute_argument_type.
enum AttributeArgumentNType {
/// ',' or ')' are ignored, otherwise they produce a parse error.
///
/// We follow the C++ model, but don't allow junk after the identifier.
-void Parser::ParseGNUAttributes(ParsedAttributesWithRange &Attrs,
- SourceLocation *EndLoc,
- LateParsedAttrList *LateAttrs, Declarator *D) {
+void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
+ SourceLocation *endLoc,
+ LateParsedAttrList *LateAttrs,
+ Declarator *D) {
assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
- SourceLocation StartLoc = Tok.getLocation(), Loc;
-
- if (!EndLoc)
- EndLoc = &Loc;
-
while (Tok.is(tok::kw___attribute)) {
SourceLocation AttrTokLoc = ConsumeToken();
- unsigned OldNumAttrs = Attrs.size();
+ unsigned OldNumAttrs = attrs.size();
unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
SourceLocation AttrNameLoc = ConsumeToken();
if (Tok.isNot(tok::l_paren)) {
- Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
+ attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
ParsedAttr::AS_GNU);
continue;
}
// Handle "parameterized" attributes
if (!LateAttrs || !isAttributeLateParsed(*AttrName)) {
- ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, nullptr,
+ ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc, nullptr,
SourceLocation(), ParsedAttr::AS_GNU, D);
continue;
}
SourceLocation Loc = Tok.getLocation();
if (ExpectAndConsume(tok::r_paren))
SkipUntil(tok::r_paren, StopAtSemi);
- if (EndLoc)
- *EndLoc = Loc;
+ if (endLoc)
+ *endLoc = Loc;
// If this was declared in a macro, attach the macro IdentifierInfo to the
// parsed attribute.
Lexer::getSourceText(ExpansionRange, SM, PP.getLangOpts());
IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName);
- for (unsigned i = OldNumAttrs; i < Attrs.size(); ++i)
- Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.getBegin());
+ for (unsigned i = OldNumAttrs; i < attrs.size(); ++i)
+ attrs[i].setMacroIdentifier(MacroII, ExpansionRange.getBegin());
if (LateAttrs) {
for (unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
}
}
}
-
- Attrs.Range = SourceRange(StartLoc, *EndLoc);
}
/// Determine whether the given attribute has an identifier argument.
}\r
}\r
\r
-// CHECK-1Z: NamespaceDecl {{.*}} attributed_case\r
-namespace attributed_case {\r
-void f(int n) {\r
- switch (n) {\r
- case 0:\r
- n--;\r
- // CHECK: AttributedStmt {{.*}} <line:[[@LINE+2]]:5, line:[[@LINE+4]]:35>\r
- // CHECK: FallThroughAttr {{.*}} <line:[[@LINE+1]]:20>\r
- __attribute__((fallthrough))\r
- // CHECK: FallThroughAttr {{.*}} <line:[[@LINE+1]]:22>\r
- __attribute__((fallthrough));\r
- case 1:\r
- n++;\r
- break;\r
- }\r
-}\r
-} // namespace attributed_case\r
-\r
// CHECK: NamespaceDecl {{.*}} attributed_stmt\r
namespace attributed_stmt {\r
// In DO_PRAGMA and _Pragma cases, `LoopHintAttr` comes from <scratch space>\r
return 1;
[[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}}
case 222:
- return 2;
- __attribute__((fallthrough)); // expected-warning{{fallthrough annotation in unreachable code}}
- case 223:
n += 400;
- case 224: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
- ;
+ case 223: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ ;
}
long p = static_cast<long>(n) * n;