mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Rework our handling of "external" definitions created by the Clang importer.
Keep track of external definitions as they are created by broadcasting them through a mutation listener interface. At name binding time, we just cache them. When a type checker is alive, it immediately performs any additional operations necessary on those types (e.g., declaring implicit constructors). This also eliminates some O(N^2) behavior in the type checker as well, because we don't have to walk through all of the module imports to find the external definitions. We just keep a single list in the ASTContext along with our place in the list. Fixes <rdar://problem/13769497>. Swift SVN r5032
This commit is contained in:
@@ -292,97 +292,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Describes an externally-synthesized definition.
|
||||
///
|
||||
/// Externally synthesized definitions are generated when the Clang module
|
||||
/// importer generates a Swift stub definition to provide a better Swift
|
||||
/// interface for a C/Objective-C/C++ construct, such a Swift constructor
|
||||
/// implemented on top of Objective-C alloc/init.
|
||||
class ExternalDefinition {
|
||||
public:
|
||||
/// \brief Describes the stage to which this external definition has been
|
||||
/// processed.
|
||||
///
|
||||
/// External definitions always start in the 'name-bound' stage.
|
||||
enum Stage {
|
||||
/// \brief All names in the definition have been bound.
|
||||
NameBound,
|
||||
/// \brief The definition has been type-checked.
|
||||
TypeChecked,
|
||||
};
|
||||
|
||||
private:
|
||||
llvm::PointerIntPair<Decl *, 2, Stage> Data;
|
||||
|
||||
public:
|
||||
ExternalDefinition(Decl *decl, Stage stage = NameBound) : Data(decl, stage) {}
|
||||
|
||||
Decl *getDecl() const { return Data.getPointer(); }
|
||||
|
||||
Stage getStage() const { return Data.getInt(); }
|
||||
void setStage(Stage stage) { Data.setInt(stage); }
|
||||
};
|
||||
|
||||
/// \brief Represents a Clang module that has been imported into Swift.
|
||||
class ClangModule : public Module {
|
||||
clang::Module *clangModule;
|
||||
|
||||
/// \brief The list of definitions that were synthesized while importing
|
||||
/// from the Clang module.
|
||||
///
|
||||
/// Various external definitions can be synthesized by the Clang module
|
||||
/// importer, such as a constructor in an imported Objective-C class, which
|
||||
/// actually invokes the Objective-C alloc/init or new.
|
||||
///
|
||||
/// FIXME: Make sure this gets freed.
|
||||
std::vector<ExternalDefinition> ExternalDefs;
|
||||
|
||||
/// \brief The list of types that were synthesized while importing from the
|
||||
/// Clang module.
|
||||
llvm::DenseSet<Type> Types;
|
||||
|
||||
public:
|
||||
ClangModule(ASTContext &ctx, Component *comp, clang::Module *clangModule);
|
||||
|
||||
/// \brief Retrieve the underlying Clang module.
|
||||
clang::Module *getClangModule() const { return clangModule; }
|
||||
|
||||
/// \brief Add the given external definition to this module.
|
||||
void addExternalDefinition(Decl *def) {
|
||||
ExternalDefs.push_back(def);
|
||||
}
|
||||
|
||||
/// \brief Add the given type to this module.
|
||||
void addType(Type t) {
|
||||
Types.insert(t);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the list of definitions that were synthesized while
|
||||
/// importing from the Clang module.
|
||||
///
|
||||
/// Various external definitions can be synthesized by the Clang module
|
||||
/// importer, such as a constructor in an imported Objective-C class, which
|
||||
/// actually invokes the Objective-C alloc/init or new.
|
||||
MutableArrayRef<ExternalDefinition> getExternalDefinitions() {
|
||||
return ExternalDefs;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the list of definitions that were synthesized while
|
||||
/// importing from the Clang module.
|
||||
///
|
||||
/// Various external definitions can be synthesized by the Clang module
|
||||
/// importer, such as a constructor in an imported Objective-C class, which
|
||||
/// actually invokes the Objective-C alloc/init or new.
|
||||
ArrayRef<ExternalDefinition> getExternalDefinitions() const {
|
||||
return ExternalDefs;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the list of types that were synthesized while importing
|
||||
/// from the Clang module.
|
||||
llvm::DenseSet<Type> const &getTypes() const {
|
||||
return Types;
|
||||
}
|
||||
|
||||
static bool classof(const DeclContext *DC) {
|
||||
return DC->getContextKind() == DeclContextKind::ClangModule;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user