Skip to content

Commit b78d538

Browse files
committed
parse: process GNU and standard attributes on top-level decls
We would previously reject valid input where GNU attributes preceded the standard attributes on top-level declarations. A previous attribute handling change had begun rejecting this whilst GCC does honour this layout. In practice, this breaks use of `extern "C"` attributed functions which use both standard and GNU attributes as experienced by the Swift runtime. Objective-C deserves an honourable mention for requiring some additional special casing. Because attributes on declarations and definitions differ in semantics, we need to replicate some of the logic for detecting attributes to declarations to which they appertain cannot be attributed. This should match the existing case for the application of GNU attributes to interfaces, protocols, and implementations. Take the opportunity to split out the tooling tests into two cases: ones which process macros and ones which do not. Special thanks to Aaron Ballman for the many hints and extensive rubber ducking that was involved in identifying the various places where we accidentally dropped attributes. Differential Revision: https://reviews.llvm.org/D137979 Fixes: llvm#58229 Reviewed By: aaron.ballman, arphaman
1 parent 26068c6 commit b78d538

File tree

11 files changed

+145
-71
lines changed

11 files changed

+145
-71
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@ Bug Fixes
298298
and Clang 15 accidentally stopped predeclaring those functions in that
299299
language mode. Clang 16 now predeclares those functions again. This fixes
300300
`Issue 56607 <https://github.com/llvm/llvm-project/issues/56607>`_.
301+
- GNU attributes being applied prior to standard attributes would be handled
302+
improperly, which was corrected to match the behaviour exhibited by GCC.
303+
`Issue 58229 <https://github.com/llvm/llvm-project/issues/58229>`_
301304

302305
Improvements to Clang's diagnostics
303306
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Parse/Parser.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,15 +1602,16 @@ class Parser : public CodeCompletionHandler {
16021602

16031603
//===--------------------------------------------------------------------===//
16041604
// C99 6.9: External Definitions.
1605-
DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributes &Attrs,
1605+
DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributes &DeclAttrs,
1606+
ParsedAttributes &DeclSpecAttrs,
16061607
ParsingDeclSpec *DS = nullptr);
16071608
bool isDeclarationAfterDeclarator();
16081609
bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
1609-
DeclGroupPtrTy
1610-
ParseDeclarationOrFunctionDefinition(ParsedAttributes &Attrs,
1611-
ParsingDeclSpec *DS = nullptr,
1612-
AccessSpecifier AS = AS_none);
1610+
DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
1611+
ParsedAttributes &DeclAttrs, ParsedAttributes &DeclSpecAttrs,
1612+
ParsingDeclSpec *DS = nullptr, AccessSpecifier AS = AS_none);
16131613
DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributes &Attrs,
1614+
ParsedAttributes &DeclSpecAttrs,
16141615
ParsingDeclSpec &DS,
16151616
AccessSpecifier AS);
16161617

@@ -1625,7 +1626,8 @@ class Parser : public CodeCompletionHandler {
16251626

16261627
// Objective-C External Declarations
16271628
void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
1628-
DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributes &Attrs);
1629+
DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
1630+
ParsedAttributes &DeclSpecAttrs);
16291631
DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
16301632
Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
16311633
ParsedAttributes &prefixAttrs);

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,10 @@ void Parser::ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,
254254
if (index == InnerNSs.size()) {
255255
while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
256256
Tok.isNot(tok::eof)) {
257-
ParsedAttributes Attrs(AttrFactory);
258-
MaybeParseCXX11Attributes(Attrs);
259-
ParseExternalDeclaration(Attrs);
257+
ParsedAttributes DeclAttrs(AttrFactory);
258+
MaybeParseCXX11Attributes(DeclAttrs);
259+
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
260+
ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
260261
}
261262

