1 //===- DeclObjC.h - Classes for representing declarations -------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the DeclObjC interface and subclasses.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_CLANG_AST_DECLOBJC_H
14 #define LLVM_CLANG_AST_DECLOBJC_H
15
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclBase.h"
18 #include "clang/AST/DeclObjCCommon.h"
19 #include "clang/AST/ExternalASTSource.h"
20 #include "clang/AST/Redeclarable.h"
21 #include "clang/AST/SelectorLocationsKind.h"
22 #include "clang/AST/Type.h"
23 #include "clang/Basic/IdentifierTable.h"
24 #include "clang/Basic/LLVM.h"
25 #include "clang/Basic/SourceLocation.h"
26 #include "clang/Basic/Specifiers.h"
27 #include "llvm/ADT/ArrayRef.h"
28 #include "llvm/ADT/DenseMap.h"
29 #include "llvm/ADT/DenseSet.h"
30 #include "llvm/ADT/None.h"
31 #include "llvm/ADT/PointerIntPair.h"
32 #include "llvm/ADT/STLExtras.h"
33 #include "llvm/ADT/StringRef.h"
34 #include "llvm/ADT/iterator_range.h"
35 #include "llvm/Support/Compiler.h"
36 #include "llvm/Support/TrailingObjects.h"
37 #include <cassert>
38 #include <cstddef>
39 #include <cstdint>
40 #include <iterator>
41 #include <string>
42 #include <utility>
43
44 namespace clang {
45
46 class ASTContext;
47 class CompoundStmt;
48 class CXXCtorInitializer;
49 class Expr;
50 class ObjCCategoryDecl;
51 class ObjCCategoryImplDecl;
52 class ObjCImplementationDecl;
53 class ObjCInterfaceDecl;
54 class ObjCIvarDecl;
55 class ObjCPropertyDecl;
56 class ObjCPropertyImplDecl;
57 class ObjCProtocolDecl;
58 class Stmt;
59
60 class ObjCListBase {
61 protected:
62 /// List is an array of pointers to objects that are not owned by this object.
63 void **List = nullptr;
64 unsigned NumElts = 0;
65
66 public:
67 ObjCListBase() = default;
68 ObjCListBase(const ObjCListBase &) = delete;
69 ObjCListBase &operator=(const ObjCListBase &) = delete;
70
size()71 unsigned size() const { return NumElts; }
empty()72 bool empty() const { return NumElts == 0; }
73
74 protected:
75 void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
76 };
77
78 /// ObjCList - This is a simple template class used to hold various lists of
79 /// decls etc, which is heavily used by the ObjC front-end. This only use case
80 /// this supports is setting the list all at once and then reading elements out
81 /// of it.
82 template <typename T>
83 class ObjCList : public ObjCListBase {
84 public:
set(T * const * InList,unsigned Elts,ASTContext & Ctx)85 void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
86 ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
87 }
88
89 using iterator = T* const *;
90
begin()91 iterator begin() const { return (iterator)List; }
end()92 iterator end() const { return (iterator)List+NumElts; }
93
94 T* operator[](unsigned Idx) const {
95 assert(Idx < NumElts && "Invalid access");
96 return (T*)List[Idx];
97 }
98 };
99
100 /// A list of Objective-C protocols, along with the source
101 /// locations at which they were referenced.
102 class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
103 SourceLocation *Locations = nullptr;
104
105 using ObjCList<ObjCProtocolDecl>::set;
106
107 public:
108 ObjCProtocolList() = default;
109
110 using loc_iterator = const SourceLocation *;
111
loc_begin()112 loc_iterator loc_begin() const { return Locations; }
loc_end()113 loc_iterator loc_end() const { return Locations + size(); }
114
115 void set(ObjCProtocolDecl* const* InList, unsigned Elts,
116 const SourceLocation *Locs, ASTContext &Ctx);
117 };
118
119 /// ObjCMethodDecl - Represents an instance or class method declaration.
120 /// ObjC methods can be declared within 4 contexts: class interfaces,
121 /// categories, protocols, and class implementations. While C++ member
122 /// functions leverage C syntax, Objective-C method syntax is modeled after
123 /// Smalltalk (using colons to specify argument types/expressions).
124 /// Here are some brief examples:
125 ///
126 /// Setter/getter instance methods:
127 /// - (void)setMenu:(NSMenu *)menu;
128 /// - (NSMenu *)menu;
129 ///
130 /// Instance method that takes 2 NSView arguments:
131 /// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
132 ///
133 /// Getter class method:
134 /// + (NSMenu *)defaultMenu;
135 ///
136 /// A selector represents a unique name for a method. The selector names for
137 /// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
138 ///
139 class ObjCMethodDecl : public NamedDecl, public DeclContext {
140 // This class stores some data in DeclContext::ObjCMethodDeclBits
141 // to save some space. Use the provided accessors to access it.
142
143 public:
144 enum ImplementationControl { None, Required, Optional };
145
146 private:
147 /// Return type of this method.
148 QualType MethodDeclType;
149
150 /// Type source information for the return type.
151 TypeSourceInfo *ReturnTInfo;
152
153 /// Array of ParmVarDecls for the formal parameters of this method
154 /// and optionally followed by selector locations.
155 void *ParamsAndSelLocs = nullptr;
156 unsigned NumParams = 0;
157
158 /// List of attributes for this method declaration.
159 SourceLocation DeclEndLoc; // the location of the ';' or '{'.
160
161 /// The following are only used for method definitions, null otherwise.
162 LazyDeclStmtPtr Body;
163
164 /// SelfDecl - Decl for the implicit self parameter. This is lazily
165 /// constructed by createImplicitParams.
166 ImplicitParamDecl *SelfDecl = nullptr;
167
168 /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
169 /// constructed by createImplicitParams.
170 ImplicitParamDecl *CmdDecl = nullptr;
171
172 ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
173 Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
174 DeclContext *contextDecl, bool isInstance = true,
175 bool isVariadic = false, bool isPropertyAccessor = false,
176 bool isSynthesizedAccessorStub = false,
177 bool isImplicitlyDeclared = false, bool isDefined = false,
178 ImplementationControl impControl = None,
179 bool HasRelatedResultType = false);
180
getSelLocsKind()181 SelectorLocationsKind getSelLocsKind() const {
182 return static_cast<SelectorLocationsKind>(ObjCMethodDeclBits.SelLocsKind);
183 }
184
setSelLocsKind(SelectorLocationsKind Kind)185 void setSelLocsKind(SelectorLocationsKind Kind) {
186 ObjCMethodDeclBits.SelLocsKind = Kind;
187 }
188
hasStandardSelLocs()189 bool hasStandardSelLocs() const {
190 return getSelLocsKind() != SelLoc_NonStandard;
191 }
192
193 /// Get a pointer to the stored selector identifiers locations array.
194 /// No locations will be stored if HasStandardSelLocs is true.
getStoredSelLocs()195 SourceLocation *getStoredSelLocs() {
196 return reinterpret_cast<SourceLocation *>(getParams() + NumParams);
197 }
getStoredSelLocs()198 const SourceLocation *getStoredSelLocs() const {
199 return reinterpret_cast<const SourceLocation *>(getParams() + NumParams);
200 }
201
202 /// Get a pointer to the stored selector identifiers locations array.
203 /// No locations will be stored if HasStandardSelLocs is true.
getParams()204 ParmVarDecl **getParams() {
205 return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs);
206 }
getParams()207 const ParmVarDecl *const *getParams() const {
208 return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
209 }
210
211 /// Get the number of stored selector identifiers locations.
212 /// No locations will be stored if HasStandardSelLocs is true.
getNumStoredSelLocs()213 unsigned getNumStoredSelLocs() const {
214 if (hasStandardSelLocs())
215 return 0;
216 return getNumSelectorLocs();
217 }
218
219 void setParamsAndSelLocs(ASTContext &C,
220 ArrayRef<ParmVarDecl*> Params,
221 ArrayRef<SourceLocation> SelLocs);
222
223 /// A definition will return its interface declaration.
224 /// An interface declaration will return its definition.
225 /// Otherwise it will return itself.
226 ObjCMethodDecl *getNextRedeclarationImpl() override;
227
228 public:
229 friend class ASTDeclReader;
230 friend class ASTDeclWriter;
231
232 static ObjCMethodDecl *
233 Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
234 Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
235 DeclContext *contextDecl, bool isInstance = true,
236 bool isVariadic = false, bool isPropertyAccessor = false,
237 bool isSynthesizedAccessorStub = false,
238 bool isImplicitlyDeclared = false, bool isDefined = false,
239 ImplementationControl impControl = None,
240 bool HasRelatedResultType = false);
241
242 static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
243
244 ObjCMethodDecl *getCanonicalDecl() override;
getCanonicalDecl()245 const ObjCMethodDecl *getCanonicalDecl() const {
246 return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
247 }
248
getObjCDeclQualifier()249 ObjCDeclQualifier getObjCDeclQualifier() const {
250 return static_cast<ObjCDeclQualifier>(ObjCMethodDeclBits.objcDeclQualifier);
251 }
252
setObjCDeclQualifier(ObjCDeclQualifier QV)253 void setObjCDeclQualifier(ObjCDeclQualifier QV) {
254 ObjCMethodDeclBits.objcDeclQualifier = QV;
255 }
256
257 /// Determine whether this method has a result type that is related
258 /// to the message receiver's type.
hasRelatedResultType()259 bool hasRelatedResultType() const {
260 return ObjCMethodDeclBits.RelatedResultType;
261 }
262
263 /// Note whether this method has a related result type.
264 void setRelatedResultType(bool RRT = true) {
265 ObjCMethodDeclBits.RelatedResultType = RRT;
266 }
267
268 /// True if this is a method redeclaration in the same interface.
isRedeclaration()269 bool isRedeclaration() const { return ObjCMethodDeclBits.IsRedeclaration; }
setIsRedeclaration(bool RD)270 void setIsRedeclaration(bool RD) { ObjCMethodDeclBits.IsRedeclaration = RD; }
271 void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
272
273 /// True if redeclared in the same interface.
hasRedeclaration()274 bool hasRedeclaration() const { return ObjCMethodDeclBits.HasRedeclaration; }
setHasRedeclaration(bool HRD)275 void setHasRedeclaration(bool HRD) const {
276 ObjCMethodDeclBits.HasRedeclaration = HRD;
277 }
278
279 /// Returns the location where the declarator ends. It will be
280 /// the location of ';' for a method declaration and the location of '{'
281 /// for a method definition.
getDeclaratorEndLoc()282 SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
283
284 // Location information, modeled after the Stmt API.
getBeginLoc()285 SourceLocation getBeginLoc() const LLVM_READONLY { return getLocation(); }
286 SourceLocation getEndLoc() const LLVM_READONLY;
getSourceRange()287 SourceRange getSourceRange() const override LLVM_READONLY {
288 return SourceRange(getLocation(), getEndLoc());
289 }
290
getSelectorStartLoc()291 SourceLocation getSelectorStartLoc() const {
292 if (isImplicit())
293 return getBeginLoc();
294 return getSelectorLoc(0);
295 }
296
getSelectorLoc(unsigned Index)297 SourceLocation getSelectorLoc(unsigned Index) const {
298 assert(Index < getNumSelectorLocs() && "Index out of range!");
299 if (hasStandardSelLocs())
300 return getStandardSelectorLoc(Index, getSelector(),
301 getSelLocsKind() == SelLoc_StandardWithSpace,
302 parameters(),
303 DeclEndLoc);
304 return getStoredSelLocs()[Index];
305 }
306
307 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
308
getNumSelectorLocs()309 unsigned getNumSelectorLocs() const {
310 if (isImplicit())
311 return 0;
312 Selector Sel = getSelector();
313 if (Sel.isUnarySelector())
314 return 1;
315 return Sel.getNumArgs();
316 }
317
318 ObjCInterfaceDecl *getClassInterface();
getClassInterface()319 const ObjCInterfaceDecl *getClassInterface() const {
320 return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
321 }
322
323 /// If this method is declared or implemented in a category, return
324 /// that category.
325 ObjCCategoryDecl *getCategory();
getCategory()326 const ObjCCategoryDecl *getCategory() const {
327 return const_cast<ObjCMethodDecl*>(this)->getCategory();
328 }
329
getSelector()330 Selector getSelector() const { return getDeclName().getObjCSelector(); }
331
getReturnType()332 QualType getReturnType() const { return MethodDeclType; }
setReturnType(QualType T)333 void setReturnType(QualType T) { MethodDeclType = T; }
334 SourceRange getReturnTypeSourceRange() const;
335
336 /// Determine the type of an expression that sends a message to this
337 /// function. This replaces the type parameters with the types they would
338 /// get if the receiver was parameterless (e.g. it may replace the type
339 /// parameter with 'id').
340 QualType getSendResultType() const;
341
342 /// Determine the type of an expression that sends a message to this
343 /// function with the given receiver type.
344 QualType getSendResultType(QualType receiverType) const;
345
getReturnTypeSourceInfo()346 TypeSourceInfo *getReturnTypeSourceInfo() const { return ReturnTInfo; }
setReturnTypeSourceInfo(TypeSourceInfo * TInfo)347 void setReturnTypeSourceInfo(TypeSourceInfo *TInfo) { ReturnTInfo = TInfo; }
348
349 // Iterator access to formal parameters.
param_size()350 unsigned param_size() const { return NumParams; }
351
352 using param_const_iterator = const ParmVarDecl *const *;
353 using param_iterator = ParmVarDecl *const *;
354 using param_range = llvm::iterator_range<param_iterator>;
355 using param_const_range = llvm::iterator_range<param_const_iterator>;
356
param_begin()357 param_const_iterator param_begin() const {
358 return param_const_iterator(getParams());
359 }
360
param_end()361 param_const_iterator param_end() const {
362 return param_const_iterator(getParams() + NumParams);
363 }
364
param_begin()365 param_iterator param_begin() { return param_iterator(getParams()); }
param_end()366 param_iterator param_end() { return param_iterator(getParams() + NumParams); }
367
368 // This method returns and of the parameters which are part of the selector
369 // name mangling requirements.
sel_param_end()370 param_const_iterator sel_param_end() const {
371 return param_begin() + getSelector().getNumArgs();
372 }
373
374 // ArrayRef access to formal parameters. This should eventually
375 // replace the iterator interface above.
parameters()376 ArrayRef<ParmVarDecl*> parameters() const {
377 return llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
378 NumParams);
379 }
380
getParamDecl(unsigned Idx)381 ParmVarDecl *getParamDecl(unsigned Idx) {
382 assert(Idx < NumParams && "Index out of bounds!");
383 return getParams()[Idx];
384 }
getParamDecl(unsigned Idx)385 const ParmVarDecl *getParamDecl(unsigned Idx) const {
386 return const_cast<ObjCMethodDecl *>(this)->getParamDecl(Idx);
387 }
388
389 /// Sets the method's parameters and selector source locations.
390 /// If the method is implicit (not coming from source) \p SelLocs is
391 /// ignored.
392 void setMethodParams(ASTContext &C,
393 ArrayRef<ParmVarDecl*> Params,
394 ArrayRef<SourceLocation> SelLocs = llvm::None);
395
396 // Iterator access to parameter types.
397 struct GetTypeFn {
operatorGetTypeFn398 QualType operator()(const ParmVarDecl *PD) const { return PD->getType(); }
399 };
400
401 using param_type_iterator =
402 llvm::mapped_iterator<param_const_iterator, GetTypeFn>;
403
param_type_begin()404 param_type_iterator param_type_begin() const {
405 return llvm::map_iterator(param_begin(), GetTypeFn());
406 }
407
param_type_end()408 param_type_iterator param_type_end() const {
409 return llvm::map_iterator(param_end(), GetTypeFn());
410 }
411
412 /// createImplicitParams - Used to lazily create the self and cmd
413 /// implicit parameters. This must be called prior to using getSelfDecl()
414 /// or getCmdDecl(). The call is ignored if the implicit parameters
415 /// have already been created.
416 void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
417
418 /// \return the type for \c self and set \arg selfIsPseudoStrong and
419 /// \arg selfIsConsumed accordingly.
420 QualType getSelfType(ASTContext &Context, const ObjCInterfaceDecl *OID,
421 bool &selfIsPseudoStrong, bool &selfIsConsumed) const;
422
getSelfDecl()423 ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
setSelfDecl(ImplicitParamDecl * SD)424 void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
getCmdDecl()425 ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
setCmdDecl(ImplicitParamDecl * CD)426 void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
427
428 /// Determines the family of this method.
429 ObjCMethodFamily getMethodFamily() const;
430
isInstanceMethod()431 bool isInstanceMethod() const { return ObjCMethodDeclBits.IsInstance; }
setInstanceMethod(bool isInst)432 void setInstanceMethod(bool isInst) {
433 ObjCMethodDeclBits.IsInstance = isInst;
434 }
435
isVariadic()436 bool isVariadic() const { return ObjCMethodDeclBits.IsVariadic; }
setVariadic(bool isVar)437 void setVariadic(bool isVar) { ObjCMethodDeclBits.IsVariadic = isVar; }
438
isClassMethod()439 bool isClassMethod() const { return !isInstanceMethod(); }
440
isPropertyAccessor()441 bool isPropertyAccessor() const {
442 return ObjCMethodDeclBits.IsPropertyAccessor;
443 }
444
setPropertyAccessor(bool isAccessor)445 void setPropertyAccessor(bool isAccessor) {
446 ObjCMethodDeclBits.IsPropertyAccessor = isAccessor;
447 }
448
isSynthesizedAccessorStub()449 bool isSynthesizedAccessorStub() const {
450 return ObjCMethodDeclBits.IsSynthesizedAccessorStub;
451 }
452
setSynthesizedAccessorStub(bool isSynthesizedAccessorStub)453 void setSynthesizedAccessorStub(bool isSynthesizedAccessorStub) {
454 ObjCMethodDeclBits.IsSynthesizedAccessorStub = isSynthesizedAccessorStub;
455 }
456
isDefined()457 bool isDefined() const { return ObjCMethodDeclBits.IsDefined; }
setDefined(bool isDefined)458 void setDefined(bool isDefined) { ObjCMethodDeclBits.IsDefined = isDefined; }
459
460 /// Whether this method overrides any other in the class hierarchy.
461 ///
462 /// A method is said to override any method in the class's
463 /// base classes, its protocols, or its categories' protocols, that has
464 /// the same selector and is of the same kind (class or instance).
465 /// A method in an implementation is not considered as overriding the same
466 /// method in the interface or its categories.
isOverriding()467 bool isOverriding() const { return ObjCMethodDeclBits.IsOverriding; }
setOverriding(bool IsOver)468 void setOverriding(bool IsOver) { ObjCMethodDeclBits.IsOverriding = IsOver; }
469
470 /// Return overridden methods for the given \p Method.
471 ///
472 /// An ObjC method is considered to override any method in the class's
473 /// base classes (and base's categories), its protocols, or its categories'
474 /// protocols, that has
475 /// the same selector and is of the same kind (class or instance).
476 /// A method in an implementation is not considered as overriding the same
477 /// method in the interface or its categories.
478 void getOverriddenMethods(
479 SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
480
481 /// True if the method was a definition but its body was skipped.
hasSkippedBody()482 bool hasSkippedBody() const { return ObjCMethodDeclBits.HasSkippedBody; }
483 void setHasSkippedBody(bool Skipped = true) {
484 ObjCMethodDeclBits.HasSkippedBody = Skipped;
485 }
486
487 /// True if the method is tagged as objc_direct
488 bool isDirectMethod() const;
489
490 /// Returns the property associated with this method's selector.
491 ///
492 /// Note that even if this particular method is not marked as a property
493 /// accessor, it is still possible for it to match a property declared in a
494 /// superclass. Pass \c false if you only want to check the current class.
495 const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const;
496
497 // Related to protocols declared in \@protocol
setDeclImplementation(ImplementationControl ic)498 void setDeclImplementation(ImplementationControl ic) {
499 ObjCMethodDeclBits.DeclImplementation = ic;
500 }
501
getImplementationControl()502 ImplementationControl getImplementationControl() const {
503 return ImplementationControl(ObjCMethodDeclBits.DeclImplementation);
504 }
505
isOptional()506 bool isOptional() const {
507 return getImplementationControl() == Optional;
508 }
509
510 /// Returns true if this specific method declaration is marked with the
511 /// designated initializer attribute.
512 bool isThisDeclarationADesignatedInitializer() const;
513
514 /// Returns true if the method selector resolves to a designated initializer
515 /// in the class's interface.
516 ///
517 /// \param InitMethod if non-null and the function returns true, it receives
518 /// the method declaration that was marked with the designated initializer
519 /// attribute.
520 bool isDesignatedInitializerForTheInterface(
521 const ObjCMethodDecl **InitMethod = nullptr) const;
522
523 /// Determine whether this method has a body.
hasBody()524 bool hasBody() const override { return Body.isValid(); }
525
526 /// Retrieve the body of this method, if it has one.
527 Stmt *getBody() const override;
528
setLazyBody(uint64_t Offset)529 void setLazyBody(uint64_t Offset) { Body = Offset; }
530
getCompoundBody()531 CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); }
setBody(Stmt * B)532 void setBody(Stmt *B) { Body = B; }
533
534 /// Returns whether this specific method is a definition.
isThisDeclarationADefinition()535 bool isThisDeclarationADefinition() const { return hasBody(); }
536
537 /// Is this method defined in the NSObject base class?
538 bool definedInNSObject(const ASTContext &) const;
539
540 // Implement isa/cast/dyncast/etc.
classof(const Decl * D)541 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)542 static bool classofKind(Kind K) { return K == ObjCMethod; }
543
castToDeclContext(const ObjCMethodDecl * D)544 static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
545 return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
546 }
547
castFromDeclContext(const DeclContext * DC)548 static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
549 return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
550 }
551 };
552
553 /// Describes the variance of a given generic parameter.
554 enum class ObjCTypeParamVariance : uint8_t {
555 /// The parameter is invariant: must match exactly.
556 Invariant,
557
558 /// The parameter is covariant, e.g., X<T> is a subtype of X<U> when
559 /// the type parameter is covariant and T is a subtype of U.
560 Covariant,
561
562 /// The parameter is contravariant, e.g., X<T> is a subtype of X<U>
563 /// when the type parameter is covariant and U is a subtype of T.
564 Contravariant,
565 };
566
567 /// Represents the declaration of an Objective-C type parameter.
568 ///
569 /// \code
570 /// @interface NSDictionary<Key : id<NSCopying>, Value>
571 /// @end
572 /// \endcode
573 ///
574 /// In the example above, both \c Key and \c Value are represented by
575 /// \c ObjCTypeParamDecl. \c Key has an explicit bound of \c id<NSCopying>,
576 /// while \c Value gets an implicit bound of \c id.
577 ///
578 /// Objective-C type parameters are typedef-names in the grammar,
579 class ObjCTypeParamDecl : public TypedefNameDecl {
580 /// Index of this type parameter in the type parameter list.
581 unsigned Index : 14;
582
583 /// The variance of the type parameter.
584 unsigned Variance : 2;
585
586 /// The location of the variance, if any.
587 SourceLocation VarianceLoc;
588
589 /// The location of the ':', which will be valid when the bound was
590 /// explicitly specified.
591 SourceLocation ColonLoc;
592
ObjCTypeParamDecl(ASTContext & ctx,DeclContext * dc,ObjCTypeParamVariance variance,SourceLocation varianceLoc,unsigned index,SourceLocation nameLoc,IdentifierInfo * name,SourceLocation colonLoc,TypeSourceInfo * boundInfo)593 ObjCTypeParamDecl(ASTContext &ctx, DeclContext *dc,
594 ObjCTypeParamVariance variance, SourceLocation varianceLoc,
595 unsigned index,
596 SourceLocation nameLoc, IdentifierInfo *name,
597 SourceLocation colonLoc, TypeSourceInfo *boundInfo)
598 : TypedefNameDecl(ObjCTypeParam, ctx, dc, nameLoc, nameLoc, name,
599 boundInfo),
600 Index(index), Variance(static_cast<unsigned>(variance)),
601 VarianceLoc(varianceLoc), ColonLoc(colonLoc) {}
602
603 void anchor() override;
604
605 public:
606 friend class ASTDeclReader;
607 friend class ASTDeclWriter;
608
609 static ObjCTypeParamDecl *Create(ASTContext &ctx, DeclContext *dc,
610 ObjCTypeParamVariance variance,
611 SourceLocation varianceLoc,
612 unsigned index,
613 SourceLocation nameLoc,
614 IdentifierInfo *name,
615 SourceLocation colonLoc,
616 TypeSourceInfo *boundInfo);
617 static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, unsigned ID);
618
619 SourceRange getSourceRange() const override LLVM_READONLY;
620
621 /// Determine the variance of this type parameter.
getVariance()622 ObjCTypeParamVariance getVariance() const {
623 return static_cast<ObjCTypeParamVariance>(Variance);
624 }
625
626 /// Set the variance of this type parameter.
setVariance(ObjCTypeParamVariance variance)627 void setVariance(ObjCTypeParamVariance variance) {
628 Variance = static_cast<unsigned>(variance);
629 }
630
631 /// Retrieve the location of the variance keyword.
getVarianceLoc()632 SourceLocation getVarianceLoc() const { return VarianceLoc; }
633
634 /// Retrieve the index into its type parameter list.
getIndex()635 unsigned getIndex() const { return Index; }
636
637 /// Whether this type parameter has an explicitly-written type bound, e.g.,
638 /// "T : NSView".
hasExplicitBound()639 bool hasExplicitBound() const { return ColonLoc.isValid(); }
640
641 /// Retrieve the location of the ':' separating the type parameter name
642 /// from the explicitly-specified bound.
getColonLoc()643 SourceLocation getColonLoc() const { return ColonLoc; }
644
645 // Implement isa/cast/dyncast/etc.
classof(const Decl * D)646 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)647 static bool classofKind(Kind K) { return K == ObjCTypeParam; }
648 };
649
650 /// Stores a list of Objective-C type parameters for a parameterized class
651 /// or a category/extension thereof.
652 ///
653 /// \code
654 /// @interface NSArray<T> // stores the <T>
655 /// @end
656 /// \endcode
657 class ObjCTypeParamList final
658 : private llvm::TrailingObjects<ObjCTypeParamList, ObjCTypeParamDecl *> {
659 /// Stores the components of a SourceRange as a POD.
660 struct PODSourceRange {
661 unsigned Begin;
662 unsigned End;
663 };
664
665 union {
666 /// Location of the left and right angle brackets.
667 PODSourceRange Brackets;
668
669 // Used only for alignment.
670 ObjCTypeParamDecl *AlignmentHack;
671 };
672
673 /// The number of parameters in the list, which are tail-allocated.
674 unsigned NumParams;
675
676 ObjCTypeParamList(SourceLocation lAngleLoc,
677 ArrayRef<ObjCTypeParamDecl *> typeParams,
678 SourceLocation rAngleLoc);
679
680 public:
681 friend TrailingObjects;
682
683 /// Create a new Objective-C type parameter list.
684 static ObjCTypeParamList *create(ASTContext &ctx,
685 SourceLocation lAngleLoc,
686 ArrayRef<ObjCTypeParamDecl *> typeParams,
687 SourceLocation rAngleLoc);
688
689 /// Iterate through the type parameters in the list.
690 using iterator = ObjCTypeParamDecl **;
691
begin()692 iterator begin() { return getTrailingObjects<ObjCTypeParamDecl *>(); }
693
end()694 iterator end() { return begin() + size(); }
695
696 /// Determine the number of type parameters in this list.
size()697 unsigned size() const { return NumParams; }
698
699 // Iterate through the type parameters in the list.
700 using const_iterator = ObjCTypeParamDecl * const *;
701
begin()702 const_iterator begin() const {
703 return getTrailingObjects<ObjCTypeParamDecl *>();
704 }
705
end()706 const_iterator end() const {
707 return begin() + size();
708 }
709
front()710 ObjCTypeParamDecl *front() const {
711 assert(size() > 0 && "empty Objective-C type parameter list");
712 return *begin();
713 }
714
back()715 ObjCTypeParamDecl *back() const {
716 assert(size() > 0 && "empty Objective-C type parameter list");
717 return *(end() - 1);
718 }
719
getLAngleLoc()720 SourceLocation getLAngleLoc() const {
721 return SourceLocation::getFromRawEncoding(Brackets.Begin);
722 }
723
getRAngleLoc()724 SourceLocation getRAngleLoc() const {
725 return SourceLocation::getFromRawEncoding(Brackets.End);
726 }
727
getSourceRange()728 SourceRange getSourceRange() const {
729 return SourceRange(getLAngleLoc(), getRAngleLoc());
730 }
731
732 /// Gather the default set of type arguments to be substituted for
733 /// these type parameters when dealing with an unspecialized type.
734 void gatherDefaultTypeArgs(SmallVectorImpl<QualType> &typeArgs) const;
735 };
736
737 enum class ObjCPropertyQueryKind : uint8_t {
738 OBJC_PR_query_unknown = 0x00,
739 OBJC_PR_query_instance,
740 OBJC_PR_query_class
741 };
742
743 /// Represents one property declaration in an Objective-C interface.
744 ///
745 /// For example:
746 /// \code{.mm}
747 /// \@property (assign, readwrite) int MyProperty;
748 /// \endcode
749 class ObjCPropertyDecl : public NamedDecl {
750 void anchor() override;
751
752 public:
753 enum SetterKind { Assign, Retain, Copy, Weak };
754 enum PropertyControl { None, Required, Optional };
755
756 private:
757 // location of \@property
758 SourceLocation AtLoc;
759
760 // location of '(' starting attribute list or null.
761 SourceLocation LParenLoc;
762
763 QualType DeclType;
764 TypeSourceInfo *DeclTypeSourceInfo;
765 unsigned PropertyAttributes : NumObjCPropertyAttrsBits;
766 unsigned PropertyAttributesAsWritten : NumObjCPropertyAttrsBits;
767
768 // \@required/\@optional
769 unsigned PropertyImplementation : 2;
770
771 // getter name of NULL if no getter
772 Selector GetterName;
773
774 // setter name of NULL if no setter
775 Selector SetterName;
776
777 // location of the getter attribute's value
778 SourceLocation GetterNameLoc;
779
780 // location of the setter attribute's value
781 SourceLocation SetterNameLoc;
782
783 // Declaration of getter instance method
784 ObjCMethodDecl *GetterMethodDecl = nullptr;
785
786 // Declaration of setter instance method
787 ObjCMethodDecl *SetterMethodDecl = nullptr;
788
789 // Synthesize ivar for this property
790 ObjCIvarDecl *PropertyIvarDecl = nullptr;
791
ObjCPropertyDecl(DeclContext * DC,SourceLocation L,IdentifierInfo * Id,SourceLocation AtLocation,SourceLocation LParenLocation,QualType T,TypeSourceInfo * TSI,PropertyControl propControl)792 ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
793 SourceLocation AtLocation, SourceLocation LParenLocation,
794 QualType T, TypeSourceInfo *TSI, PropertyControl propControl)
795 : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
796 LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
797 PropertyAttributes(ObjCPropertyAttribute::kind_noattr),
798 PropertyAttributesAsWritten(ObjCPropertyAttribute::kind_noattr),
799 PropertyImplementation(propControl), GetterName(Selector()),
800 SetterName(Selector()) {}
801
802 public:
803 static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
804 SourceLocation L,
805 IdentifierInfo *Id, SourceLocation AtLocation,
806 SourceLocation LParenLocation,
807 QualType T,
808 TypeSourceInfo *TSI,
809 PropertyControl propControl = None);
810
811 static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
812
getAtLoc()813 SourceLocation getAtLoc() const { return AtLoc; }
setAtLoc(SourceLocation L)814 void setAtLoc(SourceLocation L) { AtLoc = L; }
815
getLParenLoc()816 SourceLocation getLParenLoc() const { return LParenLoc; }
setLParenLoc(SourceLocation L)817 void setLParenLoc(SourceLocation L) { LParenLoc = L; }
818
getTypeSourceInfo()819 TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; }
820
getType()821 QualType getType() const { return DeclType; }
822
setType(QualType T,TypeSourceInfo * TSI)823 void setType(QualType T, TypeSourceInfo *TSI) {
824 DeclType = T;
825 DeclTypeSourceInfo = TSI;
826 }
827
828 /// Retrieve the type when this property is used with a specific base object
829 /// type.
830 QualType getUsageType(QualType objectType) const;
831
getPropertyAttributes()832 ObjCPropertyAttribute::Kind getPropertyAttributes() const {
833 return ObjCPropertyAttribute::Kind(PropertyAttributes);
834 }
835
setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal)836 void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal) {
837 PropertyAttributes |= PRVal;
838 }
839
overwritePropertyAttributes(unsigned PRVal)840 void overwritePropertyAttributes(unsigned PRVal) {
841 PropertyAttributes = PRVal;
842 }
843
getPropertyAttributesAsWritten()844 ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const {
845 return ObjCPropertyAttribute::Kind(PropertyAttributesAsWritten);
846 }
847
setPropertyAttributesAsWritten(ObjCPropertyAttribute::Kind PRVal)848 void setPropertyAttributesAsWritten(ObjCPropertyAttribute::Kind PRVal) {
849 PropertyAttributesAsWritten = PRVal;
850 }
851
852 // Helper methods for accessing attributes.
853
854 /// isReadOnly - Return true iff the property has a setter.
isReadOnly()855 bool isReadOnly() const {
856 return (PropertyAttributes & ObjCPropertyAttribute::kind_readonly);
857 }
858
859 /// isAtomic - Return true if the property is atomic.
isAtomic()860 bool isAtomic() const {
861 return (PropertyAttributes & ObjCPropertyAttribute::kind_atomic);
862 }
863
864 /// isRetaining - Return true if the property retains its value.
isRetaining()865 bool isRetaining() const {
866 return (PropertyAttributes & (ObjCPropertyAttribute::kind_retain |
867 ObjCPropertyAttribute::kind_strong |
868 ObjCPropertyAttribute::kind_copy));
869 }
870
isInstanceProperty()871 bool isInstanceProperty() const { return !isClassProperty(); }
isClassProperty()872 bool isClassProperty() const {
873 return PropertyAttributes & ObjCPropertyAttribute::kind_class;
874 }
isDirectProperty()875 bool isDirectProperty() const {
876 return PropertyAttributes & ObjCPropertyAttribute::kind_direct;
877 }
878
getQueryKind()879 ObjCPropertyQueryKind getQueryKind() const {
880 return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class :
881 ObjCPropertyQueryKind::OBJC_PR_query_instance;
882 }
883
getQueryKind(bool isClassProperty)884 static ObjCPropertyQueryKind getQueryKind(bool isClassProperty) {
885 return isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class :
886 ObjCPropertyQueryKind::OBJC_PR_query_instance;
887 }
888
889 /// getSetterKind - Return the method used for doing assignment in
890 /// the property setter. This is only valid if the property has been
891 /// defined to have a setter.
getSetterKind()892 SetterKind getSetterKind() const {
893 if (PropertyAttributes & ObjCPropertyAttribute::kind_strong)
894 return getType()->isBlockPointerType() ? Copy : Retain;
895 if (PropertyAttributes & ObjCPropertyAttribute::kind_retain)
896 return Retain;
897 if (PropertyAttributes & ObjCPropertyAttribute::kind_copy)
898 return Copy;
899 if (PropertyAttributes & ObjCPropertyAttribute::kind_weak)
900 return Weak;
901 return Assign;
902 }
903
getGetterName()904 Selector getGetterName() const { return GetterName; }
getGetterNameLoc()905 SourceLocation getGetterNameLoc() const { return GetterNameLoc; }
906
907 void setGetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
908 GetterName = Sel;
909 GetterNameLoc = Loc;
910 }
911
getSetterName()912 Selector getSetterName() const { return SetterName; }
getSetterNameLoc()913 SourceLocation getSetterNameLoc() const { return SetterNameLoc; }
914
915 void setSetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
916 SetterName = Sel;
917 SetterNameLoc = Loc;
918 }
919
getGetterMethodDecl()920 ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
setGetterMethodDecl(ObjCMethodDecl * gDecl)921 void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
922
getSetterMethodDecl()923 ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
setSetterMethodDecl(ObjCMethodDecl * gDecl)924 void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
925
926 // Related to \@optional/\@required declared in \@protocol
setPropertyImplementation(PropertyControl pc)927 void setPropertyImplementation(PropertyControl pc) {
928 PropertyImplementation = pc;
929 }
930
getPropertyImplementation()931 PropertyControl getPropertyImplementation() const {
932 return PropertyControl(PropertyImplementation);
933 }
934
isOptional()935 bool isOptional() const {
936 return getPropertyImplementation() == PropertyControl::Optional;
937 }
938
setPropertyIvarDecl(ObjCIvarDecl * Ivar)939 void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
940 PropertyIvarDecl = Ivar;
941 }
942
getPropertyIvarDecl()943 ObjCIvarDecl *getPropertyIvarDecl() const {
944 return PropertyIvarDecl;
945 }
946
getSourceRange()947 SourceRange getSourceRange() const override LLVM_READONLY {
948 return SourceRange(AtLoc, getLocation());
949 }
950
951 /// Get the default name of the synthesized ivar.
952 IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
953
954 /// Lookup a property by name in the specified DeclContext.
955 static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
956 const IdentifierInfo *propertyID,
957 ObjCPropertyQueryKind queryKind);
958
classof(const Decl * D)959 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)960 static bool classofKind(Kind K) { return K == ObjCProperty; }
961 };
962
963 /// ObjCContainerDecl - Represents a container for method declarations.
964 /// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
965 /// ObjCProtocolDecl, and ObjCImplDecl.
966 ///
967 class ObjCContainerDecl : public NamedDecl, public DeclContext {
968 // This class stores some data in DeclContext::ObjCContainerDeclBits
969 // to save some space. Use the provided accessors to access it.
970
971 // These two locations in the range mark the end of the method container.
972 // The first points to the '@' token, and the second to the 'end' token.
973 SourceRange AtEnd;
974
975 void anchor() override;
976
977 public:
978 ObjCContainerDecl(Kind DK, DeclContext *DC, IdentifierInfo *Id,
979 SourceLocation nameLoc, SourceLocation atStartLoc);
980
981 // Iterator access to instance/class properties.
982 using prop_iterator = specific_decl_iterator<ObjCPropertyDecl>;
983 using prop_range =
984 llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>;
985
properties()986 prop_range properties() const { return prop_range(prop_begin(), prop_end()); }
987
prop_begin()988 prop_iterator prop_begin() const {
989 return prop_iterator(decls_begin());
990 }
991
prop_end()992 prop_iterator prop_end() const {
993 return prop_iterator(decls_end());
994 }
995
996 using instprop_iterator =
997 filtered_decl_iterator<ObjCPropertyDecl,
998 &ObjCPropertyDecl::isInstanceProperty>;
999 using instprop_range = llvm::iterator_range<instprop_iterator>;
1000
instance_properties()1001 instprop_range instance_properties() const {
1002 return instprop_range(instprop_begin(), instprop_end());
1003 }
1004
instprop_begin()1005 instprop_iterator instprop_begin() const {
1006 return instprop_iterator(decls_begin());
1007 }
1008
instprop_end()1009 instprop_iterator instprop_end() const {
1010 return instprop_iterator(decls_end());
1011 }
1012
1013 using classprop_iterator =
1014 filtered_decl_iterator<ObjCPropertyDecl,
1015 &ObjCPropertyDecl::isClassProperty>;
1016 using classprop_range = llvm::iterator_range<classprop_iterator>;
1017
class_properties()1018 classprop_range class_properties() const {
1019 return classprop_range(classprop_begin(), classprop_end());
1020 }
1021
classprop_begin()1022 classprop_iterator classprop_begin() const {
1023 return classprop_iterator(decls_begin());
1024 }
1025
classprop_end()1026 classprop_iterator classprop_end() const {
1027 return classprop_iterator(decls_end());
1028 }
1029
1030 // Iterator access to instance/class methods.
1031 using method_iterator = specific_decl_iterator<ObjCMethodDecl>;
1032 using method_range =
1033 llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>;
1034
methods()1035 method_range methods() const {
1036 return method_range(meth_begin(), meth_end());
1037 }
1038
meth_begin()1039 method_iterator meth_begin() const {
1040 return method_iterator(decls_begin());
1041 }
1042
meth_end()1043 method_iterator meth_end() const {
1044 return method_iterator(decls_end());
1045 }
1046
1047 using instmeth_iterator =
1048 filtered_decl_iterator<ObjCMethodDecl,
1049 &ObjCMethodDecl::isInstanceMethod>;
1050 using instmeth_range = llvm::iterator_range<instmeth_iterator>;
1051
instance_methods()1052 instmeth_range instance_methods() const {
1053 return instmeth_range(instmeth_begin(), instmeth_end());
1054 }
1055
instmeth_begin()1056 instmeth_iterator instmeth_begin() const {
1057 return instmeth_iterator(decls_begin());
1058 }
1059
instmeth_end()1060 instmeth_iterator instmeth_end() const {
1061 return instmeth_iterator(decls_end());
1062 }
1063
1064 using classmeth_iterator =
1065 filtered_decl_iterator<ObjCMethodDecl,
1066 &ObjCMethodDecl::isClassMethod>;
1067 using classmeth_range = llvm::iterator_range<classmeth_iterator>;
1068
class_methods()1069 classmeth_range class_methods() const {
1070 return classmeth_range(classmeth_begin(), classmeth_end());
1071 }
1072
classmeth_begin()1073 classmeth_iterator classmeth_begin() const {
1074 return classmeth_iterator(decls_begin());
1075 }
1076
classmeth_end()1077 classmeth_iterator classmeth_end() const {
1078 return classmeth_iterator(decls_end());
1079 }
1080
1081 // Get the local instance/class method declared in this interface.
1082 ObjCMethodDecl *getMethod(Selector Sel, bool isInstance,
1083 bool AllowHidden = false) const;
1084
1085 ObjCMethodDecl *getInstanceMethod(Selector Sel,
1086 bool AllowHidden = false) const {
1087 return getMethod(Sel, true/*isInstance*/, AllowHidden);
1088 }
1089
1090 ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const {
1091 return getMethod(Sel, false/*isInstance*/, AllowHidden);
1092 }
1093
1094 bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
1095 ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
1096
1097 ObjCPropertyDecl *
1098 FindPropertyDeclaration(const IdentifierInfo *PropertyId,
1099 ObjCPropertyQueryKind QueryKind) const;
1100
1101 using PropertyMap =
1102 llvm::DenseMap<std::pair<IdentifierInfo *, unsigned/*isClassProperty*/>,
1103 ObjCPropertyDecl *>;
1104 using ProtocolPropertySet = llvm::SmallDenseSet<const ObjCProtocolDecl *, 8>;
1105 using PropertyDeclOrder = llvm::SmallVector<ObjCPropertyDecl *, 8>;
1106
1107 /// This routine collects list of properties to be implemented in the class.
1108 /// This includes, class's and its conforming protocols' properties.
1109 /// Note, the superclass's properties are not included in the list.
collectPropertiesToImplement(PropertyMap & PM,PropertyDeclOrder & PO)1110 virtual void collectPropertiesToImplement(PropertyMap &PM,
1111 PropertyDeclOrder &PO) const {}
1112
getAtStartLoc()1113 SourceLocation getAtStartLoc() const { return ObjCContainerDeclBits.AtStart; }
1114
setAtStartLoc(SourceLocation Loc)1115 void setAtStartLoc(SourceLocation Loc) {
1116 ObjCContainerDeclBits.AtStart = Loc;
1117 }
1118
1119 // Marks the end of the container.
getAtEndRange()1120 SourceRange getAtEndRange() const { return AtEnd; }
1121
setAtEndRange(SourceRange atEnd)1122 void setAtEndRange(SourceRange atEnd) { AtEnd = atEnd; }
1123
getSourceRange()1124 SourceRange getSourceRange() const override LLVM_READONLY {
1125 return SourceRange(getAtStartLoc(), getAtEndRange().getEnd());
1126 }
1127
1128 // Implement isa/cast/dyncast/etc.
classof(const Decl * D)1129 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1130
classofKind(Kind K)1131 static bool classofKind(Kind K) {
1132 return K >= firstObjCContainer &&
1133 K <= lastObjCContainer;
1134 }
1135
castToDeclContext(const ObjCContainerDecl * D)1136 static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
1137 return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
1138 }
1139
castFromDeclContext(const DeclContext * DC)1140 static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
1141 return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
1142 }
1143 };
1144
1145 /// Represents an ObjC class declaration.
1146 ///
1147 /// For example:
1148 ///
1149 /// \code
1150 /// // MostPrimitive declares no super class (not particularly useful).
1151 /// \@interface MostPrimitive
1152 /// // no instance variables or methods.
1153 /// \@end
1154 ///
1155 /// // NSResponder inherits from NSObject & implements NSCoding (a protocol).
1156 /// \@interface NSResponder : NSObject \<NSCoding>
1157 /// { // instance variables are represented by ObjCIvarDecl.
1158 /// id nextResponder; // nextResponder instance variable.
1159 /// }
1160 /// - (NSResponder *)nextResponder; // return a pointer to NSResponder.
1161 /// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
1162 /// \@end // to an NSEvent.
1163 /// \endcode
1164 ///
1165 /// Unlike C/C++, forward class declarations are accomplished with \@class.
1166 /// Unlike C/C++, \@class allows for a list of classes to be forward declared.
1167 /// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
1168 /// typically inherit from NSObject (an exception is NSProxy).
1169 ///
1170 class ObjCInterfaceDecl : public ObjCContainerDecl
1171 , public Redeclarable<ObjCInterfaceDecl> {
1172 friend class ASTContext;
1173
1174 /// TypeForDecl - This indicates the Type object that represents this
1175 /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
1176 mutable const Type *TypeForDecl = nullptr;
1177
1178 struct DefinitionData {
1179 /// The definition of this class, for quick access from any
1180 /// declaration.
1181 ObjCInterfaceDecl *Definition = nullptr;
1182
1183 /// When non-null, this is always an ObjCObjectType.
1184 TypeSourceInfo *SuperClassTInfo = nullptr;
1185
1186 /// Protocols referenced in the \@interface declaration
1187 ObjCProtocolList ReferencedProtocols;
1188
1189 /// Protocols reference in both the \@interface and class extensions.
1190 ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
1191
1192 /// List of categories and class extensions defined for this class.
1193 ///
1194 /// Categories are stored as a linked list in the AST, since the categories
1195 /// and class extensions come long after the initial interface declaration,
1196 /// and we avoid dynamically-resized arrays in the AST wherever possible.
1197 ObjCCategoryDecl *CategoryList = nullptr;
1198
1199 /// IvarList - List of all ivars defined by this class; including class
1200 /// extensions and implementation. This list is built lazily.
1201 ObjCIvarDecl *IvarList = nullptr;
1202
1203 /// Indicates that the contents of this Objective-C class will be
1204 /// completed by the external AST source when required.
1205 mutable unsigned ExternallyCompleted : 1;
1206
1207 /// Indicates that the ivar cache does not yet include ivars
1208 /// declared in the implementation.
1209 mutable unsigned IvarListMissingImplementation : 1;
1210
1211 /// Indicates that this interface decl contains at least one initializer
1212 /// marked with the 'objc_designated_initializer' attribute.
1213 unsigned HasDesignatedInitializers : 1;
1214
1215 enum InheritedDesignatedInitializersState {
1216 /// We didn't calculate whether the designated initializers should be
1217 /// inherited or not.
1218 IDI_Unknown = 0,
1219
1220 /// Designated initializers are inherited for the super class.
1221 IDI_Inherited = 1,
1222
1223 /// The class does not inherit designated initializers.
1224 IDI_NotInherited = 2
1225 };
1226
1227 /// One of the \c InheritedDesignatedInitializersState enumeratos.
1228 mutable unsigned InheritedDesignatedInitializers : 2;
1229
1230 /// The location of the last location in this declaration, before
1231 /// the properties/methods. For example, this will be the '>', '}', or
1232 /// identifier,
1233 SourceLocation EndLoc;
1234
DefinitionDataDefinitionData1235 DefinitionData()
1236 : ExternallyCompleted(false), IvarListMissingImplementation(true),
1237 HasDesignatedInitializers(false),
1238 InheritedDesignatedInitializers(IDI_Unknown) {}
1239 };
1240
1241 /// The type parameters associated with this class, if any.
1242 ObjCTypeParamList *TypeParamList = nullptr;
1243
1244 /// Contains a pointer to the data associated with this class,
1245 /// which will be NULL if this class has not yet been defined.
1246 ///
1247 /// The bit indicates when we don't need to check for out-of-date
1248 /// declarations. It will be set unless modules are enabled.
1249 llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
1250
1251 ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
1252 IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
1253 SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
1254 bool IsInternal);
1255
1256 void anchor() override;
1257
1258 void LoadExternalDefinition() const;
1259
data()1260 DefinitionData &data() const {
1261 assert(Data.getPointer() && "Declaration has no definition!");
1262 return *Data.getPointer();
1263 }
1264
1265 /// Allocate the definition data for this class.
1266 void allocateDefinitionData();
1267
1268 using redeclarable_base = Redeclarable<ObjCInterfaceDecl>;
1269
getNextRedeclarationImpl()1270 ObjCInterfaceDecl *getNextRedeclarationImpl() override {
1271 return getNextRedeclaration();
1272 }
1273
getPreviousDeclImpl()1274 ObjCInterfaceDecl *getPreviousDeclImpl() override {
1275 return getPreviousDecl();
1276 }
1277
getMostRecentDeclImpl()1278 ObjCInterfaceDecl *getMostRecentDeclImpl() override {
1279 return getMostRecentDecl();
1280 }
1281
1282 public:
1283 static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC,
1284 SourceLocation atLoc,
1285 IdentifierInfo *Id,
1286 ObjCTypeParamList *typeParamList,
1287 ObjCInterfaceDecl *PrevDecl,
1288 SourceLocation ClassLoc = SourceLocation(),
1289 bool isInternal = false);
1290
1291 static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
1292
1293 /// Retrieve the type parameters of this class.
1294 ///
1295 /// This function looks for a type parameter list for the given
1296 /// class; if the class has been declared (with \c \@class) but not
1297 /// defined (with \c \@interface), it will search for a declaration that
1298 /// has type parameters, skipping any declarations that do not.
1299 ObjCTypeParamList *getTypeParamList() const;
1300
1301 /// Set the type parameters of this class.
1302 ///
1303 /// This function is used by the AST importer, which must import the type
1304 /// parameters after creating their DeclContext to avoid loops.
1305 void setTypeParamList(ObjCTypeParamList *TPL);
1306
1307 /// Retrieve the type parameters written on this particular declaration of
1308 /// the class.
getTypeParamListAsWritten()1309 ObjCTypeParamList *getTypeParamListAsWritten() const {
1310 return TypeParamList;
1311 }
1312
getSourceRange()1313 SourceRange getSourceRange() const override LLVM_READONLY {
1314 if (isThisDeclarationADefinition())
1315 return ObjCContainerDecl::getSourceRange();
1316
1317 return SourceRange(getAtStartLoc(), getLocation());
1318 }
1319
1320 /// Indicate that this Objective-C class is complete, but that
1321 /// the external AST source will be responsible for filling in its contents
1322 /// when a complete class is required.
1323 void setExternallyCompleted();
1324
1325 /// Indicate that this interface decl contains at least one initializer
1326 /// marked with the 'objc_designated_initializer' attribute.
1327 void setHasDesignatedInitializers();
1328
1329 /// Returns true if this interface decl contains at least one initializer
1330 /// marked with the 'objc_designated_initializer' attribute.
1331 bool hasDesignatedInitializers() const;
1332
1333 /// Returns true if this interface decl declares a designated initializer
1334 /// or it inherites one from its super class.
declaresOrInheritsDesignatedInitializers()1335 bool declaresOrInheritsDesignatedInitializers() const {
1336 return hasDesignatedInitializers() || inheritsDesignatedInitializers();
1337 }
1338
getReferencedProtocols()1339 const ObjCProtocolList &getReferencedProtocols() const {
1340 assert(hasDefinition() && "Caller did not check for forward reference!");
1341 if (data().ExternallyCompleted)
1342 LoadExternalDefinition();
1343
1344 return data().ReferencedProtocols;
1345 }
1346
1347 ObjCImplementationDecl *getImplementation() const;
1348 void setImplementation(ObjCImplementationDecl *ImplD);
1349
1350 ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
1351
1352 // Get the local instance/class method declared in a category.
1353 ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
1354 ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
1355
getCategoryMethod(Selector Sel,bool isInstance)1356 ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
1357 return isInstance ? getCategoryInstanceMethod(Sel)
1358 : getCategoryClassMethod(Sel);
1359 }
1360
1361 using protocol_iterator = ObjCProtocolList::iterator;
1362 using protocol_range = llvm::iterator_range<protocol_iterator>;
1363
protocols()1364 protocol_range protocols() const {
1365 return protocol_range(protocol_begin(), protocol_end());
1366 }
1367
protocol_begin()1368 protocol_iterator protocol_begin() const {
1369 // FIXME: Should make sure no callers ever do this.
1370 if (!hasDefinition())
1371 return protocol_iterator();
1372
1373 if (data().ExternallyCompleted)
1374 LoadExternalDefinition();
1375
1376 return data().ReferencedProtocols.begin();
1377 }
1378
protocol_end()1379 protocol_iterator protocol_end() const {
1380 // FIXME: Should make sure no callers ever do this.
1381 if (!hasDefinition())
1382 return protocol_iterator();
1383
1384 if (data().ExternallyCompleted)
1385 LoadExternalDefinition();
1386
1387 return data().ReferencedProtocols.end();
1388 }
1389
1390 using protocol_loc_iterator = ObjCProtocolList::loc_iterator;
1391 using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>;
1392
protocol_locs()1393 protocol_loc_range protocol_locs() const {
1394 return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
1395 }
1396
protocol_loc_begin()1397 protocol_loc_iterator protocol_loc_begin() const {
1398 // FIXME: Should make sure no callers ever do this.
1399 if (!hasDefinition())
1400 return protocol_loc_iterator();
1401
1402 if (data().ExternallyCompleted)
1403 LoadExternalDefinition();
1404
1405 return data().ReferencedProtocols.loc_begin();
1406 }
1407
protocol_loc_end()1408 protocol_loc_iterator protocol_loc_end() const {
1409 // FIXME: Should make sure no callers ever do this.
1410 if (!hasDefinition())
1411 return protocol_loc_iterator();
1412
1413 if (data().ExternallyCompleted)
1414 LoadExternalDefinition();
1415
1416 return data().ReferencedProtocols.loc_end();
1417 }
1418
1419 using all_protocol_iterator = ObjCList<ObjCProtocolDecl>::iterator;
1420 using all_protocol_range = llvm::iterator_range<all_protocol_iterator>;
1421
all_referenced_protocols()1422 all_protocol_range all_referenced_protocols() const {
1423 return all_protocol_range(all_referenced_protocol_begin(),
1424 all_referenced_protocol_end());
1425 }
1426
all_referenced_protocol_begin()1427 all_protocol_iterator all_referenced_protocol_begin() const {
1428 // FIXME: Should make sure no callers ever do this.
1429 if (!hasDefinition())
1430 return all_protocol_iterator();
1431
1432 if (data().ExternallyCompleted)
1433 LoadExternalDefinition();
1434
1435 return data().AllReferencedProtocols.empty()
1436 ? protocol_begin()
1437 : data().AllReferencedProtocols.begin();
1438 }
1439
all_referenced_protocol_end()1440 all_protocol_iterator all_referenced_protocol_end() const {
1441 // FIXME: Should make sure no callers ever do this.
1442 if (!hasDefinition())
1443 return all_protocol_iterator();
1444
1445 if (data().ExternallyCompleted)
1446 LoadExternalDefinition();
1447
1448 return data().AllReferencedProtocols.empty()
1449 ? protocol_end()
1450 : data().AllReferencedProtocols.end();
1451 }
1452
1453 using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>;
1454 using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>;
1455
ivars()1456 ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
1457
ivar_begin()1458 ivar_iterator ivar_begin() const {
1459 if (const ObjCInterfaceDecl *Def = getDefinition())
1460 return ivar_iterator(Def->decls_begin());
1461
1462 // FIXME: Should make sure no callers ever do this.
1463 return ivar_iterator();
1464 }
1465
ivar_end()1466 ivar_iterator ivar_end() const {
1467 if (const ObjCInterfaceDecl *Def = getDefinition())
1468 return ivar_iterator(Def->decls_end());
1469
1470 // FIXME: Should make sure no callers ever do this.
1471 return ivar_iterator();
1472 }
1473
ivar_size()1474 unsigned ivar_size() const {
1475 return std::distance(ivar_begin(), ivar_end());
1476 }
1477
ivar_empty()1478 bool ivar_empty() const { return ivar_begin() == ivar_end(); }
1479
1480 ObjCIvarDecl *all_declared_ivar_begin();
all_declared_ivar_begin()1481 const ObjCIvarDecl *all_declared_ivar_begin() const {
1482 // Even though this modifies IvarList, it's conceptually const:
1483 // the ivar chain is essentially a cached property of ObjCInterfaceDecl.
1484 return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
1485 }
setIvarList(ObjCIvarDecl * ivar)1486 void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; }
1487
1488 /// setProtocolList - Set the list of protocols that this interface
1489 /// implements.
setProtocolList(ObjCProtocolDecl * const * List,unsigned Num,const SourceLocation * Locs,ASTContext & C)1490 void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
1491 const SourceLocation *Locs, ASTContext &C) {
1492 data().ReferencedProtocols.set(List, Num, Locs, C);
1493 }
1494
1495 /// mergeClassExtensionProtocolList - Merge class extension's protocol list
1496 /// into the protocol list for this class.
1497 void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
1498 unsigned Num,
1499 ASTContext &C);
1500
1501 /// Produce a name to be used for class's metadata. It comes either via
1502 /// objc_runtime_name attribute or class name.
1503 StringRef getObjCRuntimeNameAsString() const;
1504
1505 /// Returns the designated initializers for the interface.
1506 ///
1507 /// If this declaration does not have methods marked as designated
1508 /// initializers then the interface inherits the designated initializers of
1509 /// its super class.
1510 void getDesignatedInitializers(
1511 llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const;
1512
1513 /// Returns true if the given selector is a designated initializer for the
1514 /// interface.
1515 ///
1516 /// If this declaration does not have methods marked as designated
1517 /// initializers then the interface inherits the designated initializers of
1518 /// its super class.
1519 ///
1520 /// \param InitMethod if non-null and the function returns true, it receives
1521 /// the method that was marked as a designated initializer.
1522 bool
1523 isDesignatedInitializer(Selector Sel,
1524 const ObjCMethodDecl **InitMethod = nullptr) const;
1525
1526 /// Determine whether this particular declaration of this class is
1527 /// actually also a definition.
isThisDeclarationADefinition()1528 bool isThisDeclarationADefinition() const {
1529 return getDefinition() == this;
1530 }
1531
1532 /// Determine whether this class has been defined.
hasDefinition()1533 bool hasDefinition() const {
1534 // If the name of this class is out-of-date, bring it up-to-date, which
1535 // might bring in a definition.
1536 // Note: a null value indicates that we don't have a definition and that
1537 // modules are enabled.
1538 if (!Data.getOpaqueValue())
1539 getMostRecentDecl();
1540
1541 return Data.getPointer();
1542 }
1543
1544 /// Retrieve the definition of this class, or NULL if this class
1545 /// has been forward-declared (with \@class) but not yet defined (with
1546 /// \@interface).
getDefinition()1547 ObjCInterfaceDecl *getDefinition() {
1548 return hasDefinition()? Data.getPointer()->Definition : nullptr;
1549 }
1550
1551 /// Retrieve the definition of this class, or NULL if this class
1552 /// has been forward-declared (with \@class) but not yet defined (with
1553 /// \@interface).
getDefinition()1554 const ObjCInterfaceDecl *getDefinition() const {
1555 return hasDefinition()? Data.getPointer()->Definition : nullptr;
1556 }
1557
1558 /// Starts the definition of this Objective-C class, taking it from
1559 /// a forward declaration (\@class) to a definition (\@interface).
1560 void startDefinition();
1561
1562 /// Retrieve the superclass type.
getSuperClassType()1563 const ObjCObjectType *getSuperClassType() const {
1564 if (TypeSourceInfo *TInfo = getSuperClassTInfo())
1565 return TInfo->getType()->castAs<ObjCObjectType>();
1566
1567 return nullptr;
1568 }
1569
1570 // Retrieve the type source information for the superclass.
getSuperClassTInfo()1571 TypeSourceInfo *getSuperClassTInfo() const {
1572 // FIXME: Should make sure no callers ever do this.
1573 if (!hasDefinition())
1574 return nullptr;
1575
1576 if (data().ExternallyCompleted)
1577 LoadExternalDefinition();
1578
1579 return data().SuperClassTInfo;
1580 }
1581
1582 // Retrieve the declaration for the superclass of this class, which
1583 // does not include any type arguments that apply to the superclass.
1584 ObjCInterfaceDecl *getSuperClass() const;
1585
setSuperClass(TypeSourceInfo * superClass)1586 void setSuperClass(TypeSourceInfo *superClass) {
1587 data().SuperClassTInfo = superClass;
1588 }
1589
1590 /// Iterator that walks over the list of categories, filtering out
1591 /// those that do not meet specific criteria.
1592 ///
1593 /// This class template is used for the various permutations of category
1594 /// and extension iterators.
1595 template<bool (*Filter)(ObjCCategoryDecl *)>
1596 class filtered_category_iterator {
1597 ObjCCategoryDecl *Current = nullptr;
1598
1599 void findAcceptableCategory();
1600
1601 public:
1602 using value_type = ObjCCategoryDecl *;
1603 using reference = value_type;
1604 using pointer = value_type;
1605 using difference_type = std::ptrdiff_t;
1606 using iterator_category = std::input_iterator_tag;
1607
1608 filtered_category_iterator() = default;
filtered_category_iterator(ObjCCategoryDecl * Current)1609 explicit filtered_category_iterator(ObjCCategoryDecl *Current)
1610 : Current(Current) {
1611 findAcceptableCategory();
1612 }
1613
1614 reference operator*() const { return Current; }
1615 pointer operator->() const { return Current; }
1616
1617 filtered_category_iterator &operator++();
1618
1619 filtered_category_iterator operator++(int) {
1620 filtered_category_iterator Tmp = *this;
1621 ++(*this);
1622 return Tmp;
1623 }
1624
1625 friend bool operator==(filtered_category_iterator X,
1626 filtered_category_iterator Y) {
1627 return X.Current == Y.Current;
1628 }
1629
1630 friend bool operator!=(filtered_category_iterator X,
1631 filtered_category_iterator Y) {
1632 return X.Current != Y.Current;
1633 }
1634 };
1635
1636 private:
1637 /// Test whether the given category is visible.
1638 ///
1639 /// Used in the \c visible_categories_iterator.
1640 static bool isVisibleCategory(ObjCCategoryDecl *Cat);
1641
1642 public:
1643 /// Iterator that walks over the list of categories and extensions
1644 /// that are visible, i.e., not hidden in a non-imported submodule.
1645 using visible_categories_iterator =
1646 filtered_category_iterator<isVisibleCategory>;
1647
1648 using visible_categories_range =
1649 llvm::iterator_range<visible_categories_iterator>;
1650
visible_categories()1651 visible_categories_range visible_categories() const {
1652 return visible_categories_range(visible_categories_begin(),
1653 visible_categories_end());
1654 }
1655
1656 /// Retrieve an iterator to the beginning of the visible-categories
1657 /// list.
visible_categories_begin()1658 visible_categories_iterator visible_categories_begin() const {
1659 return visible_categories_iterator(getCategoryListRaw());
1660 }
1661
1662 /// Retrieve an iterator to the end of the visible-categories list.
visible_categories_end()1663 visible_categories_iterator visible_categories_end() const {
1664 return visible_categories_iterator();
1665 }
1666
1667 /// Determine whether the visible-categories list is empty.
visible_categories_empty()1668 bool visible_categories_empty() const {
1669 return visible_categories_begin() == visible_categories_end();
1670 }
1671
1672 private:
1673 /// Test whether the given category... is a category.
1674 ///
1675 /// Used in the \c known_categories_iterator.
isKnownCategory(ObjCCategoryDecl *)1676 static bool isKnownCategory(ObjCCategoryDecl *) { return true; }
1677
1678 public:
1679 /// Iterator that walks over all of the known categories and
1680 /// extensions, including those that are hidden.
1681 using known_categories_iterator = filtered_category_iterator<isKnownCategory>;
1682 using known_categories_range =
1683 llvm::iterator_range<known_categories_iterator>;
1684
known_categories()1685 known_categories_range known_categories() const {
1686 return known_categories_range(known_categories_begin(),
1687 known_categories_end());
1688 }
1689
1690 /// Retrieve an iterator to the beginning of the known-categories
1691 /// list.
known_categories_begin()1692 known_categories_iterator known_categories_begin() const {
1693 return known_categories_iterator(getCategoryListRaw());
1694 }
1695
1696 /// Retrieve an iterator to the end of the known-categories list.
known_categories_end()1697 known_categories_iterator known_categories_end() const {
1698 return known_categories_iterator();
1699 }
1700
1701 /// Determine whether the known-categories list is empty.
known_categories_empty()1702 bool known_categories_empty() const {
1703 return known_categories_begin() == known_categories_end();
1704 }
1705
1706 private:
1707 /// Test whether the given category is a visible extension.
1708 ///
1709 /// Used in the \c visible_extensions_iterator.
1710 static bool isVisibleExtension(ObjCCategoryDecl *Cat);
1711
1712 public:
1713 /// Iterator that walks over all of the visible extensions, skipping
1714 /// any that are known but hidden.
1715 using visible_extensions_iterator =
1716 filtered_category_iterator<isVisibleExtension>;
1717
1718 using visible_extensions_range =
1719 llvm::iterator_range<visible_extensions_iterator>;
1720
visible_extensions()1721 visible_extensions_range visible_extensions() const {
1722 return visible_extensions_range(visible_extensions_begin(),
1723 visible_extensions_end());
1724 }
1725
1726 /// Retrieve an iterator to the beginning of the visible-extensions
1727 /// list.
visible_extensions_begin()1728 visible_extensions_iterator visible_extensions_begin() const {
1729 return visible_extensions_iterator(getCategoryListRaw());
1730 }
1731
1732 /// Retrieve an iterator to the end of the visible-extensions list.
visible_extensions_end()1733 visible_extensions_iterator visible_extensions_end() const {
1734 return visible_extensions_iterator();
1735 }
1736
1737 /// Determine whether the visible-extensions list is empty.
visible_extensions_empty()1738 bool visible_extensions_empty() const {
1739 return visible_extensions_begin() == visible_extensions_end();
1740 }
1741
1742 private:
1743 /// Test whether the given category is an extension.
1744 ///
1745 /// Used in the \c known_extensions_iterator.
1746 static bool isKnownExtension(ObjCCategoryDecl *Cat);
1747
1748 public:
1749 friend class ASTDeclReader;
1750 friend class ASTDeclWriter;
1751 friend class ASTReader;
1752
1753 /// Iterator that walks over all of the known extensions.
1754 using known_extensions_iterator =
1755 filtered_category_iterator<isKnownExtension>;
1756 using known_extensions_range =
1757 llvm::iterator_range<known_extensions_iterator>;
1758
known_extensions()1759 known_extensions_range known_extensions() const {
1760 return known_extensions_range(known_extensions_begin(),
1761 known_extensions_end());
1762 }
1763
1764 /// Retrieve an iterator to the beginning of the known-extensions
1765 /// list.
known_extensions_begin()1766 known_extensions_iterator known_extensions_begin() const {
1767 return known_extensions_iterator(getCategoryListRaw());
1768 }
1769
1770 /// Retrieve an iterator to the end of the known-extensions list.
known_extensions_end()1771 known_extensions_iterator known_extensions_end() const {
1772 return known_extensions_iterator();
1773 }
1774
1775 /// Determine whether the known-extensions list is empty.
known_extensions_empty()1776 bool known_extensions_empty() const {
1777 return known_extensions_begin() == known_extensions_end();
1778 }
1779
1780 /// Retrieve the raw pointer to the start of the category/extension
1781 /// list.
getCategoryListRaw()1782 ObjCCategoryDecl* getCategoryListRaw() const {
1783 // FIXME: Should make sure no callers ever do this.
1784 if (!hasDefinition())
1785 return nullptr;
1786
1787 if (data().ExternallyCompleted)
1788 LoadExternalDefinition();
1789
1790 return data().CategoryList;
1791 }
1792
1793 /// Set the raw pointer to the start of the category/extension
1794 /// list.
setCategoryListRaw(ObjCCategoryDecl * category)1795 void setCategoryListRaw(ObjCCategoryDecl *category) {
1796 data().CategoryList = category;
1797 }
1798
1799 ObjCPropertyDecl
1800 *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId,
1801 ObjCPropertyQueryKind QueryKind) const;
1802
1803 void collectPropertiesToImplement(PropertyMap &PM,
1804 PropertyDeclOrder &PO) const override;
1805
1806 /// isSuperClassOf - Return true if this class is the specified class or is a
1807 /// super class of the specified interface class.
isSuperClassOf(const ObjCInterfaceDecl * I)1808 bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
1809 // If RHS is derived from LHS it is OK; else it is not OK.
1810 while (I != nullptr) {
1811 if (declaresSameEntity(this, I))
1812 return true;
1813
1814 I = I->getSuperClass();
1815 }
1816 return false;
1817 }
1818
1819 /// isArcWeakrefUnavailable - Checks for a class or one of its super classes
1820 /// to be incompatible with __weak references. Returns true if it is.
1821 bool isArcWeakrefUnavailable() const;
1822
1823 /// isObjCRequiresPropertyDefs - Checks that a class or one of its super
1824 /// classes must not be auto-synthesized. Returns class decl. if it must not
1825 /// be; 0, otherwise.
1826 const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const;
1827
1828 ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
1829 ObjCInterfaceDecl *&ClassDeclared);
lookupInstanceVariable(IdentifierInfo * IVarName)1830 ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
1831 ObjCInterfaceDecl *ClassDeclared;
1832 return lookupInstanceVariable(IVarName, ClassDeclared);
1833 }
1834
1835 ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name);
1836
1837 // Lookup a method. First, we search locally. If a method isn't
1838 // found, we search referenced protocols and class categories.
1839 ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
1840 bool shallowCategoryLookup = false,
1841 bool followSuper = true,
1842 const ObjCCategoryDecl *C = nullptr) const;
1843
1844 /// Lookup an instance method for a given selector.
lookupInstanceMethod(Selector Sel)1845 ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
1846 return lookupMethod(Sel, true/*isInstance*/);
1847 }
1848
1849 /// Lookup a class method for a given selector.
lookupClassMethod(Selector Sel)1850 ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
1851 return lookupMethod(Sel, false/*isInstance*/);
1852 }
1853
1854 ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
1855
1856 /// Lookup a method in the classes implementation hierarchy.
1857 ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel,
1858 bool Instance=true) const;
1859
lookupPrivateClassMethod(const Selector & Sel)1860 ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) {
1861 return lookupPrivateMethod(Sel, false);
1862 }
1863
1864 /// Lookup a setter or getter in the class hierarchy,
1865 /// including in all categories except for category passed
1866 /// as argument.
lookupPropertyAccessor(const Selector Sel,const ObjCCategoryDecl * Cat,bool IsClassProperty)1867 ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
1868 const ObjCCategoryDecl *Cat,
1869 bool IsClassProperty) const {
1870 return lookupMethod(Sel, !IsClassProperty/*isInstance*/,
1871 false/*shallowCategoryLookup*/,
1872 true /* followsSuper */,
1873 Cat);
1874 }
1875
getEndOfDefinitionLoc()1876 SourceLocation getEndOfDefinitionLoc() const {
1877 if (!hasDefinition())
1878 return getLocation();
1879
1880 return data().EndLoc;
1881 }
1882
setEndOfDefinitionLoc(SourceLocation LE)1883 void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; }
1884
1885 /// Retrieve the starting location of the superclass.
1886 SourceLocation getSuperClassLoc() const;
1887
1888 /// isImplicitInterfaceDecl - check that this is an implicitly declared
1889 /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation
1890 /// declaration without an \@interface declaration.
isImplicitInterfaceDecl()1891 bool isImplicitInterfaceDecl() const {
1892 return hasDefinition() ? data().Definition->isImplicit() : isImplicit();
1893 }
1894
1895 /// ClassImplementsProtocol - Checks that 'lProto' protocol
1896 /// has been implemented in IDecl class, its super class or categories (if
1897 /// lookupCategory is true).
1898 bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
1899 bool lookupCategory,
1900 bool RHSIsQualifiedID = false);
1901
1902 using redecl_range = redeclarable_base::redecl_range;
1903 using redecl_iterator = redeclarable_base::redecl_iterator;
1904
1905 using redeclarable_base::redecls_begin;
1906 using redeclarable_base::redecls_end;
1907 using redeclarable_base::redecls;
1908 using redeclarable_base::getPreviousDecl;
1909 using redeclarable_base::getMostRecentDecl;
1910 using redeclarable_base::isFirstDecl;
1911
1912 /// Retrieves the canonical declaration of this Objective-C class.
getCanonicalDecl()1913 ObjCInterfaceDecl *getCanonicalDecl() override { return getFirstDecl(); }
getCanonicalDecl()1914 const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); }
1915
1916 // Low-level accessor
getTypeForDecl()1917 const Type *getTypeForDecl() const { return TypeForDecl; }
setTypeForDecl(const Type * TD)1918 void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
1919
classof(const Decl * D)1920 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)1921 static bool classofKind(Kind K) { return K == ObjCInterface; }
1922
1923 private:
1924 const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
1925 bool inheritsDesignatedInitializers() const;
1926 };
1927
1928 /// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
1929 /// instance variables are identical to C. The only exception is Objective-C
1930 /// supports C++ style access control. For example:
1931 ///
1932 /// \@interface IvarExample : NSObject
1933 /// {
1934 /// id defaultToProtected;
1935 /// \@public:
1936 /// id canBePublic; // same as C++.
1937 /// \@protected:
1938 /// id canBeProtected; // same as C++.
1939 /// \@package:
1940 /// id canBePackage; // framework visibility (not available in C++).
1941 /// }
1942 ///
1943 class ObjCIvarDecl : public FieldDecl {
1944 void anchor() override;
1945
1946 public:
1947 enum AccessControl {
1948 None, Private, Protected, Public, Package
1949 };
1950
1951 private:
ObjCIvarDecl(ObjCContainerDecl * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,AccessControl ac,Expr * BW,bool synthesized)1952 ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
1953 SourceLocation IdLoc, IdentifierInfo *Id,
1954 QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
1955 bool synthesized)
1956 : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
1957 /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
1958 DeclAccess(ac), Synthesized(synthesized) {}
1959
1960 public:
1961 static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
1962 SourceLocation StartLoc, SourceLocation IdLoc,
1963 IdentifierInfo *Id, QualType T,
1964 TypeSourceInfo *TInfo,
1965 AccessControl ac, Expr *BW = nullptr,
1966 bool synthesized=false);
1967
1968 static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1969
1970 /// Return the class interface that this ivar is logically contained
1971 /// in; this is either the interface where the ivar was declared, or the
1972 /// interface the ivar is conceptually a part of in the case of synthesized
1973 /// ivars.
1974 const ObjCInterfaceDecl *getContainingInterface() const;
1975
getNextIvar()1976 ObjCIvarDecl *getNextIvar() { return NextIvar; }
getNextIvar()1977 const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
setNextIvar(ObjCIvarDecl * ivar)1978 void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
1979
setAccessControl(AccessControl ac)1980 void setAccessControl(AccessControl ac) { DeclAccess = ac; }
1981
getAccessControl()1982 AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
1983
getCanonicalAccessControl()1984 AccessControl getCanonicalAccessControl() const {
1985 return DeclAccess == None ? Protected : AccessControl(DeclAccess);
1986 }
1987
setSynthesize(bool synth)1988 void setSynthesize(bool synth) { Synthesized = synth; }
getSynthesize()1989 bool getSynthesize() const { return Synthesized; }
1990
1991 /// Retrieve the type of this instance variable when viewed as a member of a
1992 /// specific object type.
1993 QualType getUsageType(QualType objectType) const;
1994
1995 // Implement isa/cast/dyncast/etc.
classof(const Decl * D)1996 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)1997 static bool classofKind(Kind K) { return K == ObjCIvar; }
1998
1999 private:
2000 /// NextIvar - Next Ivar in the list of ivars declared in class; class's
2001 /// extensions and class's implementation
2002 ObjCIvarDecl *NextIvar = nullptr;
2003
2004 // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
2005 unsigned DeclAccess : 3;
2006 unsigned Synthesized : 1;
2007 };
2008
2009 /// Represents a field declaration created by an \@defs(...).
2010 class ObjCAtDefsFieldDecl : public FieldDecl {
ObjCAtDefsFieldDecl(DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,QualType T,Expr * BW)2011 ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
2012 SourceLocation IdLoc, IdentifierInfo *Id,
2013 QualType T, Expr *BW)
2014 : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
2015 /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
2016 BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
2017
2018 void anchor() override;
2019
2020 public:
2021 static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
2022 SourceLocation StartLoc,
2023 SourceLocation IdLoc, IdentifierInfo *Id,
2024 QualType T, Expr *BW);
2025
2026 static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2027
2028 // Implement isa/cast/dyncast/etc.
classof(const Decl * D)2029 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)2030 static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
2031 };
2032
2033 /// Represents an Objective-C protocol declaration.
2034 ///
2035 /// Objective-C protocols declare a pure abstract type (i.e., no instance
2036 /// variables are permitted). Protocols originally drew inspiration from
2037 /// C++ pure virtual functions (a C++ feature with nice semantics and lousy
2038 /// syntax:-). Here is an example:
2039 ///
2040 /// \code
2041 /// \@protocol NSDraggingInfo <refproto1, refproto2>
2042 /// - (NSWindow *)draggingDestinationWindow;
2043 /// - (NSImage *)draggedImage;
2044 /// \@end
2045 /// \endcode
2046 ///
2047 /// This says that NSDraggingInfo requires two methods and requires everything
2048 /// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
2049 /// well.
2050 ///
2051 /// \code
2052 /// \@interface ImplementsNSDraggingInfo : NSObject \<NSDraggingInfo>
2053 /// \@end
2054 /// \endcode
2055 ///
2056 /// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
2057 /// protocols are in distinct namespaces. For example, Cocoa defines both
2058 /// an NSObject protocol and class (which isn't allowed in Java). As a result,
2059 /// protocols are referenced using angle brackets as follows:
2060 ///
2061 /// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
2062 class ObjCProtocolDecl : public ObjCContainerDecl,
2063 public Redeclarable<ObjCProtocolDecl> {
2064 struct DefinitionData {
2065 // The declaration that defines this protocol.
2066 ObjCProtocolDecl *Definition;
2067
2068 /// Referenced protocols
2069 ObjCProtocolList ReferencedProtocols;
2070 };
2071
2072 /// Contains a pointer to the data associated with this class,
2073 /// which will be NULL if this class has not yet been defined.
2074 ///
2075 /// The bit indicates when we don't need to check for out-of-date
2076 /// declarations. It will be set unless modules are enabled.
2077 llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
2078
2079 ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
2080 SourceLocation nameLoc, SourceLocation atStartLoc,
2081 ObjCProtocolDecl *PrevDecl);
2082
2083 void anchor() override;
2084
data()2085 DefinitionData &data() const {
2086 assert(Data.getPointer() && "Objective-C protocol has no definition!");
2087 return *Data.getPointer();
2088 }
2089
2090 void allocateDefinitionData();
2091
2092 using redeclarable_base = Redeclarable<ObjCProtocolDecl>;
2093
getNextRedeclarationImpl()2094 ObjCProtocolDecl *getNextRedeclarationImpl() override {
2095 return getNextRedeclaration();
2096 }
2097
getPreviousDeclImpl()2098 ObjCProtocolDecl *getPreviousDeclImpl() override {
2099 return getPreviousDecl();
2100 }
2101
getMostRecentDeclImpl()2102 ObjCProtocolDecl *getMostRecentDeclImpl() override {
2103 return getMostRecentDecl();
2104 }
2105
2106 public:
2107 friend class ASTDeclReader;
2108 friend class ASTDeclWriter;
2109 friend class ASTReader;
2110
2111 static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
2112 IdentifierInfo *Id,
2113 SourceLocation nameLoc,
2114 SourceLocation atStartLoc,
2115 ObjCProtocolDecl *PrevDecl);
2116
2117 static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2118
getReferencedProtocols()2119 const ObjCProtocolList &getReferencedProtocols() const {
2120 assert(hasDefinition() && "No definition available!");
2121 return data().ReferencedProtocols;
2122 }
2123
2124 using protocol_iterator = ObjCProtocolList::iterator;
2125 using protocol_range = llvm::iterator_range<protocol_iterator>;
2126
protocols()2127 protocol_range protocols() const {
2128 return protocol_range(protocol_begin(), protocol_end());
2129 }
2130
protocol_begin()2131 protocol_iterator protocol_begin() const {
2132 if (!hasDefinition())
2133 return protocol_iterator();
2134
2135 return data().ReferencedProtocols.begin();
2136 }
2137
protocol_end()2138 protocol_iterator protocol_end() const {
2139 if (!hasDefinition())
2140 return protocol_iterator();
2141
2142 return data().ReferencedProtocols.end();
2143 }
2144
2145 using protocol_loc_iterator = ObjCProtocolList::loc_iterator;
2146 using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>;
2147
protocol_locs()2148 protocol_loc_range protocol_locs() const {
2149 return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
2150 }
2151
protocol_loc_begin()2152 protocol_loc_iterator protocol_loc_begin() const {
2153 if (!hasDefinition())
2154 return protocol_loc_iterator();
2155
2156 return data().ReferencedProtocols.loc_begin();
2157 }
2158
protocol_loc_end()2159 protocol_loc_iterator protocol_loc_end() const {
2160 if (!hasDefinition())
2161 return protocol_loc_iterator();
2162
2163 return data().ReferencedProtocols.loc_end();
2164 }
2165
protocol_size()2166 unsigned protocol_size() const {
2167 if (!hasDefinition())
2168 return 0;
2169
2170 return data().ReferencedProtocols.size();
2171 }
2172
2173 /// setProtocolList - Set the list of protocols that this interface
2174 /// implements.
setProtocolList(ObjCProtocolDecl * const * List,unsigned Num,const SourceLocation * Locs,ASTContext & C)2175 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
2176 const SourceLocation *Locs, ASTContext &C) {
2177 assert(hasDefinition() && "Protocol is not defined");
2178 data().ReferencedProtocols.set(List, Num, Locs, C);
2179 }
2180
2181 /// This is true iff the protocol is tagged with the
2182 /// `objc_non_runtime_protocol` attribute.
2183 bool isNonRuntimeProtocol() const;
2184
2185 /// Get the set of all protocols implied by this protocols inheritance
2186 /// hierarchy.
2187 void getImpliedProtocols(llvm::DenseSet<const ObjCProtocolDecl *> &IPs) const;
2188
2189 ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
2190
2191 // Lookup a method. First, we search locally. If a method isn't
2192 // found, we search referenced protocols and class categories.
2193 ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
2194
lookupInstanceMethod(Selector Sel)2195 ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
2196 return lookupMethod(Sel, true/*isInstance*/);
2197 }
2198
lookupClassMethod(Selector Sel)2199 ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
2200 return lookupMethod(Sel, false/*isInstance*/);
2201 }
2202
2203 /// Determine whether this protocol has a definition.
hasDefinition()2204 bool hasDefinition() const {
2205 // If the name of this protocol is out-of-date, bring it up-to-date, which
2206 // might bring in a definition.
2207 // Note: a null value indicates that we don't have a definition and that
2208 // modules are enabled.
2209 if (!Data.getOpaqueValue())
2210 getMostRecentDecl();
2211
2212 return Data.getPointer();
2213 }
2214
2215 /// Retrieve the definition of this protocol, if any.
getDefinition()2216 ObjCProtocolDecl *getDefinition() {
2217 return hasDefinition()? Data.getPointer()->Definition : nullptr;
2218 }
2219
2220 /// Retrieve the definition of this protocol, if any.
getDefinition()2221 const ObjCProtocolDecl *getDefinition() const {
2222 return hasDefinition()? Data.getPointer()->Definition : nullptr;
2223 }
2224
2225 /// Determine whether this particular declaration is also the
2226 /// definition.
isThisDeclarationADefinition()2227 bool isThisDeclarationADefinition() const {
2228 return getDefinition() == this;
2229 }
2230
2231 /// Starts the definition of this Objective-C protocol.
2232 void startDefinition();
2233
2234 /// Produce a name to be used for protocol's metadata. It comes either via
2235 /// objc_runtime_name attribute or protocol name.
2236 StringRef getObjCRuntimeNameAsString() const;
2237
getSourceRange()2238 SourceRange getSourceRange() const override LLVM_READONLY {
2239 if (isThisDeclarationADefinition())
2240 return ObjCContainerDecl::getSourceRange();
2241
2242 return SourceRange(getAtStartLoc(), getLocation());
2243 }
2244
2245 using redecl_range = redeclarable_base::redecl_range;
2246 using redecl_iterator = redeclarable_base::redecl_iterator;
2247
2248 using redeclarable_base::redecls_begin;
2249 using redeclarable_base::redecls_end;
2250 using redeclarable_base::redecls;
2251 using redeclarable_base::getPreviousDecl;
2252 using redeclarable_base::getMostRecentDecl;
2253 using redeclarable_base::isFirstDecl;
2254
2255 /// Retrieves the canonical declaration of this Objective-C protocol.
getCanonicalDecl()2256 ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); }
getCanonicalDecl()2257 const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
2258
2259 void collectPropertiesToImplement(PropertyMap &PM,
2260 PropertyDeclOrder &PO) const override;
2261
2262 void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
2263 ProtocolPropertySet &PS,
2264 PropertyDeclOrder &PO) const;
2265
classof(const Decl * D)2266 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)2267 static bool classofKind(Kind K) { return K == ObjCProtocol; }
2268 };
2269
2270 /// ObjCCategoryDecl - Represents a category declaration. A category allows
2271 /// you to add methods to an existing class (without subclassing or modifying
2272 /// the original class interface or implementation:-). Categories don't allow
2273 /// you to add instance data. The following example adds "myMethod" to all
2274 /// NSView's within a process:
2275 ///
2276 /// \@interface NSView (MyViewMethods)
2277 /// - myMethod;
2278 /// \@end
2279 ///
2280 /// Categories also allow you to split the implementation of a class across
2281 /// several files (a feature more naturally supported in C++).
2282 ///
2283 /// Categories were originally inspired by dynamic languages such as Common
2284 /// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
2285 /// don't support this level of dynamism, which is both powerful and dangerous.
2286 class ObjCCategoryDecl : public ObjCContainerDecl {
2287 /// Interface belonging to this category
2288 ObjCInterfaceDecl *ClassInterface;
2289
2290 /// The type parameters associated with this category, if any.
2291 ObjCTypeParamList *TypeParamList = nullptr;
2292
2293 /// referenced protocols in this category.
2294 ObjCProtocolList ReferencedProtocols;
2295
2296 /// Next category belonging to this class.
2297 /// FIXME: this should not be a singly-linked list. Move storage elsewhere.
2298 ObjCCategoryDecl *NextClassCategory = nullptr;
2299
2300 /// The location of the category name in this declaration.
2301 SourceLocation CategoryNameLoc;
2302
2303 /// class extension may have private ivars.
2304 SourceLocation IvarLBraceLoc;
2305 SourceLocation IvarRBraceLoc;
2306
2307 ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
2308 SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
2309 IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
2310 ObjCTypeParamList *typeParamList,
2311 SourceLocation IvarLBraceLoc = SourceLocation(),
2312 SourceLocation IvarRBraceLoc = SourceLocation());
2313
2314 void anchor() override;
2315
2316 public:
2317 friend class ASTDeclReader;
2318 friend class ASTDeclWriter;
2319
2320 static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
2321 SourceLocation AtLoc,
2322 SourceLocation ClassNameLoc,
2323 SourceLocation CategoryNameLoc,
2324 IdentifierInfo *Id,
2325 ObjCInterfaceDecl *IDecl,
2326 ObjCTypeParamList *typeParamList,
2327 SourceLocation IvarLBraceLoc=SourceLocation(),
2328 SourceLocation IvarRBraceLoc=SourceLocation());
2329 static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2330
getClassInterface()2331 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
getClassInterface()2332 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
2333
2334 /// Retrieve the type parameter list associated with this category or
2335 /// extension.
getTypeParamList()2336 ObjCTypeParamList *getTypeParamList() const { return TypeParamList; }
2337
2338 /// Set the type parameters of this category.
2339 ///
2340 /// This function is used by the AST importer, which must import the type
2341 /// parameters after creating their DeclContext to avoid loops.
2342 void setTypeParamList(ObjCTypeParamList *TPL);
2343
2344
2345 ObjCCategoryImplDecl *getImplementation() const;
2346 void setImplementation(ObjCCategoryImplDecl *ImplD);
2347
2348 /// setProtocolList - Set the list of protocols that this interface
2349 /// implements.
setProtocolList(ObjCProtocolDecl * const * List,unsigned Num,const SourceLocation * Locs,ASTContext & C)2350 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
2351 const SourceLocation *Locs, ASTContext &C) {
2352 ReferencedProtocols.set(List, Num, Locs, C);
2353 }
2354
getReferencedProtocols()2355 const ObjCProtocolList &getReferencedProtocols() const {
2356 return ReferencedProtocols;
2357 }
2358
2359 using protocol_iterator = ObjCProtocolList::iterator;
2360 using protocol_range = llvm::iterator_range<protocol_iterator>;
2361
protocols()2362 protocol_range protocols() const {
2363 return protocol_range(protocol_begin(), protocol_end());
2364 }
2365
protocol_begin()2366 protocol_iterator protocol_begin() const {
2367 return ReferencedProtocols.begin();
2368 }
2369
protocol_end()2370 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
protocol_size()2371 unsigned protocol_size() const { return ReferencedProtocols.size(); }
2372
2373 using protocol_loc_iterator = ObjCProtocolList::loc_iterator;
2374 using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>;
2375
protocol_locs()2376 protocol_loc_range protocol_locs() const {
2377 return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
2378 }
2379
protocol_loc_begin()2380 protocol_loc_iterator protocol_loc_begin() const {
2381 return ReferencedProtocols.loc_begin();
2382 }
2383
protocol_loc_end()2384 protocol_loc_iterator protocol_loc_end() const {
2385 return ReferencedProtocols.loc_end();
2386 }
2387
getNextClassCategory()2388 ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
2389
2390 /// Retrieve the pointer to the next stored category (or extension),
2391 /// which may be hidden.
getNextClassCategoryRaw()2392 ObjCCategoryDecl *getNextClassCategoryRaw() const {
2393 return NextClassCategory;
2394 }
2395
IsClassExtension()2396 bool IsClassExtension() const { return getIdentifier() == nullptr; }
2397
2398 using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>;
2399 using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>;
2400
ivars()2401 ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
2402
ivar_begin()2403 ivar_iterator ivar_begin() const {
2404 return ivar_iterator(decls_begin());
2405 }
2406
ivar_end()2407 ivar_iterator ivar_end() const {
2408 return ivar_iterator(decls_end());
2409 }
2410
ivar_size()2411 unsigned ivar_size() const {
2412 return std::distance(ivar_begin(), ivar_end());
2413 }
2414
ivar_empty()2415 bool ivar_empty() const {
2416 return ivar_begin() == ivar_end();
2417 }
2418
getCategoryNameLoc()2419 SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
setCategoryNameLoc(SourceLocation Loc)2420 void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
2421
setIvarLBraceLoc(SourceLocation Loc)2422 void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
getIvarLBraceLoc()2423 SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
setIvarRBraceLoc(SourceLocation Loc)2424 void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
getIvarRBraceLoc()2425 SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
2426
classof(const Decl * D)2427 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)2428 static bool classofKind(Kind K) { return K == ObjCCategory; }
2429 };
2430
2431 class ObjCImplDecl : public ObjCContainerDecl {
2432 /// Class interface for this class/category implementation
2433 ObjCInterfaceDecl *ClassInterface;
2434
2435 void anchor() override;
2436
2437 protected:
ObjCImplDecl(Kind DK,DeclContext * DC,ObjCInterfaceDecl * classInterface,IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc)2438 ObjCImplDecl(Kind DK, DeclContext *DC,
2439 ObjCInterfaceDecl *classInterface,
2440 IdentifierInfo *Id,
2441 SourceLocation nameLoc, SourceLocation atStartLoc)
2442 : ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc),
2443 ClassInterface(classInterface) {}
2444
2445 public:
getClassInterface()2446 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
getClassInterface()2447 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
2448 void setClassInterface(ObjCInterfaceDecl *IFace);
2449
addInstanceMethod(ObjCMethodDecl * method)2450 void addInstanceMethod(ObjCMethodDecl *method) {
2451 // FIXME: Context should be set correctly before we get here.
2452 method->setLexicalDeclContext(this);
2453 addDecl(method);
2454 }
2455
addClassMethod(ObjCMethodDecl * method)2456 void addClassMethod(ObjCMethodDecl *method) {
2457 // FIXME: Context should be set correctly before we get here.
2458 method->setLexicalDeclContext(this);
2459 addDecl(method);
2460 }
2461
2462 void addPropertyImplementation(ObjCPropertyImplDecl *property);
2463
2464 ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId,
2465 ObjCPropertyQueryKind queryKind) const;
2466 ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
2467
2468 // Iterator access to properties.
2469 using propimpl_iterator = specific_decl_iterator<ObjCPropertyImplDecl>;
2470 using propimpl_range =
2471 llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>;
2472
property_impls()2473 propimpl_range property_impls() const {
2474 return propimpl_range(propimpl_begin(), propimpl_end());
2475 }
2476
propimpl_begin()2477 propimpl_iterator propimpl_begin() const {
2478 return propimpl_iterator(decls_begin());
2479 }
2480
propimpl_end()2481 propimpl_iterator propimpl_end() const {
2482 return propimpl_iterator(decls_end());
2483 }
2484
classof(const Decl * D)2485 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2486
classofKind(Kind K)2487 static bool classofKind(Kind K) {
2488 return K >= firstObjCImpl && K <= lastObjCImpl;
2489 }
2490 };
2491
2492 /// ObjCCategoryImplDecl - An object of this class encapsulates a category
2493 /// \@implementation declaration. If a category class has declaration of a
2494 /// property, its implementation must be specified in the category's
2495 /// \@implementation declaration. Example:
2496 /// \@interface I \@end
2497 /// \@interface I(CATEGORY)
2498 /// \@property int p1, d1;
2499 /// \@end
2500 /// \@implementation I(CATEGORY)
2501 /// \@dynamic p1,d1;
2502 /// \@end
2503 ///
2504 /// ObjCCategoryImplDecl
2505 class ObjCCategoryImplDecl : public ObjCImplDecl {
2506 // Category name location
2507 SourceLocation CategoryNameLoc;
2508
ObjCCategoryImplDecl(DeclContext * DC,IdentifierInfo * Id,ObjCInterfaceDecl * classInterface,SourceLocation nameLoc,SourceLocation atStartLoc,SourceLocation CategoryNameLoc)2509 ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id,
2510 ObjCInterfaceDecl *classInterface,
2511 SourceLocation nameLoc, SourceLocation atStartLoc,
2512 SourceLocation CategoryNameLoc)
2513 : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id,
2514 nameLoc, atStartLoc),
2515 CategoryNameLoc(CategoryNameLoc) {}
2516
2517 void anchor() override;
2518
2519 public:
2520 friend class ASTDeclReader;
2521 friend class ASTDeclWriter;
2522
2523 static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
2524 IdentifierInfo *Id,
2525 ObjCInterfaceDecl *classInterface,
2526 SourceLocation nameLoc,
2527 SourceLocation atStartLoc,
2528 SourceLocation CategoryNameLoc);
2529 static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2530
2531 ObjCCategoryDecl *getCategoryDecl() const;
2532
getCategoryNameLoc()2533 SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
2534
classof(const Decl * D)2535 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)2536 static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
2537 };
2538
2539 raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
2540
2541 /// ObjCImplementationDecl - Represents a class definition - this is where
2542 /// method definitions are specified. For example:
2543 ///
2544 /// @code
2545 /// \@implementation MyClass
2546 /// - (void)myMethod { /* do something */ }
2547 /// \@end
2548 /// @endcode
2549 ///
2550 /// In a non-fragile runtime, instance variables can appear in the class
2551 /// interface, class extensions (nameless categories), and in the implementation
2552 /// itself, as well as being synthesized as backing storage for properties.
2553 ///
2554 /// In a fragile runtime, instance variables are specified in the class
2555 /// interface, \em not in the implementation. Nevertheless (for legacy reasons),
2556 /// we allow instance variables to be specified in the implementation. When
2557 /// specified, they need to be \em identical to the interface.
2558 class ObjCImplementationDecl : public ObjCImplDecl {
2559 /// Implementation Class's super class.
2560 ObjCInterfaceDecl *SuperClass;
2561 SourceLocation SuperLoc;
2562
2563 /// \@implementation may have private ivars.
2564 SourceLocation IvarLBraceLoc;
2565 SourceLocation IvarRBraceLoc;
2566
2567 /// Support for ivar initialization.
2568 /// The arguments used to initialize the ivars
2569 LazyCXXCtorInitializersPtr IvarInitializers;
2570 unsigned NumIvarInitializers = 0;
2571
2572 /// Do the ivars of this class require initialization other than
2573 /// zero-initialization?
2574 bool HasNonZeroConstructors : 1;
2575
2576 /// Do the ivars of this class require non-trivial destruction?
2577 bool HasDestructors : 1;
2578
2579 ObjCImplementationDecl(DeclContext *DC,
2580 ObjCInterfaceDecl *classInterface,
2581 ObjCInterfaceDecl *superDecl,
2582 SourceLocation nameLoc, SourceLocation atStartLoc,
2583 SourceLocation superLoc = SourceLocation(),
2584 SourceLocation IvarLBraceLoc=SourceLocation(),
2585 SourceLocation IvarRBraceLoc=SourceLocation())
2586 : ObjCImplDecl(ObjCImplementation, DC, classInterface,
2587 classInterface ? classInterface->getIdentifier()
2588 : nullptr,
2589 nameLoc, atStartLoc),
2590 SuperClass(superDecl), SuperLoc(superLoc),
2591 IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc),
2592 HasNonZeroConstructors(false), HasDestructors(false) {}
2593
2594 void anchor() override;
2595
2596 public:
2597 friend class ASTDeclReader;
2598 friend class ASTDeclWriter;
2599
2600 static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
2601 ObjCInterfaceDecl *classInterface,
2602 ObjCInterfaceDecl *superDecl,
2603 SourceLocation nameLoc,
2604 SourceLocation atStartLoc,
2605 SourceLocation superLoc = SourceLocation(),
2606 SourceLocation IvarLBraceLoc=SourceLocation(),
2607 SourceLocation IvarRBraceLoc=SourceLocation());
2608
2609 static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2610
2611 /// init_iterator - Iterates through the ivar initializer list.
2612 using init_iterator = CXXCtorInitializer **;
2613
2614 /// init_const_iterator - Iterates through the ivar initializer list.
2615 using init_const_iterator = CXXCtorInitializer * const *;
2616
2617 using init_range = llvm::iterator_range<init_iterator>;
2618 using init_const_range = llvm::iterator_range<init_const_iterator>;
2619
inits()2620 init_range inits() { return init_range(init_begin(), init_end()); }
2621
inits()2622 init_const_range inits() const {
2623 return init_const_range(init_begin(), init_end());
2624 }
2625
2626 /// init_begin() - Retrieve an iterator to the first initializer.
init_begin()2627 init_iterator init_begin() {
2628 const auto *ConstThis = this;
2629 return const_cast<init_iterator>(ConstThis->init_begin());
2630 }
2631
2632 /// begin() - Retrieve an iterator to the first initializer.
2633 init_const_iterator init_begin() const;
2634
2635 /// init_end() - Retrieve an iterator past the last initializer.
init_end()2636 init_iterator init_end() {
2637 return init_begin() + NumIvarInitializers;
2638 }
2639
2640 /// end() - Retrieve an iterator past the last initializer.
init_end()2641 init_const_iterator init_end() const {
2642 return init_begin() + NumIvarInitializers;
2643 }
2644
2645 /// getNumArgs - Number of ivars which must be initialized.
getNumIvarInitializers()2646 unsigned getNumIvarInitializers() const {
2647 return NumIvarInitializers;
2648 }
2649
setNumIvarInitializers(unsigned numNumIvarInitializers)2650 void setNumIvarInitializers(unsigned numNumIvarInitializers) {
2651 NumIvarInitializers = numNumIvarInitializers;
2652 }
2653
2654 void setIvarInitializers(ASTContext &C,
2655 CXXCtorInitializer ** initializers,
2656 unsigned numInitializers);
2657
2658 /// Do any of the ivars of this class (not counting its base classes)
2659 /// require construction other than zero-initialization?
hasNonZeroConstructors()2660 bool hasNonZeroConstructors() const { return HasNonZeroConstructors; }
setHasNonZeroConstructors(bool val)2661 void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; }
2662
2663 /// Do any of the ivars of this class (not counting its base classes)
2664 /// require non-trivial destruction?
hasDestructors()2665 bool hasDestructors() const { return HasDestructors; }
setHasDestructors(bool val)2666 void setHasDestructors(bool val) { HasDestructors = val; }
2667
2668 /// getIdentifier - Get the identifier that names the class
2669 /// interface associated with this implementation.
getIdentifier()2670 IdentifierInfo *getIdentifier() const {
2671 return getClassInterface()->getIdentifier();
2672 }
2673
2674 /// getName - Get the name of identifier for the class interface associated
2675 /// with this implementation as a StringRef.
2676 //
2677 // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
2678 // meaning.
getName()2679 StringRef getName() const {
2680 assert(getIdentifier() && "Name is not a simple identifier");
2681 return getIdentifier()->getName();
2682 }
2683
2684 /// Get the name of the class associated with this interface.
2685 //
2686 // FIXME: Move to StringRef API.
getNameAsString()2687 std::string getNameAsString() const { return std::string(getName()); }
2688
2689 /// Produce a name to be used for class's metadata. It comes either via
2690 /// class's objc_runtime_name attribute or class name.
2691 StringRef getObjCRuntimeNameAsString() const;
2692
getSuperClass()2693 const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
getSuperClass()2694 ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
getSuperClassLoc()2695 SourceLocation getSuperClassLoc() const { return SuperLoc; }
2696
setSuperClass(ObjCInterfaceDecl * superCls)2697 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
2698
setIvarLBraceLoc(SourceLocation Loc)2699 void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
getIvarLBraceLoc()2700 SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
setIvarRBraceLoc(SourceLocation Loc)2701 void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
getIvarRBraceLoc()2702 SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
2703
2704 using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>;
2705 using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>;
2706
ivars()2707 ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
2708
ivar_begin()2709 ivar_iterator ivar_begin() const {
2710 return ivar_iterator(decls_begin());
2711 }
2712
ivar_end()2713 ivar_iterator ivar_end() const {
2714 return ivar_iterator(decls_end());
2715 }
2716
ivar_size()2717 unsigned ivar_size() const {
2718 return std::distance(ivar_begin(), ivar_end());
2719 }
2720
ivar_empty()2721 bool ivar_empty() const {
2722 return ivar_begin() == ivar_end();
2723 }
2724
classof(const Decl * D)2725 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)2726 static bool classofKind(Kind K) { return K == ObjCImplementation; }
2727 };
2728
2729 raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
2730
2731 /// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
2732 /// declared as \@compatibility_alias alias class.
2733 class ObjCCompatibleAliasDecl : public NamedDecl {
2734 /// Class that this is an alias of.
2735 ObjCInterfaceDecl *AliasedClass;
2736
ObjCCompatibleAliasDecl(DeclContext * DC,SourceLocation L,IdentifierInfo * Id,ObjCInterfaceDecl * aliasedClass)2737 ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
2738 ObjCInterfaceDecl* aliasedClass)
2739 : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
2740
2741 void anchor() override;
2742
2743 public:
2744 static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
2745 SourceLocation L, IdentifierInfo *Id,
2746 ObjCInterfaceDecl* aliasedClass);
2747
2748 static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C,
2749 unsigned ID);
2750
getClassInterface()2751 const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
getClassInterface()2752 ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
setClassInterface(ObjCInterfaceDecl * D)2753 void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
2754
classof(const Decl * D)2755 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)2756 static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
2757 };
2758
2759 /// ObjCPropertyImplDecl - Represents implementation declaration of a property
2760 /// in a class or category implementation block. For example:
2761 /// \@synthesize prop1 = ivar1;
2762 ///
2763 class ObjCPropertyImplDecl : public Decl {
2764 public:
2765 enum Kind {
2766 Synthesize,
2767 Dynamic
2768 };
2769
2770 private:
2771 SourceLocation AtLoc; // location of \@synthesize or \@dynamic
2772
2773 /// For \@synthesize, the location of the ivar, if it was written in
2774 /// the source code.
2775 ///
2776 /// \code
2777 /// \@synthesize int a = b
2778 /// \endcode
2779 SourceLocation IvarLoc;
2780
2781 /// Property declaration being implemented
2782 ObjCPropertyDecl *PropertyDecl;
2783
2784 /// Null for \@dynamic. Required for \@synthesize.
2785 ObjCIvarDecl *PropertyIvarDecl;
2786
2787 /// The getter's definition, which has an empty body if synthesized.
2788 ObjCMethodDecl *GetterMethodDecl = nullptr;
2789 /// The getter's definition, which has an empty body if synthesized.
2790 ObjCMethodDecl *SetterMethodDecl = nullptr;
2791
2792 /// Null for \@dynamic. Non-null if property must be copy-constructed in
2793 /// getter.
2794 Expr *GetterCXXConstructor = nullptr;
2795
2796 /// Null for \@dynamic. Non-null if property has assignment operator to call
2797 /// in Setter synthesis.
2798 Expr *SetterCXXAssignment = nullptr;
2799
ObjCPropertyImplDecl(DeclContext * DC,SourceLocation atLoc,SourceLocation L,ObjCPropertyDecl * property,Kind PK,ObjCIvarDecl * ivarDecl,SourceLocation ivarLoc)2800 ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
2801 ObjCPropertyDecl *property,
2802 Kind PK,
2803 ObjCIvarDecl *ivarDecl,
2804 SourceLocation ivarLoc)
2805 : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
2806 IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl) {
2807 assert(PK == Dynamic || PropertyIvarDecl);
2808 }
2809
2810 public:
2811 friend class ASTDeclReader;
2812
2813 static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
2814 SourceLocation atLoc, SourceLocation L,
2815 ObjCPropertyDecl *property,
2816 Kind PK,
2817 ObjCIvarDecl *ivarDecl,
2818 SourceLocation ivarLoc);
2819
2820 static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2821
2822 SourceRange getSourceRange() const override LLVM_READONLY;
2823
getBeginLoc()2824 SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; }
setAtLoc(SourceLocation Loc)2825 void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
2826
getPropertyDecl()2827 ObjCPropertyDecl *getPropertyDecl() const {
2828 return PropertyDecl;
2829 }
setPropertyDecl(ObjCPropertyDecl * Prop)2830 void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
2831
getPropertyImplementation()2832 Kind getPropertyImplementation() const {
2833 return PropertyIvarDecl ? Synthesize : Dynamic;
2834 }
2835
getPropertyIvarDecl()2836 ObjCIvarDecl *getPropertyIvarDecl() const {
2837 return PropertyIvarDecl;
2838 }
getPropertyIvarDeclLoc()2839 SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
2840
setPropertyIvarDecl(ObjCIvarDecl * Ivar,SourceLocation IvarLoc)2841 void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
2842 SourceLocation IvarLoc) {
2843 PropertyIvarDecl = Ivar;
2844 this->IvarLoc = IvarLoc;
2845 }
2846
2847 /// For \@synthesize, returns true if an ivar name was explicitly
2848 /// specified.
2849 ///
2850 /// \code
2851 /// \@synthesize int a = b; // true
2852 /// \@synthesize int a; // false
2853 /// \endcode
isIvarNameSpecified()2854 bool isIvarNameSpecified() const {
2855 return IvarLoc.isValid() && IvarLoc != getLocation();
2856 }
2857
getGetterMethodDecl()2858 ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
setGetterMethodDecl(ObjCMethodDecl * MD)2859 void setGetterMethodDecl(ObjCMethodDecl *MD) { GetterMethodDecl = MD; }
2860
getSetterMethodDecl()2861 ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
setSetterMethodDecl(ObjCMethodDecl * MD)2862 void setSetterMethodDecl(ObjCMethodDecl *MD) { SetterMethodDecl = MD; }
2863
getGetterCXXConstructor()2864 Expr *getGetterCXXConstructor() const {
2865 return GetterCXXConstructor;
2866 }
2867
setGetterCXXConstructor(Expr * getterCXXConstructor)2868 void setGetterCXXConstructor(Expr *getterCXXConstructor) {
2869 GetterCXXConstructor = getterCXXConstructor;
2870 }
2871
getSetterCXXAssignment()2872 Expr *getSetterCXXAssignment() const {
2873 return SetterCXXAssignment;
2874 }
2875
setSetterCXXAssignment(Expr * setterCXXAssignment)2876 void setSetterCXXAssignment(Expr *setterCXXAssignment) {
2877 SetterCXXAssignment = setterCXXAssignment;
2878 }
2879
classof(const Decl * D)2880 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Decl::Kind K)2881 static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
2882 };
2883
2884 template<bool (*Filter)(ObjCCategoryDecl *)>
2885 void
2886 ObjCInterfaceDecl::filtered_category_iterator<Filter>::
findAcceptableCategory()2887 findAcceptableCategory() {
2888 while (Current && !Filter(Current))
2889 Current = Current->getNextClassCategoryRaw();
2890 }
2891
2892 template<bool (*Filter)(ObjCCategoryDecl *)>
2893 inline ObjCInterfaceDecl::filtered_category_iterator<Filter> &
2894 ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() {
2895 Current = Current->getNextClassCategoryRaw();
2896 findAcceptableCategory();
2897 return *this;
2898 }
2899
isVisibleCategory(ObjCCategoryDecl * Cat)2900 inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) {
2901 return Cat->isUnconditionallyVisible();
2902 }
2903
isVisibleExtension(ObjCCategoryDecl * Cat)2904 inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
2905 return Cat->IsClassExtension() && Cat->isUnconditionallyVisible();
2906 }
2907
isKnownExtension(ObjCCategoryDecl * Cat)2908 inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
2909 return Cat->IsClassExtension();
2910 }
2911
2912 } // namespace clang
2913
2914 #endif // LLVM_CLANG_AST_DECLOBJC_H
2915