Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -292,13 +292,6 @@ } } else if (const auto *OCD = dyn_cast(DC)) { OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')'; - } else if (isa(DC)) { - // We can extract the type of the class from the self pointer. - if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) { - QualType ClassTy = - cast(SelfDecl->getType())->getPointeeType(); - ClassTy.print(OS, PrintingPolicy(LangOptions())); - } } OS << ' ' << OMD->getSelector().getAsString() << ']'; Index: clang/lib/CodeGen/CGObjCMac.cpp =================================================================== --- clang/lib/CodeGen/CGObjCMac.cpp +++ clang/lib/CodeGen/CGObjCMac.cpp @@ -4027,7 +4027,7 @@ 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 @@ 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; } Index: clang/lib/Sema/SemaDeclObjC.cpp =================================================================== --- clang/lib/Sema/SemaDeclObjC.cpp +++ clang/lib/Sema/SemaDeclObjC.cpp @@ -383,9 +383,6 @@ // Create Decl objects for each parameter, entrring them in the scope for // binding to their use. - // Insert the invisible arguments, self and _cmd! - MDecl->createImplicitParams(Context, MDecl->getClassInterface()); - PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope); PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope); @@ -4869,6 +4866,9 @@ } } + // Insert the invisible arguments, self and _cmd! + ObjCMethod->createImplicitParams(Context, ObjCMethod->getClassInterface()); + ActOnDocumentableDecl(ObjCMethod); return ObjCMethod; Index: clang/lib/Serialization/ASTWriterDecl.cpp =================================================================== --- clang/lib/Serialization/ASTWriterDecl.cpp +++ clang/lib/Serialization/ASTWriterDecl.cpp @@ -664,8 +664,7 @@ 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()); Index: clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp =================================================================== --- clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -722,13 +722,6 @@ } else if (const auto *OCD = dyn_cast(DC)) { OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')'; - } else if (isa(DC)) { - // We can extract the type of the class from the self pointer. - if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) { - QualType ClassTy = - cast(SelfDecl->getType())->getPointeeType(); - ClassTy.print(OS, PrintingPolicy(LangOptions())); - } } OS << ' ' << OMD->getSelector().getAsString() << ']'; Index: clang/test/CodeGenObjC/direct-method.m =================================================================== --- clang/test/CodeGenObjC/direct-method.m +++ 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 @@ } @end +// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty]" @interface Foo : Root { id __strong _cause_cxx_destruct; @@ -173,3 +182,11 @@ // 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]; +}