Skip to content

Remove more usages of DeclChecker::IsFirstPass #15453

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
5 changes: 5 additions & 0 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,11 @@ class ASTContext {
/// nested within it.
void addExternalDecl(Decl *decl);

/// Add a declaration that was synthesized to a per-source file list if
/// if is part of a source file, or the external declarations list if
/// it is part of an imported type context.
void addSynthesizedDecl(Decl *decl);

/// Add a cleanup function to be called when the ASTContext is deallocated.
void addCleanup(std::function<void(void)> cleanup);

Expand Down
8 changes: 8 additions & 0 deletions include/swift/AST/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,14 @@ class SourceFile final : public FileUnit {
/// complete, we diagnose.
llvm::SetVector<const DeclAttribute *> AttrsRequiringFoundation;

/// A set of synthesized declarations that need to be type checked.
llvm::SmallVector<Decl *, 8> SynthesizedDecls;

/// We might perform type checking on the same source file more than once,
/// if its the main file or a REPL instance, so keep track of the last
/// checked synthesized declaration to avoid duplicating work.
unsigned LastCheckedSynthesizedDecl = 0;

/// A mapping from Objective-C selectors to the methods that have
/// those selectors.
llvm::DenseMap<ObjCSelector, llvm::TinyPtrVector<AbstractFunctionDecl *>>
Expand Down
10 changes: 10 additions & 0 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1340,6 +1340,16 @@ void ASTContext::addExternalDecl(Decl *decl) {
ExternalDefinitions.insert(decl);
}

void ASTContext::addSynthesizedDecl(Decl *decl) {
auto *mod = cast<FileUnit>(decl->getDeclContext()->getModuleScopeContext());
if (mod->getKind() == FileUnitKind::ClangModule) {
ExternalDefinitions.insert(decl);
return;
}

cast<SourceFile>(mod)->SynthesizedDecls.push_back(decl);
}

void ASTContext::addCleanup(std::function<void(void)> cleanup) {
Impl.Cleanups.push_back(std::move(cleanup));
}
Expand Down
1 change: 0 additions & 1 deletion lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1661,7 +1661,6 @@ ClangImporter::Implementation::Implementation(ASTContext &ctx,
nameImporter() {}

ClangImporter::Implementation::~Implementation() {
assert(NumCurrentImportingEntities == 0);
#ifndef NDEBUG
SwiftContext.SourceMgr.verifyAllBuffers();
#endif
Expand Down
46 changes: 10 additions & 36 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ makeEnumRawValueConstructor(ClangImporter::Implementation &Impl,
ctorDecl->setBody(body);
ctorDecl->setBodyTypeCheckedIfPresent();

C.addExternalDecl(ctorDecl);
Impl.registerExternalDecl(ctorDecl);

return ctorDecl;
}
Expand Down Expand Up @@ -580,7 +580,7 @@ static AccessorDecl *makeEnumRawValueGetter(ClangImporter::Implementation &Impl,

getterDecl->setBody(body);
getterDecl->setBodyTypeCheckedIfPresent();
C.addExternalDecl(getterDecl);
Impl.registerExternalDecl(getterDecl);
return getterDecl;
}

Expand Down Expand Up @@ -663,7 +663,7 @@ static AccessorDecl *makeStructRawValueGetter(
getterDecl->setBody(body);
getterDecl->setBodyTypeCheckedIfPresent();

C.addExternalDecl(getterDecl);
Impl.registerExternalDecl(getterDecl);
return getterDecl;
}

Expand Down Expand Up @@ -830,7 +830,7 @@ makeIndirectFieldAccessors(ClangImporter::Implementation &Impl,
/*implicit*/ true);
getterDecl->setBody(body);
getterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
C.addExternalDecl(getterDecl);
Impl.registerExternalDecl(getterDecl);
}

// Synthesize the setter body
Expand All @@ -855,7 +855,7 @@ makeIndirectFieldAccessors(ClangImporter::Implementation &Impl,
/*implicit*/ true);
setterDecl->setBody(body);
setterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
C.addExternalDecl(setterDecl);
Impl.registerExternalDecl(setterDecl);
}

return { getterDecl, setterDecl };
Expand Down Expand Up @@ -916,7 +916,7 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl,
/*implicit*/ true);
getterDecl->setBody(body);
getterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
C.addExternalDecl(getterDecl);
Impl.registerExternalDecl(getterDecl);
}

