Skip to content

Commit beab9f3

Browse files
committed
[Sema] Move @objc-without-Foundation checking to TypeCheckAttr
There doesn't seem to be any reason to delay this diagnostic until after type-checking has finished any more, so run it along with the rest of attribute checking.
1 parent a1716fe commit beab9f3

File tree

6 files changed

+39
-52
lines changed

6 files changed

+39
-52
lines changed

include/swift/AST/SourceFile.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,6 @@ class SourceFile final : public FileUnit {
251251
/// The list of local type declarations in the source file.
252252
llvm::SetVector<TypeDecl *> LocalTypeDecls;
253253

254-
/// A set of special declaration attributes which require the
255-
/// Foundation module to be imported to work. If the foundation
256-
/// module is still not imported by the time type checking is
257-
/// complete, we diagnose.
258-
llvm::SetVector<const DeclAttribute *> AttrsRequiringFoundation;
259-
260254
/// A set of synthesized declarations that need to be type checked.
261255
llvm::SmallVector<Decl *, 8> SynthesizedDecls;
262256

lib/Parse/ParseDecl.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3935,15 +3935,6 @@ Parser::parseDecl(ParseDeclOptions Flags,
39353935
DeclResult.setHasCodeCompletion();
39363936
}
39373937

3938-
if (auto SF = CurDeclContext->getParentSourceFile()) {
3939-
if (!getScopeInfo().isInactiveConfigBlock()) {
3940-
for (auto Attr : Attributes) {
3941-
if (isa<ObjCAttr>(Attr))
3942-
SF->AttrsRequiringFoundation.insert(Attr);
3943-
}
3944-
}
3945-
}
3946-
39473938
if (DeclResult.isNonNull()) {
39483939
Decl *D = DeclResult.get();
39493940
if (!declWasHandledAlready(D))

lib/Sema/TypeCheckAttr.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/DiagnosticsParse.h"
2424
#include "swift/AST/GenericEnvironment.h"
2525
#include "swift/AST/GenericSignatureBuilder.h"
26+
#include "swift/AST/ImportCache.h"
2627
#include "swift/AST/ModuleNameLookup.h"
2728
#include "swift/AST/NameLookup.h"
2829
#include "swift/AST/NameLookupRequests.h"
@@ -882,6 +883,41 @@ static bool checkObjCDeclContext(Decl *D) {
882883
return false;
883884
}
884885

886+
static void diagnoseObjCAttrWithoutFoundation(ObjCAttr *attr, Decl *decl) {
887+
auto *SF = decl->getDeclContext()->getParentSourceFile();
888+
assert(SF);
889+
890+
// We only care about explicitly written @objc attributes.
891+
if (attr->isImplicit())
892+
return;
893+
894+
auto &ctx = SF->getASTContext();
895+
if (ctx.LangOpts.EnableObjCInterop) {
896+
// Don't diagnose in a SIL file.
897+
if (SF->Kind == SourceFileKind::SIL)
898+
return;
899+
900+
// Don't diagnose for -disable-objc-attr-requires-foundation-module.
901+
if (!ctx.LangOpts.EnableObjCAttrRequiresFoundation)
902+
return;
903+
}
904+
905+
// If we have the Foundation module, @objc is okay.
906+
auto *foundation = ctx.getLoadedModule(ctx.Id_Foundation);
907+
if (foundation && ctx.getImportCache().isImportedBy(foundation, SF))
908+
return;
909+
910+
if (!ctx.LangOpts.EnableObjCInterop) {
911+
ctx.Diags.diagnose(attr->getLocation(), diag::objc_interop_disabled)
912+
.fixItRemove(attr->getRangeWithAt());
913+
}
914+
915+
ctx.Diags.diagnose(attr->getLocation(),
916+
diag::attr_used_without_required_module, attr,
917+
ctx.Id_Foundation)
918+
.highlight(attr->getRangeWithAt());
919+
}
920+
885921
void AttributeChecker::visitObjCAttr(ObjCAttr *attr) {
886922
// Only certain decls can be ObjC.
887923
Optional<Diag<>> error;
@@ -988,6 +1024,9 @@ void AttributeChecker::visitObjCAttr(ObjCAttr *attr) {
9881024
// Enum elements require names.
9891025
diagnoseAndRemoveAttr(attr, diag::objc_enum_case_req_name);
9901026
}
1027+
1028+
// Diagnose an @objc attribute used without importing Foundation.
1029+
diagnoseObjCAttrWithoutFoundation(attr, D);
9911030
}
9921031

9931032
void AttributeChecker::visitNonObjCAttr(NonObjCAttr *attr) {

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,39 +1699,6 @@ void markAsObjC(ValueDecl *D, ObjCReason reason,
16991699
}
17001700
}
17011701

1702-
void swift::diagnoseAttrsRequiringFoundation(SourceFile &SF) {
1703-
auto &Ctx = SF.getASTContext();
1704-
1705-
bool ImportsFoundationModule = false;
1706-
1707-
if (Ctx.LangOpts.EnableObjCInterop) {
1708-
if (!Ctx.LangOpts.EnableObjCAttrRequiresFoundation)
1709-
return;
1710-
if (SF.Kind == SourceFileKind::SIL)
1711-
return;
1712-
}
1713-
1714-
for (auto import : namelookup::getAllImports(&SF)) {
1715-
if (import.second->getName() == Ctx.Id_Foundation) {
1716-
ImportsFoundationModule = true;
1717-
break;
1718-
}
1719-
}
1720-
1721-
if (ImportsFoundationModule)
1722-
return;
1723-
1724-
for (auto Attr : SF.AttrsRequiringFoundation) {
1725-
if (!Ctx.LangOpts.EnableObjCInterop)
1726-
Ctx.Diags.diagnose(Attr->getLocation(), diag::objc_interop_disabled)
1727-
.fixItRemove(Attr->getRangeWithAt());
1728-
Ctx.Diags.diagnose(Attr->getLocation(),
1729-
diag::attr_used_without_required_module,
1730-
Attr, Ctx.Id_Foundation)
1731-
.highlight(Attr->getRangeWithAt());
1732-
}
1733-
}
1734-
17351702
/// Compute the information used to describe an Objective-C redeclaration.
17361703
std::pair<unsigned, DeclName> swift::getObjCMethodDiagInfo(
17371704
AbstractFunctionDecl *member) {

lib/Sema/TypeChecker.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,6 @@ void swift::performWholeModuleTypeChecking(SourceFile &SF) {
389389
auto &Ctx = SF.getASTContext();
390390
FrontendStatsTracer tracer(Ctx.Stats,
391391
"perform-whole-module-type-checking");
392-
diagnoseAttrsRequiringFoundation(SF);
393392
diagnoseObjCMethodConflicts(SF);
394393
diagnoseObjCUnsatisfiedOptReqConflicts(SF);
395394
diagnoseUnintendedObjCMethodOverrides(SF);

lib/Sema/TypeChecker.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,9 +1410,6 @@ bool isOverrideBasedOnType(const ValueDecl *decl, Type declTy,
14101410
/// could fulfill a protocol requirement for it.
14111411
bool isMemberOperator(FuncDecl *decl, Type type);
14121412

1413-
/// Complain if @objc or dynamic is used without importing Foundation.
1414-
void diagnoseAttrsRequiringFoundation(SourceFile &SF);
1415-
14161413
/// Returns `true` iff `AdditiveArithmetic` derived conformances are enabled.
14171414
bool isAdditiveArithmeticConformanceDerivationEnabled(SourceFile &SF);
14181415

0 commit comments

Comments
 (0)