Skip to content

Commit f3efd69

Browse files
committed
[ObjC] Make sure that the implicit arguments for direct methods have been setup
This commit sets the Self and Imp declarations for ObjC method declarations, in addition to the definitions. It also fixes a bunch of code in clang that had wrong assumptions about when getSelfDecl() would be set: - CGDebugInfo::getObjCMethodName and AnalysisConsumer::getFunctionName would assume that it was set for method declarations part of a protocol, which they never were, and that self would be a Class type, which it isn't as it is id for a protocol. Also use the Canonical Decl to index the set of Direct methods so that when calls and implementations interleave, the same llvm::Function is used and the same symbol name emitted. Radar-Id: rdar://problem/57661767 Patch by: Pierre Habouzit Differential Revision: https://reviews.llvm.org/D71091
1 parent 3b42eb3 commit f3efd69

File tree

7 files changed

+27
-22
lines changed

7 files changed

+27
-22
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -292,13 +292,6 @@ StringRef CGDebugInfo::getObjCMethodName(const ObjCMethodDecl *OMD) {
292292
}
293293
} else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
294294
OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';
295-
} else if (isa<ObjCProtocolDecl>(DC)) {
296-
// We can extract the type of the class from the self pointer.
297-
if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) {
298-
QualType ClassTy =
299-
cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType();
300-
ClassTy.print(OS, PrintingPolicy(LangOptions()));
301-
}
302295
}
303296
OS << ' ' << OMD->getSelector().getAsString() << ']';
304297

clang/lib/CodeGen/CGObjCMac.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4027,7 +4027,7 @@ llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
40274027
llvm::Function *
40284028
CGObjCCommonMac::GenerateDirectMethod(const ObjCMethodDecl *OMD,
40294029
const ObjCContainerDecl *CD) {
4030-
auto I = DirectMethodDefinitions.find(OMD);
4030+
auto I = DirectMethodDefinitions.find(OMD->getCanonicalDecl());
40314031
if (I != DirectMethodDefinitions.end())
40324032
return I->second;
40334033

@@ -4040,7 +4040,7 @@ CGObjCCommonMac::GenerateDirectMethod(const ObjCMethodDecl *OMD,
40404040
llvm::Function *Method =
40414041
llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
40424042
Name.str(), &CGM.getModule());
4043-
DirectMethodDefinitions.insert(std::make_pair(OMD, Method));
4043+
DirectMethodDefinitions.insert(std::make_pair(OMD->getCanonicalDecl(), Method));
40444044

40454045
return Method;
40464046
}

clang/lib/Sema/SemaDeclObjC.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4869,6 +4869,9 @@ Decl *Sema::ActOnMethodDeclaration(
48694869
}
48704870
}
48714871

4872+
// Insert the invisible arguments, self and _cmd!
4873+
ObjCMethod->createImplicitParams(Context, ObjCMethod->getClassInterface());
4874+
48724875
ActOnDocumentableDecl(ObjCMethod);
48734876

48744877
return ObjCMethod;

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,9 +1017,9 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
10171017
// definitions rarely show up in headers.
10181018
Reader.PendingBodies[MD] = GetCurrentCursorOffset();
10191019
HasPendingBody = true;
1020-
MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>());
1021-
MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>());
10221020
}
1021+
MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>());
1022+
MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>());
10231023
MD->setInstanceMethod(Record.readInt());
10241024
MD->setVariadic(Record.readInt());
10251025
MD->setPropertyAccessor(Record.readInt());

clang/lib/Serialization/ASTWriterDecl.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -664,14 +664,13 @@ void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
664664
VisitNamedDecl(D);
665665
// FIXME: convert to LazyStmtPtr?
666666
// Unlike C/C++, method bodies will never be in header files.
667-
bool HasBodyStuff = D->getBody() != nullptr ||
668-
D->getSelfDecl() != nullptr || D->getCmdDecl() != nullptr;
667+
bool HasBodyStuff = D->getBody() != nullptr;
669668
Record.push_back(HasBodyStuff);
670669
if (HasBodyStuff) {
671670
Record.AddStmt(D->getBody());
672-
Record.AddDeclRef(D->getSelfDecl());
673-
Record.AddDeclRef(D->getCmdDecl());
674671
}
672+
Record.AddDeclRef(D->getSelfDecl());
673+
Record.AddDeclRef(D->getCmdDecl());
675674
Record.push_back(D->isInstanceMethod());
676675
Record.push_back(D->isVariadic());
677676
Record.push_back(D->isPropertyAccessor());

clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -722,13 +722,6 @@ std::string AnalysisConsumer::getFunctionName(const Decl *D) {
722722
} else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
723723
OS << OCD->getClassInterface()->getName() << '('
724724
<< OCD->getName() << ')';
725-
} else if (isa<ObjCProtocolDecl>(DC)) {
726-
// We can extract the type of the class from the self pointer.
727-
if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) {
728-
QualType ClassTy =
729-
cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType();
730-
ClassTy.print(OS, PrintingPolicy(LangOptions()));
731-
}
732725
}
733726
OS << ' ' << OMD->getSelector().getAsString() << ']';
734727

clang/test/CodeGenObjC/direct-method.m

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,17 @@
1111

1212
__attribute__((objc_root_class))
1313
@interface Root
14+
- (int)getInt __attribute__((objc_direct));
15+
@property(direct, readonly) int intProperty;
16+
@property(direct, readonly) int intProperty2;
1417
@end
1518

1619
@implementation Root
20+
// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty2]"
21+
- (int)intProperty2 {
22+
return 42;
23+
}
24+
1725
// CHECK-LABEL: define hidden i32 @"\01-[Root getInt]"(
1826
- (int)getInt __attribute__((objc_direct)) {
1927
// loading parameters
@@ -152,6 +160,7 @@ + (struct my_aggregate_struct)classGetAggregate __attribute__((objc_direct)) {
152160
}
153161

154162
@end
163+
// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty]"
155164

156165
@interface Foo : Root {
157166
id __strong _cause_cxx_destruct;
@@ -173,3 +182,11 @@ @implementation Foo
173182
// CHECK-LABEL: define hidden void @"\01-[Foo setGetDynamic_setDirect:]"(
174183
// CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"(
175184
@end
185+
186+
int useRoot(Root *r) {
187+
// CHECK-LABEL: define i32 @useRoot
188+
// CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root getInt]"
189+
// CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty]"
190+
// CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty2]"
191+
return [r getInt] + [r intProperty] + [r intProperty2];
192+
}

0 commit comments

Comments
 (0)