// Synthesize the setter body
Expand Down Expand Up @@ -950,7 +950,7 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl,
/*implicit*/ true);
setterDecl->setBody(body);
setterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
C.addExternalDecl(setterDecl);
Impl.registerExternalDecl(setterDecl);
}

return { getterDecl, setterDecl };
Expand Down Expand Up @@ -7742,36 +7742,12 @@ ClangImporter::Implementation::importDeclImpl(const clang::NamedDecl *ClangDecl,
}

void ClangImporter::Implementation::startedImportingEntity() {
++NumCurrentImportingEntities;
++NumTotalImportedEntities;
// FIXME: (transitional) increment the redundant "always-on" counter.
if (SwiftContext.Stats)
SwiftContext.Stats->getFrontendCounters().NumTotalClangImportedEntities++;
}

void ClangImporter::Implementation::finishedImportingEntity() {
assert(NumCurrentImportingEntities &&
"finishedImportingEntity not paired with startedImportingEntity");
if (NumCurrentImportingEntities == 1) {
// We decrease NumCurrentImportingEntities only after pending actions
// are finished, to avoid recursively re-calling finishPendingActions().
finishPendingActions();
}
--NumCurrentImportingEntities;
}

void ClangImporter::Implementation::finishPendingActions() {
if (RegisteredExternalDecls.empty())
return;

if (!hasFinishedTypeChecking()) {
for (auto *D : RegisteredExternalDecls)
SwiftContext.addExternalDecl(D);
}

RegisteredExternalDecls.clear();
}

