summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/DeclObjC.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/DeclObjC.h')
-rw-r--r--include/clang/AST/DeclObjC.h2742
1 files changed, 0 insertions, 2742 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
deleted file mode 100644
index f46078f..0000000
--- a/include/clang/AST/DeclObjC.h
+++ /dev/null
@@ -1,2742 +0,0 @@
-//===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the DeclObjC interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLOBJC_H
-#define LLVM_CLANG_AST_DECLOBJC_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/SelectorLocationsKind.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-class Expr;
-class Stmt;
-class FunctionDecl;
-class RecordDecl;
-class ObjCIvarDecl;
-class ObjCMethodDecl;
-class ObjCProtocolDecl;
-class ObjCCategoryDecl;
-class ObjCPropertyDecl;
-class ObjCPropertyImplDecl;
-class CXXCtorInitializer;
-
-class ObjCListBase {
- ObjCListBase(const ObjCListBase &) = delete;
- void operator=(const ObjCListBase &) = delete;
-protected:
- /// List is an array of pointers to objects that are not owned by this object.
- void **List;
- unsigned NumElts;
-
-public:
- ObjCListBase() : List(nullptr), NumElts(0) {}
- unsigned size() const { return NumElts; }
- bool empty() const { return NumElts == 0; }
-
-protected:
- void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
-};
-
-
-/// ObjCList - This is a simple template class used to hold various lists of
-/// decls etc, which is heavily used by the ObjC front-end. This only use case
-/// this supports is setting the list all at once and then reading elements out
-/// of it.
-template <typename T>
-class ObjCList : public ObjCListBase {
-public:
- void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
- ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
- }
-
- typedef T* const * iterator;
- iterator begin() const { return (iterator)List; }
- iterator end() const { return (iterator)List+NumElts; }
-
- T* operator[](unsigned Idx) const {
- assert(Idx < NumElts && "Invalid access");
- return (T*)List[Idx];
- }
-};
-
-/// \brief A list of Objective-C protocols, along with the source
-/// locations at which they were referenced.
-class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
- SourceLocation *Locations;
-
- using ObjCList<ObjCProtocolDecl>::set;
-
-public:
- ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(nullptr) { }
-
- typedef const SourceLocation *loc_iterator;
- loc_iterator loc_begin() const { return Locations; }
- loc_iterator loc_end() const { return Locations + size(); }
-
- void set(ObjCProtocolDecl* const* InList, unsigned Elts,
- const SourceLocation *Locs, ASTContext &Ctx);
-};
-
-
-/// ObjCMethodDecl - Represents an instance or class method declaration.
-/// ObjC methods can be declared within 4 contexts: class interfaces,
-/// categories, protocols, and class implementations. While C++ member
-/// functions leverage C syntax, Objective-C method syntax is modeled after
-/// Smalltalk (using colons to specify argument types/expressions).
-/// Here are some brief examples:
-///
-/// Setter/getter instance methods:
-/// - (void)setMenu:(NSMenu *)menu;
-/// - (NSMenu *)menu;
-///
-/// Instance method that takes 2 NSView arguments:
-/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
-///
-/// Getter class method:
-/// + (NSMenu *)defaultMenu;
-///
-/// A selector represents a unique name for a method. The selector names for
-/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
-///
-class ObjCMethodDecl : public NamedDecl, public DeclContext {
-public:
- enum ImplementationControl { None, Required, Optional };
-private:
- // The conventional meaning of this method; an ObjCMethodFamily.
- // This is not serialized; instead, it is computed on demand and
- // cached.
- mutable unsigned Family : ObjCMethodFamilyBitWidth;
-
- /// instance (true) or class (false) method.
- unsigned IsInstance : 1;
- unsigned IsVariadic : 1;
-
- /// True if this method is the getter or setter for an explicit property.
- unsigned IsPropertyAccessor : 1;
-
- // Method has a definition.
- unsigned IsDefined : 1;
-
- /// \brief Method redeclaration in the same interface.
- unsigned IsRedeclaration : 1;
-
- /// \brief Is redeclared in the same interface.
- mutable unsigned HasRedeclaration : 1;
-
- // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
- /// \@required/\@optional
- unsigned DeclImplementation : 2;
-
- // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
- /// in, inout, etc.
- unsigned objcDeclQualifier : 7;
-
- /// \brief Indicates whether this method has a related result type.
- unsigned RelatedResultType : 1;
-
- /// \brief Whether the locations of the selector identifiers are in a
- /// "standard" position, a enum SelectorLocationsKind.
- unsigned SelLocsKind : 2;
-
- /// \brief Whether this method overrides any other in the class hierarchy.
- ///
- /// A method is said to override any method in the class's
- /// base classes, its protocols, or its categories' protocols, that has
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- unsigned IsOverriding : 1;
-
- /// \brief Indicates if the method was a definition but its body was skipped.
- unsigned HasSkippedBody : 1;
-
- // Return type of this method.
- QualType MethodDeclType;
-
- // Type source information for the return type.
- TypeSourceInfo *ReturnTInfo;
-
- /// \brief Array of ParmVarDecls for the formal parameters of this method
- /// and optionally followed by selector locations.
- void *ParamsAndSelLocs;
- unsigned NumParams;
-
- /// List of attributes for this method declaration.
- SourceLocation DeclEndLoc; // the location of the ';' or '{'.
-
- // The following are only used for method definitions, null otherwise.
- LazyDeclStmtPtr Body;
-
- /// SelfDecl - Decl for the implicit self parameter. This is lazily
- /// constructed by createImplicitParams.
- ImplicitParamDecl *SelfDecl;
- /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
- /// constructed by createImplicitParams.
- ImplicitParamDecl *CmdDecl;
-
- SelectorLocationsKind getSelLocsKind() const {
- return (SelectorLocationsKind)SelLocsKind;
- }
- bool hasStandardSelLocs() const {
- return getSelLocsKind() != SelLoc_NonStandard;
- }
-
- /// \brief Get a pointer to the stored selector identifiers locations array.
- /// No locations will be stored if HasStandardSelLocs is true.
- SourceLocation *getStoredSelLocs() {
- return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
- }
- const SourceLocation *getStoredSelLocs() const {
- return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
- }
-
- /// \brief Get a pointer to the stored selector identifiers locations array.
- /// No locations will be stored if HasStandardSelLocs is true.
- ParmVarDecl **getParams() {
- return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs);
- }
- const ParmVarDecl *const *getParams() const {
- return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
- }
-
- /// \brief Get the number of stored selector identifiers locations.
- /// No locations will be stored if HasStandardSelLocs is true.
- unsigned getNumStoredSelLocs() const {
- if (hasStandardSelLocs())
- return 0;
- return getNumSelectorLocs();
- }
-
- void setParamsAndSelLocs(ASTContext &C,
- ArrayRef<ParmVarDecl*> Params,
- ArrayRef<SourceLocation> SelLocs);
-
- ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
- DeclContext *contextDecl, bool isInstance = true,
- bool isVariadic = false, bool isPropertyAccessor = false,
- bool isImplicitlyDeclared = false, bool isDefined = false,
- ImplementationControl impControl = None,
- bool HasRelatedResultType = false)
- : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
- DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
- IsInstance(isInstance), IsVariadic(isVariadic),
- IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined),
- IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl),
- objcDeclQualifier(OBJC_TQ_None),
- RelatedResultType(HasRelatedResultType),
- SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
- MethodDeclType(T), ReturnTInfo(ReturnTInfo), ParamsAndSelLocs(nullptr),
- NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(nullptr),
- CmdDecl(nullptr) {
- setImplicit(isImplicitlyDeclared);
- }
-
- /// \brief A definition will return its interface declaration.
- /// An interface declaration will return its definition.
- /// Otherwise it will return itself.
- ObjCMethodDecl *getNextRedeclarationImpl() override;
-
-public:
- static ObjCMethodDecl *
- Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
- DeclContext *contextDecl, bool isInstance = true,
- bool isVariadic = false, bool isPropertyAccessor = false,
- bool isImplicitlyDeclared = false, bool isDefined = false,
- ImplementationControl impControl = None,
- bool HasRelatedResultType = false);
-
- static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- ObjCMethodDecl *getCanonicalDecl() override;
- const ObjCMethodDecl *getCanonicalDecl() const {
- return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
- }
-
- ObjCDeclQualifier getObjCDeclQualifier() const {
- return ObjCDeclQualifier(objcDeclQualifier);
- }
- void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
-
- /// \brief Determine whether this method has a result type that is related
- /// to the message receiver's type.
- bool hasRelatedResultType() const { return RelatedResultType; }
-
- /// \brief Note whether this method has a related result type.
- void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
-
- /// \brief True if this is a method redeclaration in the same interface.
- bool isRedeclaration() const { return IsRedeclaration; }
- void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
-
- /// \brief Returns the location where the declarator ends. It will be
- /// the location of ';' for a method declaration and the location of '{'
- /// for a method definition.
- SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
-
- // Location information, modeled after the Stmt API.
- SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY;
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(getLocation(), getLocEnd());
- }
-
- SourceLocation getSelectorStartLoc() const {
- if (isImplicit())
- return getLocStart();
- return getSelectorLoc(0);
- }
- SourceLocation getSelectorLoc(unsigned Index) const {
- assert(Index < getNumSelectorLocs() && "Index out of range!");
- if (hasStandardSelLocs())
- return getStandardSelectorLoc(Index, getSelector(),
- getSelLocsKind() == SelLoc_StandardWithSpace,
- parameters(),
- DeclEndLoc);
- return getStoredSelLocs()[Index];
- }
-
- void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
-
- unsigned getNumSelectorLocs() const {
- if (isImplicit())
- return 0;
- Selector Sel = getSelector();
- if (Sel.isUnarySelector())
- return 1;
- return Sel.getNumArgs();
- }
-
- ObjCInterfaceDecl *getClassInterface();
- const ObjCInterfaceDecl *getClassInterface() const {
- return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
- }
-
- Selector getSelector() const { return getDeclName().getObjCSelector(); }
-
- QualType getReturnType() const { return MethodDeclType; }
- void setReturnType(QualType T) { MethodDeclType = T; }
- SourceRange getReturnTypeSourceRange() const;
-
- /// \brief Determine the type of an expression that sends a message to this
- /// function. This replaces the type parameters with the types they would
- /// get if the receiver was parameterless (e.g. it may replace the type
- /// parameter with 'id').
- QualType getSendResultType() const;
-
- /// Determine the type of an expression that sends a message to this
- /// function with the given receiver type.
- QualType getSendResultType(QualType receiverType) const;
-
- TypeSourceInfo *getReturnTypeSourceInfo() const { return ReturnTInfo; }
- void setReturnTypeSourceInfo(TypeSourceInfo *TInfo) { ReturnTInfo = TInfo; }
-
- // Iterator access to formal parameters.
- unsigned param_size() const { return NumParams; }
- typedef const ParmVarDecl *const *param_const_iterator;
- typedef ParmVarDecl *const *param_iterator;
- typedef llvm::iterator_range<param_iterator> param_range;
- typedef llvm::iterator_range<param_const_iterator> param_const_range;
-
- param_range params() { return param_range(param_begin(), param_end()); }
- param_const_range params() const {
- return param_const_range(param_begin(), param_end());
- }
-
- param_const_iterator param_begin() const {
- return param_const_iterator(getParams());
- }
- param_const_iterator param_end() const {
- return param_const_iterator(getParams() + NumParams);
- }
- param_iterator param_begin() { return param_iterator(getParams()); }
- param_iterator param_end() { return param_iterator(getParams() + NumParams); }
-
- // This method returns and of the parameters which are part of the selector
- // name mangling requirements.
- param_const_iterator sel_param_end() const {
- return param_begin() + getSelector().getNumArgs();
- }
-
- // ArrayRef access to formal parameters. This should eventually
- // replace the iterator interface above.
- ArrayRef<ParmVarDecl*> parameters() const {
- return llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
- NumParams);
- }
-
- /// \brief Sets the method's parameters and selector source locations.
- /// If the method is implicit (not coming from source) \p SelLocs is
- /// ignored.
- void setMethodParams(ASTContext &C,
- ArrayRef<ParmVarDecl*> Params,
- ArrayRef<SourceLocation> SelLocs = llvm::None);
-
- // Iterator access to parameter types.
- typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
- typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
- param_type_iterator;
-
- param_type_iterator param_type_begin() const {
- return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
- }
- param_type_iterator param_type_end() const {
- return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
- }
-
- /// createImplicitParams - Used to lazily create the self and cmd
- /// implict parameters. This must be called prior to using getSelfDecl()
- /// or getCmdDecl(). The call is ignored if the implicit paramters
- /// have already been created.
- void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
-
- /// \return the type for \c self and set \arg selfIsPseudoStrong and
- /// \arg selfIsConsumed accordingly.
- QualType getSelfType(ASTContext &Context, const ObjCInterfaceDecl *OID,
- bool &selfIsPseudoStrong, bool &selfIsConsumed);
-
- ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
- void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
- ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
- void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
-
- /// Determines the family of this method.
- ObjCMethodFamily getMethodFamily() const;
-
- bool isInstanceMethod() const { return IsInstance; }
- void setInstanceMethod(bool isInst) { IsInstance = isInst; }
- bool isVariadic() const { return IsVariadic; }
- void setVariadic(bool isVar) { IsVariadic = isVar; }
-
- bool isClassMethod() const { return !IsInstance; }
-
- bool isPropertyAccessor() const { return IsPropertyAccessor; }
- void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; }
-
- bool isDefined() const { return IsDefined; }
- void setDefined(bool isDefined) { IsDefined = isDefined; }
-
- /// \brief Whether this method overrides any other in the class hierarchy.
- ///
- /// A method is said to override any method in the class's
- /// base classes, its protocols, or its categories' protocols, that has
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- bool isOverriding() const { return IsOverriding; }
- void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
-
- /// \brief Return overridden methods for the given \p Method.
- ///
- /// An ObjC method is considered to override any method in the class's
- /// base classes (and base's categories), its protocols, or its categories'
- /// protocols, that has
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- void getOverriddenMethods(
- SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
-
- /// \brief True if the method was a definition but its body was skipped.
- bool hasSkippedBody() const { return HasSkippedBody; }
- void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
-
- /// \brief Returns the property associated with this method's selector.
- ///
- /// Note that even if this particular method is not marked as a property
- /// accessor, it is still possible for it to match a property declared in a
- /// superclass. Pass \c false if you only want to check the current class.
- const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const;
-
- // Related to protocols declared in \@protocol
- void setDeclImplementation(ImplementationControl ic) {
- DeclImplementation = ic;
- }
- ImplementationControl getImplementationControl() const {
- return ImplementationControl(DeclImplementation);
- }
-
- /// Returns true if this specific method declaration is marked with the
- /// designated initializer attribute.
- bool isThisDeclarationADesignatedInitializer() const;
-
- /// Returns true if the method selector resolves to a designated initializer
- /// in the class's interface.
- ///
- /// \param InitMethod if non-null and the function returns true, it receives
- /// the method declaration that was marked with the designated initializer
- /// attribute.
- bool isDesignatedInitializerForTheInterface(
- const ObjCMethodDecl **InitMethod = nullptr) const;
-
- /// \brief Determine whether this method has a body.
- bool hasBody() const override { return Body.isValid(); }
-
- /// \brief Retrieve the body of this method, if it has one.
- Stmt *getBody() const override;
-
- void setLazyBody(uint64_t Offset) { Body = Offset; }
-
- CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); }
- void setBody(Stmt *B) { Body = B; }
-
- /// \brief Returns whether this specific method is a definition.
- bool isThisDeclarationADefinition() const { return hasBody(); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCMethod; }
- static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
- return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
- }
- static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Describes the variance of a given generic parameter.
-enum class ObjCTypeParamVariance : uint8_t {
- /// The parameter is invariant: must match exactly.
- Invariant,
- /// The parameter is covariant, e.g., X<T> is a subtype of X<U> when
- /// the type parameter is covariant and T is a subtype of U.
- Covariant,
- /// The parameter is contravariant, e.g., X<T> is a subtype of X<U>
- /// when the type parameter is covariant and U is a subtype of T.
- Contravariant,
-};
-
-/// Represents the declaration of an Objective-C type parameter.
-///
-/// \code
-/// @interface NSDictionary<Key : id<NSCopying>, Value>
-/// @end
-/// \endcode
-///
-/// In the example above, both \c Key and \c Value are represented by
-/// \c ObjCTypeParamDecl. \c Key has an explicit bound of \c id<NSCopying>,
-/// while \c Value gets an implicit bound of \c id.
-///
-/// Objective-C type parameters are typedef-names in the grammar,
-class ObjCTypeParamDecl : public TypedefNameDecl {
- void anchor() override;
-
- /// Index of this type parameter in the type parameter list.
- unsigned Index : 14;
-
- /// The variance of the type parameter.
- unsigned Variance : 2;
-
- /// The location of the variance, if any.
- SourceLocation VarianceLoc;
-
- /// The location of the ':', which will be valid when the bound was
- /// explicitly specified.
- SourceLocation ColonLoc;
-
- ObjCTypeParamDecl(ASTContext &ctx, DeclContext *dc,
- ObjCTypeParamVariance variance, SourceLocation varianceLoc,
- unsigned index,
- SourceLocation nameLoc, IdentifierInfo *name,
- SourceLocation colonLoc, TypeSourceInfo *boundInfo)
- : TypedefNameDecl(ObjCTypeParam, ctx, dc, nameLoc, nameLoc, name,
- boundInfo),
- Index(index), Variance(static_cast<unsigned>(variance)),
- VarianceLoc(varianceLoc), ColonLoc(colonLoc) { }
-
-public:
- static ObjCTypeParamDecl *Create(ASTContext &ctx, DeclContext *dc,
- ObjCTypeParamVariance variance,
- SourceLocation varianceLoc,
- unsigned index,
- SourceLocation nameLoc,
- IdentifierInfo *name,
- SourceLocation colonLoc,
- TypeSourceInfo *boundInfo);
- static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// Determine the variance of this type parameter.
- ObjCTypeParamVariance getVariance() const {
- return static_cast<ObjCTypeParamVariance>(Variance);
- }
-
- /// Set the variance of this type parameter.
- void setVariance(ObjCTypeParamVariance variance) {
- Variance = static_cast<unsigned>(variance);
- }
-
- /// Retrieve the location of the variance keyword.
- SourceLocation getVarianceLoc() const { return VarianceLoc; }
-
- /// Retrieve the index into its type parameter list.
- unsigned getIndex() const { return Index; }
-
- /// Whether this type parameter has an explicitly-written type bound, e.g.,
- /// "T : NSView".
- bool hasExplicitBound() const { return ColonLoc.isValid(); }
-
- /// Retrieve the location of the ':' separating the type parameter name
- /// from the explicitly-specified bound.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCTypeParam; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Stores a list of Objective-C type parameters for a parameterized class
-/// or a category/extension thereof.
-///
-/// \code
-/// @interface NSArray<T> // stores the <T>
-/// @end
-/// \endcode
-class ObjCTypeParamList final
- : private llvm::TrailingObjects<ObjCTypeParamList, ObjCTypeParamDecl *> {
- /// Stores the components of a SourceRange as a POD.
- struct PODSourceRange {
- unsigned Begin;
- unsigned End;
- };
-
- union {
- /// Location of the left and right angle brackets.
- PODSourceRange Brackets;
-
- // Used only for alignment.
- ObjCTypeParamDecl *AlignmentHack;
- };
-
- /// The number of parameters in the list, which are tail-allocated.
- unsigned NumParams;
-
- ObjCTypeParamList(SourceLocation lAngleLoc,
- ArrayRef<ObjCTypeParamDecl *> typeParams,
- SourceLocation rAngleLoc);
-
-public:
- /// Create a new Objective-C type parameter list.
- static ObjCTypeParamList *create(ASTContext &ctx,
- SourceLocation lAngleLoc,
- ArrayRef<ObjCTypeParamDecl *> typeParams,
- SourceLocation rAngleLoc);
-
- /// Iterate through the type parameters in the list.
- typedef ObjCTypeParamDecl **iterator;
-
- iterator begin() { return getTrailingObjects<ObjCTypeParamDecl *>(); }
-
- iterator end() { return begin() + size(); }
-
- /// Determine the number of type parameters in this list.
- unsigned size() const { return NumParams; }
-
- // Iterate through the type parameters in the list.
- typedef ObjCTypeParamDecl * const *const_iterator;
-
- const_iterator begin() const {
- return getTrailingObjects<ObjCTypeParamDecl *>();
- }
-
- const_iterator end() const {
- return begin() + size();
- }
-
- ObjCTypeParamDecl *front() const {
- assert(size() > 0 && "empty Objective-C type parameter list");
- return *begin();
- }
-
- ObjCTypeParamDecl *back() const {
- assert(size() > 0 && "empty Objective-C type parameter list");
- return *(end() - 1);
- }
-
- SourceLocation getLAngleLoc() const {
- return SourceLocation::getFromRawEncoding(Brackets.Begin);
- }
- SourceLocation getRAngleLoc() const {
- return SourceLocation::getFromRawEncoding(Brackets.End);
- }
- SourceRange getSourceRange() const {
- return SourceRange(getLAngleLoc(), getRAngleLoc());
- }
-
- /// Gather the default set of type arguments to be substituted for
- /// these type parameters when dealing with an unspecialized type.
- void gatherDefaultTypeArgs(SmallVectorImpl<QualType> &typeArgs) const;
- friend TrailingObjects;
-};
-
-/// ObjCContainerDecl - Represents a container for method declarations.
-/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
-/// ObjCProtocolDecl, and ObjCImplDecl.
-///
-class ObjCContainerDecl : public NamedDecl, public DeclContext {
- void anchor() override;
-
- SourceLocation AtStart;
-
- // These two locations in the range mark the end of the method container.
- // The first points to the '@' token, and the second to the 'end' token.
- SourceRange AtEnd;
-public:
-
- ObjCContainerDecl(Kind DK, DeclContext *DC,
- IdentifierInfo *Id, SourceLocation nameLoc,
- SourceLocation atStartLoc)
- : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
-
- // Iterator access to properties.
- typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
- prop_range;
-
- prop_range properties() const { return prop_range(prop_begin(), prop_end()); }
- prop_iterator prop_begin() const {
- return prop_iterator(decls_begin());
- }
- prop_iterator prop_end() const {
- return prop_iterator(decls_end());
- }
-
- // Iterator access to instance/class methods.
- typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>
- method_range;
-
- method_range methods() const {
- return method_range(meth_begin(), meth_end());
- }
- method_iterator meth_begin() const {
- return method_iterator(decls_begin());
- }
- method_iterator meth_end() const {
- return method_iterator(decls_end());
- }
-
- typedef filtered_decl_iterator<ObjCMethodDecl,
- &ObjCMethodDecl::isInstanceMethod>
- instmeth_iterator;
- typedef llvm::iterator_range<instmeth_iterator> instmeth_range;
-
- instmeth_range instance_methods() const {
- return instmeth_range(instmeth_begin(), instmeth_end());
- }
- instmeth_iterator instmeth_begin() const {
- return instmeth_iterator(decls_begin());
- }
- instmeth_iterator instmeth_end() const {
- return instmeth_iterator(decls_end());
- }
-
- typedef filtered_decl_iterator<ObjCMethodDecl,
- &ObjCMethodDecl::isClassMethod>
- classmeth_iterator;
- typedef llvm::iterator_range<classmeth_iterator> classmeth_range;
-
- classmeth_range class_methods() const {
- return classmeth_range(classmeth_begin(), classmeth_end());
- }
- classmeth_iterator classmeth_begin() const {
- return classmeth_iterator(decls_begin());
- }
- classmeth_iterator classmeth_end() const {
- return classmeth_iterator(decls_end());
- }
-
- // Get the local instance/class method declared in this interface.
- ObjCMethodDecl *getMethod(Selector Sel, bool isInstance,
- bool AllowHidden = false) const;
- ObjCMethodDecl *getInstanceMethod(Selector Sel,
- bool AllowHidden = false) const {
- return getMethod(Sel, true/*isInstance*/, AllowHidden);
- }
- ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const {
- return getMethod(Sel, false/*isInstance*/, AllowHidden);
- }
- bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
- ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
-
- ObjCPropertyDecl *
- FindPropertyDeclaration(const IdentifierInfo *PropertyId) const;
-
- typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
-
- typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*>
- ProtocolPropertyMap;
-
- typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder;
-
- /// This routine collects list of properties to be implemented in the class.
- /// This includes, class's and its conforming protocols' properties.
- /// Note, the superclass's properties are not included in the list.
- virtual void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const {}
-
- SourceLocation getAtStartLoc() const { return AtStart; }
- void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
-
- // Marks the end of the container.
- SourceRange getAtEndRange() const {
- return AtEnd;
- }
- void setAtEndRange(SourceRange atEnd) {
- AtEnd = atEnd;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(AtStart, getAtEndRange().getEnd());
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstObjCContainer &&
- K <= lastObjCContainer;
- }
-
- static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
- return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
- }
- static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
- }
-};
-
-/// \brief Represents an ObjC class declaration.
-///
-/// For example:
-///
-/// \code
-/// // MostPrimitive declares no super class (not particularly useful).
-/// \@interface MostPrimitive
-/// // no instance variables or methods.
-/// \@end
-///
-/// // NSResponder inherits from NSObject & implements NSCoding (a protocol).
-/// \@interface NSResponder : NSObject \<NSCoding>
-/// { // instance variables are represented by ObjCIvarDecl.
-/// id nextResponder; // nextResponder instance variable.
-/// }
-/// - (NSResponder *)nextResponder; // return a pointer to NSResponder.
-/// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
-/// \@end // to an NSEvent.
-/// \endcode
-///
-/// Unlike C/C++, forward class declarations are accomplished with \@class.
-/// Unlike C/C++, \@class allows for a list of classes to be forward declared.
-/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
-/// typically inherit from NSObject (an exception is NSProxy).
-///
-class ObjCInterfaceDecl : public ObjCContainerDecl
- , public Redeclarable<ObjCInterfaceDecl> {
- void anchor() override;
-
- /// TypeForDecl - This indicates the Type object that represents this
- /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
- mutable const Type *TypeForDecl;
- friend class ASTContext;
-
- struct DefinitionData {
- /// \brief The definition of this class, for quick access from any
- /// declaration.
- ObjCInterfaceDecl *Definition;
-
- /// When non-null, this is always an ObjCObjectType.
- TypeSourceInfo *SuperClassTInfo;
-
- /// Protocols referenced in the \@interface declaration
- ObjCProtocolList ReferencedProtocols;
-
- /// Protocols reference in both the \@interface and class extensions.
- ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
-
- /// \brief List of categories and class extensions defined for this class.
- ///
- /// Categories are stored as a linked list in the AST, since the categories
- /// and class extensions come long after the initial interface declaration,
- /// and we avoid dynamically-resized arrays in the AST wherever possible.
- ObjCCategoryDecl *CategoryList;
-
- /// IvarList - List of all ivars defined by this class; including class
- /// extensions and implementation. This list is built lazily.
- ObjCIvarDecl *IvarList;
-
- /// \brief Indicates that the contents of this Objective-C class will be
- /// completed by the external AST source when required.
- mutable bool ExternallyCompleted : 1;
-
- /// \brief Indicates that the ivar cache does not yet include ivars
- /// declared in the implementation.
- mutable bool IvarListMissingImplementation : 1;
-
- /// Indicates that this interface decl contains at least one initializer
- /// marked with the 'objc_designated_initializer' attribute.
- bool HasDesignatedInitializers : 1;
-
- enum InheritedDesignatedInitializersState {
- /// We didn't calculate whether the designated initializers should be
- /// inherited or not.
- IDI_Unknown = 0,
- /// Designated initializers are inherited for the super class.
- IDI_Inherited = 1,
- /// The class does not inherit designated initializers.
- IDI_NotInherited = 2
- };
- /// One of the \c InheritedDesignatedInitializersState enumeratos.
- mutable unsigned InheritedDesignatedInitializers : 2;
-
- /// \brief The location of the last location in this declaration, before
- /// the properties/methods. For example, this will be the '>', '}', or
- /// identifier,
- SourceLocation EndLoc;
-
- DefinitionData() : Definition(), SuperClassTInfo(), CategoryList(), IvarList(),
- ExternallyCompleted(),
- IvarListMissingImplementation(true),
- HasDesignatedInitializers(),
- InheritedDesignatedInitializers(IDI_Unknown) { }
- };
-
- ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
- IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
- SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
- bool IsInternal);
-
- void LoadExternalDefinition() const;
-
- /// The type parameters associated with this class, if any.
- ObjCTypeParamList *TypeParamList;
-
- /// \brief Contains a pointer to the data associated with this class,
- /// which will be NULL if this class has not yet been defined.
- ///
- /// The bit indicates when we don't need to check for out-of-date
- /// declarations. It will be set unless modules are enabled.
- llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
-
- DefinitionData &data() const {
- assert(Data.getPointer() && "Declaration has no definition!");
- return *Data.getPointer();
- }
-
- /// \brief Allocate the definition data for this class.
- void allocateDefinitionData();
-
- typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
- ObjCInterfaceDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- ObjCInterfaceDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- ObjCInterfaceDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation atLoc,
- IdentifierInfo *Id,
- ObjCTypeParamList *typeParamList,
- ObjCInterfaceDecl *PrevDecl,
- SourceLocation ClassLoc = SourceLocation(),
- bool isInternal = false);
-
- static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
-
- /// Retrieve the type parameters of this class.
- ///
- /// This function looks for a type parameter list for the given
- /// class; if the class has been declared (with \c \@class) but not
- /// defined (with \c \@interface), it will search for a declaration that
- /// has type parameters, skipping any declarations that do not.
- ObjCTypeParamList *getTypeParamList() const;
-
- /// Set the type parameters of this class.
- ///
- /// This function is used by the AST importer, which must import the type
- /// parameters after creating their DeclContext to avoid loops.
- void setTypeParamList(ObjCTypeParamList *TPL);
-
- /// Retrieve the type parameters written on this particular declaration of
- /// the class.
- ObjCTypeParamList *getTypeParamListAsWritten() const {
- return TypeParamList;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- if (isThisDeclarationADefinition())
- return ObjCContainerDecl::getSourceRange();
-
- return SourceRange(getAtStartLoc(), getLocation());
- }
-
- /// \brief Indicate that this Objective-C class is complete, but that
- /// the external AST source will be responsible for filling in its contents
- /// when a complete class is required.
- void setExternallyCompleted();
-
- /// Indicate that this interface decl contains at least one initializer
- /// marked with the 'objc_designated_initializer' attribute.
- void setHasDesignatedInitializers();
-
- /// Returns true if this interface decl contains at least one initializer
- /// marked with the 'objc_designated_initializer' attribute.
- bool hasDesignatedInitializers() const;
-
- /// Returns true if this interface decl declares a designated initializer
- /// or it inherites one from its super class.
- bool declaresOrInheritsDesignatedInitializers() const {
- return hasDesignatedInitializers() || inheritsDesignatedInitializers();
- }
-
- const ObjCProtocolList &getReferencedProtocols() const {
- assert(hasDefinition() && "Caller did not check for forward reference!");
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols;
- }
-
- ObjCImplementationDecl *getImplementation() const;
- void setImplementation(ObjCImplementationDecl *ImplD);
-
- ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
-
- // Get the local instance/class method declared in a category.
- ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
- ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
- ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
- return isInstance ? getCategoryInstanceMethod(Sel)
- : getCategoryClassMethod(Sel);
- }
-
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
-
- protocol_range protocols() const {
- return protocol_range(protocol_begin(), protocol_end());
- }
- protocol_iterator protocol_begin() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.begin();
- }
- protocol_iterator protocol_end() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.end();
- }
-
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
-
- protocol_loc_range protocol_locs() const {
- return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
- }
- protocol_loc_iterator protocol_loc_begin() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.loc_begin();
- }
-
- protocol_loc_iterator protocol_loc_end() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.loc_end();
- }
-
- typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
- typedef llvm::iterator_range<all_protocol_iterator> all_protocol_range;
-
- all_protocol_range all_referenced_protocols() const {
- return all_protocol_range(all_referenced_protocol_begin(),
- all_referenced_protocol_end());
- }
- all_protocol_iterator all_referenced_protocol_begin() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return all_protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().AllReferencedProtocols.empty()
- ? protocol_begin()
- : data().AllReferencedProtocols.begin();
- }
- all_protocol_iterator all_referenced_protocol_end() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return all_protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().AllReferencedProtocols.empty()
- ? protocol_end()
- : data().AllReferencedProtocols.end();
- }
-
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
-
- ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
- ivar_iterator ivar_begin() const {
- if (const ObjCInterfaceDecl *Def = getDefinition())
- return ivar_iterator(Def->decls_begin());
-
- // FIXME: Should make sure no callers ever do this.
- return ivar_iterator();
- }
- ivar_iterator ivar_end() const {
- if (const ObjCInterfaceDecl *Def = getDefinition())
- return ivar_iterator(Def->decls_end());
-
- // FIXME: Should make sure no callers ever do this.
- return ivar_iterator();
- }
-
- unsigned ivar_size() const {
- return std::distance(ivar_begin(), ivar_end());
- }
-
- bool ivar_empty() const { return ivar_begin() == ivar_end(); }
-
- ObjCIvarDecl *all_declared_ivar_begin();
- const ObjCIvarDecl *all_declared_ivar_begin() const {
- // Even though this modifies IvarList, it's conceptually const:
- // the ivar chain is essentially a cached property of ObjCInterfaceDecl.
- return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
- }
- void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; }
-
- /// setProtocolList - Set the list of protocols that this interface
- /// implements.
- void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
- const SourceLocation *Locs, ASTContext &C) {
- data().ReferencedProtocols.set(List, Num, Locs, C);
- }
-
- /// mergeClassExtensionProtocolList - Merge class extension's protocol list
- /// into the protocol list for this class.
- void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
- unsigned Num,
- ASTContext &C);
-
- /// Produce a name to be used for class's metadata. It comes either via
- /// objc_runtime_name attribute or class name.
- StringRef getObjCRuntimeNameAsString() const;
-
- /// Returns the designated initializers for the interface.
- ///
- /// If this declaration does not have methods marked as designated
- /// initializers then the interface inherits the designated initializers of
- /// its super class.
- void getDesignatedInitializers(
- llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const;
-
- /// Returns true if the given selector is a designated initializer for the
- /// interface.
- ///
- /// If this declaration does not have methods marked as designated
- /// initializers then the interface inherits the designated initializers of
- /// its super class.
- ///
- /// \param InitMethod if non-null and the function returns true, it receives
- /// the method that was marked as a designated initializer.
- bool
- isDesignatedInitializer(Selector Sel,
- const ObjCMethodDecl **InitMethod = nullptr) const;
-
- /// \brief Determine whether this particular declaration of this class is
- /// actually also a definition.
- bool isThisDeclarationADefinition() const {
- return getDefinition() == this;
- }
-
- /// \brief Determine whether this class has been defined.
- bool hasDefinition() const {
- // If the name of this class is out-of-date, bring it up-to-date, which
- // might bring in a definition.
- // Note: a null value indicates that we don't have a definition and that
- // modules are enabled.
- if (!Data.getOpaqueValue())
- getMostRecentDecl();
-
- return Data.getPointer();
- }
-
- /// \brief Retrieve the definition of this class, or NULL if this class
- /// has been forward-declared (with \@class) but not yet defined (with
- /// \@interface).
- ObjCInterfaceDecl *getDefinition() {
- return hasDefinition()? Data.getPointer()->Definition : nullptr;
- }
-
- /// \brief Retrieve the definition of this class, or NULL if this class
- /// has been forward-declared (with \@class) but not yet defined (with
- /// \@interface).
- const ObjCInterfaceDecl *getDefinition() const {
- return hasDefinition()? Data.getPointer()->Definition : nullptr;
- }
-
- /// \brief Starts the definition of this Objective-C class, taking it from
- /// a forward declaration (\@class) to a definition (\@interface).
- void startDefinition();
-
- /// Retrieve the superclass type.
- const ObjCObjectType *getSuperClassType() const {
- if (TypeSourceInfo *TInfo = getSuperClassTInfo())
- return TInfo->getType()->castAs<ObjCObjectType>();
-
- return nullptr;
- }
-
- // Retrieve the type source information for the superclass.
- TypeSourceInfo *getSuperClassTInfo() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return nullptr;
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().SuperClassTInfo;
- }
-
- // Retrieve the declaration for the superclass of this class, which
- // does not include any type arguments that apply to the superclass.
- ObjCInterfaceDecl *getSuperClass() const;
-
- void setSuperClass(TypeSourceInfo *superClass) {
- data().SuperClassTInfo = superClass;
- }
-
- /// \brief Iterator that walks over the list of categories, filtering out
- /// those that do not meet specific criteria.
- ///
- /// This class template is used for the various permutations of category
- /// and extension iterators.
- template<bool (*Filter)(ObjCCategoryDecl *)>
- class filtered_category_iterator {
- ObjCCategoryDecl *Current;
-
- void findAcceptableCategory();
-
- public:
- typedef ObjCCategoryDecl * value_type;
- typedef value_type reference;
- typedef value_type pointer;
- typedef std::ptrdiff_t difference_type;
- typedef std::input_iterator_tag iterator_category;
-
- filtered_category_iterator() : Current(nullptr) { }
- explicit filtered_category_iterator(ObjCCategoryDecl *Current)
- : Current(Current)
- {
- findAcceptableCategory();
- }
-
- reference operator*() const { return Current; }
- pointer operator->() const { return Current; }
-
- filtered_category_iterator &operator++();
-
- filtered_category_iterator operator++(int) {
- filtered_category_iterator Tmp = *this;
- ++(*this);
- return Tmp;
- }
-
- friend bool operator==(filtered_category_iterator X,
- filtered_category_iterator Y) {
- return X.Current == Y.Current;
- }
-
- friend bool operator!=(filtered_category_iterator X,
- filtered_category_iterator Y) {
- return X.Current != Y.Current;
- }
- };
-
-private:
- /// \brief Test whether the given category is visible.
- ///
- /// Used in the \c visible_categories_iterator.
- static bool isVisibleCategory(ObjCCategoryDecl *Cat);
-
-public:
- /// \brief Iterator that walks over the list of categories and extensions
- /// that are visible, i.e., not hidden in a non-imported submodule.
- typedef filtered_category_iterator<isVisibleCategory>
- visible_categories_iterator;
-
- typedef llvm::iterator_range<visible_categories_iterator>
- visible_categories_range;
-
- visible_categories_range visible_categories() const {
- return visible_categories_range(visible_categories_begin(),
- visible_categories_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the visible-categories
- /// list.
- visible_categories_iterator visible_categories_begin() const {
- return visible_categories_iterator(getCategoryListRaw());
- }
-
- /// \brief Retrieve an iterator to the end of the visible-categories list.
- visible_categories_iterator visible_categories_end() const {
- return visible_categories_iterator();
- }
-
- /// \brief Determine whether the visible-categories list is empty.
- bool visible_categories_empty() const {
- return visible_categories_begin() == visible_categories_end();
- }
-
-private:
- /// \brief Test whether the given category... is a category.
- ///
- /// Used in the \c known_categories_iterator.
- static bool isKnownCategory(ObjCCategoryDecl *) { return true; }
-
-public:
- /// \brief Iterator that walks over all of the known categories and
- /// extensions, including those that are hidden.
- typedef filtered_category_iterator<isKnownCategory> known_categories_iterator;
- typedef llvm::iterator_range<known_categories_iterator>
- known_categories_range;
-
- known_categories_range known_categories() const {
- return known_categories_range(known_categories_begin(),
- known_categories_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the known-categories
- /// list.
- known_categories_iterator known_categories_begin() const {
- return known_categories_iterator(getCategoryListRaw());
- }
-
- /// \brief Retrieve an iterator to the end of the known-categories list.
- known_categories_iterator known_categories_end() const {
- return known_categories_iterator();
- }
-
- /// \brief Determine whether the known-categories list is empty.
- bool known_categories_empty() const {
- return known_categories_begin() == known_categories_end();
- }
-
-private:
- /// \brief Test whether the given category is a visible extension.
- ///
- /// Used in the \c visible_extensions_iterator.
- static bool isVisibleExtension(ObjCCategoryDecl *Cat);
-
-public:
- /// \brief Iterator that walks over all of the visible extensions, skipping
- /// any that are known but hidden.
- typedef filtered_category_iterator<isVisibleExtension>
- visible_extensions_iterator;
-
- typedef llvm::iterator_range<visible_extensions_iterator>
- visible_extensions_range;
-
- visible_extensions_range visible_extensions() const {
- return visible_extensions_range(visible_extensions_begin(),
- visible_extensions_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the visible-extensions
- /// list.
- visible_extensions_iterator visible_extensions_begin() const {
- return visible_extensions_iterator(getCategoryListRaw());
- }
-
- /// \brief Retrieve an iterator to the end of the visible-extensions list.
- visible_extensions_iterator visible_extensions_end() const {
- return visible_extensions_iterator();
- }
-
- /// \brief Determine whether the visible-extensions list is empty.
- bool visible_extensions_empty() const {
- return visible_extensions_begin() == visible_extensions_end();
- }
-
-private:
- /// \brief Test whether the given category is an extension.
- ///
- /// Used in the \c known_extensions_iterator.
- static bool isKnownExtension(ObjCCategoryDecl *Cat);
-
-public:
- /// \brief Iterator that walks over all of the known extensions.
- typedef filtered_category_iterator<isKnownExtension>
- known_extensions_iterator;
- typedef llvm::iterator_range<known_extensions_iterator>
- known_extensions_range;
-
- known_extensions_range known_extensions() const {
- return known_extensions_range(known_extensions_begin(),
- known_extensions_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the known-extensions
- /// list.
- known_extensions_iterator known_extensions_begin() const {
- return known_extensions_iterator(getCategoryListRaw());
- }
-
- /// \brief Retrieve an iterator to the end of the known-extensions list.
- known_extensions_iterator known_extensions_end() const {
- return known_extensions_iterator();
- }
-
- /// \brief Determine whether the known-extensions list is empty.
- bool known_extensions_empty() const {
- return known_extensions_begin() == known_extensions_end();
- }
-
- /// \brief Retrieve the raw pointer to the start of the category/extension
- /// list.
- ObjCCategoryDecl* getCategoryListRaw() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return nullptr;
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().CategoryList;
- }
-
- /// \brief Set the raw pointer to the start of the category/extension
- /// list.
- void setCategoryListRaw(ObjCCategoryDecl *category) {
- data().CategoryList = category;
- }
-
- ObjCPropertyDecl
- *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
-
- void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const override;
-
- /// isSuperClassOf - Return true if this class is the specified class or is a
- /// super class of the specified interface class.
- bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
- // If RHS is derived from LHS it is OK; else it is not OK.
- while (I != nullptr) {
- if (declaresSameEntity(this, I))
- return true;
-
- I = I->getSuperClass();
- }
- return false;
- }
-
- /// isArcWeakrefUnavailable - Checks for a class or one of its super classes
- /// to be incompatible with __weak references. Returns true if it is.
- bool isArcWeakrefUnavailable() const;
-
- /// isObjCRequiresPropertyDefs - Checks that a class or one of its super
- /// classes must not be auto-synthesized. Returns class decl. if it must not
- /// be; 0, otherwise.
- const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const;
-
- ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
- ObjCInterfaceDecl *&ClassDeclared);
- ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
- ObjCInterfaceDecl *ClassDeclared;
- return lookupInstanceVariable(IVarName, ClassDeclared);
- }
-
- ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name);
-
- // Lookup a method. First, we search locally. If a method isn't
- // found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
- bool shallowCategoryLookup = false,
- bool followSuper = true,
- const ObjCCategoryDecl *C = nullptr) const;
-
- /// Lookup an instance method for a given selector.
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
- return lookupMethod(Sel, true/*isInstance*/);
- }
-
- /// Lookup a class method for a given selector.
- ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
- return lookupMethod(Sel, false/*isInstance*/);
- }
- ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
-
- /// \brief Lookup a method in the classes implementation hierarchy.
- ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel,
- bool Instance=true) const;
-
- ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) {
- return lookupPrivateMethod(Sel, false);
- }
-
- /// \brief Lookup a setter or getter in the class hierarchy,
- /// including in all categories except for category passed
- /// as argument.
- ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
- const ObjCCategoryDecl *Cat) const {
- return lookupMethod(Sel, true/*isInstance*/,
- false/*shallowCategoryLookup*/,
- true /* followsSuper */,
- Cat);
- }
-
- SourceLocation getEndOfDefinitionLoc() const {
- if (!hasDefinition())
- return getLocation();
-
- return data().EndLoc;
- }
-
- void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; }
-
- /// Retrieve the starting location of the superclass.
- SourceLocation getSuperClassLoc() const;
-
- /// isImplicitInterfaceDecl - check that this is an implicitly declared
- /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation
- /// declaration without an \@interface declaration.
- bool isImplicitInterfaceDecl() const {
- return hasDefinition() ? data().Definition->isImplicit() : isImplicit();
- }
-
- /// ClassImplementsProtocol - Checks that 'lProto' protocol
- /// has been implemented in IDecl class, its super class or categories (if
- /// lookupCategory is true).
- bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
- bool lookupCategory,
- bool RHSIsQualifiedID = false);
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- /// Retrieves the canonical declaration of this Objective-C class.
- ObjCInterfaceDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- // Low-level accessor
- const Type *getTypeForDecl() const { return TypeForDecl; }
- void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCInterface; }
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-
-private:
- const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
- bool inheritsDesignatedInitializers() const;
-};
-
-/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
-/// instance variables are identical to C. The only exception is Objective-C
-/// supports C++ style access control. For example:
-///
-/// \@interface IvarExample : NSObject
-/// {
-/// id defaultToProtected;
-/// \@public:
-/// id canBePublic; // same as C++.
-/// \@protected:
-/// id canBeProtected; // same as C++.
-/// \@package:
-/// id canBePackage; // framework visibility (not available in C++).
-/// }
-///
-class ObjCIvarDecl : public FieldDecl {
- void anchor() override;
-
-public:
- enum AccessControl {
- None, Private, Protected, Public, Package
- };
-
-private:
- ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
- bool synthesized)
- : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
- /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
- NextIvar(nullptr), DeclAccess(ac), Synthesized(synthesized) {}
-
-public:
- static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo,
- AccessControl ac, Expr *BW = nullptr,
- bool synthesized=false);
-
- static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// \brief Return the class interface that this ivar is logically contained
- /// in; this is either the interface where the ivar was declared, or the
- /// interface the ivar is conceptually a part of in the case of synthesized
- /// ivars.
- const ObjCInterfaceDecl *getContainingInterface() const;
-
- ObjCIvarDecl *getNextIvar() { return NextIvar; }
- const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
- void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
-
- void setAccessControl(AccessControl ac) { DeclAccess = ac; }
-
- AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
-
- AccessControl getCanonicalAccessControl() const {
- return DeclAccess == None ? Protected : AccessControl(DeclAccess);
- }
-
- void setSynthesize(bool synth) { Synthesized = synth; }
- bool getSynthesize() const { return Synthesized; }
-
- /// Retrieve the type of this instance variable when viewed as a member of a
- /// specific object type.
- QualType getUsageType(QualType objectType) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCIvar; }
-private:
- /// NextIvar - Next Ivar in the list of ivars declared in class; class's
- /// extensions and class's implementation
- ObjCIvarDecl *NextIvar;
-
- // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
- unsigned DeclAccess : 3;
- unsigned Synthesized : 1;
-};
-
-
-/// \brief Represents a field declaration created by an \@defs(...).
-class ObjCAtDefsFieldDecl : public FieldDecl {
- void anchor() override;
- ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, Expr *BW)
- : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
- /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
- BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
-
-public:
- static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, Expr *BW);
-
- static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
-};
-
-/// \brief Represents an Objective-C protocol declaration.
-///
-/// Objective-C protocols declare a pure abstract type (i.e., no instance
-/// variables are permitted). Protocols originally drew inspiration from
-/// C++ pure virtual functions (a C++ feature with nice semantics and lousy
-/// syntax:-). Here is an example:
-///
-/// \code
-/// \@protocol NSDraggingInfo <refproto1, refproto2>
-/// - (NSWindow *)draggingDestinationWindow;
-/// - (NSImage *)draggedImage;
-/// \@end
-/// \endcode
-///
-/// This says that NSDraggingInfo requires two methods and requires everything
-/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
-/// well.
-///
-/// \code
-/// \@interface ImplementsNSDraggingInfo : NSObject \<NSDraggingInfo>
-/// \@end
-/// \endcode
-///
-/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
-/// protocols are in distinct namespaces. For example, Cocoa defines both
-/// an NSObject protocol and class (which isn't allowed in Java). As a result,
-/// protocols are referenced using angle brackets as follows:
-///
-/// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
-///
-class ObjCProtocolDecl : public ObjCContainerDecl,
- public Redeclarable<ObjCProtocolDecl> {
- void anchor() override;
-
- struct DefinitionData {
- // \brief The declaration that defines this protocol.
- ObjCProtocolDecl *Definition;
-
- /// \brief Referenced protocols
- ObjCProtocolList ReferencedProtocols;
- };
-
- /// \brief Contains a pointer to the data associated with this class,
- /// which will be NULL if this class has not yet been defined.
- ///
- /// The bit indicates when we don't need to check for out-of-date
- /// declarations. It will be set unless modules are enabled.
- llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
-
- DefinitionData &data() const {
- assert(Data.getPointer() && "Objective-C protocol has no definition!");
- return *Data.getPointer();
- }
-
- ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
- SourceLocation nameLoc, SourceLocation atStartLoc,
- ObjCProtocolDecl *PrevDecl);
-
- void allocateDefinitionData();
-
- typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
- ObjCProtocolDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- ObjCProtocolDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- ObjCProtocolDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
- IdentifierInfo *Id,
- SourceLocation nameLoc,
- SourceLocation atStartLoc,
- ObjCProtocolDecl *PrevDecl);
-
- static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- const ObjCProtocolList &getReferencedProtocols() const {
- assert(hasDefinition() && "No definition available!");
- return data().ReferencedProtocols;
- }
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
-
- protocol_range protocols() const {
- return protocol_range(protocol_begin(), protocol_end());
- }
- protocol_iterator protocol_begin() const {
- if (!hasDefinition())
- return protocol_iterator();
-
- return data().ReferencedProtocols.begin();
- }
- protocol_iterator protocol_end() const {
- if (!hasDefinition())
- return protocol_iterator();
-
- return data().ReferencedProtocols.end();
- }
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
-
- protocol_loc_range protocol_locs() const {
- return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
- }
- protocol_loc_iterator protocol_loc_begin() const {
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- return data().ReferencedProtocols.loc_begin();
- }
- protocol_loc_iterator protocol_loc_end() const {
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- return data().ReferencedProtocols.loc_end();
- }
- unsigned protocol_size() const {
- if (!hasDefinition())
- return 0;
-
- return data().ReferencedProtocols.size();
- }
-
- /// setProtocolList - Set the list of protocols that this interface
- /// implements.
- void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
- const SourceLocation *Locs, ASTContext &C) {
- assert(hasDefinition() && "Protocol is not defined");
- data().ReferencedProtocols.set(List, Num, Locs, C);
- }
-
- ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
-
- // Lookup a method. First, we search locally. If a method isn't
- // found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
- return lookupMethod(Sel, true/*isInstance*/);
- }
- ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
- return lookupMethod(Sel, false/*isInstance*/);
- }
-
- /// \brief Determine whether this protocol has a definition.
- bool hasDefinition() const {
- // If the name of this protocol is out-of-date, bring it up-to-date, which
- // might bring in a definition.
- // Note: a null value indicates that we don't have a definition and that
- // modules are enabled.
- if (!Data.getOpaqueValue())
- getMostRecentDecl();
-
- return Data.getPointer();
- }
-
- /// \brief Retrieve the definition of this protocol, if any.
- ObjCProtocolDecl *getDefinition() {
- return hasDefinition()? Data.getPointer()->Definition : nullptr;
- }
-
- /// \brief Retrieve the definition of this protocol, if any.
- const ObjCProtocolDecl *getDefinition() const {
- return hasDefinition()? Data.getPointer()->Definition : nullptr;
- }
-
- /// \brief Determine whether this particular declaration is also the
- /// definition.
- bool isThisDeclarationADefinition() const {
- return getDefinition() == this;
- }
-
- /// \brief Starts the definition of this Objective-C protocol.
- void startDefinition();
-
- /// Produce a name to be used for protocol's metadata. It comes either via
- /// objc_runtime_name attribute or protocol name.
- StringRef getObjCRuntimeNameAsString() const;
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- if (isThisDeclarationADefinition())
- return ObjCContainerDecl::getSourceRange();
-
- return SourceRange(getAtStartLoc(), getLocation());
- }
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- /// Retrieves the canonical declaration of this Objective-C protocol.
- ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const override;
-
- void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
- ProtocolPropertyMap &PM) const;
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCProtocol; }
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// ObjCCategoryDecl - Represents a category declaration. A category allows
-/// you to add methods to an existing class (without subclassing or modifying
-/// the original class interface or implementation:-). Categories don't allow
-/// you to add instance data. The following example adds "myMethod" to all
-/// NSView's within a process:
-///
-/// \@interface NSView (MyViewMethods)
-/// - myMethod;
-/// \@end
-///
-/// Categories also allow you to split the implementation of a class across
-/// several files (a feature more naturally supported in C++).
-///
-/// Categories were originally inspired by dynamic languages such as Common
-/// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
-/// don't support this level of dynamism, which is both powerful and dangerous.
-///
-class ObjCCategoryDecl : public ObjCContainerDecl {
- void anchor() override;
-
- /// Interface belonging to this category
- ObjCInterfaceDecl *ClassInterface;
-
- /// The type parameters associated with this category, if any.
- ObjCTypeParamList *TypeParamList;
-
- /// referenced protocols in this category.
- ObjCProtocolList ReferencedProtocols;
-
- /// Next category belonging to this class.
- /// FIXME: this should not be a singly-linked list. Move storage elsewhere.
- ObjCCategoryDecl *NextClassCategory;
-
- /// \brief The location of the category name in this declaration.
- SourceLocation CategoryNameLoc;
-
- /// class extension may have private ivars.
- SourceLocation IvarLBraceLoc;
- SourceLocation IvarRBraceLoc;
-
- ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
- SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
- IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
- ObjCTypeParamList *typeParamList,
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation());
-
-public:
-
- static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation AtLoc,
- SourceLocation ClassNameLoc,
- SourceLocation CategoryNameLoc,
- IdentifierInfo *Id,
- ObjCInterfaceDecl *IDecl,
- ObjCTypeParamList *typeParamList,
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation());
- static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
- const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
-
- /// Retrieve the type parameter list associated with this category or
- /// extension.
- ObjCTypeParamList *getTypeParamList() const { return TypeParamList; }
-
- /// Set the type parameters of this category.
- ///
- /// This function is used by the AST importer, which must import the type
- /// parameters after creating their DeclContext to avoid loops.
- void setTypeParamList(ObjCTypeParamList *TPL);
-
-
- ObjCCategoryImplDecl *getImplementation() const;
- void setImplementation(ObjCCategoryImplDecl *ImplD);
-
- /// setProtocolList - Set the list of protocols that this interface
- /// implements.
- void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
- const SourceLocation *Locs, ASTContext &C) {
- ReferencedProtocols.set(List, Num, Locs, C);
- }
-
- const ObjCProtocolList &getReferencedProtocols() const {
- return ReferencedProtocols;
- }
-
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
-
- protocol_range protocols() const {
- return protocol_range(protocol_begin(), protocol_end());
- }
- protocol_iterator protocol_begin() const {
- return ReferencedProtocols.begin();
- }
- protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
- unsigned protocol_size() const { return ReferencedProtocols.size(); }
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
-
- protocol_loc_range protocol_locs() const {
- return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
- }
- protocol_loc_iterator protocol_loc_begin() const {
- return ReferencedProtocols.loc_begin();
- }
- protocol_loc_iterator protocol_loc_end() const {
- return ReferencedProtocols.loc_end();
- }
-
- ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
-
- /// \brief Retrieve the pointer to the next stored category (or extension),
- /// which may be hidden.
- ObjCCategoryDecl *getNextClassCategoryRaw() const {
- return NextClassCategory;
- }
-
- bool IsClassExtension() const { return getIdentifier() == nullptr; }
-
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
-
- ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
- ivar_iterator ivar_begin() const {
- return ivar_iterator(decls_begin());
- }
- ivar_iterator ivar_end() const {
- return ivar_iterator(decls_end());
- }
- unsigned ivar_size() const {
- return std::distance(ivar_begin(), ivar_end());
- }
- bool ivar_empty() const {
- return ivar_begin() == ivar_end();
- }
-
- SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
- void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
-
- void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
- SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
- void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
- SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCCategory; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-class ObjCImplDecl : public ObjCContainerDecl {
- void anchor() override;
-
- /// Class interface for this class/category implementation
- ObjCInterfaceDecl *ClassInterface;
-
-protected:
- ObjCImplDecl(Kind DK, DeclContext *DC,
- ObjCInterfaceDecl *classInterface,
- SourceLocation nameLoc, SourceLocation atStartLoc)
- : ObjCContainerDecl(DK, DC,
- classInterface? classInterface->getIdentifier()
- : nullptr,
- nameLoc, atStartLoc),
- ClassInterface(classInterface) {}
-
-public:
- const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
- ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
- void setClassInterface(ObjCInterfaceDecl *IFace);
-
- void addInstanceMethod(ObjCMethodDecl *method) {
- // FIXME: Context should be set correctly before we get here.
- method->setLexicalDeclContext(this);
- addDecl(method);
- }
- void addClassMethod(ObjCMethodDecl *method) {
- // FIXME: Context should be set correctly before we get here.
- method->setLexicalDeclContext(this);
- addDecl(method);
- }
-
- void addPropertyImplementation(ObjCPropertyImplDecl *property);
-
- ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
- ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
-
- // Iterator access to properties.
- typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>
- propimpl_range;
-
- propimpl_range property_impls() const {
- return propimpl_range(propimpl_begin(), propimpl_end());
- }
- propimpl_iterator propimpl_begin() const {
- return propimpl_iterator(decls_begin());
- }
- propimpl_iterator propimpl_end() const {
- return propimpl_iterator(decls_end());
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstObjCImpl && K <= lastObjCImpl;
- }
-};
-
-/// ObjCCategoryImplDecl - An object of this class encapsulates a category
-/// \@implementation declaration. If a category class has declaration of a
-/// property, its implementation must be specified in the category's
-/// \@implementation declaration. Example:
-/// \@interface I \@end
-/// \@interface I(CATEGORY)
-/// \@property int p1, d1;
-/// \@end
-/// \@implementation I(CATEGORY)
-/// \@dynamic p1,d1;
-/// \@end
-///
-/// ObjCCategoryImplDecl
-class ObjCCategoryImplDecl : public ObjCImplDecl {
- void anchor() override;
-
- // Category name
- IdentifierInfo *Id;
-
- // Category name location
- SourceLocation CategoryNameLoc;
-
- ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id,
- ObjCInterfaceDecl *classInterface,
- SourceLocation nameLoc, SourceLocation atStartLoc,
- SourceLocation CategoryNameLoc)
- : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
- Id(Id), CategoryNameLoc(CategoryNameLoc) {}
-public:
- static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
- IdentifierInfo *Id,
- ObjCInterfaceDecl *classInterface,
- SourceLocation nameLoc,
- SourceLocation atStartLoc,
- SourceLocation CategoryNameLoc);
- static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// getIdentifier - Get the identifier that names the category
- /// interface associated with this implementation.
- /// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
- /// with a different meaning. For example:
- /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
- /// returns the class interface name, whereas
- /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
- /// returns the category name.
- IdentifierInfo *getIdentifier() const {
- return Id;
- }
- void setIdentifier(IdentifierInfo *II) { Id = II; }
-
- ObjCCategoryDecl *getCategoryDecl() const;
-
- SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
-
- /// getName - Get the name of identifier for the class interface associated
- /// with this implementation as a StringRef.
- //
- // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
- // meaning.
- StringRef getName() const { return Id ? Id->getName() : StringRef(); }
-
- /// @brief Get the name of the class associated with this interface.
- //
- // FIXME: Deprecated, move clients to getName().
- std::string getNameAsString() const {
- return getName();
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
-
-/// ObjCImplementationDecl - Represents a class definition - this is where
-/// method definitions are specified. For example:
-///
-/// @code
-/// \@implementation MyClass
-/// - (void)myMethod { /* do something */ }
-/// \@end
-/// @endcode
-///
-/// In a non-fragile runtime, instance variables can appear in the class
-/// interface, class extensions (nameless categories), and in the implementation
-/// itself, as well as being synthesized as backing storage for properties.
-///
-/// In a fragile runtime, instance variables are specified in the class
-/// interface, \em not in the implementation. Nevertheless (for legacy reasons),
-/// we allow instance variables to be specified in the implementation. When
-/// specified, they need to be \em identical to the interface.
-class ObjCImplementationDecl : public ObjCImplDecl {
- void anchor() override;
- /// Implementation Class's super class.
- ObjCInterfaceDecl *SuperClass;
- SourceLocation SuperLoc;
-
- /// \@implementation may have private ivars.
- SourceLocation IvarLBraceLoc;
- SourceLocation IvarRBraceLoc;
-
- /// Support for ivar initialization.
- /// \brief The arguments used to initialize the ivars
- LazyCXXCtorInitializersPtr IvarInitializers;
- unsigned NumIvarInitializers;
-
- /// Do the ivars of this class require initialization other than
- /// zero-initialization?
- bool HasNonZeroConstructors : 1;
-
- /// Do the ivars of this class require non-trivial destruction?
- bool HasDestructors : 1;
-
- ObjCImplementationDecl(DeclContext *DC,
- ObjCInterfaceDecl *classInterface,
- ObjCInterfaceDecl *superDecl,
- SourceLocation nameLoc, SourceLocation atStartLoc,
- SourceLocation superLoc = SourceLocation(),
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation())
- : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
- SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
- IvarRBraceLoc(IvarRBraceLoc),
- IvarInitializers(nullptr), NumIvarInitializers(0),
- HasNonZeroConstructors(false), HasDestructors(false) {}
-public:
- static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
- ObjCInterfaceDecl *classInterface,
- ObjCInterfaceDecl *superDecl,
- SourceLocation nameLoc,
- SourceLocation atStartLoc,
- SourceLocation superLoc = SourceLocation(),
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation());
-
- static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// init_iterator - Iterates through the ivar initializer list.
- typedef CXXCtorInitializer **init_iterator;
-
- /// init_const_iterator - Iterates through the ivar initializer list.
- typedef CXXCtorInitializer * const * init_const_iterator;
-
- typedef llvm::iterator_range<init_iterator> init_range;
- typedef llvm::iterator_range<init_const_iterator> init_const_range;
-
- init_range inits() { return init_range(init_begin(), init_end()); }
- init_const_range inits() const {
- return init_const_range(init_begin(), init_end());
- }
-
- /// init_begin() - Retrieve an iterator to the first initializer.
- init_iterator init_begin() {
- const auto *ConstThis = this;
- return const_cast<init_iterator>(ConstThis->init_begin());
- }
- /// begin() - Retrieve an iterator to the first initializer.
- init_const_iterator init_begin() const;
-
- /// init_end() - Retrieve an iterator past the last initializer.
- init_iterator init_end() {
- return init_begin() + NumIvarInitializers;
- }
- /// end() - Retrieve an iterator past the last initializer.
- init_const_iterator init_end() const {
- return init_begin() + NumIvarInitializers;
- }
- /// getNumArgs - Number of ivars which must be initialized.
- unsigned getNumIvarInitializers() const {
- return NumIvarInitializers;
- }
-
- void setNumIvarInitializers(unsigned numNumIvarInitializers) {
- NumIvarInitializers = numNumIvarInitializers;
- }
-
- void setIvarInitializers(ASTContext &C,
- CXXCtorInitializer ** initializers,
- unsigned numInitializers);
-
- /// Do any of the ivars of this class (not counting its base classes)
- /// require construction other than zero-initialization?
- bool hasNonZeroConstructors() const { return HasNonZeroConstructors; }
- void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; }
-
- /// Do any of the ivars of this class (not counting its base classes)
- /// require non-trivial destruction?
- bool hasDestructors() const { return HasDestructors; }
- void setHasDestructors(bool val) { HasDestructors = val; }
-
- /// getIdentifier - Get the identifier that names the class
- /// interface associated with this implementation.
- IdentifierInfo *getIdentifier() const {
- return getClassInterface()->getIdentifier();
- }
-
- /// getName - Get the name of identifier for the class interface associated
- /// with this implementation as a StringRef.
- //
- // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
- // meaning.
- StringRef getName() const {
- assert(getIdentifier() && "Name is not a simple identifier");
- return getIdentifier()->getName();
- }
-
- /// @brief Get the name of the class associated with this interface.
- //
- // FIXME: Move to StringRef API.
- std::string getNameAsString() const {
- return getName();
- }
-
- /// Produce a name to be used for class's metadata. It comes either via
- /// class's objc_runtime_name attribute or class name.
- StringRef getObjCRuntimeNameAsString() const;
-
- const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
- ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
- SourceLocation getSuperClassLoc() const { return SuperLoc; }
-
- void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
-
- void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
- SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
- void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
- SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
-
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
-
- ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
- ivar_iterator ivar_begin() const {
- return ivar_iterator(decls_begin());
- }
- ivar_iterator ivar_end() const {
- return ivar_iterator(decls_end());
- }
- unsigned ivar_size() const {
- return std::distance(ivar_begin(), ivar_end());
- }
- bool ivar_empty() const {
- return ivar_begin() == ivar_end();
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCImplementation; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
-
-/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
-/// declared as \@compatibility_alias alias class.
-class ObjCCompatibleAliasDecl : public NamedDecl {
- void anchor() override;
- /// Class that this is an alias of.
- ObjCInterfaceDecl *AliasedClass;
-
- ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl* aliasedClass)
- : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
-public:
- static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl* aliasedClass);
-
- static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
-
- const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
- ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
- void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
-
-};
-
-/// \brief Represents one property declaration in an Objective-C interface.
-///
-/// For example:
-/// \code{.mm}
-/// \@property (assign, readwrite) int MyProperty;
-/// \endcode
-class ObjCPropertyDecl : public NamedDecl {
- void anchor() override;
-public:
- enum PropertyAttributeKind {
- OBJC_PR_noattr = 0x00,
- OBJC_PR_readonly = 0x01,
- OBJC_PR_getter = 0x02,
- OBJC_PR_assign = 0x04,
- OBJC_PR_readwrite = 0x08,
- OBJC_PR_retain = 0x10,
- OBJC_PR_copy = 0x20,
- OBJC_PR_nonatomic = 0x40,
- OBJC_PR_setter = 0x80,
- OBJC_PR_atomic = 0x100,
- OBJC_PR_weak = 0x200,
- OBJC_PR_strong = 0x400,
- OBJC_PR_unsafe_unretained = 0x800,
- /// Indicates that the nullability of the type was spelled with a
- /// property attribute rather than a type qualifier.
- OBJC_PR_nullability = 0x1000,
- OBJC_PR_null_resettable = 0x2000
- // Adding a property should change NumPropertyAttrsBits
- };
-
- enum {
- /// \brief Number of bits fitting all the property attributes.
- NumPropertyAttrsBits = 14
- };
-
- enum SetterKind { Assign, Retain, Copy, Weak };
- enum PropertyControl { None, Required, Optional };
-private:
- SourceLocation AtLoc; // location of \@property
- SourceLocation LParenLoc; // location of '(' starting attribute list or null.
- QualType DeclType;
- TypeSourceInfo *DeclTypeSourceInfo;
- unsigned PropertyAttributes : NumPropertyAttrsBits;
- unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
- // \@required/\@optional
- unsigned PropertyImplementation : 2;
-
- Selector GetterName; // getter name of NULL if no getter
- Selector SetterName; // setter name of NULL if no setter
-
- ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
- ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
- ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
-
- ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- SourceLocation AtLocation, SourceLocation LParenLocation,
- QualType T, TypeSourceInfo *TSI,
- PropertyControl propControl)
- : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
- LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
- PropertyAttributes(OBJC_PR_noattr),
- PropertyAttributesAsWritten(OBJC_PR_noattr),
- PropertyImplementation(propControl),
- GetterName(Selector()),
- SetterName(Selector()),
- GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
- PropertyIvarDecl(nullptr) {}
-
-public:
- static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- IdentifierInfo *Id, SourceLocation AtLocation,
- SourceLocation LParenLocation,
- QualType T,
- TypeSourceInfo *TSI,
- PropertyControl propControl = None);
-
- static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceLocation getAtLoc() const { return AtLoc; }
- void setAtLoc(SourceLocation L) { AtLoc = L; }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
-
- TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; }
-
- QualType getType() const { return DeclType; }
-
- void setType(QualType T, TypeSourceInfo *TSI) {
- DeclType = T;
- DeclTypeSourceInfo = TSI;
- }
-
- /// Retrieve the type when this property is used with a specific base object
- /// type.
- QualType getUsageType(QualType objectType) const;
-
- PropertyAttributeKind getPropertyAttributes() const {
- return PropertyAttributeKind(PropertyAttributes);
- }
- void setPropertyAttributes(PropertyAttributeKind PRVal) {
- PropertyAttributes |= PRVal;
- }
- void overwritePropertyAttributes(unsigned PRVal) {
- PropertyAttributes = PRVal;
- }
-
- PropertyAttributeKind getPropertyAttributesAsWritten() const {
- return PropertyAttributeKind(PropertyAttributesAsWritten);
- }
-
- void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
- PropertyAttributesAsWritten = PRVal;
- }
-
- // Helper methods for accessing attributes.
-
- /// isReadOnly - Return true iff the property has a setter.
- bool isReadOnly() const {
- return (PropertyAttributes & OBJC_PR_readonly);
- }
-
- /// isAtomic - Return true if the property is atomic.
- bool isAtomic() const {
- return (PropertyAttributes & OBJC_PR_atomic);
- }
-
- /// isRetaining - Return true if the property retains its value.
- bool isRetaining() const {
- return (PropertyAttributes &
- (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
- }
-
- /// getSetterKind - Return the method used for doing assignment in
- /// the property setter. This is only valid if the property has been
- /// defined to have a setter.
- SetterKind getSetterKind() const {
- if (PropertyAttributes & OBJC_PR_strong)
- return getType()->isBlockPointerType() ? Copy : Retain;
- if (PropertyAttributes & OBJC_PR_retain)
- return Retain;
- if (PropertyAttributes & OBJC_PR_copy)
- return Copy;
- if (PropertyAttributes & OBJC_PR_weak)
- return Weak;
- return Assign;
- }
-
- Selector getGetterName() const { return GetterName; }
- void setGetterName(Selector Sel) { GetterName = Sel; }
-
- Selector getSetterName() const { return SetterName; }
- void setSetterName(Selector Sel) { SetterName = Sel; }
-
- ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
- void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
-
- ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
- void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
-
- // Related to \@optional/\@required declared in \@protocol
- void setPropertyImplementation(PropertyControl pc) {
- PropertyImplementation = pc;
- }
- PropertyControl getPropertyImplementation() const {
- return PropertyControl(PropertyImplementation);
- }
-
- void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
- PropertyIvarDecl = Ivar;
- }
- ObjCIvarDecl *getPropertyIvarDecl() const {
- return PropertyIvarDecl;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(AtLoc, getLocation());
- }
-
- /// Get the default name of the synthesized ivar.
- IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
-
- /// Lookup a property by name in the specified DeclContext.
- static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
- const IdentifierInfo *propertyID);
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCProperty; }
-};
-
-/// ObjCPropertyImplDecl - Represents implementation declaration of a property
-/// in a class or category implementation block. For example:
-/// \@synthesize prop1 = ivar1;
-///
-class ObjCPropertyImplDecl : public Decl {
-public:
- enum Kind {
- Synthesize,
- Dynamic
- };
-private:
- SourceLocation AtLoc; // location of \@synthesize or \@dynamic
-
- /// \brief For \@synthesize, the location of the ivar, if it was written in
- /// the source code.
- ///
- /// \code
- /// \@synthesize int a = b
- /// \endcode
- SourceLocation IvarLoc;
-
- /// Property declaration being implemented
- ObjCPropertyDecl *PropertyDecl;
-
- /// Null for \@dynamic. Required for \@synthesize.
- ObjCIvarDecl *PropertyIvarDecl;
-
- /// Null for \@dynamic. Non-null if property must be copy-constructed in
- /// getter.
- Expr *GetterCXXConstructor;
-
- /// Null for \@dynamic. Non-null if property has assignment operator to call
- /// in Setter synthesis.
- Expr *SetterCXXAssignment;
-
- ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
- ObjCPropertyDecl *property,
- Kind PK,
- ObjCIvarDecl *ivarDecl,
- SourceLocation ivarLoc)
- : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
- IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
- GetterCXXConstructor(nullptr), SetterCXXAssignment(nullptr) {
- assert (PK == Dynamic || PropertyIvarDecl);
- }
-
-public:
- static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation atLoc, SourceLocation L,
- ObjCPropertyDecl *property,
- Kind PK,
- ObjCIvarDecl *ivarDecl,
- SourceLocation ivarLoc);
-
- static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
-
- ObjCPropertyDecl *getPropertyDecl() const {
- return PropertyDecl;
- }
- void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
-
- Kind getPropertyImplementation() const {
- return PropertyIvarDecl ? Synthesize : Dynamic;
- }
-
- ObjCIvarDecl *getPropertyIvarDecl() const {
- return PropertyIvarDecl;
- }
- SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
-
- void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
- SourceLocation IvarLoc) {
- PropertyIvarDecl = Ivar;
- this->IvarLoc = IvarLoc;
- }
-
- /// \brief For \@synthesize, returns true if an ivar name was explicitly
- /// specified.
- ///
- /// \code
- /// \@synthesize int a = b; // true
- /// \@synthesize int a; // false
- /// \endcode
- bool isIvarNameSpecified() const {
- return IvarLoc.isValid() && IvarLoc != getLocation();
- }
-
- Expr *getGetterCXXConstructor() const {
- return GetterCXXConstructor;
- }
- void setGetterCXXConstructor(Expr *getterCXXConstructor) {
- GetterCXXConstructor = getterCXXConstructor;
- }
-
- Expr *getSetterCXXAssignment() const {
- return SetterCXXAssignment;
- }
- void setSetterCXXAssignment(Expr *setterCXXAssignment) {
- SetterCXXAssignment = setterCXXAssignment;
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
-
- friend class ASTDeclReader;
-};
-
-template<bool (*Filter)(ObjCCategoryDecl *)>
-void
-ObjCInterfaceDecl::filtered_category_iterator<Filter>::
-findAcceptableCategory() {
- while (Current && !Filter(Current))
- Current = Current->getNextClassCategoryRaw();
-}
-
-template<bool (*Filter)(ObjCCategoryDecl *)>
-inline ObjCInterfaceDecl::filtered_category_iterator<Filter> &
-ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() {
- Current = Current->getNextClassCategoryRaw();
- findAcceptableCategory();
- return *this;
-}
-
-inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) {
- return !Cat->isHidden();
-}
-
-inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension() && !Cat->isHidden();
-}
-
-inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension();
-}
-
-} // end namespace clang
-#endif
OpenPOWER on IntegriCloud