262263
// The caller is what called check -- we are simply calling
@@ -359,6 +360,7 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {
359360

360361
ParsedAttributes DeclAttrs(AttrFactory);
361362
MaybeParseCXX11Attributes(DeclAttrs);
363+
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
362364

363365
if (Tok.isNot(tok::l_brace)) {
364366
// Reset the source range in DS, as the leading "extern"
@@ -367,7 +369,7 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {
367369
DS.SetRangeEnd(SourceLocation());
368370
// ... but anyway remember that such an "extern" was seen.
369371
DS.setExternInLinkageSpec(true);
370-
ParseExternalDeclaration(DeclAttrs, &DS);
372+
ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs, &DS);
371373
return LinkageSpec ? Actions.ActOnFinishLinkageSpecification(
372374
getCurScope(), LinkageSpec, SourceLocation())
373375
: nullptr;
@@ -407,9 +409,9 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {
407409
break;
408410
[[fallthrough]];
409411
default:
410-
ParsedAttributes Attrs(AttrFactory);
411-
MaybeParseCXX11Attributes(Attrs);
412-
ParseExternalDeclaration(Attrs);
412+
ParsedAttributes DeclAttrs(AttrFactory);
413+
MaybeParseCXX11Attributes(DeclAttrs);
414+
ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
413415
continue;
414416
}
415417

@@ -439,9 +441,10 @@ Decl *Parser::ParseExportDeclaration() {
439441

440442
if (Tok.isNot(tok::l_brace)) {
441443
// FIXME: Factor out a ParseExternalDeclarationWithAttrs.
442-
ParsedAttributes Attrs(AttrFactory);
443-
MaybeParseCXX11Attributes(Attrs);
444-
ParseExternalDeclaration(Attrs);
444+
ParsedAttributes DeclAttrs(AttrFactory);
445+
MaybeParseCXX11Attributes(DeclAttrs);
446+
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
447+
ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
445448
return Actions.ActOnFinishExportDecl(getCurScope(), ExportDecl,
446449
SourceLocation());
447450
}
@@ -458,9 +461,10 @@ Decl *Parser::ParseExportDeclaration() {
458461

459462
while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
460463
Tok.isNot(tok::eof)) {
461-
ParsedAttributes Attrs(AttrFactory);
462-
MaybeParseCXX11Attributes(Attrs);
463-
ParseExternalDeclaration(Attrs);
464+
ParsedAttributes DeclAttrs(AttrFactory);
465+
MaybeParseCXX11Attributes(DeclAttrs);
466+
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
467+
ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
464468
}
465469

466470
T.consumeClose();

clang/lib/Parse/ParseHLSL.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,11 @@ Decl *Parser::ParseHLSLBuffer(SourceLocation &DeclEnd) {
7777

7878
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
7979
// FIXME: support attribute on constants inside cbuffer/tbuffer.
80-
ParsedAttributes Attrs(AttrFactory);
80+
ParsedAttributes DeclAttrs(AttrFactory);
81+
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
8182

82-
DeclGroupPtrTy Result = ParseExternalDeclaration(Attrs);
83+
DeclGroupPtrTy Result =
84+
ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
8385
if (!validateDeclsInsideHLSLBuffer(Result, IdentifierLoc, IsCBuffer,
8486
*this)) {
8587
T.skipToEnd();

clang/lib/Parse/ParseObjc.cpp

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) {
4646
/// [OBJC] objc-protocol-definition
4747
/// [OBJC] objc-method-definition
4848
/// [OBJC] '@' 'end'
49-
Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives(ParsedAttributes &Attrs) {
49+
Parser::DeclGroupPtrTy
50+
Parser::ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
51+
ParsedAttributes &DeclSpecAttrs) {
52+
DeclAttrs.takeAllFrom(DeclSpecAttrs);
53+
5054
SourceLocation AtLoc = ConsumeToken(); // the "@"
5155

5256
if (Tok.is(tok::code_completion)) {
@@ -55,17 +59,29 @@ Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives(ParsedAttributes &Attrs) {
5559
return nullptr;
5660
}
5761

62+
switch (Tok.getObjCKeywordID()) {
63+
case tok::objc_interface:
64+
case tok::objc_protocol:
65+
case tok::objc_implementation:
66+
break;
67+
default:
68+
llvm::for_each(DeclAttrs, [this](const auto &Attr) {
69+
if (Attr.isGNUAttribute())
70+
Diag(Tok.getLocation(), diag::err_objc_unexpected_attr);
71+
});
72+
}
73+
5874
Decl *SingleDecl = nullptr;
5975
switch (Tok.getObjCKeywordID()) {
6076
case tok::objc_class:
6177
return ParseObjCAtClassDeclaration(AtLoc);
6278
case tok::objc_interface:
63-
SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, Attrs);
79+
SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, DeclAttrs);
6480
break;
6581
case tok::objc_protocol:
66-
return ParseObjCAtProtocolDeclaration(AtLoc, Attrs);
82+
return ParseObjCAtProtocolDeclaration(AtLoc, DeclAttrs);
6783
case tok::objc_implementation:
68-
return ParseObjCAtImplementationDeclaration(AtLoc, Attrs);
84+
return ParseObjCAtImplementationDeclaration(AtLoc, DeclAttrs);
6985
case tok::objc_end:
7086
return ParseObjCAtEndDeclaration(AtLoc);
7187
case tok::objc_compatibility_alias:
@@ -651,21 +667,23 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
651667
if (Tok.is(tok::r_brace))
652668
break;
653669

654-
ParsedAttributes EmptyAttrs(AttrFactory);
670+
ParsedAttributes EmptyDeclAttrs(AttrFactory);
671+
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
655672

656673
// Since we call ParseDeclarationOrFunctionDefinition() instead of
657674
// ParseExternalDeclaration() below (so that this doesn't parse nested
658675
// @interfaces), this needs to duplicate some code from the latter.
659676
if (Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
660677
SourceLocation DeclEnd;
661678
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
662-
allTUVariables.push_back(ParseDeclaration(
663-
DeclaratorContext::File, DeclEnd, EmptyAttrs, EmptyDeclSpecAttrs));
679+
allTUVariables.push_back(ParseDeclaration(DeclaratorContext::File,
680+
DeclEnd, EmptyDeclAttrs,
681+
EmptyDeclSpecAttrs));
664682
continue;
665683
}
666684

667-
allTUVariables.push_back(
668-
ParseDeclarationOrFunctionDefinition(EmptyAttrs));
685+
allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(
686+
EmptyDeclAttrs, EmptyDeclSpecAttrs));
669687
continue;
670688
}
671689

@@ -2236,9 +2254,11 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
22362254
{
22372255
ObjCImplParsingDataRAII ObjCImplParsing(*this, ObjCImpDecl);
22382256
while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
2239-
ParsedAttributes attrs(AttrFactory);
2240-
MaybeParseCXX11Attributes(attrs);
2241-
if (DeclGroupPtrTy DGP = ParseExternalDeclaration(attrs)) {
2257+
ParsedAttributes DeclAttrs(AttrFactory);
2258+
MaybeParseCXX11Attributes(DeclAttrs);
2259+
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2260+
if (DeclGroupPtrTy DGP =
2261+
ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs)) {
22422262
DeclGroupRef DG = DGP.get();
22432263
DeclsInGroup.append(DG.begin(), DG.end());
22442264
}

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2304,9 +2304,10 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
23042304
// Here we expect to see some function declaration.
23052305
if (AS == AS_none) {
23062306
assert(TagType == DeclSpec::TST_unspecified);
2307+
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
23072308
MaybeParseCXX11Attributes(Attrs);
23082309
ParsingDeclSpec PDS(*this);
2309-
Ptr = ParseExternalDeclaration(Attrs, &PDS);
2310+
Ptr = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs, &PDS);
23102311
} else {
23112312
Ptr =
23122313
ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);

clang/lib/Parse/Parser.cpp

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -731,10 +731,17 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
731731
break;
732732
}
733733

734-
ParsedAttributes attrs(AttrFactory);
735-
MaybeParseCXX11Attributes(attrs);
736-
737-
Result = ParseExternalDeclaration(attrs);
734+
ParsedAttributes DeclAttrs(AttrFactory);
735+
ParsedAttributes DeclSpecAttrs(AttrFactory);
736+
// GNU attributes are applied to the declaration specification while the
737+
// standard attributes are applied to the declaration. We parse the two
738+
// attribute sets into different containters so we can apply them during
739+
// the regular parsing process.
740+
while (MaybeParseCXX11Attributes(DeclAttrs) ||
741+
MaybeParseGNUAttributes(DeclSpecAttrs))
742+
;
743+
744+
Result = ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);
738745
// An empty Result might mean a line with ';' or some parsing error, ignore
739746
// it.
740747
if (Result) {
@@ -777,8 +784,10 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
777784
///
778785
/// [Modules-TS] module-import-declaration
779786
///
780-
Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
781-
ParsingDeclSpec *DS) {
787+
Parser::DeclGroupPtrTy
788+
Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
789+
ParsedAttributes &DeclSpecAttrs,
790+
ParsingDeclSpec *DS) {
782791
DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
783792
ParenBraceBracketBalancer BalancerRAIIObj(*this);
784793

@@ -866,7 +875,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
866875
// __extension__ silences extension warnings in the subexpression.
867876
ExtensionRAIIObject O(Diags); // Use RAII to do this.
868877
ConsumeToken();
869-
return ParseExternalDeclaration(Attrs);
878+
return ParseExternalDeclaration(Attrs, DeclSpecAttrs);
870879
}
871880
case tok::kw_asm: {
872881
ProhibitAttributes(Attrs);
@@ -894,7 +903,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
894903
break;
895904
}
896905
case tok::at:
897-
return ParseObjCAtDirectives(Attrs);
906+
return ParseObjCAtDirectives(Attrs, DeclSpecAttrs);
898907
case tok::minus:
899908
case tok::plus:
900909
if (!getLangOpts().ObjC) {
@@ -942,18 +951,16 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
942951
// A function definition cannot start with any of these keywords.
943952
{
944953
SourceLocation DeclEnd;
945-
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
946954
return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs,
947-
EmptyDeclSpecAttrs);
955+
DeclSpecAttrs);
948956
}
949957

950958
case tok::kw_cbuffer:
951959
case tok::kw_tbuffer:
952960
if (getLangOpts().HLSL) {
953961
SourceLocation DeclEnd;
954-
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
955962
return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs,
956-
EmptyDeclSpecAttrs);
963+
DeclSpecAttrs);
957964
}
958965
goto dont_know;
959966

@@ -964,9 +971,8 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
964971
Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
965972
<< 0;
966973
SourceLocation DeclEnd;
967-
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
968974
return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs,
969-
EmptyDeclSpecAttrs);
975+
DeclSpecAttrs);
970976
}
971977
goto dont_know;
972978

@@ -977,9 +983,8 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
977983
// Inline namespaces. Allowed as an extension even in C++03.
978984
if (NextKind == tok::kw_namespace) {
979985
SourceLocation DeclEnd;
980-
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
981986
return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs,
982-
EmptyDeclSpecAttrs);
987+
DeclSpecAttrs);
983988
}
984989

985990
// Parse (then ignore) 'inline' prior to a template instantiation. This is
@@ -988,9 +993,8 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
988993
Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
989994
<< 1;
990995
SourceLocation DeclEnd;
991-
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
992996
return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs,
993-
EmptyDeclSpecAttrs);
997+
DeclSpecAttrs);
994998
}
995999
}
9961000
goto dont_know;
@@ -1026,7 +1030,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
10261030
return nullptr;
10271031
}
10281032
// We can't tell whether this is a function-definition or declaration yet.
1029-
return ParseDeclarationOrFunctionDefinition(Attrs, DS);
1033+
return ParseDeclarationOrFunctionDefinition(Attrs, DeclSpecAttrs, DS);
10301034
}
10311035

