Skip to content

Commit f8f14b4

Browse files
committed
[Clang importer] Use ParseSourceFileRequest for parsing swift_attr attributes
The Clang importer was directly calling into the parser to parse the attribute (or modifier) within swift_attr. Aside from being gross, this isn't possible with ASTGen. Instead, teach ParseSourceFileRequest to deal with modifiers in the same way that the Clang importer was hardcoding, and have the Clang importer pull the attributes/modifiers off of the "missing" declaration introduced by the request. One benefit of this approach is that we're only parsing each swift_attr source buffer once, then cloning the attributes each time it's used, so we should be doing less work overall. Fixes rdar://139119159.
1 parent 7872fc6 commit f8f14b4

File tree

4 files changed

+30
-40
lines changed

4 files changed

+30
-40
lines changed

include/swift/Parse/Parser.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,11 @@ class Parser {
13221322
///
13231323
/// Parsing a floating attribute list will produce a `MissingDecl` with
13241324
/// the attribute list attached.
1325-
void parseExpandedAttributeList(SmallVectorImpl<ASTNode> &items);
1325+
///
1326+
/// If isFromClangAttribute, we also parse modifiers and suppress any
1327+
/// diagnostics about bad modifiers.
1328+
void parseExpandedAttributeList(SmallVectorImpl<ASTNode> &items,
1329+
bool isFromClangAttribute);
13261330

13271331
/// Parse the result of member macro expansion, which is a floating
13281332
/// member list.

lib/ClangImporter/ImportDecl.cpp

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
#include "swift/ClangImporter/ClangImporterRequests.h"
5353
#include "swift/ClangImporter/ClangModule.h"
5454
#include "swift/Parse/Lexer.h"
55-
#include "swift/Parse/Parser.h"
5655
#include "swift/Strings.h"
5756
#include "clang/AST/ASTContext.h"
5857
#include "clang/AST/Attr.h"
@@ -8281,7 +8280,6 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
82818280

82828281
std::optional<const clang::SwiftAttrAttr *> seenMainActorAttr;
82838282
const clang::SwiftAttrAttr *seenMutabilityAttr = nullptr;
8284-
PatternBindingInitializer *initContext = nullptr;
82858283

82868284
auto importAttrsFromDecl = [&](const clang::NamedDecl *ClangDecl) {
82878285
//
@@ -8406,37 +8404,12 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
84068404
*MappedDecl->getDeclContext()->getParentModule(),
84078405
swiftAttr->getAttribute());
84088406

8409-
// Spin up a parser.
8410-
swift::Parser parser(
8411-
sourceFile.getBufferID(), sourceFile, &SwiftContext.Diags,
8412-
nullptr, nullptr);
8413-
// Prime the lexer.
8414-
parser.consumeTokenWithoutFeedingReceiver();
8415-
8416-
bool hadError = false;
8417-
if (parser.Tok.is(tok::at_sign)) {
8418-
SourceLoc atEndLoc = parser.Tok.getRange().getEnd();
8419-
SourceLoc atLoc = parser.consumeToken(tok::at_sign);
8420-
hadError = parser
8421-
.parseDeclAttribute(MappedDecl->getAttrs(), atLoc,
8422-
atEndLoc, initContext,
8423-
/*isFromClangAttribute=*/true)
8424-
.isError();
8425-
} else {
8426-
SourceLoc staticLoc;
8427-
StaticSpellingKind staticSpelling;
8428-
hadError = parser
8429-
.parseDeclModifierList(MappedDecl->getAttrs(), staticLoc,
8430-
staticSpelling,
8431-
/*isFromClangAttribute=*/true)
8432-
.isError();
8433-
}
8434-
8435-
if (hadError) {
8436-
// Complain about the unhandled attribute or modifier.
8437-
HeaderLoc attrLoc(swiftAttr->getLocation());
8438-
diagnose(attrLoc, diag::clang_swift_attr_unhandled,
8439-
swiftAttr->getAttribute());
8407+
// Collect the attributes from the synthesized top-level declaration in
8408+
// the source file.
8409+
auto topLevelDecls = sourceFile.getTopLevelDecls();
8410+
for (auto decl : topLevelDecls) {
8411+
for (auto attr : decl->getAttrs())
8412+
MappedDecl->getAttrs().add(attr->clone(SwiftContext));
84408413
}
84418414
}
84428415

lib/Parse/ParseDecl.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8166,17 +8166,28 @@ void Parser::parseTopLevelAccessors(
81668166
items.push_back(accessor);
81678167
}
81688168

8169-
void Parser::parseExpandedAttributeList(SmallVectorImpl<ASTNode> &items) {
8169+
void Parser::parseExpandedAttributeList(SmallVectorImpl<ASTNode> &items,
8170+
bool isFromClangAttribute) {
81708171
if (Tok.is(tok::NUM_TOKENS))
81718172
consumeTokenWithoutFeedingReceiver();
81728173

81738174
DeclAttributes attributes;
81748175
parseDeclAttributeList(attributes);
81758176

8177+
// If this is coming from a Clang attribute, also parse modifiers.
8178+
if (isFromClangAttribute && !Tok.is(tok::eof)) {
8179+
SourceLoc staticLoc;
8180+
StaticSpellingKind staticSpelling;
8181+
parseDeclModifierList(
8182+
attributes, staticLoc, staticSpelling, isFromClangAttribute);
8183+
}
8184+
81768185
// Consume remaining tokens.
81778186
while (!Tok.is(tok::eof)) {
8178-
diagnose(Tok.getLoc(), diag::unexpected_attribute_expansion,
8179-
Tok.getText());
8187+
if (!isFromClangAttribute) {
8188+
diagnose(Tok.getLoc(), diag::unexpected_attribute_expansion,
8189+
Tok.getText());
8190+
}
81808191
consumeToken();
81818192
}
81828193

lib/Parse/ParseRequests.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,10 +379,12 @@ SourceFileParsingResult parseSourceFile(SourceFile &SF) {
379379
}
380380

381381
case GeneratedSourceInfo::MemberAttributeMacroExpansion:
382-
case GeneratedSourceInfo::Attribute: {
383-
parser.parseExpandedAttributeList(items);
382+
parser.parseExpandedAttributeList(items, /*isFromClangAttribute=*/false);
383+
break;
384+
385+
case GeneratedSourceInfo::Attribute:
386+
parser.parseExpandedAttributeList(items, /*isFromClangAttribute=*/true);
384387
break;
385-
}
386388

387389
case GeneratedSourceInfo::PeerMacroExpansion: {
388390
if (parser.CurDeclContext->isTypeContext()) {

0 commit comments

Comments
 (0)