Redeclare Objective-C property accessors inside the ObjCImplDecl in which they are synthesized.
This patch is motivated by (and factored out from)
https://reviews.llvm.org/D66121 which is a debug info bugfix. Starting
with DWARF 5 all Objective-C methods are nested inside their
containing type, and that patch implements this for synthesized
Objective-C properties.
1. SemaObjCProperty populates a list of synthesized accessors that may
need to inserted into an ObjCImplDecl.
2. SemaDeclObjC::ActOnEnd inserts forward-declarations for all
accessors for which no override was provided into their
ObjCImplDecl. This patch does *not* synthesize AST function
*bodies*. Moving that code from the static analyzer into Sema may
be a good idea though.
3. Places that expect all methods to have bodies have been updated.
I did not update the static analyzer's inliner for synthesized
properties to point back to the property declaration (see
test/Analysis/Inputs/expected-plists/nullability-notes.m.plist), which
I believed to be more bug than a feature.
Differential Revision: https://reviews.llvm.org/D68108
rdar://problem/53782400
diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index 4549506..831f95e 100644
--- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -908,9 +908,9 @@
static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP,
ObjCPropertyDecl *PD,
bool getter) {
- return getter ? !IMP->getInstanceMethod(PD->getGetterName())
- : !IMP->getInstanceMethod(PD->getSetterName());
-
+ auto *OMD = IMP->getInstanceMethod(getter ? PD->getGetterName()
+ : PD->getSetterName());
+ return !OMD || OMD->isSynthesizedAccessorStub();
}
void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
@@ -952,7 +952,7 @@
"id objc_getProperty(id, SEL, long, bool);\n";
}
RewriteObjCMethodDecl(OID->getContainingInterface(),
- PD->getGetterMethodDecl(), Getr);
+ PID->getGetterMethodDecl(), Getr);
Getr += "{ ";
// Synthesize an explicit cast to gain access to the ivar.
// See objc-act.c:objc_synthesize_new_getter() for details.
@@ -960,7 +960,7 @@
// return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
Getr += "typedef ";
const FunctionType *FPRetType = nullptr;
- RewriteTypeIntoString(PD->getGetterMethodDecl()->getReturnType(), Getr,
+ RewriteTypeIntoString(PID->getGetterMethodDecl()->getReturnType(), Getr,
FPRetType);
Getr += " _TYPE";
if (FPRetType) {
@@ -1012,7 +1012,7 @@
}
RewriteObjCMethodDecl(OID->getContainingInterface(),
- PD->getSetterMethodDecl(), Setr);
+ PID->getSetterMethodDecl(), Setr);
Setr += "{ ";
// Synthesize an explicit cast to initialize the ivar.
// See objc-act.c:objc_synthesize_new_setter() for details.
@@ -1346,6 +1346,8 @@
InsertText(CID->getBeginLoc(), "// ");
for (auto *OMD : IMD ? IMD->instance_methods() : CID->instance_methods()) {
+ if (!OMD->getBody())
+ continue;
std::string ResultStr;
RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
SourceLocation LocStart = OMD->getBeginLoc();
@@ -1357,6 +1359,8 @@
}
for (auto *OMD : IMD ? IMD->class_methods() : CID->class_methods()) {
+ if (!OMD->getBody())
+ continue;
std::string ResultStr;
RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
SourceLocation LocStart = OMD->getBeginLoc();
@@ -7031,12 +7035,12 @@
ObjCPropertyDecl *PD = Prop->getPropertyDecl();
if (!PD)
continue;
- if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+ if (ObjCMethodDecl *Getter = Prop->getGetterMethodDecl())
if (mustSynthesizeSetterGetterMethod(IDecl, PD, true /*getter*/))
InstanceMethods.push_back(Getter);
if (PD->isReadOnly())
continue;
- if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+ if (ObjCMethodDecl *Setter = Prop->getSetterMethodDecl())
if (mustSynthesizeSetterGetterMethod(IDecl, PD, false /*setter*/))
InstanceMethods.push_back(Setter);
}
@@ -7281,11 +7285,11 @@
ObjCPropertyDecl *PD = Prop->getPropertyDecl();
if (!PD)
continue;
- if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+ if (ObjCMethodDecl *Getter = Prop->getGetterMethodDecl())
InstanceMethods.push_back(Getter);
if (PD->isReadOnly())
continue;
- if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+ if (ObjCMethodDecl *Setter = Prop->getSetterMethodDecl())
InstanceMethods.push_back(Setter);
}