/// Look up associated type requirements in the conforming type.
static void finishTypeWitnesses(
NormalProtocolConformance *conformance) {
Expand Down Expand Up @@ -7982,7 +7958,7 @@ Decl *ClangImporter::Implementation::importDeclAndCacheImpl(
bool TypedefIsSuperfluous = false;
bool HadForwardDeclaration = false;

ImportingEntityRAII ImportingEntity(*this);
startedImportingEntity();
Decl *Result = importDeclImpl(ClangDecl, version, TypedefIsSuperfluous,
HadForwardDeclaration);
if (!Result)
Expand Down Expand Up @@ -8479,7 +8455,7 @@ void ClangImporter::Implementation::loadAllMembersIntoExtension(
return;

// Get ready to actually load the members.
ImportingEntityRAII Importing(*this);
startedImportingEntity();

// Load the members.
for (auto entry : table->lookupGlobalsAsMembers(effectiveClangContext)) {
Expand Down Expand Up @@ -8579,13 +8555,11 @@ void ClangImporter::Implementation::loadAllMembersOfObjcContainer(
loadMembersOfBaseImportedFromClang(ext);
}

ImportingEntityRAII Importing(*this);
startedImportingEntity();

SmallVector<Decl *, 16> members;
collectMembersToAdd(objcContainer, D, DC, members);

// Add the members now, before ~ImportingEntityRAII does work that might
// involve them.
for (auto member : members) {
IDC->addMember(member);
}
Expand Down
3 changes: 2 additions & 1 deletion lib/ClangImporter/ImportMacro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,8 @@ ValueDecl *ClangImporter::Implementation::importMacro(Identifier name,
known->second.push_back({macro, nullptr});
}

ImportingEntityRAII ImportingEntity(*this);
startedImportingEntity();

// We haven't tried to import this macro yet. Do so now, and cache the
// result.

Expand Down
21 changes: 2 additions & 19 deletions lib/ClangImporter/ImporterImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -557,11 +557,6 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
/// Records those modules that we have looked up.
llvm::DenseMap<Identifier, ModuleDecl *> checkedModules;

/// External Decls that we have imported but not passed to the ASTContext yet.
SmallVector<Decl *, 4> RegisteredExternalDecls;

unsigned NumCurrentImportingEntities = 0;

/// Mapping from delayed conformance IDs to the set of delayed
/// protocol conformances.
llvm::DenseMap<unsigned, SmallVector<ProtocolConformance *, 4>>
Expand All @@ -576,19 +571,6 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
ImportedProtocols;

void startedImportingEntity();
void finishedImportingEntity();
void finishPendingActions();

struct ImportingEntityRAII {
Implementation &Impl;

ImportingEntityRAII(Implementation &Impl) : Impl(Impl) {
Impl.startedImportingEntity();
}
~ImportingEntityRAII() {
Impl.finishedImportingEntity();
}
};

public:
importer::PlatformAvailability platformAvailability;
Expand Down Expand Up @@ -624,7 +606,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation

public:
void registerExternalDecl(Decl *D) {
RegisteredExternalDecls.push_back(D);
if (!hasFinishedTypeChecking())
SwiftContext.addExternalDecl(D);
}

void recordImplicitUnwrapForDecl(Decl *decl, bool isIUO) {
Expand Down
26 changes: 4 additions & 22 deletions lib/Sema/CodeSynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,6 @@ static bool needsDynamicMaterializeForSet(AbstractStorageDecl *storage) {
return storage->isDynamic() || storage->hasClangNode();
}

// True if a generated accessor needs to be registered as an external decl.
bool needsToBeRegisteredAsExternalDecl(AbstractStorageDecl *storage) {
// Either the storage itself was imported from Clang...
if (storage->hasClangNode())
return true;

// ...or it was synthesized into an imported context.
const DeclContext *dc = storage->getDeclContext();
return isa<ClangModuleUnit>(dc->getModuleScopeContext());
}

/// Mark the accessor as transparent if we can.
///
/// If the storage is inside a fixed-layout nominal type, we can mark the
Expand Down Expand Up @@ -396,12 +385,9 @@ createMaterializeForSetPrototype(AbstractStorageDecl *storage,
maybeMarkTransparent(materializeForSet, storage, TC);

AvailabilityInference::applyInferredAvailableAttrs(materializeForSet,
asAvailableAs, ctx);
asAvailableAs, ctx);

// If the property came from ObjC, we need to register this as an external
// definition to be compiled.
if (needsToBeRegisteredAsExternalDecl(storage))
TC.Context.addExternalDecl(materializeForSet);
TC.Context.addSynthesizedDecl(materializeForSet);
TC.DeclsToFinalize.insert(materializeForSet);

return materializeForSet;
Expand Down Expand Up @@ -734,9 +720,7 @@ static void synthesizeTrivialGetter(AccessorDecl *getter,
SourceLoc loc = storage->getLoc();
getter->setBody(BraceStmt::create(ctx, loc, returnStmt, loc, true));

// Register the accessor as an external decl if the storage was imported.
if (needsToBeRegisteredAsExternalDecl(storage))
TC.Context.addExternalDecl(getter);
TC.Context.addSynthesizedDecl(getter);
TC.DeclsToFinalize.insert(getter);
}

Expand All @@ -754,9 +738,7 @@ static void synthesizeTrivialSetter(AccessorDecl *setter,
setterBody, TC);
setter->setBody(BraceStmt::create(ctx, loc, setterBody, loc, true));

// Register the accessor as an external decl if the storage was imported.
if (needsToBeRegisteredAsExternalDecl(storage))
TC.Context.addExternalDecl(setter);
TC.Context.addSynthesizedDecl(setter);
TC.DeclsToFinalize.insert(setter);
}

Expand Down
12 changes: 2 additions & 10 deletions lib/Sema/DerivedConformanceCodable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,11 +769,7 @@ static FuncDecl *deriveEncodable_encode(TypeChecker &tc, Decl *parentDecl,
encodeDecl->setValidationStarted();
encodeDecl->setAccess(target->getFormalAccess());

// If the type was not imported, the derived conformance is either from the
// type itself or an extension, in which case we will emit the declaration
// normally.
if (target->hasClangNode())
tc.Context.addExternalDecl(encodeDecl);
tc.Context.addSynthesizedDecl(encodeDecl);

target->addMember(encodeDecl);
return encodeDecl;
Expand Down Expand Up @@ -1112,11 +1108,7 @@ static ValueDecl *deriveDecodable_init(TypeChecker &tc, Decl *parentDecl,
initDecl->setInitializerInterfaceType(initializerType);
initDecl->setAccess(target->getFormalAccess());

// If the type was not imported, the derived conformance is either from the
// type itself or an extension, in which case we will emit the declaration
// normally.
if (target->hasClangNode())
tc.Context.addExternalDecl(initDecl);
tc.Context.addSynthesizedDecl(initDecl);

target->addMember(initDecl);
return initDecl;
Expand Down
6 changes: 1 addition & 5 deletions lib/Sema/DerivedConformanceCodingKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,7 @@ static ValueDecl *deriveInitDecl(TypeChecker &tc, Decl *parentDecl,
initDecl->setAccess(enumDecl->getFormalAccess());
initDecl->setValidationStarted();

// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration
// normally.
if (enumDecl->hasClangNode())
tc.Context.addExternalDecl(initDecl);
tc.Context.addSynthesizedDecl(initDecl);

cast<IterableDeclContext>(parentDecl)->addMember(initDecl);
return initDecl;
Expand Down
15 changes: 4 additions & 11 deletions lib/Sema/DerivedConformanceEquatableHashable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,11 +661,7 @@ deriveEquatable_eq(TypeChecker &tc, Decl *parentDecl, NominalTypeDecl *typeDecl,
eqDecl->copyFormalAccessFrom(typeDecl);
eqDecl->setValidationStarted();

// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration
// normally.
if (typeDecl->hasClangNode())
tc.Context.addExternalDecl(eqDecl);
tc.Context.addSynthesizedDecl(eqDecl);

// Add the operator to the parent scope.
cast<IterableDeclContext>(parentDecl)->addMember(eqDecl);
Expand Down Expand Up @@ -1054,12 +1050,6 @@ deriveHashable_hashValue(TypeChecker &tc, Decl *parentDecl,
getterDecl->setValidationStarted();
getterDecl->copyFormalAccessFrom(typeDecl);

// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration
// normally.
if (typeDecl->hasClangNode())
tc.Context.addExternalDecl(getterDecl);

// Finish creating the property.
hashValueDecl->setImplicit();
hashValueDecl->setInterfaceType(intType);
Expand All @@ -1081,6 +1071,9 @@ deriveHashable_hashValue(TypeChecker &tc, Decl *parentDecl,
parentDC);
patDecl->setImplicit();

tc.Context.addSynthesizedDecl(hashValueDecl);
tc.Context.addSynthesizedDecl(getterDecl);

auto dc = cast<IterableDeclContext>(parentDecl);
dc->addMember(getterDecl);
dc->addMember(hashValueDecl);
Expand Down
6 changes: 1 addition & 5 deletions lib/Sema/DerivedConformanceRawRepresentable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,7 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
initDecl->copyFormalAccessFrom(enumDecl);
initDecl->setValidationStarted();

// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration
// normally.
if (enumDecl->hasClangNode())
tc.Context.addExternalDecl(initDecl);
tc.Context.addSynthesizedDecl(initDecl);

cast<IterableDeclContext>(parentDecl)->addMember(initDecl);
return initDecl;
Expand Down
Loading