10321036
// This routine returns a DeclGroup, if the thing we parsed only contains a
@@ -1091,7 +1095,17 @@ bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
10911095
/// [OMP] allocate-directive [TODO]
10921096
///
10931097
Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal(
1094-
ParsedAttributes &Attrs, ParsingDeclSpec &DS, AccessSpecifier AS) {
1098+
ParsedAttributes &Attrs, ParsedAttributes &DeclSpecAttrs,
1099+
ParsingDeclSpec &DS, AccessSpecifier AS) {
1100+
// Because we assume that the DeclSpec has not yet been initialised, we simply
1101+
// overwrite the source range and attribute the provided leading declspec
1102+
// attributes.
1103+
assert(DS.getSourceRange().isInvalid() &&
1104+
"expected uninitialised source range");
1105+
DS.SetRangeStart(DeclSpecAttrs.Range.getBegin());
1106+
DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd());
1107+
DS.takeAttributesFrom(DeclSpecAttrs);
1108+
10951109
MaybeParseMicrosoftAttributes(DS.getAttributes());
10961110
// Parse the common declaration-specifiers piece.
10971111
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS,
@@ -1190,17 +1204,18 @@ Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal(
11901204
}
11911205

11921206
Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition(
1193-
ParsedAttributes &Attrs, ParsingDeclSpec *DS, AccessSpecifier AS) {
1207+
ParsedAttributes &Attrs, ParsedAttributes &DeclSpecAttrs,
1208+
ParsingDeclSpec *DS, AccessSpecifier AS) {
11941209
if (DS) {
1195-
return ParseDeclOrFunctionDefInternal(Attrs, *DS, AS);
1210+
return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, *DS, AS);
11961211
} else {
11971212
ParsingDeclSpec PDS(*this);
11981213
// Must temporarily exit the objective-c container scope for
11991214
// parsing c constructs and re-enter objc container scope
12001215
// afterwards.
12011216
ObjCDeclContextSwitch ObjCDC(*this);
12021217

1203-
return ParseDeclOrFunctionDefInternal(Attrs, PDS, AS);
1218+
return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, PDS, AS);
12041219
}
12051220
}
12061221

@@ -2342,7 +2357,8 @@ void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
23422357
while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
23432358
ParsedAttributes Attrs(AttrFactory);
23442359
MaybeParseCXX11Attributes(Attrs);
2345-
DeclGroupPtrTy Result = ParseExternalDeclaration(Attrs);
2360+
ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2361+
DeclGroupPtrTy Result = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs);
23462362
if (Result && !getCurScope()->getParent())
23472363
Actions.getASTConsumer().HandleTopLevelDecl(Result.get());
23482364
}

0 commit comments

Comments
 (0)