diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 0d921e3c0e8558a914a353406aa6b67b9482c4d0..ce56b946130e4bab0882061d0a542078a1139a55 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -387,24 +387,48 @@ void ObjCInterfaceDecl::addPropertyMethods( llvm::SmallVector &insMethods) { // Find the default getter and if one not found, add one. ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName()); - if (GetterDecl) { - // An instance method with same name as property getter name found. - property->setGetterMethodDecl(GetterDecl); - } - else { + if (!GetterDecl) { // No instance method of same name as property getter name was found. // Declare a getter method and add it to the list of methods // for this class. - QualType resultDeclType = property->getType(); - ObjCMethodDecl* ObjCMethod = - ObjCMethodDecl::Create(Context, property->getLocation(), - property->getLocation(), - property->getGetterName(), resultDeclType, - this, - true, false, true, ObjCMethodDecl::Required); - property->setGetterMethodDecl(ObjCMethod); - insMethods.push_back(ObjCMethod); + GetterDecl = + ObjCMethodDecl::Create(Context, property->getLocation(), + property->getLocation(), + property->getGetterName(), + property->getType(), + this, + true, false, true, ObjCMethodDecl::Required); + insMethods.push_back(GetterDecl); + } + property->setGetterMethodDecl(GetterDecl); + + // Find the default setter and if one not found, add one. + ObjCMethodDecl *SetterDecl = getInstanceMethod(property->getSetterName()); + if (!SetterDecl) { + // No instance method of same name as property setter name was found. + // Declare a setter method and add it to the list of methods + // for this class. + SetterDecl = + ObjCMethodDecl::Create(Context, property->getLocation(), + property->getLocation(), + property->getSetterName(), + property->getType(), + this, + true, false, true, ObjCMethodDecl::Required); + insMethods.push_back(SetterDecl); + + // Invent the arguments for the setter. We don't bother making a + // nice name for the argument. + ParmVarDecl *Argument = ParmVarDecl::Create(Context, + SetterDecl, + SourceLocation(), + property->getIdentifier(), + property->getType(), + VarDecl::None, + 0, 0); + SetterDecl->setMethodParams(&Argument, 1); } + property->setSetterMethodDecl(SetterDecl); } /// addProperties - Insert property declaration AST nodes into diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 5758460412111df4abb54a106eb0748e2f887914..a2f4eb2508ea2844d65a121a7960282abbf3c8c4 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -212,6 +212,23 @@ Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration( return 0; } +/// constructSetterName - Return the setter name for the given +/// identifier, i.e. "set" + Name where the initial character of Name +/// has been capitalized. +static IdentifierInfo *constructSetterName(IdentifierTable &Idents, + const IdentifierInfo *Name) { + unsigned N = Name->getLength(); + char *SelectorName = new char[3 + N]; + memcpy(SelectorName, "set", 3); + memcpy(&SelectorName[3], Name->getName(), N); + SelectorName[3] = toupper(SelectorName[3]); + + IdentifierInfo *Setter = + &Idents.get(SelectorName, &SelectorName[3 + N]); + delete[] SelectorName; + return Setter; +} + /// objc-interface-decl-list: /// empty /// objc-interface-decl-list objc-property-decl [OBJC2] @@ -276,11 +293,12 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, PP.getSelectorTable().getNullarySelector(OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier()); + IdentifierInfo *SetterName = OCDS.getSetterName(); + if (!SetterName) + SetterName = constructSetterName(PP.getIdentifierTable(), + FD.D.getIdentifier()); Selector SetterSel = - PP.getSelectorTable().getNullarySelector(OCDS.getSetterName() - ? OCDS.getSetterName() - // FIXME. This is not right! - : FD.D.getIdentifier()); + PP.getSelectorTable().getUnarySelector(SetterName); DeclTy *Property = Actions.ActOnProperty(CurScope, AtLoc, FD, OCDS, GetterSel, SetterSel,