Author: Alex Lorenz Date: 2019-12-06T14:28:28-08:00 New Revision: f3efd6957474bfd3b9b232ac6e4b3608174c3b79
URL: https://github.com/llvm/llvm-project/commit/f3efd6957474bfd3b9b232ac6e4b3608174c3b79 DIFF: https://github.com/llvm/llvm-project/commit/f3efd6957474bfd3b9b232ac6e4b3608174c3b79.diff LOG: [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 Added: Modified: clang/lib/CodeGen/CGDebugInfo.cpp clang/lib/CodeGen/CGObjCMac.cpp clang/lib/Sema/SemaDeclObjC.cpp clang/lib/Serialization/ASTReaderDecl.cpp clang/lib/Serialization/ASTWriterDecl.cpp clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp clang/test/CodeGenObjC/direct-method.m Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 8d6406c02773..7ea3c0850fe2 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -292,13 +292,6 @@ StringRef CGDebugInfo::getObjCMethodName(const ObjCMethodDecl *OMD) { } } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) { OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')'; - } else if (isa<ObjCProtocolDecl>(DC)) { - // We can extract the type of the class from the self pointer. - if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) { - QualType ClassTy = - cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType(); - ClassTy.print(OS, PrintingPolicy(LangOptions())); - } } OS << ' ' << OMD->getSelector().getAsString() << ']'; diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 775e3406da7e..5bd04bc88b75 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -4027,7 +4027,7 @@ llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, llvm::Function * CGObjCCommonMac::GenerateDirectMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD) { - auto I = DirectMethodDefinitions.find(OMD); + auto I = DirectMethodDefinitions.find(OMD->getCanonicalDecl()); if (I != DirectMethodDefinitions.end()) return I->second; @@ -4040,7 +4040,7 @@ CGObjCCommonMac::GenerateDirectMethod(const ObjCMethodDecl *OMD, llvm::Function *Method = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage, Name.str(), &CGM.getModule()); - DirectMethodDefinitions.insert(std::make_pair(OMD, Method)); + DirectMethodDefinitions.insert(std::make_pair(OMD->getCanonicalDecl(), Method)); return Method; } diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index e84dc47a1ee1..70c04571ac67 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -4869,6 +4869,9 @@ Decl *Sema::ActOnMethodDeclaration( } } + // Insert the invisible arguments, self and _cmd! + ObjCMethod->createImplicitParams(Context, ObjCMethod->getClassInterface()); + ActOnDocumentableDecl(ObjCMethod); return ObjCMethod; diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index d989f46c4ab4..8990379069b3 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1017,9 +1017,9 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { // definitions rarely show up in headers. Reader.PendingBodies[MD] = GetCurrentCursorOffset(); HasPendingBody = true; - MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>()); - MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>()); } + MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>()); + MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>()); MD->setInstanceMethod(Record.readInt()); MD->setVariadic(Record.readInt()); MD->setPropertyAccessor(Record.readInt()); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 38eb64e52e4a..eaf2c5458be7 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -664,14 +664,13 @@ void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) { VisitNamedDecl(D); // FIXME: convert to LazyStmtPtr? // Unlike C/C++, method bodies will never be in header files. - bool HasBodyStuff = D->getBody() != nullptr || - D->getSelfDecl() != nullptr || D->getCmdDecl() != nullptr; + bool HasBodyStuff = D->getBody() != nullptr; Record.push_back(HasBodyStuff); if (HasBodyStuff) { Record.AddStmt(D->getBody()); - Record.AddDeclRef(D->getSelfDecl()); - Record.AddDeclRef(D->getCmdDecl()); } + Record.AddDeclRef(D->getSelfDecl()); + Record.AddDeclRef(D->getCmdDecl()); Record.push_back(D->isInstanceMethod()); Record.push_back(D->isVariadic()); Record.push_back(D->isPropertyAccessor()); diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 8236907ea773..fea8100c3b3b 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -722,13 +722,6 @@ std::string AnalysisConsumer::getFunctionName(const Decl *D) { } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) { OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')'; - } else if (isa<ObjCProtocolDecl>(DC)) { - // We can extract the type of the class from the self pointer. - if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) { - QualType ClassTy = - cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType(); - ClassTy.print(OS, PrintingPolicy(LangOptions())); - } } OS << ' ' << OMD->getSelector().getAsString() << ']'; diff --git a/clang/test/CodeGenObjC/direct-method.m b/clang/test/CodeGenObjC/direct-method.m index dd9b670b3e4c..eb5a52eb11a2 100644 --- a/clang/test/CodeGenObjC/direct-method.m +++ b/clang/test/CodeGenObjC/direct-method.m @@ -11,9 +11,17 @@ __attribute__((objc_root_class)) @interface Root +- (int)getInt __attribute__((objc_direct)); +@property(direct, readonly) int intProperty; +@property(direct, readonly) int intProperty2; @end @implementation Root +// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty2]" +- (int)intProperty2 { + return 42; +} + // CHECK-LABEL: define hidden i32 @"\01-[Root getInt]"( - (int)getInt __attribute__((objc_direct)) { // loading parameters @@ -152,6 +160,7 @@ + (struct my_aggregate_struct)classGetAggregate __attribute__((objc_direct)) { } @end +// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty]" @interface Foo : Root { id __strong _cause_cxx_destruct; @@ -173,3 +182,11 @@ @implementation Foo // CHECK-LABEL: define hidden void @"\01-[Foo setGetDynamic_setDirect:]"( // CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"( @end + +int useRoot(Root *r) { + // CHECK-LABEL: define i32 @useRoot + // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root getInt]" + // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty]" + // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty2]" + return [r getInt] + [r intProperty] + [r intProperty2]; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits