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 @@ -4836,6 +4836,8 @@ cast(ClassDecl)->addDecl(ObjCMethod); } + ObjCMethod->createImplicitParams(Context, ObjCMethod->getClassInterface()); + if (PrevMethod) { // You can never have two method definitions with the same name. Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl) Index: clang/test/CodeGenObjC/direct-method.m =================================================================== --- clang/test/CodeGenObjC/direct-method.m +++ clang/test/CodeGenObjC/direct-method.m @@ -11,6 +11,7 @@ __attribute__((objc_root_class)) @interface Root +- (int)getInt __attribute__((objc_direct)); @end @implementation Root @@ -173,3 +174,9 @@ // CHECK-LABEL: define hidden void @"\01-[Foo setGetDynamic_setDirect:]"( // CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"( @end + +int useRoot(Root *r) { + // CHEC-LABEL: define i32 @useRoot + // CHECK: %call = call i32 bitcast {{.*}} @"\01-[Root getInt]" + return [r getInt]; +}