SemaObjCProperty.cpp 113 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718
  1. //===--- SemaObjCProperty.cpp - Semantic Analysis for ObjC @property ------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements semantic analysis for Objective C @property and
  10. // @synthesize declarations.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/Sema/SemaInternal.h"
  14. #include "clang/AST/ASTMutationListener.h"
  15. #include "clang/AST/DeclObjC.h"
  16. #include "clang/AST/ExprCXX.h"
  17. #include "clang/AST/ExprObjC.h"
  18. #include "clang/Basic/SourceManager.h"
  19. #include "clang/Lex/Lexer.h"
  20. #include "clang/Lex/Preprocessor.h"
  21. #include "clang/Sema/Initialization.h"
  22. #include "llvm/ADT/DenseSet.h"
  23. #include "llvm/ADT/SmallString.h"
  24. using namespace clang;
  25. //===----------------------------------------------------------------------===//
  26. // Grammar actions.
  27. //===----------------------------------------------------------------------===//
  28. /// getImpliedARCOwnership - Given a set of property attributes and a
  29. /// type, infer an expected lifetime. The type's ownership qualification
  30. /// is not considered.
  31. ///
  32. /// Returns OCL_None if the attributes as stated do not imply an ownership.
  33. /// Never returns OCL_Autoreleasing.
  34. static Qualifiers::ObjCLifetime getImpliedARCOwnership(
  35. ObjCPropertyDecl::PropertyAttributeKind attrs,
  36. QualType type) {
  37. // retain, strong, copy, weak, and unsafe_unretained are only legal
  38. // on properties of retainable pointer type.
  39. if (attrs & (ObjCPropertyDecl::OBJC_PR_retain |
  40. ObjCPropertyDecl::OBJC_PR_strong |
  41. ObjCPropertyDecl::OBJC_PR_copy)) {
  42. return Qualifiers::OCL_Strong;
  43. } else if (attrs & ObjCPropertyDecl::OBJC_PR_weak) {
  44. return Qualifiers::OCL_Weak;
  45. } else if (attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) {
  46. return Qualifiers::OCL_ExplicitNone;
  47. }
  48. // assign can appear on other types, so we have to check the
  49. // property type.
  50. if (attrs & ObjCPropertyDecl::OBJC_PR_assign &&
  51. type->isObjCRetainableType()) {
  52. return Qualifiers::OCL_ExplicitNone;
  53. }
  54. return Qualifiers::OCL_None;
  55. }
  56. /// Check the internal consistency of a property declaration with
  57. /// an explicit ownership qualifier.
  58. static void checkPropertyDeclWithOwnership(Sema &S,
  59. ObjCPropertyDecl *property) {
  60. if (property->isInvalidDecl()) return;
  61. ObjCPropertyDecl::PropertyAttributeKind propertyKind
  62. = property->getPropertyAttributes();
  63. Qualifiers::ObjCLifetime propertyLifetime
  64. = property->getType().getObjCLifetime();
  65. assert(propertyLifetime != Qualifiers::OCL_None);
  66. Qualifiers::ObjCLifetime expectedLifetime
  67. = getImpliedARCOwnership(propertyKind, property->getType());
  68. if (!expectedLifetime) {
  69. // We have a lifetime qualifier but no dominating property
  70. // attribute. That's okay, but restore reasonable invariants by
  71. // setting the property attribute according to the lifetime
  72. // qualifier.
  73. ObjCPropertyDecl::PropertyAttributeKind attr;
  74. if (propertyLifetime == Qualifiers::OCL_Strong) {
  75. attr = ObjCPropertyDecl::OBJC_PR_strong;
  76. } else if (propertyLifetime == Qualifiers::OCL_Weak) {
  77. attr = ObjCPropertyDecl::OBJC_PR_weak;
  78. } else {
  79. assert(propertyLifetime == Qualifiers::OCL_ExplicitNone);
  80. attr = ObjCPropertyDecl::OBJC_PR_unsafe_unretained;
  81. }
  82. property->setPropertyAttributes(attr);
  83. return;
  84. }
  85. if (propertyLifetime == expectedLifetime) return;
  86. property->setInvalidDecl();
  87. S.Diag(property->getLocation(),
  88. diag::err_arc_inconsistent_property_ownership)
  89. << property->getDeclName()
  90. << expectedLifetime
  91. << propertyLifetime;
  92. }
  93. /// Check this Objective-C property against a property declared in the
  94. /// given protocol.
  95. static void
  96. CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop,
  97. ObjCProtocolDecl *Proto,
  98. llvm::SmallPtrSetImpl<ObjCProtocolDecl *> &Known) {
  99. // Have we seen this protocol before?
  100. if (!Known.insert(Proto).second)
  101. return;
  102. // Look for a property with the same name.
  103. DeclContext::lookup_result R = Proto->lookup(Prop->getDeclName());
  104. for (unsigned I = 0, N = R.size(); I != N; ++I) {
  105. if (ObjCPropertyDecl *ProtoProp = dyn_cast<ObjCPropertyDecl>(R[I])) {
  106. S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true);
  107. return;
  108. }
  109. }
  110. // Check this property against any protocols we inherit.
  111. for (auto *P : Proto->protocols())
  112. CheckPropertyAgainstProtocol(S, Prop, P, Known);
  113. }
  114. static unsigned deducePropertyOwnershipFromType(Sema &S, QualType T) {
  115. // In GC mode, just look for the __weak qualifier.
  116. if (S.getLangOpts().getGC() != LangOptions::NonGC) {
  117. if (T.isObjCGCWeak()) return ObjCDeclSpec::DQ_PR_weak;
  118. // In ARC/MRC, look for an explicit ownership qualifier.
  119. // For some reason, this only applies to __weak.
  120. } else if (auto ownership = T.getObjCLifetime()) {
  121. switch (ownership) {
  122. case Qualifiers::OCL_Weak:
  123. return ObjCDeclSpec::DQ_PR_weak;
  124. case Qualifiers::OCL_Strong:
  125. return ObjCDeclSpec::DQ_PR_strong;
  126. case Qualifiers::OCL_ExplicitNone:
  127. return ObjCDeclSpec::DQ_PR_unsafe_unretained;
  128. case Qualifiers::OCL_Autoreleasing:
  129. case Qualifiers::OCL_None:
  130. return 0;
  131. }
  132. llvm_unreachable("bad qualifier");
  133. }
  134. return 0;
  135. }
  136. static const unsigned OwnershipMask =
  137. (ObjCPropertyDecl::OBJC_PR_assign |
  138. ObjCPropertyDecl::OBJC_PR_retain |
  139. ObjCPropertyDecl::OBJC_PR_copy |
  140. ObjCPropertyDecl::OBJC_PR_weak |
  141. ObjCPropertyDecl::OBJC_PR_strong |
  142. ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
  143. static unsigned getOwnershipRule(unsigned attr) {
  144. unsigned result = attr & OwnershipMask;
  145. // From an ownership perspective, assign and unsafe_unretained are
  146. // identical; make sure one also implies the other.
  147. if (result & (ObjCPropertyDecl::OBJC_PR_assign |
  148. ObjCPropertyDecl::OBJC_PR_unsafe_unretained)) {
  149. result |= ObjCPropertyDecl::OBJC_PR_assign |
  150. ObjCPropertyDecl::OBJC_PR_unsafe_unretained;
  151. }
  152. return result;
  153. }
  154. Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
  155. SourceLocation LParenLoc,
  156. FieldDeclarator &FD,
  157. ObjCDeclSpec &ODS,
  158. Selector GetterSel,
  159. Selector SetterSel,
  160. tok::ObjCKeywordKind MethodImplKind,
  161. DeclContext *lexicalDC) {
  162. unsigned Attributes = ODS.getPropertyAttributes();
  163. FD.D.setObjCWeakProperty((Attributes & ObjCDeclSpec::DQ_PR_weak) != 0);
  164. TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S);
  165. QualType T = TSI->getType();
  166. if (!getOwnershipRule(Attributes)) {
  167. Attributes |= deducePropertyOwnershipFromType(*this, T);
  168. }
  169. bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
  170. // default is readwrite!
  171. !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
  172. // Proceed with constructing the ObjCPropertyDecls.
  173. ObjCContainerDecl *ClassDecl = cast<ObjCContainerDecl>(CurContext);
  174. ObjCPropertyDecl *Res = nullptr;
  175. if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
  176. if (CDecl->IsClassExtension()) {
  177. Res = HandlePropertyInClassExtension(S, AtLoc, LParenLoc,
  178. FD,
  179. GetterSel, ODS.getGetterNameLoc(),
  180. SetterSel, ODS.getSetterNameLoc(),
  181. isReadWrite, Attributes,
  182. ODS.getPropertyAttributes(),
  183. T, TSI, MethodImplKind);
  184. if (!Res)
  185. return nullptr;
  186. }
  187. }
  188. if (!Res) {
  189. Res = CreatePropertyDecl(S, ClassDecl, AtLoc, LParenLoc, FD,
  190. GetterSel, ODS.getGetterNameLoc(), SetterSel,
  191. ODS.getSetterNameLoc(), isReadWrite, Attributes,
  192. ODS.getPropertyAttributes(), T, TSI,
  193. MethodImplKind);
  194. if (lexicalDC)
  195. Res->setLexicalDeclContext(lexicalDC);
  196. }
  197. // Validate the attributes on the @property.
  198. CheckObjCPropertyAttributes(Res, AtLoc, Attributes,
  199. (isa<ObjCInterfaceDecl>(ClassDecl) ||
  200. isa<ObjCProtocolDecl>(ClassDecl)));
  201. // Check consistency if the type has explicit ownership qualification.
  202. if (Res->getType().getObjCLifetime())
  203. checkPropertyDeclWithOwnership(*this, Res);
  204. llvm::SmallPtrSet<ObjCProtocolDecl *, 16> KnownProtos;
  205. if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
  206. // For a class, compare the property against a property in our superclass.
  207. bool FoundInSuper = false;
  208. ObjCInterfaceDecl *CurrentInterfaceDecl = IFace;
  209. while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) {
  210. DeclContext::lookup_result R = Super->lookup(Res->getDeclName());
  211. for (unsigned I = 0, N = R.size(); I != N; ++I) {
  212. if (ObjCPropertyDecl *SuperProp = dyn_cast<ObjCPropertyDecl>(R[I])) {
  213. DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false);
  214. FoundInSuper = true;
  215. break;
  216. }
  217. }
  218. if (FoundInSuper)
  219. break;
  220. else
  221. CurrentInterfaceDecl = Super;
  222. }
  223. if (FoundInSuper) {
  224. // Also compare the property against a property in our protocols.
  225. for (auto *P : CurrentInterfaceDecl->protocols()) {
  226. CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
  227. }
  228. } else {
  229. // Slower path: look in all protocols we referenced.
  230. for (auto *P : IFace->all_referenced_protocols()) {
  231. CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
  232. }
  233. }
  234. } else if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
  235. // We don't check if class extension. Because properties in class extension
  236. // are meant to override some of the attributes and checking has already done
  237. // when property in class extension is constructed.
  238. if (!Cat->IsClassExtension())
  239. for (auto *P : Cat->protocols())
  240. CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
  241. } else {
  242. ObjCProtocolDecl *Proto = cast<ObjCProtocolDecl>(ClassDecl);
  243. for (auto *P : Proto->protocols())
  244. CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
  245. }
  246. ActOnDocumentableDecl(Res);
  247. return Res;
  248. }
  249. static ObjCPropertyDecl::PropertyAttributeKind
  250. makePropertyAttributesAsWritten(unsigned Attributes) {
  251. unsigned attributesAsWritten = 0;
  252. if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
  253. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readonly;
  254. if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
  255. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readwrite;
  256. if (Attributes & ObjCDeclSpec::DQ_PR_getter)
  257. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_getter;
  258. if (Attributes & ObjCDeclSpec::DQ_PR_setter)
  259. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_setter;
  260. if (Attributes & ObjCDeclSpec::DQ_PR_assign)
  261. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_assign;
  262. if (Attributes & ObjCDeclSpec::DQ_PR_retain)
  263. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_retain;
  264. if (Attributes & ObjCDeclSpec::DQ_PR_strong)
  265. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_strong;
  266. if (Attributes & ObjCDeclSpec::DQ_PR_weak)
  267. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_weak;
  268. if (Attributes & ObjCDeclSpec::DQ_PR_copy)
  269. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_copy;
  270. if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
  271. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_unsafe_unretained;
  272. if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
  273. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_nonatomic;
  274. if (Attributes & ObjCDeclSpec::DQ_PR_atomic)
  275. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_atomic;
  276. if (Attributes & ObjCDeclSpec::DQ_PR_class)
  277. attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_class;
  278. return (ObjCPropertyDecl::PropertyAttributeKind)attributesAsWritten;
  279. }
  280. static bool LocPropertyAttribute( ASTContext &Context, const char *attrName,
  281. SourceLocation LParenLoc, SourceLocation &Loc) {
  282. if (LParenLoc.isMacroID())
  283. return false;
  284. SourceManager &SM = Context.getSourceManager();
  285. std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(LParenLoc);
  286. // Try to load the file buffer.
  287. bool invalidTemp = false;
  288. StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
  289. if (invalidTemp)
  290. return false;
  291. const char *tokenBegin = file.data() + locInfo.second;
  292. // Lex from the start of the given location.
  293. Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
  294. Context.getLangOpts(),
  295. file.begin(), tokenBegin, file.end());
  296. Token Tok;
  297. do {
  298. lexer.LexFromRawLexer(Tok);
  299. if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == attrName) {
  300. Loc = Tok.getLocation();
  301. return true;
  302. }
  303. } while (Tok.isNot(tok::r_paren));
  304. return false;
  305. }
  306. /// Check for a mismatch in the atomicity of the given properties.
  307. static void checkAtomicPropertyMismatch(Sema &S,
  308. ObjCPropertyDecl *OldProperty,
  309. ObjCPropertyDecl *NewProperty,
  310. bool PropagateAtomicity) {
  311. // If the atomicity of both matches, we're done.
  312. bool OldIsAtomic =
  313. (OldProperty->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic)
  314. == 0;
  315. bool NewIsAtomic =
  316. (NewProperty->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic)
  317. == 0;
  318. if (OldIsAtomic == NewIsAtomic) return;
  319. // Determine whether the given property is readonly and implicitly
  320. // atomic.
  321. auto isImplicitlyReadonlyAtomic = [](ObjCPropertyDecl *Property) -> bool {
  322. // Is it readonly?
  323. auto Attrs = Property->getPropertyAttributes();
  324. if ((Attrs & ObjCPropertyDecl::OBJC_PR_readonly) == 0) return false;
  325. // Is it nonatomic?
  326. if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) return false;
  327. // Was 'atomic' specified directly?
  328. if (Property->getPropertyAttributesAsWritten() &
  329. ObjCPropertyDecl::OBJC_PR_atomic)
  330. return false;
  331. return true;
  332. };
  333. // If we're allowed to propagate atomicity, and the new property did
  334. // not specify atomicity at all, propagate.
  335. const unsigned AtomicityMask =
  336. (ObjCPropertyDecl::OBJC_PR_atomic | ObjCPropertyDecl::OBJC_PR_nonatomic);
  337. if (PropagateAtomicity &&
  338. ((NewProperty->getPropertyAttributesAsWritten() & AtomicityMask) == 0)) {
  339. unsigned Attrs = NewProperty->getPropertyAttributes();
  340. Attrs = Attrs & ~AtomicityMask;
  341. if (OldIsAtomic)
  342. Attrs |= ObjCPropertyDecl::OBJC_PR_atomic;
  343. else
  344. Attrs |= ObjCPropertyDecl::OBJC_PR_nonatomic;
  345. NewProperty->overwritePropertyAttributes(Attrs);
  346. return;
  347. }
  348. // One of the properties is atomic; if it's a readonly property, and
  349. // 'atomic' wasn't explicitly specified, we're okay.
  350. if ((OldIsAtomic && isImplicitlyReadonlyAtomic(OldProperty)) ||
  351. (NewIsAtomic && isImplicitlyReadonlyAtomic(NewProperty)))
  352. return;
  353. // Diagnose the conflict.
  354. const IdentifierInfo *OldContextName;
  355. auto *OldDC = OldProperty->getDeclContext();
  356. if (auto Category = dyn_cast<ObjCCategoryDecl>(OldDC))
  357. OldContextName = Category->getClassInterface()->getIdentifier();
  358. else
  359. OldContextName = cast<ObjCContainerDecl>(OldDC)->getIdentifier();
  360. S.Diag(NewProperty->getLocation(), diag::warn_property_attribute)
  361. << NewProperty->getDeclName() << "atomic"
  362. << OldContextName;
  363. S.Diag(OldProperty->getLocation(), diag::note_property_declare);
  364. }
  365. ObjCPropertyDecl *
  366. Sema::HandlePropertyInClassExtension(Scope *S,
  367. SourceLocation AtLoc,
  368. SourceLocation LParenLoc,
  369. FieldDeclarator &FD,
  370. Selector GetterSel,
  371. SourceLocation GetterNameLoc,
  372. Selector SetterSel,
  373. SourceLocation SetterNameLoc,
  374. const bool isReadWrite,
  375. unsigned &Attributes,
  376. const unsigned AttributesAsWritten,
  377. QualType T,
  378. TypeSourceInfo *TSI,
  379. tok::ObjCKeywordKind MethodImplKind) {
  380. ObjCCategoryDecl *CDecl = cast<ObjCCategoryDecl>(CurContext);
  381. // Diagnose if this property is already in continuation class.
  382. DeclContext *DC = CurContext;
  383. IdentifierInfo *PropertyId = FD.D.getIdentifier();
  384. ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface();
  385. // We need to look in the @interface to see if the @property was
  386. // already declared.
  387. if (!CCPrimary) {
  388. Diag(CDecl->getLocation(), diag::err_continuation_class);
  389. return nullptr;
  390. }
  391. bool isClassProperty = (AttributesAsWritten & ObjCDeclSpec::DQ_PR_class) ||
  392. (Attributes & ObjCDeclSpec::DQ_PR_class);
  393. // Find the property in the extended class's primary class or
  394. // extensions.
  395. ObjCPropertyDecl *PIDecl = CCPrimary->FindPropertyVisibleInPrimaryClass(
  396. PropertyId, ObjCPropertyDecl::getQueryKind(isClassProperty));
  397. // If we found a property in an extension, complain.
  398. if (PIDecl && isa<ObjCCategoryDecl>(PIDecl->getDeclContext())) {
  399. Diag(AtLoc, diag::err_duplicate_property);
  400. Diag(PIDecl->getLocation(), diag::note_property_declare);
  401. return nullptr;
  402. }
  403. // Check for consistency with the previous declaration, if there is one.
  404. if (PIDecl) {
  405. // A readonly property declared in the primary class can be refined
  406. // by adding a readwrite property within an extension.
  407. // Anything else is an error.
  408. if (!(PIDecl->isReadOnly() && isReadWrite)) {
  409. // Tailor the diagnostics for the common case where a readwrite
  410. // property is declared both in the @interface and the continuation.
  411. // This is a common error where the user often intended the original
  412. // declaration to be readonly.
  413. unsigned diag =
  414. (Attributes & ObjCDeclSpec::DQ_PR_readwrite) &&
  415. (PIDecl->getPropertyAttributesAsWritten() &
  416. ObjCPropertyDecl::OBJC_PR_readwrite)
  417. ? diag::err_use_continuation_class_redeclaration_readwrite
  418. : diag::err_use_continuation_class;
  419. Diag(AtLoc, diag)
  420. << CCPrimary->getDeclName();
  421. Diag(PIDecl->getLocation(), diag::note_property_declare);
  422. return nullptr;
  423. }
  424. // Check for consistency of getters.
  425. if (PIDecl->getGetterName() != GetterSel) {
  426. // If the getter was written explicitly, complain.
  427. if (AttributesAsWritten & ObjCDeclSpec::DQ_PR_getter) {
  428. Diag(AtLoc, diag::warn_property_redecl_getter_mismatch)
  429. << PIDecl->getGetterName() << GetterSel;
  430. Diag(PIDecl->getLocation(), diag::note_property_declare);
  431. }
  432. // Always adopt the getter from the original declaration.
  433. GetterSel = PIDecl->getGetterName();
  434. Attributes |= ObjCDeclSpec::DQ_PR_getter;
  435. }
  436. // Check consistency of ownership.
  437. unsigned ExistingOwnership
  438. = getOwnershipRule(PIDecl->getPropertyAttributes());
  439. unsigned NewOwnership = getOwnershipRule(Attributes);
  440. if (ExistingOwnership && NewOwnership != ExistingOwnership) {
  441. // If the ownership was written explicitly, complain.
  442. if (getOwnershipRule(AttributesAsWritten)) {
  443. Diag(AtLoc, diag::warn_property_attr_mismatch);
  444. Diag(PIDecl->getLocation(), diag::note_property_declare);
  445. }
  446. // Take the ownership from the original property.
  447. Attributes = (Attributes & ~OwnershipMask) | ExistingOwnership;
  448. }
  449. // If the redeclaration is 'weak' but the original property is not,
  450. if ((Attributes & ObjCPropertyDecl::OBJC_PR_weak) &&
  451. !(PIDecl->getPropertyAttributesAsWritten()
  452. & ObjCPropertyDecl::OBJC_PR_weak) &&
  453. PIDecl->getType()->getAs<ObjCObjectPointerType>() &&
  454. PIDecl->getType().getObjCLifetime() == Qualifiers::OCL_None) {
  455. Diag(AtLoc, diag::warn_property_implicitly_mismatched);
  456. Diag(PIDecl->getLocation(), diag::note_property_declare);
  457. }
  458. }
  459. // Create a new ObjCPropertyDecl with the DeclContext being
  460. // the class extension.
  461. ObjCPropertyDecl *PDecl = CreatePropertyDecl(S, CDecl, AtLoc, LParenLoc,
  462. FD, GetterSel, GetterNameLoc,
  463. SetterSel, SetterNameLoc,
  464. isReadWrite,
  465. Attributes, AttributesAsWritten,
  466. T, TSI, MethodImplKind, DC);
  467. // If there was no declaration of a property with the same name in
  468. // the primary class, we're done.
  469. if (!PIDecl) {
  470. ProcessPropertyDecl(PDecl);
  471. return PDecl;
  472. }
  473. if (!Context.hasSameType(PIDecl->getType(), PDecl->getType())) {
  474. bool IncompatibleObjC = false;
  475. QualType ConvertedType;
  476. // Relax the strict type matching for property type in continuation class.
  477. // Allow property object type of continuation class to be different as long
  478. // as it narrows the object type in its primary class property. Note that
  479. // this conversion is safe only because the wider type is for a 'readonly'
  480. // property in primary class and 'narrowed' type for a 'readwrite' property
  481. // in continuation class.
  482. QualType PrimaryClassPropertyT = Context.getCanonicalType(PIDecl->getType());
  483. QualType ClassExtPropertyT = Context.getCanonicalType(PDecl->getType());
  484. if (!isa<ObjCObjectPointerType>(PrimaryClassPropertyT) ||
  485. !isa<ObjCObjectPointerType>(ClassExtPropertyT) ||
  486. (!isObjCPointerConversion(ClassExtPropertyT, PrimaryClassPropertyT,
  487. ConvertedType, IncompatibleObjC))
  488. || IncompatibleObjC) {
  489. Diag(AtLoc,
  490. diag::err_type_mismatch_continuation_class) << PDecl->getType();
  491. Diag(PIDecl->getLocation(), diag::note_property_declare);
  492. return nullptr;
  493. }
  494. }
  495. // Check that atomicity of property in class extension matches the previous
  496. // declaration.
  497. checkAtomicPropertyMismatch(*this, PIDecl, PDecl, true);
  498. // Make sure getter/setter are appropriately synthesized.
  499. ProcessPropertyDecl(PDecl);
  500. return PDecl;
  501. }
  502. ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
  503. ObjCContainerDecl *CDecl,
  504. SourceLocation AtLoc,
  505. SourceLocation LParenLoc,
  506. FieldDeclarator &FD,
  507. Selector GetterSel,
  508. SourceLocation GetterNameLoc,
  509. Selector SetterSel,
  510. SourceLocation SetterNameLoc,
  511. const bool isReadWrite,
  512. const unsigned Attributes,
  513. const unsigned AttributesAsWritten,
  514. QualType T,
  515. TypeSourceInfo *TInfo,
  516. tok::ObjCKeywordKind MethodImplKind,
  517. DeclContext *lexicalDC){
  518. IdentifierInfo *PropertyId = FD.D.getIdentifier();
  519. // Property defaults to 'assign' if it is readwrite, unless this is ARC
  520. // and the type is retainable.
  521. bool isAssign;
  522. if (Attributes & (ObjCDeclSpec::DQ_PR_assign |
  523. ObjCDeclSpec::DQ_PR_unsafe_unretained)) {
  524. isAssign = true;
  525. } else if (getOwnershipRule(Attributes) || !isReadWrite) {
  526. isAssign = false;
  527. } else {
  528. isAssign = (!getLangOpts().ObjCAutoRefCount ||
  529. !T->isObjCRetainableType());
  530. }
  531. // Issue a warning if property is 'assign' as default and its
  532. // object, which is gc'able conforms to NSCopying protocol
  533. if (getLangOpts().getGC() != LangOptions::NonGC &&
  534. isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign)) {
  535. if (const ObjCObjectPointerType *ObjPtrTy =
  536. T->getAs<ObjCObjectPointerType>()) {
  537. ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
  538. if (IDecl)
  539. if (ObjCProtocolDecl* PNSCopying =
  540. LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc))
  541. if (IDecl->ClassImplementsProtocol(PNSCopying, true))
  542. Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;
  543. }
  544. }
  545. if (T->isObjCObjectType()) {
  546. SourceLocation StarLoc = TInfo->getTypeLoc().getEndLoc();
  547. StarLoc = getLocForEndOfToken(StarLoc);
  548. Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object)
  549. << FixItHint::CreateInsertion(StarLoc, "*");
  550. T = Context.getObjCObjectPointerType(T);
  551. SourceLocation TLoc = TInfo->getTypeLoc().getBeginLoc();
  552. TInfo = Context.getTrivialTypeSourceInfo(T, TLoc);
  553. }
  554. DeclContext *DC = CDecl;
  555. ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC,
  556. FD.D.getIdentifierLoc(),
  557. PropertyId, AtLoc,
  558. LParenLoc, T, TInfo);
  559. bool isClassProperty = (AttributesAsWritten & ObjCDeclSpec::DQ_PR_class) ||
  560. (Attributes & ObjCDeclSpec::DQ_PR_class);
  561. // Class property and instance property can have the same name.
  562. if (ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
  563. DC, PropertyId, ObjCPropertyDecl::getQueryKind(isClassProperty))) {
  564. Diag(PDecl->getLocation(), diag::err_duplicate_property);
  565. Diag(prevDecl->getLocation(), diag::note_property_declare);
  566. PDecl->setInvalidDecl();
  567. }
  568. else {
  569. DC->addDecl(PDecl);
  570. if (lexicalDC)
  571. PDecl->setLexicalDeclContext(lexicalDC);
  572. }
  573. if (T->isArrayType() || T->isFunctionType()) {
  574. Diag(AtLoc, diag::err_property_type) << T;
  575. PDecl->setInvalidDecl();
  576. }
  577. ProcessDeclAttributes(S, PDecl, FD.D);
  578. // Regardless of setter/getter attribute, we save the default getter/setter
  579. // selector names in anticipation of declaration of setter/getter methods.
  580. PDecl->setGetterName(GetterSel, GetterNameLoc);
  581. PDecl->setSetterName(SetterSel, SetterNameLoc);
  582. PDecl->setPropertyAttributesAsWritten(
  583. makePropertyAttributesAsWritten(AttributesAsWritten));
  584. if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
  585. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
  586. if (Attributes & ObjCDeclSpec::DQ_PR_getter)
  587. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
  588. if (Attributes & ObjCDeclSpec::DQ_PR_setter)
  589. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
  590. if (isReadWrite)
  591. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
  592. if (Attributes & ObjCDeclSpec::DQ_PR_retain)
  593. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
  594. if (Attributes & ObjCDeclSpec::DQ_PR_strong)
  595. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
  596. if (Attributes & ObjCDeclSpec::DQ_PR_weak)
  597. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak);
  598. if (Attributes & ObjCDeclSpec::DQ_PR_copy)
  599. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
  600. if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
  601. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
  602. if (isAssign)
  603. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
  604. // In the semantic attributes, one of nonatomic or atomic is always set.
  605. if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
  606. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
  607. else
  608. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_atomic);
  609. // 'unsafe_unretained' is alias for 'assign'.
  610. if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
  611. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
  612. if (isAssign)
  613. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
  614. if (MethodImplKind == tok::objc_required)
  615. PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
  616. else if (MethodImplKind == tok::objc_optional)
  617. PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
  618. if (Attributes & ObjCDeclSpec::DQ_PR_nullability)
  619. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nullability);
  620. if (Attributes & ObjCDeclSpec::DQ_PR_null_resettable)
  621. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_null_resettable);
  622. if (Attributes & ObjCDeclSpec::DQ_PR_class)
  623. PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_class);
  624. return PDecl;
  625. }
  626. static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc,
  627. ObjCPropertyDecl *property,
  628. ObjCIvarDecl *ivar) {
  629. if (property->isInvalidDecl() || ivar->isInvalidDecl()) return;
  630. QualType ivarType = ivar->getType();
  631. Qualifiers::ObjCLifetime ivarLifetime = ivarType.getObjCLifetime();
  632. // The lifetime implied by the property's attributes.
  633. Qualifiers::ObjCLifetime propertyLifetime =
  634. getImpliedARCOwnership(property->getPropertyAttributes(),
  635. property->getType());
  636. // We're fine if they match.
  637. if (propertyLifetime == ivarLifetime) return;
  638. // None isn't a valid lifetime for an object ivar in ARC, and
  639. // __autoreleasing is never valid; don't diagnose twice.
  640. if ((ivarLifetime == Qualifiers::OCL_None &&
  641. S.getLangOpts().ObjCAutoRefCount) ||
  642. ivarLifetime == Qualifiers::OCL_Autoreleasing)
  643. return;
  644. // If the ivar is private, and it's implicitly __unsafe_unretained
  645. // because of its type, then pretend it was actually implicitly
  646. // __strong. This is only sound because we're processing the
  647. // property implementation before parsing any method bodies.
  648. if (ivarLifetime == Qualifiers::OCL_ExplicitNone &&
  649. propertyLifetime == Qualifiers::OCL_Strong &&
  650. ivar->getAccessControl() == ObjCIvarDecl::Private) {
  651. SplitQualType split = ivarType.split();
  652. if (split.Quals.hasObjCLifetime()) {
  653. assert(ivarType->isObjCARCImplicitlyUnretainedType());
  654. split.Quals.setObjCLifetime(Qualifiers::OCL_Strong);
  655. ivarType = S.Context.getQualifiedType(split);
  656. ivar->setType(ivarType);
  657. return;
  658. }
  659. }
  660. switch (propertyLifetime) {
  661. case Qualifiers::OCL_Strong:
  662. S.Diag(ivar->getLocation(), diag::err_arc_strong_property_ownership)
  663. << property->getDeclName()
  664. << ivar->getDeclName()
  665. << ivarLifetime;
  666. break;
  667. case Qualifiers::OCL_Weak:
  668. S.Diag(ivar->getLocation(), diag::err_weak_property)
  669. << property->getDeclName()
  670. << ivar->getDeclName();
  671. break;
  672. case Qualifiers::OCL_ExplicitNone:
  673. S.Diag(ivar->getLocation(), diag::err_arc_assign_property_ownership)
  674. << property->getDeclName()
  675. << ivar->getDeclName()
  676. << ((property->getPropertyAttributesAsWritten()
  677. & ObjCPropertyDecl::OBJC_PR_assign) != 0);
  678. break;
  679. case Qualifiers::OCL_Autoreleasing:
  680. llvm_unreachable("properties cannot be autoreleasing");
  681. case Qualifiers::OCL_None:
  682. // Any other property should be ignored.
  683. return;
  684. }
  685. S.Diag(property->getLocation(), diag::note_property_declare);
  686. if (propertyImplLoc.isValid())
  687. S.Diag(propertyImplLoc, diag::note_property_synthesize);
  688. }
  689. /// setImpliedPropertyAttributeForReadOnlyProperty -
  690. /// This routine evaludates life-time attributes for a 'readonly'
  691. /// property with no known lifetime of its own, using backing
  692. /// 'ivar's attribute, if any. If no backing 'ivar', property's
  693. /// life-time is assumed 'strong'.
  694. static void setImpliedPropertyAttributeForReadOnlyProperty(
  695. ObjCPropertyDecl *property, ObjCIvarDecl *ivar) {
  696. Qualifiers::ObjCLifetime propertyLifetime =
  697. getImpliedARCOwnership(property->getPropertyAttributes(),
  698. property->getType());
  699. if (propertyLifetime != Qualifiers::OCL_None)
  700. return;
  701. if (!ivar) {
  702. // if no backing ivar, make property 'strong'.
  703. property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
  704. return;
  705. }
  706. // property assumes owenership of backing ivar.
  707. QualType ivarType = ivar->getType();
  708. Qualifiers::ObjCLifetime ivarLifetime = ivarType.getObjCLifetime();
  709. if (ivarLifetime == Qualifiers::OCL_Strong)
  710. property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
  711. else if (ivarLifetime == Qualifiers::OCL_Weak)
  712. property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak);
  713. }
  714. static bool
  715. isIncompatiblePropertyAttribute(unsigned Attr1, unsigned Attr2,
  716. ObjCPropertyDecl::PropertyAttributeKind Kind) {
  717. return (Attr1 & Kind) != (Attr2 & Kind);
  718. }
  719. static bool areIncompatiblePropertyAttributes(unsigned Attr1, unsigned Attr2,
  720. unsigned Kinds) {
  721. return ((Attr1 & Kinds) != 0) != ((Attr2 & Kinds) != 0);
  722. }
  723. /// SelectPropertyForSynthesisFromProtocols - Finds the most appropriate
  724. /// property declaration that should be synthesised in all of the inherited
  725. /// protocols. It also diagnoses properties declared in inherited protocols with
  726. /// mismatched types or attributes, since any of them can be candidate for
  727. /// synthesis.
  728. static ObjCPropertyDecl *
  729. SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc,
  730. ObjCInterfaceDecl *ClassDecl,
  731. ObjCPropertyDecl *Property) {
  732. assert(isa<ObjCProtocolDecl>(Property->getDeclContext()) &&
  733. "Expected a property from a protocol");
  734. ObjCInterfaceDecl::ProtocolPropertySet ProtocolSet;
  735. ObjCInterfaceDecl::PropertyDeclOrder Properties;
  736. for (const auto *PI : ClassDecl->all_referenced_protocols()) {
  737. if (const ObjCProtocolDecl *PDecl = PI->getDefinition())
  738. PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
  739. Properties);
  740. }
  741. if (ObjCInterfaceDecl *SDecl = ClassDecl->getSuperClass()) {
  742. while (SDecl) {
  743. for (const auto *PI : SDecl->all_referenced_protocols()) {
  744. if (const ObjCProtocolDecl *PDecl = PI->getDefinition())
  745. PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
  746. Properties);
  747. }
  748. SDecl = SDecl->getSuperClass();
  749. }
  750. }
  751. if (Properties.empty())
  752. return Property;
  753. ObjCPropertyDecl *OriginalProperty = Property;
  754. size_t SelectedIndex = 0;
  755. for (const auto &Prop : llvm::enumerate(Properties)) {
  756. // Select the 'readwrite' property if such property exists.
  757. if (Property->isReadOnly() && !Prop.value()->isReadOnly()) {
  758. Property = Prop.value();
  759. SelectedIndex = Prop.index();
  760. }
  761. }
  762. if (Property != OriginalProperty) {
  763. // Check that the old property is compatible with the new one.
  764. Properties[SelectedIndex] = OriginalProperty;
  765. }
  766. QualType RHSType = S.Context.getCanonicalType(Property->getType());
  767. unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();
  768. enum MismatchKind {
  769. IncompatibleType = 0,
  770. HasNoExpectedAttribute,
  771. HasUnexpectedAttribute,
  772. DifferentGetter,
  773. DifferentSetter
  774. };
  775. // Represents a property from another protocol that conflicts with the
  776. // selected declaration.
  777. struct MismatchingProperty {
  778. const ObjCPropertyDecl *Prop;
  779. MismatchKind Kind;
  780. StringRef AttributeName;
  781. };
  782. SmallVector<MismatchingProperty, 4> Mismatches;
  783. for (ObjCPropertyDecl *Prop : Properties) {
  784. // Verify the property attributes.
  785. unsigned Attr = Prop->getPropertyAttributesAsWritten();
  786. if (Attr != OriginalAttributes) {
  787. auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName) {
  788. MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute
  789. : HasUnexpectedAttribute;
  790. Mismatches.push_back({Prop, Kind, AttributeName});
  791. };
  792. // The ownership might be incompatible unless the property has no explicit
  793. // ownership.
  794. bool HasOwnership = (Attr & (ObjCPropertyDecl::OBJC_PR_retain |
  795. ObjCPropertyDecl::OBJC_PR_strong |
  796. ObjCPropertyDecl::OBJC_PR_copy |
  797. ObjCPropertyDecl::OBJC_PR_assign |
  798. ObjCPropertyDecl::OBJC_PR_unsafe_unretained |
  799. ObjCPropertyDecl::OBJC_PR_weak)) != 0;
  800. if (HasOwnership &&
  801. isIncompatiblePropertyAttribute(OriginalAttributes, Attr,
  802. ObjCPropertyDecl::OBJC_PR_copy)) {
  803. Diag(OriginalAttributes & ObjCPropertyDecl::OBJC_PR_copy, "copy");
  804. continue;
  805. }
  806. if (HasOwnership && areIncompatiblePropertyAttributes(
  807. OriginalAttributes, Attr,
  808. ObjCPropertyDecl::OBJC_PR_retain |
  809. ObjCPropertyDecl::OBJC_PR_strong)) {
  810. Diag(OriginalAttributes & (ObjCPropertyDecl::OBJC_PR_retain |
  811. ObjCPropertyDecl::OBJC_PR_strong),
  812. "retain (or strong)");
  813. continue;
  814. }
  815. if (isIncompatiblePropertyAttribute(OriginalAttributes, Attr,
  816. ObjCPropertyDecl::OBJC_PR_atomic)) {
  817. Diag(OriginalAttributes & ObjCPropertyDecl::OBJC_PR_atomic, "atomic");
  818. continue;
  819. }
  820. }
  821. if (Property->getGetterName() != Prop->getGetterName()) {
  822. Mismatches.push_back({Prop, DifferentGetter, ""});
  823. continue;
  824. }
  825. if (!Property->isReadOnly() && !Prop->isReadOnly() &&
  826. Property->getSetterName() != Prop->getSetterName()) {
  827. Mismatches.push_back({Prop, DifferentSetter, ""});
  828. continue;
  829. }
  830. QualType LHSType = S.Context.getCanonicalType(Prop->getType());
  831. if (!S.Context.propertyTypesAreCompatible(LHSType, RHSType)) {
  832. bool IncompatibleObjC = false;
  833. QualType ConvertedType;
  834. if (!S.isObjCPointerConversion(RHSType, LHSType, ConvertedType, IncompatibleObjC)
  835. || IncompatibleObjC) {
  836. Mismatches.push_back({Prop, IncompatibleType, ""});
  837. continue;
  838. }
  839. }
  840. }
  841. if (Mismatches.empty())
  842. return Property;
  843. // Diagnose incompability.
  844. {
  845. bool HasIncompatibleAttributes = false;
  846. for (const auto &Note : Mismatches)
  847. HasIncompatibleAttributes =
  848. Note.Kind != IncompatibleType ? true : HasIncompatibleAttributes;
  849. // Promote the warning to an error if there are incompatible attributes or
  850. // incompatible types together with readwrite/readonly incompatibility.
  851. auto Diag = S.Diag(Property->getLocation(),
  852. Property != OriginalProperty || HasIncompatibleAttributes
  853. ? diag::err_protocol_property_mismatch
  854. : diag::warn_protocol_property_mismatch);
  855. Diag << Mismatches[0].Kind;
  856. switch (Mismatches[0].Kind) {
  857. case IncompatibleType:
  858. Diag << Property->getType();
  859. break;
  860. case HasNoExpectedAttribute:
  861. case HasUnexpectedAttribute:
  862. Diag << Mismatches[0].AttributeName;
  863. break;
  864. case DifferentGetter:
  865. Diag << Property->getGetterName();
  866. break;
  867. case DifferentSetter:
  868. Diag << Property->getSetterName();
  869. break;
  870. }
  871. }
  872. for (const auto &Note : Mismatches) {
  873. auto Diag =
  874. S.Diag(Note.Prop->getLocation(), diag::note_protocol_property_declare)
  875. << Note.Kind;
  876. switch (Note.Kind) {
  877. case IncompatibleType:
  878. Diag << Note.Prop->getType();
  879. break;
  880. case HasNoExpectedAttribute:
  881. case HasUnexpectedAttribute:
  882. Diag << Note.AttributeName;
  883. break;
  884. case DifferentGetter:
  885. Diag << Note.Prop->getGetterName();
  886. break;
  887. case DifferentSetter:
  888. Diag << Note.Prop->getSetterName();
  889. break;
  890. }
  891. }
  892. if (AtLoc.isValid())
  893. S.Diag(AtLoc, diag::note_property_synthesize);
  894. return Property;
  895. }
  896. /// Determine whether any storage attributes were written on the property.
  897. static bool hasWrittenStorageAttribute(ObjCPropertyDecl *Prop,
  898. ObjCPropertyQueryKind QueryKind) {
  899. if (Prop->getPropertyAttributesAsWritten() & OwnershipMask) return true;
  900. // If this is a readwrite property in a class extension that refines
  901. // a readonly property in the original class definition, check it as
  902. // well.
  903. // If it's a readonly property, we're not interested.
  904. if (Prop->isReadOnly()) return false;
  905. // Is it declared in an extension?
  906. auto Category = dyn_cast<ObjCCategoryDecl>(Prop->getDeclContext());
  907. if (!Category || !Category->IsClassExtension()) return false;
  908. // Find the corresponding property in the primary class definition.
  909. auto OrigClass = Category->getClassInterface();
  910. for (auto Found : OrigClass->lookup(Prop->getDeclName())) {
  911. if (ObjCPropertyDecl *OrigProp = dyn_cast<ObjCPropertyDecl>(Found))
  912. return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;
  913. }
  914. // Look through all of the protocols.
  915. for (const auto *Proto : OrigClass->all_referenced_protocols()) {
  916. if (ObjCPropertyDecl *OrigProp = Proto->FindPropertyDeclaration(
  917. Prop->getIdentifier(), QueryKind))
  918. return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;
  919. }
  920. return false;
  921. }
  922. /// ActOnPropertyImplDecl - This routine performs semantic checks and
  923. /// builds the AST node for a property implementation declaration; declared
  924. /// as \@synthesize or \@dynamic.
  925. ///
  926. Decl *Sema::ActOnPropertyImplDecl(Scope *S,
  927. SourceLocation AtLoc,
  928. SourceLocation PropertyLoc,
  929. bool Synthesize,
  930. IdentifierInfo *PropertyId,
  931. IdentifierInfo *PropertyIvar,
  932. SourceLocation PropertyIvarLoc,
  933. ObjCPropertyQueryKind QueryKind) {
  934. ObjCContainerDecl *ClassImpDecl =
  935. dyn_cast<ObjCContainerDecl>(CurContext);
  936. // Make sure we have a context for the property implementation declaration.
  937. if (!ClassImpDecl) {
  938. Diag(AtLoc, diag::err_missing_property_context);
  939. return nullptr;
  940. }
  941. if (PropertyIvarLoc.isInvalid())
  942. PropertyIvarLoc = PropertyLoc;
  943. SourceLocation PropertyDiagLoc = PropertyLoc;
  944. if (PropertyDiagLoc.isInvalid())
  945. PropertyDiagLoc = ClassImpDecl->getBeginLoc();
  946. ObjCPropertyDecl *property = nullptr;
  947. ObjCInterfaceDecl *IDecl = nullptr;
  948. // Find the class or category class where this property must have
  949. // a declaration.
  950. ObjCImplementationDecl *IC = nullptr;
  951. ObjCCategoryImplDecl *CatImplClass = nullptr;
  952. if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
  953. IDecl = IC->getClassInterface();
  954. // We always synthesize an interface for an implementation
  955. // without an interface decl. So, IDecl is always non-zero.
  956. assert(IDecl &&
  957. "ActOnPropertyImplDecl - @implementation without @interface");
  958. // Look for this property declaration in the @implementation's @interface
  959. property = IDecl->FindPropertyDeclaration(PropertyId, QueryKind);
  960. if (!property) {
  961. Diag(PropertyLoc, diag::err_bad_property_decl) << IDecl->getDeclName();
  962. return nullptr;
  963. }
  964. if (property->isClassProperty() && Synthesize) {
  965. Diag(PropertyLoc, diag::err_synthesize_on_class_property) << PropertyId;
  966. return nullptr;
  967. }
  968. unsigned PIkind = property->getPropertyAttributesAsWritten();
  969. if ((PIkind & (ObjCPropertyDecl::OBJC_PR_atomic |
  970. ObjCPropertyDecl::OBJC_PR_nonatomic) ) == 0) {
  971. if (AtLoc.isValid())
  972. Diag(AtLoc, diag::warn_implicit_atomic_property);
  973. else
  974. Diag(IC->getLocation(), diag::warn_auto_implicit_atomic_property);
  975. Diag(property->getLocation(), diag::note_property_declare);
  976. }
  977. if (const ObjCCategoryDecl *CD =
  978. dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
  979. if (!CD->IsClassExtension()) {
  980. Diag(PropertyLoc, diag::err_category_property) << CD->getDeclName();
  981. Diag(property->getLocation(), diag::note_property_declare);
  982. return nullptr;
  983. }
  984. }
  985. if (Synthesize&&
  986. (PIkind & ObjCPropertyDecl::OBJC_PR_readonly) &&
  987. property->hasAttr<IBOutletAttr>() &&
  988. !AtLoc.isValid()) {
  989. bool ReadWriteProperty = false;
  990. // Search into the class extensions and see if 'readonly property is
  991. // redeclared 'readwrite', then no warning is to be issued.
  992. for (auto *Ext : IDecl->known_extensions()) {
  993. DeclContext::lookup_result R = Ext->lookup(property->getDeclName());
  994. if (!R.empty())
  995. if (ObjCPropertyDecl *ExtProp = dyn_cast<ObjCPropertyDecl>(R[0])) {
  996. PIkind = ExtProp->getPropertyAttributesAsWritten();
  997. if (PIkind & ObjCPropertyDecl::OBJC_PR_readwrite) {
  998. ReadWriteProperty = true;
  999. break;
  1000. }
  1001. }
  1002. }
  1003. if (!ReadWriteProperty) {
  1004. Diag(property->getLocation(), diag::warn_auto_readonly_iboutlet_property)
  1005. << property;
  1006. SourceLocation readonlyLoc;
  1007. if (LocPropertyAttribute(Context, "readonly",
  1008. property->getLParenLoc(), readonlyLoc)) {
  1009. SourceLocation endLoc =
  1010. readonlyLoc.getLocWithOffset(strlen("readonly")-1);
  1011. SourceRange ReadonlySourceRange(readonlyLoc, endLoc);
  1012. Diag(property->getLocation(),
  1013. diag::note_auto_readonly_iboutlet_fixup_suggest) <<
  1014. FixItHint::CreateReplacement(ReadonlySourceRange, "readwrite");
  1015. }
  1016. }
  1017. }
  1018. if (Synthesize && isa<ObjCProtocolDecl>(property->getDeclContext()))
  1019. property = SelectPropertyForSynthesisFromProtocols(*this, AtLoc, IDecl,
  1020. property);
  1021. } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
  1022. if (Synthesize) {
  1023. Diag(AtLoc, diag::err_synthesize_category_decl);
  1024. return nullptr;
  1025. }
  1026. IDecl = CatImplClass->getClassInterface();
  1027. if (!IDecl) {
  1028. Diag(AtLoc, diag::err_missing_property_interface);
  1029. return nullptr;
  1030. }
  1031. ObjCCategoryDecl *Category =
  1032. IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
  1033. // If category for this implementation not found, it is an error which
  1034. // has already been reported eralier.
  1035. if (!Category)
  1036. return nullptr;
  1037. // Look for this property declaration in @implementation's category
  1038. property = Category->FindPropertyDeclaration(PropertyId, QueryKind);
  1039. if (!property) {
  1040. Diag(PropertyLoc, diag::err_bad_category_property_decl)
  1041. << Category->getDeclName();
  1042. return nullptr;
  1043. }
  1044. } else {
  1045. Diag(AtLoc, diag::err_bad_property_context);
  1046. return nullptr;
  1047. }
  1048. ObjCIvarDecl *Ivar = nullptr;
  1049. bool CompleteTypeErr = false;
  1050. bool compat = true;
  1051. // Check that we have a valid, previously declared ivar for @synthesize
  1052. if (Synthesize) {
  1053. // @synthesize
  1054. if (!PropertyIvar)
  1055. PropertyIvar = PropertyId;
  1056. // Check that this is a previously declared 'ivar' in 'IDecl' interface
  1057. ObjCInterfaceDecl *ClassDeclared;
  1058. Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared);
  1059. QualType PropType = property->getType();
  1060. QualType PropertyIvarType = PropType.getNonReferenceType();
  1061. if (RequireCompleteType(PropertyDiagLoc, PropertyIvarType,
  1062. diag::err_incomplete_synthesized_property,
  1063. property->getDeclName())) {
  1064. Diag(property->getLocation(), diag::note_property_declare);
  1065. CompleteTypeErr = true;
  1066. }
  1067. if (getLangOpts().ObjCAutoRefCount &&
  1068. (property->getPropertyAttributesAsWritten() &
  1069. ObjCPropertyDecl::OBJC_PR_readonly) &&
  1070. PropertyIvarType->isObjCRetainableType()) {
  1071. setImpliedPropertyAttributeForReadOnlyProperty(property, Ivar);
  1072. }
  1073. ObjCPropertyDecl::PropertyAttributeKind kind
  1074. = property->getPropertyAttributes();
  1075. bool isARCWeak = false;
  1076. if (kind & ObjCPropertyDecl::OBJC_PR_weak) {
  1077. // Add GC __weak to the ivar type if the property is weak.
  1078. if (getLangOpts().getGC() != LangOptions::NonGC) {
  1079. assert(!getLangOpts().ObjCAutoRefCount);
  1080. if (PropertyIvarType.isObjCGCStrong()) {
  1081. Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type);
  1082. Diag(property->getLocation(), diag::note_property_declare);
  1083. } else {
  1084. PropertyIvarType =
  1085. Context.getObjCGCQualType(PropertyIvarType, Qualifiers::Weak);
  1086. }
  1087. // Otherwise, check whether ARC __weak is enabled and works with
  1088. // the property type.
  1089. } else {
  1090. if (!getLangOpts().ObjCWeak) {
  1091. // Only complain here when synthesizing an ivar.
  1092. if (!Ivar) {
  1093. Diag(PropertyDiagLoc,
  1094. getLangOpts().ObjCWeakRuntime
  1095. ? diag::err_synthesizing_arc_weak_property_disabled
  1096. : diag::err_synthesizing_arc_weak_property_no_runtime);
  1097. Diag(property->getLocation(), diag::note_property_declare);
  1098. }
  1099. CompleteTypeErr = true; // suppress later diagnostics about the ivar
  1100. } else {
  1101. isARCWeak = true;
  1102. if (const ObjCObjectPointerType *ObjT =
  1103. PropertyIvarType->getAs<ObjCObjectPointerType>()) {
  1104. const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl();
  1105. if (ObjI && ObjI->isArcWeakrefUnavailable()) {
  1106. Diag(property->getLocation(),
  1107. diag::err_arc_weak_unavailable_property)
  1108. << PropertyIvarType;
  1109. Diag(ClassImpDecl->getLocation(), diag::note_implemented_by_class)
  1110. << ClassImpDecl->getName();
  1111. }
  1112. }
  1113. }
  1114. }
  1115. }
  1116. if (AtLoc.isInvalid()) {
  1117. // Check when default synthesizing a property that there is
  1118. // an ivar matching property name and issue warning; since this
  1119. // is the most common case of not using an ivar used for backing
  1120. // property in non-default synthesis case.
  1121. ObjCInterfaceDecl *ClassDeclared=nullptr;
  1122. ObjCIvarDecl *originalIvar =
  1123. IDecl->lookupInstanceVariable(property->getIdentifier(),
  1124. ClassDeclared);
  1125. if (originalIvar) {
  1126. Diag(PropertyDiagLoc,
  1127. diag::warn_autosynthesis_property_ivar_match)
  1128. << PropertyId << (Ivar == nullptr) << PropertyIvar
  1129. << originalIvar->getIdentifier();
  1130. Diag(property->getLocation(), diag::note_property_declare);
  1131. Diag(originalIvar->getLocation(), diag::note_ivar_decl);
  1132. }
  1133. }
  1134. if (!Ivar) {
  1135. // In ARC, give the ivar a lifetime qualifier based on the
  1136. // property attributes.
  1137. if ((getLangOpts().ObjCAutoRefCount || isARCWeak) &&
  1138. !PropertyIvarType.getObjCLifetime() &&
  1139. PropertyIvarType->isObjCRetainableType()) {
  1140. // It's an error if we have to do this and the user didn't
  1141. // explicitly write an ownership attribute on the property.
  1142. if (!hasWrittenStorageAttribute(property, QueryKind) &&
  1143. !(kind & ObjCPropertyDecl::OBJC_PR_strong)) {
  1144. Diag(PropertyDiagLoc,
  1145. diag::err_arc_objc_property_default_assign_on_object);
  1146. Diag(property->getLocation(), diag::note_property_declare);
  1147. } else {
  1148. Qualifiers::ObjCLifetime lifetime =
  1149. getImpliedARCOwnership(kind, PropertyIvarType);
  1150. assert(lifetime && "no lifetime for property?");
  1151. Qualifiers qs;
  1152. qs.addObjCLifetime(lifetime);
  1153. PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs);
  1154. }
  1155. }
  1156. Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl,
  1157. PropertyIvarLoc,PropertyIvarLoc, PropertyIvar,
  1158. PropertyIvarType, /*TInfo=*/nullptr,
  1159. ObjCIvarDecl::Private,
  1160. (Expr *)nullptr, true);
  1161. if (RequireNonAbstractType(PropertyIvarLoc,
  1162. PropertyIvarType,
  1163. diag::err_abstract_type_in_decl,
  1164. AbstractSynthesizedIvarType)) {
  1165. Diag(property->getLocation(), diag::note_property_declare);
  1166. // An abstract type is as bad as an incomplete type.
  1167. CompleteTypeErr = true;
  1168. }
  1169. if (!CompleteTypeErr) {
  1170. const RecordType *RecordTy = PropertyIvarType->getAs<RecordType>();
  1171. if (RecordTy && RecordTy->getDecl()->hasFlexibleArrayMember()) {
  1172. Diag(PropertyIvarLoc, diag::err_synthesize_variable_sized_ivar)
  1173. << PropertyIvarType;
  1174. CompleteTypeErr = true; // suppress later diagnostics about the ivar
  1175. }
  1176. }
  1177. if (CompleteTypeErr)
  1178. Ivar->setInvalidDecl();
  1179. ClassImpDecl->addDecl(Ivar);
  1180. IDecl->makeDeclVisibleInContext(Ivar);
  1181. if (getLangOpts().ObjCRuntime.isFragile())
  1182. Diag(PropertyDiagLoc, diag::err_missing_property_ivar_decl)
  1183. << PropertyId;
  1184. // Note! I deliberately want it to fall thru so, we have a
  1185. // a property implementation and to avoid future warnings.
  1186. } else if (getLangOpts().ObjCRuntime.isNonFragile() &&
  1187. !declaresSameEntity(ClassDeclared, IDecl)) {
  1188. Diag(PropertyDiagLoc, diag::err_ivar_in_superclass_use)
  1189. << property->getDeclName() << Ivar->getDeclName()
  1190. << ClassDeclared->getDeclName();
  1191. Diag(Ivar->getLocation(), diag::note_previous_access_declaration)
  1192. << Ivar << Ivar->getName();
  1193. // Note! I deliberately want it to fall thru so more errors are caught.
  1194. }
  1195. property->setPropertyIvarDecl(Ivar);
  1196. QualType IvarType = Context.getCanonicalType(Ivar->getType());
  1197. // Check that type of property and its ivar are type compatible.
  1198. if (!Context.hasSameType(PropertyIvarType, IvarType)) {
  1199. if (isa<ObjCObjectPointerType>(PropertyIvarType)
  1200. && isa<ObjCObjectPointerType>(IvarType))
  1201. compat =
  1202. Context.canAssignObjCInterfaces(
  1203. PropertyIvarType->getAs<ObjCObjectPointerType>(),
  1204. IvarType->getAs<ObjCObjectPointerType>());
  1205. else {
  1206. compat = (CheckAssignmentConstraints(PropertyIvarLoc, PropertyIvarType,
  1207. IvarType)
  1208. == Compatible);
  1209. }
  1210. if (!compat) {
  1211. Diag(PropertyDiagLoc, diag::err_property_ivar_type)
  1212. << property->getDeclName() << PropType
  1213. << Ivar->getDeclName() << IvarType;
  1214. Diag(Ivar->getLocation(), diag::note_ivar_decl);
  1215. // Note! I deliberately want it to fall thru so, we have a
  1216. // a property implementation and to avoid future warnings.
  1217. }
  1218. else {
  1219. // FIXME! Rules for properties are somewhat different that those
  1220. // for assignments. Use a new routine to consolidate all cases;
  1221. // specifically for property redeclarations as well as for ivars.
  1222. QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType();
  1223. QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType();
  1224. if (lhsType != rhsType &&
  1225. lhsType->isArithmeticType()) {
  1226. Diag(PropertyDiagLoc, diag::err_property_ivar_type)
  1227. << property->getDeclName() << PropType
  1228. << Ivar->getDeclName() << IvarType;
  1229. Diag(Ivar->getLocation(), diag::note_ivar_decl);
  1230. // Fall thru - see previous comment
  1231. }
  1232. }
  1233. // __weak is explicit. So it works on Canonical type.
  1234. if ((PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() &&
  1235. getLangOpts().getGC() != LangOptions::NonGC)) {
  1236. Diag(PropertyDiagLoc, diag::err_weak_property)
  1237. << property->getDeclName() << Ivar->getDeclName();
  1238. Diag(Ivar->getLocation(), diag::note_ivar_decl);
  1239. // Fall thru - see previous comment
  1240. }
  1241. // Fall thru - see previous comment
  1242. if ((property->getType()->isObjCObjectPointerType() ||
  1243. PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() &&
  1244. getLangOpts().getGC() != LangOptions::NonGC) {
  1245. Diag(PropertyDiagLoc, diag::err_strong_property)
  1246. << property->getDeclName() << Ivar->getDeclName();
  1247. // Fall thru - see previous comment
  1248. }
  1249. }
  1250. if (getLangOpts().ObjCAutoRefCount || isARCWeak ||
  1251. Ivar->getType().getObjCLifetime())
  1252. checkARCPropertyImpl(*this, PropertyLoc, property, Ivar);
  1253. } else if (PropertyIvar)
  1254. // @dynamic
  1255. Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl);
  1256. assert (property && "ActOnPropertyImplDecl - property declaration missing");
  1257. ObjCPropertyImplDecl *PIDecl =
  1258. ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc,
  1259. property,
  1260. (Synthesize ?
  1261. ObjCPropertyImplDecl::Synthesize
  1262. : ObjCPropertyImplDecl::Dynamic),
  1263. Ivar, PropertyIvarLoc);
  1264. if (CompleteTypeErr || !compat)
  1265. PIDecl->setInvalidDecl();
  1266. if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
  1267. getterMethod->createImplicitParams(Context, IDecl);
  1268. if (getLangOpts().CPlusPlus && Synthesize && !CompleteTypeErr &&
  1269. Ivar->getType()->isRecordType()) {
  1270. // For Objective-C++, need to synthesize the AST for the IVAR object to be
  1271. // returned by the getter as it must conform to C++'s copy-return rules.
  1272. // FIXME. Eventually we want to do this for Objective-C as well.
  1273. SynthesizedFunctionScope Scope(*this, getterMethod);
  1274. ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl();
  1275. DeclRefExpr *SelfExpr = new (Context)
  1276. DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue,
  1277. PropertyDiagLoc);
  1278. MarkDeclRefReferenced(SelfExpr);
  1279. Expr *LoadSelfExpr =
  1280. ImplicitCastExpr::Create(Context, SelfDecl->getType(),
  1281. CK_LValueToRValue, SelfExpr, nullptr,
  1282. VK_RValue);
  1283. Expr *IvarRefExpr =
  1284. new (Context) ObjCIvarRefExpr(Ivar,
  1285. Ivar->getUsageType(SelfDecl->getType()),
  1286. PropertyDiagLoc,
  1287. Ivar->getLocation(),
  1288. LoadSelfExpr, true, true);
  1289. ExprResult Res = PerformCopyInitialization(
  1290. InitializedEntity::InitializeResult(PropertyDiagLoc,
  1291. getterMethod->getReturnType(),
  1292. /*NRVO=*/false),
  1293. PropertyDiagLoc, IvarRefExpr);
  1294. if (!Res.isInvalid()) {
  1295. Expr *ResExpr = Res.getAs<Expr>();
  1296. if (ResExpr)
  1297. ResExpr = MaybeCreateExprWithCleanups(ResExpr);
  1298. PIDecl->setGetterCXXConstructor(ResExpr);
  1299. }
  1300. }
  1301. if (property->hasAttr<NSReturnsNotRetainedAttr>() &&
  1302. !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
  1303. Diag(getterMethod->getLocation(),
  1304. diag::warn_property_getter_owning_mismatch);
  1305. Diag(property->getLocation(), diag::note_property_declare);
  1306. }
  1307. if (getLangOpts().ObjCAutoRefCount && Synthesize)
  1308. switch (getterMethod->getMethodFamily()) {
  1309. case OMF_retain:
  1310. case OMF_retainCount:
  1311. case OMF_release:
  1312. case OMF_autorelease:
  1313. Diag(getterMethod->getLocation(), diag::err_arc_illegal_method_def)
  1314. << 1 << getterMethod->getSelector();
  1315. break;
  1316. default:
  1317. break;
  1318. }
  1319. }
  1320. if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
  1321. setterMethod->createImplicitParams(Context, IDecl);
  1322. if (getLangOpts().CPlusPlus && Synthesize && !CompleteTypeErr &&
  1323. Ivar->getType()->isRecordType()) {
  1324. // FIXME. Eventually we want to do this for Objective-C as well.
  1325. SynthesizedFunctionScope Scope(*this, setterMethod);
  1326. ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
  1327. DeclRefExpr *SelfExpr = new (Context)
  1328. DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue,
  1329. PropertyDiagLoc);
  1330. MarkDeclRefReferenced(SelfExpr);
  1331. Expr *LoadSelfExpr =
  1332. ImplicitCastExpr::Create(Context, SelfDecl->getType(),
  1333. CK_LValueToRValue, SelfExpr, nullptr,
  1334. VK_RValue);
  1335. Expr *lhs =
  1336. new (Context) ObjCIvarRefExpr(Ivar,
  1337. Ivar->getUsageType(SelfDecl->getType()),
  1338. PropertyDiagLoc,
  1339. Ivar->getLocation(),
  1340. LoadSelfExpr, true, true);
  1341. ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
  1342. ParmVarDecl *Param = (*P);
  1343. QualType T = Param->getType().getNonReferenceType();
  1344. DeclRefExpr *rhs = new (Context)
  1345. DeclRefExpr(Context, Param, false, T, VK_LValue, PropertyDiagLoc);
  1346. MarkDeclRefReferenced(rhs);
  1347. ExprResult Res = BuildBinOp(S, PropertyDiagLoc,
  1348. BO_Assign, lhs, rhs);
  1349. if (property->getPropertyAttributes() &
  1350. ObjCPropertyDecl::OBJC_PR_atomic) {
  1351. Expr *callExpr = Res.getAs<Expr>();
  1352. if (const CXXOperatorCallExpr *CXXCE =
  1353. dyn_cast_or_null<CXXOperatorCallExpr>(callExpr))
  1354. if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
  1355. if (!FuncDecl->isTrivial())
  1356. if (property->getType()->isReferenceType()) {
  1357. Diag(PropertyDiagLoc,
  1358. diag::err_atomic_property_nontrivial_assign_op)
  1359. << property->getType();
  1360. Diag(FuncDecl->getBeginLoc(), diag::note_callee_decl)
  1361. << FuncDecl;
  1362. }
  1363. }
  1364. PIDecl->setSetterCXXAssignment(Res.getAs<Expr>());
  1365. }
  1366. }
  1367. if (IC) {
  1368. if (Synthesize)
  1369. if (ObjCPropertyImplDecl *PPIDecl =
  1370. IC->FindPropertyImplIvarDecl(PropertyIvar)) {
  1371. Diag(PropertyLoc, diag::err_duplicate_ivar_use)
  1372. << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
  1373. << PropertyIvar;
  1374. Diag(PPIDecl->getLocation(), diag::note_previous_use);
  1375. }
  1376. if (ObjCPropertyImplDecl *PPIDecl
  1377. = IC->FindPropertyImplDecl(PropertyId, QueryKind)) {
  1378. Diag(PropertyLoc, diag::err_property_implemented) << PropertyId;
  1379. Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
  1380. return nullptr;
  1381. }
  1382. IC->addPropertyImplementation(PIDecl);
  1383. if (getLangOpts().ObjCDefaultSynthProperties &&
  1384. getLangOpts().ObjCRuntime.isNonFragile() &&
  1385. !IDecl->isObjCRequiresPropertyDefs()) {
  1386. // Diagnose if an ivar was lazily synthesdized due to a previous
  1387. // use and if 1) property is @dynamic or 2) property is synthesized
  1388. // but it requires an ivar of different name.
  1389. ObjCInterfaceDecl *ClassDeclared=nullptr;
  1390. ObjCIvarDecl *Ivar = nullptr;
  1391. if (!Synthesize)
  1392. Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
  1393. else {
  1394. if (PropertyIvar && PropertyIvar != PropertyId)
  1395. Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
  1396. }
  1397. // Issue diagnostics only if Ivar belongs to current class.
  1398. if (Ivar && Ivar->getSynthesize() &&
  1399. declaresSameEntity(IC->getClassInterface(), ClassDeclared)) {
  1400. Diag(Ivar->getLocation(), diag::err_undeclared_var_use)
  1401. << PropertyId;
  1402. Ivar->setInvalidDecl();
  1403. }
  1404. }
  1405. } else {
  1406. if (Synthesize)
  1407. if (ObjCPropertyImplDecl *PPIDecl =
  1408. CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) {
  1409. Diag(PropertyDiagLoc, diag::err_duplicate_ivar_use)
  1410. << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
  1411. << PropertyIvar;
  1412. Diag(PPIDecl->getLocation(), diag::note_previous_use);
  1413. }
  1414. if (ObjCPropertyImplDecl *PPIDecl =
  1415. CatImplClass->FindPropertyImplDecl(PropertyId, QueryKind)) {
  1416. Diag(PropertyDiagLoc, diag::err_property_implemented) << PropertyId;
  1417. Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
  1418. return nullptr;
  1419. }
  1420. CatImplClass->addPropertyImplementation(PIDecl);
  1421. }
  1422. return PIDecl;
  1423. }
  1424. //===----------------------------------------------------------------------===//
  1425. // Helper methods.
  1426. //===----------------------------------------------------------------------===//
  1427. /// DiagnosePropertyMismatch - Compares two properties for their
  1428. /// attributes and types and warns on a variety of inconsistencies.
  1429. ///
  1430. void
  1431. Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
  1432. ObjCPropertyDecl *SuperProperty,
  1433. const IdentifierInfo *inheritedName,
  1434. bool OverridingProtocolProperty) {
  1435. ObjCPropertyDecl::PropertyAttributeKind CAttr =
  1436. Property->getPropertyAttributes();
  1437. ObjCPropertyDecl::PropertyAttributeKind SAttr =
  1438. SuperProperty->getPropertyAttributes();
  1439. // We allow readonly properties without an explicit ownership
  1440. // (assign/unsafe_unretained/weak/retain/strong/copy) in super class
  1441. // to be overridden by a property with any explicit ownership in the subclass.
  1442. if (!OverridingProtocolProperty &&
  1443. !getOwnershipRule(SAttr) && getOwnershipRule(CAttr))
  1444. ;
  1445. else {
  1446. if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
  1447. && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
  1448. Diag(Property->getLocation(), diag::warn_readonly_property)
  1449. << Property->getDeclName() << inheritedName;
  1450. if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
  1451. != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
  1452. Diag(Property->getLocation(), diag::warn_property_attribute)
  1453. << Property->getDeclName() << "copy" << inheritedName;
  1454. else if (!(SAttr & ObjCPropertyDecl::OBJC_PR_readonly)){
  1455. unsigned CAttrRetain =
  1456. (CAttr &
  1457. (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong));
  1458. unsigned SAttrRetain =
  1459. (SAttr &
  1460. (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong));
  1461. bool CStrong = (CAttrRetain != 0);
  1462. bool SStrong = (SAttrRetain != 0);
  1463. if (CStrong != SStrong)
  1464. Diag(Property->getLocation(), diag::warn_property_attribute)
  1465. << Property->getDeclName() << "retain (or strong)" << inheritedName;
  1466. }
  1467. }
  1468. // Check for nonatomic; note that nonatomic is effectively
  1469. // meaningless for readonly properties, so don't diagnose if the
  1470. // atomic property is 'readonly'.
  1471. checkAtomicPropertyMismatch(*this, SuperProperty, Property, false);
  1472. // Readonly properties from protocols can be implemented as "readwrite"
  1473. // with a custom setter name.
  1474. if (Property->getSetterName() != SuperProperty->getSetterName() &&
  1475. !(SuperProperty->isReadOnly() &&
  1476. isa<ObjCProtocolDecl>(SuperProperty->getDeclContext()))) {
  1477. Diag(Property->getLocation(), diag::warn_property_attribute)
  1478. << Property->getDeclName() << "setter" << inheritedName;
  1479. Diag(SuperProperty->getLocation(), diag::note_property_declare);
  1480. }
  1481. if (Property->getGetterName() != SuperProperty->getGetterName()) {
  1482. Diag(Property->getLocation(), diag::warn_property_attribute)
  1483. << Property->getDeclName() << "getter" << inheritedName;
  1484. Diag(SuperProperty->getLocation(), diag::note_property_declare);
  1485. }
  1486. QualType LHSType =
  1487. Context.getCanonicalType(SuperProperty->getType());
  1488. QualType RHSType =
  1489. Context.getCanonicalType(Property->getType());
  1490. if (!Context.propertyTypesAreCompatible(LHSType, RHSType)) {
  1491. // Do cases not handled in above.
  1492. // FIXME. For future support of covariant property types, revisit this.
  1493. bool IncompatibleObjC = false;
  1494. QualType ConvertedType;
  1495. if (!isObjCPointerConversion(RHSType, LHSType,
  1496. ConvertedType, IncompatibleObjC) ||
  1497. IncompatibleObjC) {
  1498. Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)
  1499. << Property->getType() << SuperProperty->getType() << inheritedName;
  1500. Diag(SuperProperty->getLocation(), diag::note_property_declare);
  1501. }
  1502. }
  1503. }
  1504. bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property,
  1505. ObjCMethodDecl *GetterMethod,
  1506. SourceLocation Loc) {
  1507. if (!GetterMethod)
  1508. return false;
  1509. QualType GetterType = GetterMethod->getReturnType().getNonReferenceType();
  1510. QualType PropertyRValueType =
  1511. property->getType().getNonReferenceType().getAtomicUnqualifiedType();
  1512. bool compat = Context.hasSameType(PropertyRValueType, GetterType);
  1513. if (!compat) {
  1514. const ObjCObjectPointerType *propertyObjCPtr = nullptr;
  1515. const ObjCObjectPointerType *getterObjCPtr = nullptr;
  1516. if ((propertyObjCPtr =
  1517. PropertyRValueType->getAs<ObjCObjectPointerType>()) &&
  1518. (getterObjCPtr = GetterType->getAs<ObjCObjectPointerType>()))
  1519. compat = Context.canAssignObjCInterfaces(getterObjCPtr, propertyObjCPtr);
  1520. else if (CheckAssignmentConstraints(Loc, GetterType, PropertyRValueType)
  1521. != Compatible) {
  1522. Diag(Loc, diag::err_property_accessor_type)
  1523. << property->getDeclName() << PropertyRValueType
  1524. << GetterMethod->getSelector() << GetterType;
  1525. Diag(GetterMethod->getLocation(), diag::note_declared_at);
  1526. return true;
  1527. } else {
  1528. compat = true;
  1529. QualType lhsType = Context.getCanonicalType(PropertyRValueType);
  1530. QualType rhsType =Context.getCanonicalType(GetterType).getUnqualifiedType();
  1531. if (lhsType != rhsType && lhsType->isArithmeticType())
  1532. compat = false;
  1533. }
  1534. }
  1535. if (!compat) {
  1536. Diag(Loc, diag::warn_accessor_property_type_mismatch)
  1537. << property->getDeclName()
  1538. << GetterMethod->getSelector();
  1539. Diag(GetterMethod->getLocation(), diag::note_declared_at);
  1540. return true;
  1541. }
  1542. return false;
  1543. }
  1544. /// CollectImmediateProperties - This routine collects all properties in
  1545. /// the class and its conforming protocols; but not those in its super class.
  1546. static void
  1547. CollectImmediateProperties(ObjCContainerDecl *CDecl,
  1548. ObjCContainerDecl::PropertyMap &PropMap,
  1549. ObjCContainerDecl::PropertyMap &SuperPropMap,
  1550. bool CollectClassPropsOnly = false,
  1551. bool IncludeProtocols = true) {
  1552. if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
  1553. for (auto *Prop : IDecl->properties()) {
  1554. if (CollectClassPropsOnly && !Prop->isClassProperty())
  1555. continue;
  1556. PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
  1557. Prop;
  1558. }
  1559. // Collect the properties from visible extensions.
  1560. for (auto *Ext : IDecl->visible_extensions())
  1561. CollectImmediateProperties(Ext, PropMap, SuperPropMap,
  1562. CollectClassPropsOnly, IncludeProtocols);
  1563. if (IncludeProtocols) {
  1564. // Scan through class's protocols.
  1565. for (auto *PI : IDecl->all_referenced_protocols())
  1566. CollectImmediateProperties(PI, PropMap, SuperPropMap,
  1567. CollectClassPropsOnly);
  1568. }
  1569. }
  1570. if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
  1571. for (auto *Prop : CATDecl->properties()) {
  1572. if (CollectClassPropsOnly && !Prop->isClassProperty())
  1573. continue;
  1574. PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
  1575. Prop;
  1576. }
  1577. if (IncludeProtocols) {
  1578. // Scan through class's protocols.
  1579. for (auto *PI : CATDecl->protocols())
  1580. CollectImmediateProperties(PI, PropMap, SuperPropMap,
  1581. CollectClassPropsOnly);
  1582. }
  1583. }
  1584. else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
  1585. for (auto *Prop : PDecl->properties()) {
  1586. if (CollectClassPropsOnly && !Prop->isClassProperty())
  1587. continue;
  1588. ObjCPropertyDecl *PropertyFromSuper =
  1589. SuperPropMap[std::make_pair(Prop->getIdentifier(),
  1590. Prop->isClassProperty())];
  1591. // Exclude property for protocols which conform to class's super-class,
  1592. // as super-class has to implement the property.
  1593. if (!PropertyFromSuper ||
  1594. PropertyFromSuper->getIdentifier() != Prop->getIdentifier()) {
  1595. ObjCPropertyDecl *&PropEntry =
  1596. PropMap[std::make_pair(Prop->getIdentifier(),
  1597. Prop->isClassProperty())];
  1598. if (!PropEntry)
  1599. PropEntry = Prop;
  1600. }
  1601. }
  1602. // Scan through protocol's protocols.
  1603. for (auto *PI : PDecl->protocols())
  1604. CollectImmediateProperties(PI, PropMap, SuperPropMap,
  1605. CollectClassPropsOnly);
  1606. }
  1607. }
  1608. /// CollectSuperClassPropertyImplementations - This routine collects list of
  1609. /// properties to be implemented in super class(s) and also coming from their
  1610. /// conforming protocols.
  1611. static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl,
  1612. ObjCInterfaceDecl::PropertyMap &PropMap) {
  1613. if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) {
  1614. ObjCInterfaceDecl::PropertyDeclOrder PO;
  1615. while (SDecl) {
  1616. SDecl->collectPropertiesToImplement(PropMap, PO);
  1617. SDecl = SDecl->getSuperClass();
  1618. }
  1619. }
  1620. }
  1621. /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is
  1622. /// an ivar synthesized for 'Method' and 'Method' is a property accessor
  1623. /// declared in class 'IFace'.
  1624. bool
  1625. Sema::IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace,
  1626. ObjCMethodDecl *Method, ObjCIvarDecl *IV) {
  1627. if (!IV->getSynthesize())
  1628. return false;
  1629. ObjCMethodDecl *IMD = IFace->lookupMethod(Method->getSelector(),
  1630. Method->isInstanceMethod());
  1631. if (!IMD || !IMD->isPropertyAccessor())
  1632. return false;
  1633. // look up a property declaration whose one of its accessors is implemented
  1634. // by this method.
  1635. for (const auto *Property : IFace->instance_properties()) {
  1636. if ((Property->getGetterName() == IMD->getSelector() ||
  1637. Property->getSetterName() == IMD->getSelector()) &&
  1638. (Property->getPropertyIvarDecl() == IV))
  1639. return true;
  1640. }
  1641. // Also look up property declaration in class extension whose one of its
  1642. // accessors is implemented by this method.
  1643. for (const auto *Ext : IFace->known_extensions())
  1644. for (const auto *Property : Ext->instance_properties())
  1645. if ((Property->getGetterName() == IMD->getSelector() ||
  1646. Property->getSetterName() == IMD->getSelector()) &&
  1647. (Property->getPropertyIvarDecl() == IV))
  1648. return true;
  1649. return false;
  1650. }
  1651. static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl,
  1652. ObjCPropertyDecl *Prop) {
  1653. bool SuperClassImplementsGetter = false;
  1654. bool SuperClassImplementsSetter = false;
  1655. if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly)
  1656. SuperClassImplementsSetter = true;
  1657. while (IDecl->getSuperClass()) {
  1658. ObjCInterfaceDecl *SDecl = IDecl->getSuperClass();
  1659. if (!SuperClassImplementsGetter && SDecl->getInstanceMethod(Prop->getGetterName()))
  1660. SuperClassImplementsGetter = true;
  1661. if (!SuperClassImplementsSetter && SDecl->getInstanceMethod(Prop->getSetterName()))
  1662. SuperClassImplementsSetter = true;
  1663. if (SuperClassImplementsGetter && SuperClassImplementsSetter)
  1664. return true;
  1665. IDecl = IDecl->getSuperClass();
  1666. }
  1667. return false;
  1668. }
  1669. /// Default synthesizes all properties which must be synthesized
  1670. /// in class's \@implementation.
  1671. void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl,
  1672. ObjCInterfaceDecl *IDecl,
  1673. SourceLocation AtEnd) {
  1674. ObjCInterfaceDecl::PropertyMap PropMap;
  1675. ObjCInterfaceDecl::PropertyDeclOrder PropertyOrder;
  1676. IDecl->collectPropertiesToImplement(PropMap, PropertyOrder);
  1677. if (PropMap.empty())
  1678. return;
  1679. ObjCInterfaceDecl::PropertyMap SuperPropMap;
  1680. CollectSuperClassPropertyImplementations(IDecl, SuperPropMap);
  1681. for (unsigned i = 0, e = PropertyOrder.size(); i != e; i++) {
  1682. ObjCPropertyDecl *Prop = PropertyOrder[i];
  1683. // Is there a matching property synthesize/dynamic?
  1684. if (Prop->isInvalidDecl() ||
  1685. Prop->isClassProperty() ||
  1686. Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional)
  1687. continue;
  1688. // Property may have been synthesized by user.
  1689. if (IMPDecl->FindPropertyImplDecl(
  1690. Prop->getIdentifier(), Prop->getQueryKind()))
  1691. continue;
  1692. if (IMPDecl->getInstanceMethod(Prop->getGetterName())) {
  1693. if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly)
  1694. continue;
  1695. if (IMPDecl->getInstanceMethod(Prop->getSetterName()))
  1696. continue;
  1697. }
  1698. if (ObjCPropertyImplDecl *PID =
  1699. IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) {
  1700. Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
  1701. << Prop->getIdentifier();
  1702. if (PID->getLocation().isValid())
  1703. Diag(PID->getLocation(), diag::note_property_synthesize);
  1704. continue;
  1705. }
  1706. ObjCPropertyDecl *PropInSuperClass =
  1707. SuperPropMap[std::make_pair(Prop->getIdentifier(),
  1708. Prop->isClassProperty())];
  1709. if (ObjCProtocolDecl *Proto =
  1710. dyn_cast<ObjCProtocolDecl>(Prop->getDeclContext())) {
  1711. // We won't auto-synthesize properties declared in protocols.
  1712. // Suppress the warning if class's superclass implements property's
  1713. // getter and implements property's setter (if readwrite property).
  1714. // Or, if property is going to be implemented in its super class.
  1715. if (!SuperClassImplementsProperty(IDecl, Prop) && !PropInSuperClass) {
  1716. Diag(IMPDecl->getLocation(),
  1717. diag::warn_auto_synthesizing_protocol_property)
  1718. << Prop << Proto;
  1719. Diag(Prop->getLocation(), diag::note_property_declare);
  1720. std::string FixIt =
  1721. (Twine("@synthesize ") + Prop->getName() + ";\n\n").str();
  1722. Diag(AtEnd, diag::note_add_synthesize_directive)
  1723. << FixItHint::CreateInsertion(AtEnd, FixIt);
  1724. }
  1725. continue;
  1726. }
  1727. // If property to be implemented in the super class, ignore.
  1728. if (PropInSuperClass) {
  1729. if ((Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite) &&
  1730. (PropInSuperClass->getPropertyAttributes() &
  1731. ObjCPropertyDecl::OBJC_PR_readonly) &&
  1732. !IMPDecl->getInstanceMethod(Prop->getSetterName()) &&
  1733. !IDecl->HasUserDeclaredSetterMethod(Prop)) {
  1734. Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property)
  1735. << Prop->getIdentifier();
  1736. Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
  1737. }
  1738. else {
  1739. Diag(Prop->getLocation(), diag::warn_autosynthesis_property_in_superclass)
  1740. << Prop->getIdentifier();
  1741. Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
  1742. Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);
  1743. }
  1744. continue;
  1745. }
  1746. // We use invalid SourceLocations for the synthesized ivars since they
  1747. // aren't really synthesized at a particular location; they just exist.
  1748. // Saying that they are located at the @implementation isn't really going
  1749. // to help users.
  1750. ObjCPropertyImplDecl *PIDecl = dyn_cast_or_null<ObjCPropertyImplDecl>(
  1751. ActOnPropertyImplDecl(S, SourceLocation(), SourceLocation(),
  1752. true,
  1753. /* property = */ Prop->getIdentifier(),
  1754. /* ivar = */ Prop->getDefaultSynthIvarName(Context),
  1755. Prop->getLocation(), Prop->getQueryKind()));
  1756. if (PIDecl && !Prop->isUnavailable()) {
  1757. Diag(Prop->getLocation(), diag::warn_missing_explicit_synthesis);
  1758. Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);
  1759. }
  1760. }
  1761. }
  1762. void Sema::DefaultSynthesizeProperties(Scope *S, Decl *D,
  1763. SourceLocation AtEnd) {
  1764. if (!LangOpts.ObjCDefaultSynthProperties || LangOpts.ObjCRuntime.isFragile())
  1765. return;
  1766. ObjCImplementationDecl *IC=dyn_cast_or_null<ObjCImplementationDecl>(D);
  1767. if (!IC)
  1768. return;
  1769. if (ObjCInterfaceDecl* IDecl = IC->getClassInterface())
  1770. if (!IDecl->isObjCRequiresPropertyDefs())
  1771. DefaultSynthesizeProperties(S, IC, IDecl, AtEnd);
  1772. }
  1773. static void DiagnoseUnimplementedAccessor(
  1774. Sema &S, ObjCInterfaceDecl *PrimaryClass, Selector Method,
  1775. ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, ObjCCategoryDecl *C,
  1776. ObjCPropertyDecl *Prop,
  1777. llvm::SmallPtrSet<const ObjCMethodDecl *, 8> &SMap) {
  1778. // Check to see if we have a corresponding selector in SMap and with the
  1779. // right method type.
  1780. auto I = llvm::find_if(SMap, [&](const ObjCMethodDecl *x) {
  1781. return x->getSelector() == Method &&
  1782. x->isClassMethod() == Prop->isClassProperty();
  1783. });
  1784. // When reporting on missing property setter/getter implementation in
  1785. // categories, do not report when they are declared in primary class,
  1786. // class's protocol, or one of it super classes. This is because,
  1787. // the class is going to implement them.
  1788. if (I == SMap.end() &&
  1789. (PrimaryClass == nullptr ||
  1790. !PrimaryClass->lookupPropertyAccessor(Method, C,
  1791. Prop->isClassProperty()))) {
  1792. unsigned diag =
  1793. isa<ObjCCategoryDecl>(CDecl)
  1794. ? (Prop->isClassProperty()
  1795. ? diag::warn_impl_required_in_category_for_class_property
  1796. : diag::warn_setter_getter_impl_required_in_category)
  1797. : (Prop->isClassProperty()
  1798. ? diag::warn_impl_required_for_class_property
  1799. : diag::warn_setter_getter_impl_required);
  1800. S.Diag(IMPDecl->getLocation(), diag) << Prop->getDeclName() << Method;
  1801. S.Diag(Prop->getLocation(), diag::note_property_declare);
  1802. if (S.LangOpts.ObjCDefaultSynthProperties &&
  1803. S.LangOpts.ObjCRuntime.isNonFragile())
  1804. if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl))
  1805. if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs())
  1806. S.Diag(RID->getLocation(), diag::note_suppressed_class_declare);
  1807. }
  1808. }
  1809. void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
  1810. ObjCContainerDecl *CDecl,
  1811. bool SynthesizeProperties) {
  1812. ObjCContainerDecl::PropertyMap PropMap;
  1813. ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
  1814. // Since we don't synthesize class properties, we should emit diagnose even
  1815. // if SynthesizeProperties is true.
  1816. ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
  1817. // Gather properties which need not be implemented in this class
  1818. // or category.
  1819. if (!IDecl)
  1820. if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
  1821. // For categories, no need to implement properties declared in
  1822. // its primary class (and its super classes) if property is
  1823. // declared in one of those containers.
  1824. if ((IDecl = C->getClassInterface())) {
  1825. ObjCInterfaceDecl::PropertyDeclOrder PO;
  1826. IDecl->collectPropertiesToImplement(NoNeedToImplPropMap, PO);
  1827. }
  1828. }
  1829. if (IDecl)
  1830. CollectSuperClassPropertyImplementations(IDecl, NoNeedToImplPropMap);
  1831. // When SynthesizeProperties is true, we only check class properties.
  1832. CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap,
  1833. SynthesizeProperties/*CollectClassPropsOnly*/);
  1834. // Scan the @interface to see if any of the protocols it adopts
  1835. // require an explicit implementation, via attribute
  1836. // 'objc_protocol_requires_explicit_implementation'.
  1837. if (IDecl) {
  1838. std::unique_ptr<ObjCContainerDecl::PropertyMap> LazyMap;
  1839. for (auto *PDecl : IDecl->all_referenced_protocols()) {
  1840. if (!PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
  1841. continue;
  1842. // Lazily construct a set of all the properties in the @interface
  1843. // of the class, without looking at the superclass. We cannot
  1844. // use the call to CollectImmediateProperties() above as that
  1845. // utilizes information from the super class's properties as well
  1846. // as scans the adopted protocols. This work only triggers for protocols
  1847. // with the attribute, which is very rare, and only occurs when
  1848. // analyzing the @implementation.
  1849. if (!LazyMap) {
  1850. ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
  1851. LazyMap.reset(new ObjCContainerDecl::PropertyMap());
  1852. CollectImmediateProperties(CDecl, *LazyMap, NoNeedToImplPropMap,
  1853. /* CollectClassPropsOnly */ false,
  1854. /* IncludeProtocols */ false);
  1855. }
  1856. // Add the properties of 'PDecl' to the list of properties that
  1857. // need to be implemented.
  1858. for (auto *PropDecl : PDecl->properties()) {
  1859. if ((*LazyMap)[std::make_pair(PropDecl->getIdentifier(),
  1860. PropDecl->isClassProperty())])
  1861. continue;
  1862. PropMap[std::make_pair(PropDecl->getIdentifier(),
  1863. PropDecl->isClassProperty())] = PropDecl;
  1864. }
  1865. }
  1866. }
  1867. if (PropMap.empty())
  1868. return;
  1869. llvm::DenseSet<ObjCPropertyDecl *> PropImplMap;
  1870. for (const auto *I : IMPDecl->property_impls())
  1871. PropImplMap.insert(I->getPropertyDecl());
  1872. llvm::SmallPtrSet<const ObjCMethodDecl *, 8> InsMap;
  1873. // Collect property accessors implemented in current implementation.
  1874. for (const auto *I : IMPDecl->methods())
  1875. InsMap.insert(I);
  1876. ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
  1877. ObjCInterfaceDecl *PrimaryClass = nullptr;
  1878. if (C && !C->IsClassExtension())
  1879. if ((PrimaryClass = C->getClassInterface()))
  1880. // Report unimplemented properties in the category as well.
  1881. if (ObjCImplDecl *IMP = PrimaryClass->getImplementation()) {
  1882. // When reporting on missing setter/getters, do not report when
  1883. // setter/getter is implemented in category's primary class
  1884. // implementation.
  1885. for (const auto *I : IMP->methods())
  1886. InsMap.insert(I);
  1887. }
  1888. for (ObjCContainerDecl::PropertyMap::iterator
  1889. P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
  1890. ObjCPropertyDecl *Prop = P->second;
  1891. // Is there a matching property synthesize/dynamic?
  1892. if (Prop->isInvalidDecl() ||
  1893. Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
  1894. PropImplMap.count(Prop) ||
  1895. Prop->getAvailability() == AR_Unavailable)
  1896. continue;
  1897. // Diagnose unimplemented getters and setters.
  1898. DiagnoseUnimplementedAccessor(*this,
  1899. PrimaryClass, Prop->getGetterName(), IMPDecl, CDecl, C, Prop, InsMap);
  1900. if (!Prop->isReadOnly())
  1901. DiagnoseUnimplementedAccessor(*this,
  1902. PrimaryClass, Prop->getSetterName(),
  1903. IMPDecl, CDecl, C, Prop, InsMap);
  1904. }
  1905. }
  1906. void Sema::diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl) {
  1907. for (const auto *propertyImpl : impDecl->property_impls()) {
  1908. const auto *property = propertyImpl->getPropertyDecl();
  1909. // Warn about null_resettable properties with synthesized setters,
  1910. // because the setter won't properly handle nil.
  1911. if (propertyImpl->getPropertyImplementation()
  1912. == ObjCPropertyImplDecl::Synthesize &&
  1913. (property->getPropertyAttributes() &
  1914. ObjCPropertyDecl::OBJC_PR_null_resettable) &&
  1915. property->getGetterMethodDecl() &&
  1916. property->getSetterMethodDecl()) {
  1917. auto *getterMethod = property->getGetterMethodDecl();
  1918. auto *setterMethod = property->getSetterMethodDecl();
  1919. if (!impDecl->getInstanceMethod(setterMethod->getSelector()) &&
  1920. !impDecl->getInstanceMethod(getterMethod->getSelector())) {
  1921. SourceLocation loc = propertyImpl->getLocation();
  1922. if (loc.isInvalid())
  1923. loc = impDecl->getBeginLoc();
  1924. Diag(loc, diag::warn_null_resettable_setter)
  1925. << setterMethod->getSelector() << property->getDeclName();
  1926. }
  1927. }
  1928. }
  1929. }
  1930. void
  1931. Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl,
  1932. ObjCInterfaceDecl* IDecl) {
  1933. // Rules apply in non-GC mode only
  1934. if (getLangOpts().getGC() != LangOptions::NonGC)
  1935. return;
  1936. ObjCContainerDecl::PropertyMap PM;
  1937. for (auto *Prop : IDecl->properties())
  1938. PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
  1939. for (const auto *Ext : IDecl->known_extensions())
  1940. for (auto *Prop : Ext->properties())
  1941. PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
  1942. for (ObjCContainerDecl::PropertyMap::iterator I = PM.begin(), E = PM.end();
  1943. I != E; ++I) {
  1944. const ObjCPropertyDecl *Property = I->second;
  1945. ObjCMethodDecl *GetterMethod = nullptr;
  1946. ObjCMethodDecl *SetterMethod = nullptr;
  1947. bool LookedUpGetterSetter = false;
  1948. unsigned Attributes = Property->getPropertyAttributes();
  1949. unsigned AttributesAsWritten = Property->getPropertyAttributesAsWritten();
  1950. if (!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic) &&
  1951. !(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_nonatomic)) {
  1952. GetterMethod = Property->isClassProperty() ?
  1953. IMPDecl->getClassMethod(Property->getGetterName()) :
  1954. IMPDecl->getInstanceMethod(Property->getGetterName());
  1955. SetterMethod = Property->isClassProperty() ?
  1956. IMPDecl->getClassMethod(Property->getSetterName()) :
  1957. IMPDecl->getInstanceMethod(Property->getSetterName());
  1958. LookedUpGetterSetter = true;
  1959. if (GetterMethod) {
  1960. Diag(GetterMethod->getLocation(),
  1961. diag::warn_default_atomic_custom_getter_setter)
  1962. << Property->getIdentifier() << 0;
  1963. Diag(Property->getLocation(), diag::note_property_declare);
  1964. }
  1965. if (SetterMethod) {
  1966. Diag(SetterMethod->getLocation(),
  1967. diag::warn_default_atomic_custom_getter_setter)
  1968. << Property->getIdentifier() << 1;
  1969. Diag(Property->getLocation(), diag::note_property_declare);
  1970. }
  1971. }
  1972. // We only care about readwrite atomic property.
  1973. if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) ||
  1974. !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite))
  1975. continue;
  1976. if (const ObjCPropertyImplDecl *PIDecl = IMPDecl->FindPropertyImplDecl(
  1977. Property->getIdentifier(), Property->getQueryKind())) {
  1978. if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
  1979. continue;
  1980. if (!LookedUpGetterSetter) {
  1981. GetterMethod = Property->isClassProperty() ?
  1982. IMPDecl->getClassMethod(Property->getGetterName()) :
  1983. IMPDecl->getInstanceMethod(Property->getGetterName());
  1984. SetterMethod = Property->isClassProperty() ?
  1985. IMPDecl->getClassMethod(Property->getSetterName()) :
  1986. IMPDecl->getInstanceMethod(Property->getSetterName());
  1987. }
  1988. if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) {
  1989. SourceLocation MethodLoc =
  1990. (GetterMethod ? GetterMethod->getLocation()
  1991. : SetterMethod->getLocation());
  1992. Diag(MethodLoc, diag::warn_atomic_property_rule)
  1993. << Property->getIdentifier() << (GetterMethod != nullptr)
  1994. << (SetterMethod != nullptr);
  1995. // fixit stuff.
  1996. if (Property->getLParenLoc().isValid() &&
  1997. !(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic)) {
  1998. // @property () ... case.
  1999. SourceLocation AfterLParen =
  2000. getLocForEndOfToken(Property->getLParenLoc());
  2001. StringRef NonatomicStr = AttributesAsWritten? "nonatomic, "
  2002. : "nonatomic";
  2003. Diag(Property->getLocation(),
  2004. diag::note_atomic_property_fixup_suggest)
  2005. << FixItHint::CreateInsertion(AfterLParen, NonatomicStr);
  2006. } else if (Property->getLParenLoc().isInvalid()) {
  2007. //@property id etc.
  2008. SourceLocation startLoc =
  2009. Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
  2010. Diag(Property->getLocation(),
  2011. diag::note_atomic_property_fixup_suggest)
  2012. << FixItHint::CreateInsertion(startLoc, "(nonatomic) ");
  2013. }
  2014. else
  2015. Diag(MethodLoc, diag::note_atomic_property_fixup_suggest);
  2016. Diag(Property->getLocation(), diag::note_property_declare);
  2017. }
  2018. }
  2019. }
  2020. }
  2021. void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D) {
  2022. if (getLangOpts().getGC() == LangOptions::GCOnly)
  2023. return;
  2024. for (const auto *PID : D->property_impls()) {
  2025. const ObjCPropertyDecl *PD = PID->getPropertyDecl();
  2026. if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() &&
  2027. !PD->isClassProperty() &&
  2028. !D->getInstanceMethod(PD->getGetterName())) {
  2029. ObjCMethodDecl *method = PD->getGetterMethodDecl();
  2030. if (!method)
  2031. continue;
  2032. ObjCMethodFamily family = method->getMethodFamily();
  2033. if (family == OMF_alloc || family == OMF_copy ||
  2034. family == OMF_mutableCopy || family == OMF_new) {
  2035. if (getLangOpts().ObjCAutoRefCount)
  2036. Diag(PD->getLocation(), diag::err_cocoa_naming_owned_rule);
  2037. else
  2038. Diag(PD->getLocation(), diag::warn_cocoa_naming_owned_rule);
  2039. // Look for a getter explicitly declared alongside the property.
  2040. // If we find one, use its location for the note.
  2041. SourceLocation noteLoc = PD->getLocation();
  2042. SourceLocation fixItLoc;
  2043. for (auto *getterRedecl : method->redecls()) {
  2044. if (getterRedecl->isImplicit())
  2045. continue;
  2046. if (getterRedecl->getDeclContext() != PD->getDeclContext())
  2047. continue;
  2048. noteLoc = getterRedecl->getLocation();
  2049. fixItLoc = getterRedecl->getEndLoc();
  2050. }
  2051. Preprocessor &PP = getPreprocessor();
  2052. TokenValue tokens[] = {
  2053. tok::kw___attribute, tok::l_paren, tok::l_paren,
  2054. PP.getIdentifierInfo("objc_method_family"), tok::l_paren,
  2055. PP.getIdentifierInfo("none"), tok::r_paren,
  2056. tok::r_paren, tok::r_paren
  2057. };
  2058. StringRef spelling = "__attribute__((objc_method_family(none)))";
  2059. StringRef macroName = PP.getLastMacroWithSpelling(noteLoc, tokens);
  2060. if (!macroName.empty())
  2061. spelling = macroName;
  2062. auto noteDiag = Diag(noteLoc, diag::note_cocoa_naming_declare_family)
  2063. << method->getDeclName() << spelling;
  2064. if (fixItLoc.isValid()) {
  2065. SmallString<64> fixItText(" ");
  2066. fixItText += spelling;
  2067. noteDiag << FixItHint::CreateInsertion(fixItLoc, fixItText);
  2068. }
  2069. }
  2070. }
  2071. }
  2072. }
  2073. void Sema::DiagnoseMissingDesignatedInitOverrides(
  2074. const ObjCImplementationDecl *ImplD,
  2075. const ObjCInterfaceDecl *IFD) {
  2076. assert(IFD->hasDesignatedInitializers());
  2077. const ObjCInterfaceDecl *SuperD = IFD->getSuperClass();
  2078. if (!SuperD)
  2079. return;
  2080. SelectorSet InitSelSet;
  2081. for (const auto *I : ImplD->instance_methods())
  2082. if (I->getMethodFamily() == OMF_init)
  2083. InitSelSet.insert(I->getSelector());
  2084. SmallVector<const ObjCMethodDecl *, 8> DesignatedInits;
  2085. SuperD->getDesignatedInitializers(DesignatedInits);
  2086. for (SmallVector<const ObjCMethodDecl *, 8>::iterator
  2087. I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
  2088. const ObjCMethodDecl *MD = *I;
  2089. if (!InitSelSet.count(MD->getSelector())) {
  2090. // Don't emit a diagnostic if the overriding method in the subclass is
  2091. // marked as unavailable.
  2092. bool Ignore = false;
  2093. if (auto *IMD = IFD->getInstanceMethod(MD->getSelector())) {
  2094. Ignore = IMD->isUnavailable();
  2095. } else {
  2096. // Check the methods declared in the class extensions too.
  2097. for (auto *Ext : IFD->visible_extensions())
  2098. if (auto *IMD = Ext->getInstanceMethod(MD->getSelector())) {
  2099. Ignore = IMD->isUnavailable();
  2100. break;
  2101. }
  2102. }
  2103. if (!Ignore) {
  2104. Diag(ImplD->getLocation(),
  2105. diag::warn_objc_implementation_missing_designated_init_override)
  2106. << MD->getSelector();
  2107. Diag(MD->getLocation(), diag::note_objc_designated_init_marked_here);
  2108. }
  2109. }
  2110. }
  2111. }
  2112. /// AddPropertyAttrs - Propagates attributes from a property to the
  2113. /// implicitly-declared getter or setter for that property.
  2114. static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod,
  2115. ObjCPropertyDecl *Property) {
  2116. // Should we just clone all attributes over?
  2117. for (const auto *A : Property->attrs()) {
  2118. if (isa<DeprecatedAttr>(A) ||
  2119. isa<UnavailableAttr>(A) ||
  2120. isa<AvailabilityAttr>(A))
  2121. PropertyMethod->addAttr(A->clone(S.Context));
  2122. }
  2123. }
  2124. /// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods
  2125. /// have the property type and issue diagnostics if they don't.
  2126. /// Also synthesize a getter/setter method if none exist (and update the
  2127. /// appropriate lookup tables.
  2128. void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property) {
  2129. ObjCMethodDecl *GetterMethod, *SetterMethod;
  2130. ObjCContainerDecl *CD = cast<ObjCContainerDecl>(property->getDeclContext());
  2131. if (CD->isInvalidDecl())
  2132. return;
  2133. bool IsClassProperty = property->isClassProperty();
  2134. GetterMethod = IsClassProperty ?
  2135. CD->getClassMethod(property->getGetterName()) :
  2136. CD->getInstanceMethod(property->getGetterName());
  2137. // if setter or getter is not found in class extension, it might be
  2138. // in the primary class.
  2139. if (!GetterMethod)
  2140. if (const ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CD))
  2141. if (CatDecl->IsClassExtension())
  2142. GetterMethod = IsClassProperty ? CatDecl->getClassInterface()->
  2143. getClassMethod(property->getGetterName()) :
  2144. CatDecl->getClassInterface()->
  2145. getInstanceMethod(property->getGetterName());
  2146. SetterMethod = IsClassProperty ?
  2147. CD->getClassMethod(property->getSetterName()) :
  2148. CD->getInstanceMethod(property->getSetterName());
  2149. if (!SetterMethod)
  2150. if (const ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CD))
  2151. if (CatDecl->IsClassExtension())
  2152. SetterMethod = IsClassProperty ? CatDecl->getClassInterface()->
  2153. getClassMethod(property->getSetterName()) :
  2154. CatDecl->getClassInterface()->
  2155. getInstanceMethod(property->getSetterName());
  2156. DiagnosePropertyAccessorMismatch(property, GetterMethod,
  2157. property->getLocation());
  2158. if (!property->isReadOnly() && SetterMethod) {
  2159. if (Context.getCanonicalType(SetterMethod->getReturnType()) !=
  2160. Context.VoidTy)
  2161. Diag(SetterMethod->getLocation(), diag::err_setter_type_void);
  2162. if (SetterMethod->param_size() != 1 ||
  2163. !Context.hasSameUnqualifiedType(
  2164. (*SetterMethod->param_begin())->getType().getNonReferenceType(),
  2165. property->getType().getNonReferenceType())) {
  2166. Diag(property->getLocation(),
  2167. diag::warn_accessor_property_type_mismatch)
  2168. << property->getDeclName()
  2169. << SetterMethod->getSelector();
  2170. Diag(SetterMethod->getLocation(), diag::note_declared_at);
  2171. }
  2172. }
  2173. // Synthesize getter/setter methods if none exist.
  2174. // Find the default getter and if one not found, add one.
  2175. // FIXME: The synthesized property we set here is misleading. We almost always
  2176. // synthesize these methods unless the user explicitly provided prototypes
  2177. // (which is odd, but allowed). Sema should be typechecking that the
  2178. // declarations jive in that situation (which it is not currently).
  2179. if (!GetterMethod) {
  2180. // No instance/class method of same name as property getter name was found.
  2181. // Declare a getter method and add it to the list of methods
  2182. // for this class.
  2183. SourceLocation Loc = property->getLocation();
  2184. // The getter returns the declared property type with all qualifiers
  2185. // removed.
  2186. QualType resultTy = property->getType().getAtomicUnqualifiedType();
  2187. // If the property is null_resettable, the getter returns nonnull.
  2188. if (property->getPropertyAttributes() &
  2189. ObjCPropertyDecl::OBJC_PR_null_resettable) {
  2190. QualType modifiedTy = resultTy;
  2191. if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {
  2192. if (*nullability == NullabilityKind::Unspecified)
  2193. resultTy = Context.getAttributedType(attr::TypeNonNull,
  2194. modifiedTy, modifiedTy);
  2195. }
  2196. }
  2197. GetterMethod = ObjCMethodDecl::Create(Context, Loc, Loc,
  2198. property->getGetterName(),
  2199. resultTy, nullptr, CD,
  2200. !IsClassProperty, /*isVariadic=*/false,
  2201. /*isPropertyAccessor=*/true,
  2202. /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
  2203. (property->getPropertyImplementation() ==
  2204. ObjCPropertyDecl::Optional) ?
  2205. ObjCMethodDecl::Optional :
  2206. ObjCMethodDecl::Required);
  2207. CD->addDecl(GetterMethod);
  2208. AddPropertyAttrs(*this, GetterMethod, property);
  2209. if (property->hasAttr<NSReturnsNotRetainedAttr>())
  2210. GetterMethod->addAttr(NSReturnsNotRetainedAttr::CreateImplicit(Context,
  2211. Loc));
  2212. if (property->hasAttr<ObjCReturnsInnerPointerAttr>())
  2213. GetterMethod->addAttr(
  2214. ObjCReturnsInnerPointerAttr::CreateImplicit(Context, Loc));
  2215. if (const SectionAttr *SA = property->getAttr<SectionAttr>())
  2216. GetterMethod->addAttr(SectionAttr::CreateImplicit(
  2217. Context, SA->getName(), Loc, AttributeCommonInfo::AS_GNU,
  2218. SectionAttr::GNU_section));
  2219. if (getLangOpts().ObjCAutoRefCount)
  2220. CheckARCMethodDecl(GetterMethod);
  2221. } else
  2222. // A user declared getter will be synthesize when @synthesize of
  2223. // the property with the same name is seen in the @implementation
  2224. GetterMethod->setPropertyAccessor(true);
  2225. property->setGetterMethodDecl(GetterMethod);
  2226. // Skip setter if property is read-only.
  2227. if (!property->isReadOnly()) {
  2228. // Find the default setter and if one not found, add one.
  2229. if (!SetterMethod) {
  2230. // No instance/class method of same name as property setter name was
  2231. // found.
  2232. // Declare a setter method and add it to the list of methods
  2233. // for this class.
  2234. SourceLocation Loc = property->getLocation();
  2235. SetterMethod =
  2236. ObjCMethodDecl::Create(Context, Loc, Loc,
  2237. property->getSetterName(), Context.VoidTy,
  2238. nullptr, CD, !IsClassProperty,
  2239. /*isVariadic=*/false,
  2240. /*isPropertyAccessor=*/true,
  2241. /*isImplicitlyDeclared=*/true,
  2242. /*isDefined=*/false,
  2243. (property->getPropertyImplementation() ==
  2244. ObjCPropertyDecl::Optional) ?
  2245. ObjCMethodDecl::Optional :
  2246. ObjCMethodDecl::Required);
  2247. // Remove all qualifiers from the setter's parameter type.
  2248. QualType paramTy =
  2249. property->getType().getUnqualifiedType().getAtomicUnqualifiedType();
  2250. // If the property is null_resettable, the setter accepts a
  2251. // nullable value.
  2252. if (property->getPropertyAttributes() &
  2253. ObjCPropertyDecl::OBJC_PR_null_resettable) {
  2254. QualType modifiedTy = paramTy;
  2255. if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)){
  2256. if (*nullability == NullabilityKind::Unspecified)
  2257. paramTy = Context.getAttributedType(attr::TypeNullable,
  2258. modifiedTy, modifiedTy);
  2259. }
  2260. }
  2261. // Invent the arguments for the setter. We don't bother making a
  2262. // nice name for the argument.
  2263. ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod,
  2264. Loc, Loc,
  2265. property->getIdentifier(),
  2266. paramTy,
  2267. /*TInfo=*/nullptr,
  2268. SC_None,
  2269. nullptr);
  2270. SetterMethod->setMethodParams(Context, Argument, None);
  2271. AddPropertyAttrs(*this, SetterMethod, property);
  2272. CD->addDecl(SetterMethod);
  2273. if (const SectionAttr *SA = property->getAttr<SectionAttr>())
  2274. SetterMethod->addAttr(SectionAttr::CreateImplicit(
  2275. Context, SA->getName(), Loc, AttributeCommonInfo::AS_GNU,
  2276. SectionAttr::GNU_section));
  2277. // It's possible for the user to have set a very odd custom
  2278. // setter selector that causes it to have a method family.
  2279. if (getLangOpts().ObjCAutoRefCount)
  2280. CheckARCMethodDecl(SetterMethod);
  2281. } else
  2282. // A user declared setter will be synthesize when @synthesize of
  2283. // the property with the same name is seen in the @implementation
  2284. SetterMethod->setPropertyAccessor(true);
  2285. property->setSetterMethodDecl(SetterMethod);
  2286. }
  2287. // Add any synthesized methods to the global pool. This allows us to
  2288. // handle the following, which is supported by GCC (and part of the design).
  2289. //
  2290. // @interface Foo
  2291. // @property double bar;
  2292. // @end
  2293. //
  2294. // void thisIsUnfortunate() {
  2295. // id foo;
  2296. // double bar = [foo bar];
  2297. // }
  2298. //
  2299. if (!IsClassProperty) {
  2300. if (GetterMethod)
  2301. AddInstanceMethodToGlobalPool(GetterMethod);
  2302. if (SetterMethod)
  2303. AddInstanceMethodToGlobalPool(SetterMethod);
  2304. } else {
  2305. if (GetterMethod)
  2306. AddFactoryMethodToGlobalPool(GetterMethod);
  2307. if (SetterMethod)
  2308. AddFactoryMethodToGlobalPool(SetterMethod);
  2309. }
  2310. ObjCInterfaceDecl *CurrentClass = dyn_cast<ObjCInterfaceDecl>(CD);
  2311. if (!CurrentClass) {
  2312. if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CD))
  2313. CurrentClass = Cat->getClassInterface();
  2314. else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(CD))
  2315. CurrentClass = Impl->getClassInterface();
  2316. }
  2317. if (GetterMethod)
  2318. CheckObjCMethodOverrides(GetterMethod, CurrentClass, Sema::RTC_Unknown);
  2319. if (SetterMethod)
  2320. CheckObjCMethodOverrides(SetterMethod, CurrentClass, Sema::RTC_Unknown);
  2321. }
  2322. void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
  2323. SourceLocation Loc,
  2324. unsigned &Attributes,
  2325. bool propertyInPrimaryClass) {
  2326. // FIXME: Improve the reported location.
  2327. if (!PDecl || PDecl->isInvalidDecl())
  2328. return;
  2329. if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
  2330. (Attributes & ObjCDeclSpec::DQ_PR_readwrite))
  2331. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2332. << "readonly" << "readwrite";
  2333. ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl);
  2334. QualType PropertyTy = PropertyDecl->getType();
  2335. // Check for copy or retain on non-object types.
  2336. if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy |
  2337. ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong)) &&
  2338. !PropertyTy->isObjCRetainableType() &&
  2339. !PropertyDecl->hasAttr<ObjCNSObjectAttr>()) {
  2340. Diag(Loc, diag::err_objc_property_requires_object)
  2341. << (Attributes & ObjCDeclSpec::DQ_PR_weak ? "weak" :
  2342. Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain (or strong)");
  2343. Attributes &= ~(ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy |
  2344. ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong);
  2345. PropertyDecl->setInvalidDecl();
  2346. }
  2347. // Check for assign on object types.
  2348. if ((Attributes & ObjCDeclSpec::DQ_PR_assign) &&
  2349. !(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) &&
  2350. PropertyTy->isObjCRetainableType() &&
  2351. !PropertyTy->isObjCARCImplicitlyUnretainedType()) {
  2352. Diag(Loc, diag::warn_objc_property_assign_on_object);
  2353. }
  2354. // Check for more than one of { assign, copy, retain }.
  2355. if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
  2356. if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
  2357. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2358. << "assign" << "copy";
  2359. Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
  2360. }
  2361. if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
  2362. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2363. << "assign" << "retain";
  2364. Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
  2365. }
  2366. if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
  2367. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2368. << "assign" << "strong";
  2369. Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
  2370. }
  2371. if (getLangOpts().ObjCAutoRefCount &&
  2372. (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
  2373. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2374. << "assign" << "weak";
  2375. Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
  2376. }
  2377. if (PropertyDecl->hasAttr<IBOutletCollectionAttr>())
  2378. Diag(Loc, diag::warn_iboutletcollection_property_assign);
  2379. } else if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) {
  2380. if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
  2381. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2382. << "unsafe_unretained" << "copy";
  2383. Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
  2384. }
  2385. if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
  2386. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2387. << "unsafe_unretained" << "retain";
  2388. Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
  2389. }
  2390. if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
  2391. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2392. << "unsafe_unretained" << "strong";
  2393. Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
  2394. }
  2395. if (getLangOpts().ObjCAutoRefCount &&
  2396. (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
  2397. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2398. << "unsafe_unretained" << "weak";
  2399. Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
  2400. }
  2401. } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
  2402. if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
  2403. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2404. << "copy" << "retain";
  2405. Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
  2406. }
  2407. if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
  2408. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2409. << "copy" << "strong";
  2410. Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
  2411. }
  2412. if (Attributes & ObjCDeclSpec::DQ_PR_weak) {
  2413. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2414. << "copy" << "weak";
  2415. Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
  2416. }
  2417. }
  2418. else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) &&
  2419. (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
  2420. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2421. << "retain" << "weak";
  2422. Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
  2423. }
  2424. else if ((Attributes & ObjCDeclSpec::DQ_PR_strong) &&
  2425. (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
  2426. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2427. << "strong" << "weak";
  2428. Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
  2429. }
  2430. if (Attributes & ObjCDeclSpec::DQ_PR_weak) {
  2431. // 'weak' and 'nonnull' are mutually exclusive.
  2432. if (auto nullability = PropertyTy->getNullability(Context)) {
  2433. if (*nullability == NullabilityKind::NonNull)
  2434. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2435. << "nonnull" << "weak";
  2436. }
  2437. }
  2438. if ((Attributes & ObjCDeclSpec::DQ_PR_atomic) &&
  2439. (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)) {
  2440. Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
  2441. << "atomic" << "nonatomic";
  2442. Attributes &= ~ObjCDeclSpec::DQ_PR_atomic;
  2443. }
  2444. // Warn if user supplied no assignment attribute, property is
  2445. // readwrite, and this is an object type.
  2446. if (!getOwnershipRule(Attributes) && PropertyTy->isObjCRetainableType()) {
  2447. if (Attributes & ObjCDeclSpec::DQ_PR_readonly) {
  2448. // do nothing
  2449. } else if (getLangOpts().ObjCAutoRefCount) {
  2450. // With arc, @property definitions should default to strong when
  2451. // not specified.
  2452. PropertyDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
  2453. } else if (PropertyTy->isObjCObjectPointerType()) {
  2454. bool isAnyClassTy =
  2455. (PropertyTy->isObjCClassType() ||
  2456. PropertyTy->isObjCQualifiedClassType());
  2457. // In non-gc, non-arc mode, 'Class' is treated as a 'void *' no need to
  2458. // issue any warning.
  2459. if (isAnyClassTy && getLangOpts().getGC() == LangOptions::NonGC)
  2460. ;
  2461. else if (propertyInPrimaryClass) {
  2462. // Don't issue warning on property with no life time in class
  2463. // extension as it is inherited from property in primary class.
  2464. // Skip this warning in gc-only mode.
  2465. if (getLangOpts().getGC() != LangOptions::GCOnly)
  2466. Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
  2467. // If non-gc code warn that this is likely inappropriate.
  2468. if (getLangOpts().getGC() == LangOptions::NonGC)
  2469. Diag(Loc, diag::warn_objc_property_default_assign_on_object);
  2470. }
  2471. }
  2472. // FIXME: Implement warning dependent on NSCopying being
  2473. // implemented. See also:
  2474. // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496>
  2475. // (please trim this list while you are at it).
  2476. }
  2477. if (!(Attributes & ObjCDeclSpec::DQ_PR_copy)
  2478. &&!(Attributes & ObjCDeclSpec::DQ_PR_readonly)
  2479. && getLangOpts().getGC() == LangOptions::GCOnly
  2480. && PropertyTy->isBlockPointerType())
  2481. Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
  2482. else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) &&
  2483. !(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
  2484. !(Attributes & ObjCDeclSpec::DQ_PR_strong) &&
  2485. PropertyTy->isBlockPointerType())
  2486. Diag(Loc, diag::warn_objc_property_retain_of_block);
  2487. if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
  2488. (Attributes & ObjCDeclSpec::DQ_PR_setter))
  2489. Diag(Loc, diag::warn_objc_readonly_property_has_setter);
  2490. }