Commit f3efd695 authored by Alex Lorenz's avatar Alex Lorenz
Browse files

[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
parent 3b42eb35
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -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() << ']';

+2 −2
Original line number Diff line number Diff line
@@ -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;
}
+3 −0
Original line number Diff line number Diff line
@@ -4869,6 +4869,9 @@ Decl *Sema::ActOnMethodDeclaration(
    }
  }

  // Insert the invisible arguments, self and _cmd!
  ObjCMethod->createImplicitParams(Context, ObjCMethod->getClassInterface());

  ActOnDocumentableDecl(ObjCMethod);

  return ObjCMethod;
+2 −2
Original line number Diff line number Diff line
@@ -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->setInstanceMethod(Record.readInt());
  MD->setVariadic(Record.readInt());
  MD->setPropertyAccessor(Record.readInt());
+3 −4
Original line number Diff line number Diff line
@@ -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.push_back(D->isInstanceMethod());
  Record.push_back(D->isVariadic());
  Record.push_back(D->isPropertyAccessor());
Loading