SemaObjCProperty.cpp 104 KB

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