예제 #1
0
void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx,
                                                      ObjCInterfaceDecl *D) {
  for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end();
       M != MEnd; ++M) {
    ObjCMethodDecl *Method = (*M);
    if (Method->isPropertyAccessor() ||  Method->param_size() != 0)
      continue;
    // Is this method candidate to be a getter?
    QualType GRT = Method->getResultType();
    if (GRT->isVoidType())
      continue;
    Selector GetterSelector = Method->getSelector();
    IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0);
    Selector SetterSelector =
      SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
                                             PP.getSelectorTable(),
                                             getterName);
    if (ObjCMethodDecl *SetterMethod = D->lookupMethod(SetterSelector, true)) {
      // Is this a valid setter, matching the target getter?
      QualType SRT = SetterMethod->getResultType();
      if (!SRT->isVoidType())
        continue;
      const ParmVarDecl *argDecl = *SetterMethod->param_begin();
      QualType ArgType = argDecl->getType();
      if (!Ctx.hasSameType(ArgType, GRT))
          continue;
        edit::Commit commit(*Editor);
        edit::rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit);
        Editor->commit(commit);
      }
  }
}
예제 #2
0
/// ObjCGetTypeForMethodDefinition - Builds the type for a method definition
/// declarator
QualType Sema::ObjCGetTypeForMethodDefinition(DeclPtrTy D) {
  ObjCMethodDecl *MDecl = cast<ObjCMethodDecl>(D.getAs<Decl>());
  QualType T = MDecl->getResultType();
  llvm::SmallVector<QualType, 16> ArgTys;
  
  // Add the first two invisible argument types for self and _cmd.
  if (MDecl->isInstanceMethod()) {
    QualType selfTy = Context.getObjCInterfaceType(MDecl->getClassInterface());
    selfTy = Context.getPointerType(selfTy);
    ArgTys.push_back(selfTy);
  } else
    ArgTys.push_back(Context.getObjCIdType());
  ArgTys.push_back(Context.getObjCSelType());
      
  for (ObjCMethodDecl::param_iterator PI = MDecl->param_begin(),
       E = MDecl->param_end(); PI != E; ++PI) {
    QualType ArgTy = (*PI)->getType();
    assert(!ArgTy.isNull() && "Couldn't parse type?");
    ArgTy = adjustParameterType(ArgTy);
    ArgTys.push_back(ArgTy);
  }
  T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
                              MDecl->isVariadic(), 0);
  return T;
}
예제 #3
0
void
NSErrorChecker::CheckSignature(const ObjCMethodDecl& M, QualType& ResultTy,
                             llvm::SmallVectorImpl<VarDecl*>& ErrorParams) {

  ResultTy = M.getResultType();

  for (ObjCMethodDecl::param_iterator I=M.param_begin(),
       E=M.param_end(); I!=E; ++I)  {

    QualType T = (*I)->getType();

    if (isNSErrorWarning) {
      if (CheckNSErrorArgument(T)) ErrorParams.push_back(*I);
    }
    else if (CheckCFErrorArgument(T))
      ErrorParams.push_back(*I);
  }
}
예제 #4
0
/// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
/// objective C interface.  This is a property reference expression.
ExprResult Sema::
HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
                          Expr *BaseExpr, DeclarationName MemberName,
                          SourceLocation MemberLoc,
                          SourceLocation SuperLoc, QualType SuperType,
                          bool Super) {
  const ObjCInterfaceType *IFaceT = OPT->getInterfaceType();
  ObjCInterfaceDecl *IFace = IFaceT->getDecl();
  IdentifierInfo *Member = MemberName.getAsIdentifierInfo();

  if (IFace->isForwardDecl()) {
    Diag(MemberLoc, diag::err_property_not_found_forward_class)
         << MemberName << QualType(OPT, 0);
    Diag(IFace->getLocation(), diag::note_forward_class);
    return ExprError();
  }
  // Search for a declared property first.
  if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Member)) {
    // Check whether we can reference this property.
    if (DiagnoseUseOfDecl(PD, MemberLoc))
      return ExprError();
    QualType ResTy = PD->getType();
    Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
    ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
    if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc))
      ResTy = Getter->getResultType();

    if (Super)
      return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
                                                     VK_LValue, OK_ObjCProperty,
                                                     MemberLoc, 
                                                     SuperLoc, SuperType));
    else
      return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
                                                     VK_LValue, OK_ObjCProperty,
                                                     MemberLoc, BaseExpr));
  }
  // Check protocols on qualified interfaces.
  for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
       E = OPT->qual_end(); I != E; ++I)
    if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Member)) {
      // Check whether we can reference this property.
      if (DiagnoseUseOfDecl(PD, MemberLoc))
        return ExprError();
      if (Super)
        return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
                                                       VK_LValue,
                                                       OK_ObjCProperty,
                                                       MemberLoc, 
                                                       SuperLoc, SuperType));
      else
        return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
                                                       VK_LValue,
                                                       OK_ObjCProperty,
                                                       MemberLoc,
                                                       BaseExpr));
    }
  // If that failed, look for an "implicit" property by seeing if the nullary
  // selector is implemented.

  // FIXME: The logic for looking up nullary and unary selectors should be
  // shared with the code in ActOnInstanceMessage.

  Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
  ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
  
  // May be founf in property's qualified list.
  if (!Getter)
    Getter = LookupMethodInQualifiedType(Sel, OPT, true);

  // If this reference is in an @implementation, check for 'private' methods.
  if (!Getter)
    Getter = IFace->lookupPrivateMethod(Sel);

  // Look through local category implementations associated with the class.
  if (!Getter)
    Getter = IFace->getCategoryInstanceMethod(Sel);
  if (Getter) {
    // Check if we can reference this property.
    if (DiagnoseUseOfDecl(Getter, MemberLoc))
      return ExprError();
  }
  // If we found a getter then this may be a valid dot-reference, we
  // will look for the matching setter, in case it is needed.
  Selector SetterSel =
    SelectorTable::constructSetterName(PP.getIdentifierTable(),
                                       PP.getSelectorTable(), Member);
  ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
  
  // May be founf in property's qualified list.
  if (!Setter)
    Setter = LookupMethodInQualifiedType(SetterSel, OPT, true);
  
  if (!Setter) {
    // If this reference is in an @implementation, also check for 'private'
    // methods.
    Setter = IFace->lookupPrivateMethod(SetterSel);
  }
  // Look through local category implementations associated with the class.
  if (!Setter)
    Setter = IFace->getCategoryInstanceMethod(SetterSel);
    
  if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
    return ExprError();

  if (Getter || Setter) {
    QualType PType;
    if (Getter)
      PType = Getter->getSendResultType();
    else {
      ParmVarDecl *ArgDecl = *Setter->param_begin();
      PType = ArgDecl->getType();
    }
    
    ExprValueKind VK = VK_LValue;
    ExprObjectKind OK = OK_ObjCProperty;
    if (!getLangOptions().CPlusPlus && !PType.hasQualifiers() &&
        PType->isVoidType())
      VK = VK_RValue, OK = OK_Ordinary;

    if (Super)
      return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
                                                     PType, VK, OK,
                                                     MemberLoc,
                                                     SuperLoc, SuperType));
    else
      return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
                                                     PType, VK, OK,
                                                     MemberLoc, BaseExpr));

  }

  // Attempt to correct for typos in property names.
  LookupResult Res(*this, MemberName, MemberLoc, LookupOrdinaryName);
  if (CorrectTypo(Res, 0, 0, IFace, false, CTC_NoKeywords, OPT) &&
      Res.getAsSingle<ObjCPropertyDecl>()) {
    DeclarationName TypoResult = Res.getLookupName();
    Diag(MemberLoc, diag::err_property_not_found_suggest)
      << MemberName << QualType(OPT, 0) << TypoResult
      << FixItHint::CreateReplacement(MemberLoc, TypoResult.getAsString());
    ObjCPropertyDecl *Property = Res.getAsSingle<ObjCPropertyDecl>();
    Diag(Property->getLocation(), diag::note_previous_decl)
      << Property->getDeclName();
    return HandleExprPropertyRefExpr(OPT, BaseExpr, TypoResult, MemberLoc,
                                     SuperLoc, SuperType, Super);
  }
  ObjCInterfaceDecl *ClassDeclared;
  if (ObjCIvarDecl *Ivar = 
      IFace->lookupInstanceVariable(Member, ClassDeclared)) {
    QualType T = Ivar->getType();
    if (const ObjCObjectPointerType * OBJPT = 
        T->getAsObjCInterfacePointerType()) {
      const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
      if (ObjCInterfaceDecl *IFace = IFaceT->getDecl())
        if (IFace->isForwardDecl()) {
          Diag(MemberLoc, diag::err_property_not_as_forward_class)
          << MemberName << IFace;
          Diag(IFace->getLocation(), diag::note_forward_class);
          return ExprError();
        }
    }
  }
  
  Diag(MemberLoc, diag::err_property_not_found)
    << MemberName << QualType(OPT, 0);
  if (Setter)
    Diag(Setter->getLocation(), diag::note_getter_unavailable)
          << MemberName << BaseExpr->getSourceRange();
  return ExprError();
}