SemaObjCProperty.cpp 104 KB

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