mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Implement debug info for willset/didset, and teach dispatch to be non-virtual
to didset/will set since we don't drop these in the class vtable. Swift SVN r13056
This commit is contained in:
@@ -3095,6 +3095,9 @@ public:
|
|||||||
/// isGetterOrSetter - Determine whether this is a getter or a setter vs.
|
/// isGetterOrSetter - Determine whether this is a getter or a setter vs.
|
||||||
/// a normal function.
|
/// a normal function.
|
||||||
bool isGetterOrSetter() const { return isGetter() || isSetter(); }
|
bool isGetterOrSetter() const { return isGetter() || isSetter(); }
|
||||||
|
bool isDidSetWillSet() const {
|
||||||
|
return getAccessorKind() == IsDidSet || getAccessorKind() == IsWillSet;
|
||||||
|
}
|
||||||
bool isAccessor() const { return getAccessorKind() != NotAccessor; }
|
bool isAccessor() const { return getAccessorKind() != NotAccessor; }
|
||||||
|
|
||||||
/// Creates the implicit 'DynamicSelf' generic parameter.
|
/// Creates the implicit 'DynamicSelf' generic parameter.
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ private:
|
|||||||
void maybeAddMethod(FuncDecl *fn, ResilienceExpansion explosionLevel,
|
void maybeAddMethod(FuncDecl *fn, ResilienceExpansion explosionLevel,
|
||||||
unsigned uncurryLevel) {
|
unsigned uncurryLevel) {
|
||||||
// Ignore getters and setters. This is probably wrong!
|
// Ignore getters and setters. This is probably wrong!
|
||||||
if (fn->isGetterOrSetter())
|
if (fn->isAccessor())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If the method overrides something, we don't need a new entry.
|
// If the method overrides something, we don't need a new entry.
|
||||||
|
|||||||
@@ -1083,7 +1083,7 @@ namespace {
|
|||||||
|
|
||||||
// getters and setters funcdecls will be handled by their parent
|
// getters and setters funcdecls will be handled by their parent
|
||||||
// var/subscript.
|
// var/subscript.
|
||||||
if (method->isGetterOrSetter()) return;
|
if (method->isAccessor()) return;
|
||||||
|
|
||||||
llvm::Constant *entry = emitObjCMethodDescriptor(IGM, method);
|
llvm::Constant *entry = emitObjCMethodDescriptor(IGM, method);
|
||||||
if (!method->isStatic()) {
|
if (!method->isStatic()) {
|
||||||
|
|||||||
@@ -1171,7 +1171,7 @@ irgen::emitObjCSubscriptMethodDescriptors(IRGenModule &IGM,
|
|||||||
|
|
||||||
bool irgen::requiresObjCMethodDescriptor(FuncDecl *method) {
|
bool irgen::requiresObjCMethodDescriptor(FuncDecl *method) {
|
||||||
// Property accessors should be generated alongside the property.
|
// Property accessors should be generated alongside the property.
|
||||||
if (method->isGetterOrSetter())
|
if (method->isAccessor())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// We don't export generic methods or subclasses to IRGen yet.
|
// We don't export generic methods or subclasses to IRGen yet.
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void visitFunc(FuncDecl *func) {
|
void visitFunc(FuncDecl *func) {
|
||||||
if (func->isGetterOrSetter())
|
if (func->isAccessor())
|
||||||
// FIXME: To be implemented.
|
// FIXME: To be implemented.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -366,11 +366,19 @@ llvm::DIFile IRGenDebugInfo::getOrCreateFile(const char *Filename) {
|
|||||||
StringRef IRGenDebugInfo::getName(const FuncDecl &FD) {
|
StringRef IRGenDebugInfo::getName(const FuncDecl &FD) {
|
||||||
// Getters and Setters are anonymous functions, so we forge a name
|
// Getters and Setters are anonymous functions, so we forge a name
|
||||||
// using its parent declaration.
|
// using its parent declaration.
|
||||||
if (FD.isGetterOrSetter())
|
if (FD.isAccessor())
|
||||||
if (ValueDecl *VD = FD.getAccessorStorageDecl()) {
|
if (ValueDecl *VD = FD.getAccessorStorageDecl()) {
|
||||||
|
const char *Kind;
|
||||||
|
switch (FD.getAccessorKind()) {
|
||||||
|
case FuncDecl::NotAccessor: assert(0 && "we know this is an accessor");
|
||||||
|
case FuncDecl::IsGetter: Kind = ".get"; break;
|
||||||
|
case FuncDecl::IsSetter: Kind = ".set"; break;
|
||||||
|
case FuncDecl::IsWillSet: Kind = ".willset"; break;
|
||||||
|
case FuncDecl::IsDidSet: Kind = ".didset"; break;
|
||||||
|
}
|
||||||
|
|
||||||
SmallVector<char, 64> Buf;
|
SmallVector<char, 64> Buf;
|
||||||
StringRef Name = (VD->getName().str() +
|
StringRef Name = (VD->getName().str() +Twine(Kind)).toStringRef(Buf);
|
||||||
Twine(FD.isGetter() ? ".get":".set")).toStringRef(Buf);
|
|
||||||
return BumpAllocatedString(Name);
|
return BumpAllocatedString(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -800,7 +800,10 @@ public:
|
|||||||
// FIXME: Or if it's an ObjC method. Extension methods on classes will
|
// FIXME: Or if it's an ObjC method. Extension methods on classes will
|
||||||
// hopefully become dynamically dispatched too.
|
// hopefully become dynamically dispatched too.
|
||||||
if (auto *fd = dyn_cast<FuncDecl>(e->getDecl())) {
|
if (auto *fd = dyn_cast<FuncDecl>(e->getDecl())) {
|
||||||
if (isa<ClassDecl>(fd->getDeclContext()) || fd->isObjC()) {
|
if (fd->isObjC() ||
|
||||||
|
(isa<ClassDecl>(fd->getDeclContext()) &&
|
||||||
|
// didSet and willSet methods can always be directly dispatched.
|
||||||
|
!fd->isDidSetWillSet())) {
|
||||||
ApplyExpr *thisCallSite = callSites.back();
|
ApplyExpr *thisCallSite = callSites.back();
|
||||||
callSites.pop_back();
|
callSites.pop_back();
|
||||||
setSelfParam(gen.emitRValue(thisCallSite->getArg()), thisCallSite);
|
setSelfParam(gen.emitRValue(thisCallSite->getArg()), thisCallSite);
|
||||||
|
|||||||
Reference in New Issue
Block a user