diff options
Diffstat (limited to 'include/clang/AST/DeclObjC.h')
-rw-r--r-- | include/clang/AST/DeclObjC.h | 504 |
1 files changed, 352 insertions, 152 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 2e760d658e43..db3b0849382a 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -41,7 +41,7 @@ protected: unsigned NumElts; public: - ObjCListBase() : List(0), NumElts(0) {} + ObjCListBase() : List(nullptr), NumElts(0) {} unsigned size() const { return NumElts; } bool empty() const { return NumElts == 0; } @@ -79,7 +79,7 @@ class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> { using ObjCList<ObjCProtocolDecl>::set; public: - ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { } + ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(nullptr) { } typedef const SourceLocation *loc_iterator; loc_iterator loc_begin() const { return Locations; } @@ -162,11 +162,11 @@ private: /// \brief Indicates if the method was a definition but its body was skipped. unsigned HasSkippedBody : 1; - // Result type of this method. + // Return type of this method. QualType MethodDeclType; - // Type source information for the result type. - TypeSourceInfo *ResultTInfo; + // 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. @@ -224,54 +224,44 @@ private: ArrayRef<SourceLocation> SelLocs); ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, - Selector SelInfo, QualType T, - TypeSourceInfo *ResultTInfo, - DeclContext *contextDecl, - bool isInstance = true, - bool isVariadic = false, - bool isPropertyAccessor = false, - bool isImplicitlyDeclared = false, - bool isDefined = false, + 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), ResultTInfo(ResultTInfo), - ParamsAndSelLocs(0), NumParams(0), - DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) { + : 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. - virtual ObjCMethodDecl *getNextRedeclaration(); + ObjCMethodDecl *getNextRedeclarationImpl() override; public: - static ObjCMethodDecl *Create(ASTContext &C, - SourceLocation beginLoc, - SourceLocation endLoc, - Selector SelInfo, - QualType T, - TypeSourceInfo *ResultTInfo, - 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 * + 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); - - virtual ObjCMethodDecl *getCanonicalDecl(); + + ObjCMethodDecl *getCanonicalDecl() override; const ObjCMethodDecl *getCanonicalDecl() const { return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl(); } @@ -300,7 +290,7 @@ public: // Location information, modeled after the Stmt API. SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); } SourceLocation getLocEnd() const LLVM_READONLY; - virtual SourceRange getSourceRange() const LLVM_READONLY { + SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(getLocation(), getLocEnd()); } @@ -314,8 +304,7 @@ public: if (hasStandardSelLocs()) return getStandardSelectorLoc(Index, getSelector(), getSelLocsKind() == SelLoc_StandardWithSpace, - llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()), - NumParams), + parameters(), DeclEndLoc); return getStoredSelLocs()[Index]; } @@ -338,32 +327,52 @@ public: Selector getSelector() const { return getDeclName().getObjCSelector(); } - QualType getResultType() const { return MethodDeclType; } - void setResultType(QualType T) { MethodDeclType = T; } + QualType getReturnType() const { return MethodDeclType; } + void setReturnType(QualType T) { MethodDeclType = T; } /// \brief Determine the type of an expression that sends a message to this /// function. QualType getSendResultType() const { - return getResultType().getNonLValueExprType(getASTContext()); + return getReturnType().getNonLValueExprType(getASTContext()); } - TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; } - void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; } + 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; - param_const_iterator param_begin() const { return getParams(); } - param_const_iterator param_end() const { return getParams() + NumParams; } - param_iterator param_begin() { return getParams(); } - param_iterator param_end() { return getParams() + NumParams; } + 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. @@ -375,12 +384,12 @@ public: // Iterator access to parameter types. typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun; typedef llvm::mapped_iterator<param_const_iterator, deref_fun> - arg_type_iterator; + param_type_iterator; - arg_type_iterator arg_type_begin() const { + param_type_iterator param_type_begin() const { return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType)); } - arg_type_iterator arg_type_end() const { + param_type_iterator param_type_end() const { return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType)); } @@ -451,11 +460,24 @@ public: 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. - virtual bool hasBody() const { return Body.isValid(); } + bool hasBody() const override { return Body.isValid(); } /// \brief Retrieve the body of this method, if it has one. - virtual Stmt *getBody() const; + Stmt *getBody() const override; void setLazyBody(uint64_t Offset) { Body = Offset; } @@ -484,7 +506,7 @@ public: /// ObjCProtocolDecl, and ObjCImplDecl. /// class ObjCContainerDecl : public NamedDecl, public DeclContext { - virtual void anchor(); + void anchor() override; SourceLocation AtStart; @@ -500,6 +522,10 @@ public: // 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()); } @@ -509,6 +535,12 @@ public: // 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()); } @@ -519,6 +551,11 @@ public: 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()); } @@ -529,6 +566,11 @@ public: 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()); } @@ -575,7 +617,7 @@ public: AtEnd = atEnd; } - virtual SourceRange getSourceRange() const LLVM_READONLY { + SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(AtStart, getAtEndRange().getEnd()); } @@ -621,7 +663,7 @@ public: /// class ObjCInterfaceDecl : public ObjCContainerDecl , public Redeclarable<ObjCInterfaceDecl> { - virtual void anchor(); + void anchor() override; /// TypeForDecl - This indicates the Type object that represents this /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType @@ -661,6 +703,22 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// 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 superclass, if any. SourceLocation SuperClassLoc; @@ -671,12 +729,14 @@ class ObjCInterfaceDecl : public ObjCContainerDecl DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), ExternallyCompleted(), - IvarListMissingImplementation(true) { } + IvarListMissingImplementation(true), + HasDesignatedInitializers(), + InheritedDesignatedInitializers(IDI_Unknown) { } }; - ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, - SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, - bool isInternal); + ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc, + IdentifierInfo *Id, SourceLocation CLoc, + ObjCInterfaceDecl *PrevDecl, bool IsInternal); void LoadExternalDefinition() const; @@ -696,13 +756,13 @@ class ObjCInterfaceDecl : public ObjCContainerDecl void allocateDefinitionData(); typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base; - virtual ObjCInterfaceDecl *getNextRedeclaration() { - return RedeclLink.getNext(); + ObjCInterfaceDecl *getNextRedeclarationImpl() override { + return getNextRedeclaration(); } - virtual ObjCInterfaceDecl *getPreviousDeclImpl() { + ObjCInterfaceDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } - virtual ObjCInterfaceDecl *getMostRecentDeclImpl() { + ObjCInterfaceDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } @@ -714,9 +774,9 @@ public: SourceLocation ClassLoc = SourceLocation(), bool isInternal = false); - static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID); - virtual SourceRange getSourceRange() const LLVM_READONLY { + SourceRange getSourceRange() const override LLVM_READONLY { if (isThisDeclarationADefinition()) return ObjCContainerDecl::getSourceRange(); @@ -728,6 +788,20 @@ public: /// 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) @@ -750,7 +824,11 @@ public: } 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()) @@ -773,7 +851,11 @@ public: } 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()) @@ -797,7 +879,12 @@ public: } 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()) @@ -824,7 +911,9 @@ public: } 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()); @@ -867,6 +956,31 @@ public: 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 { @@ -894,14 +1008,14 @@ public: /// has been forward-declared (with \@class) but not yet defined (with /// \@interface). ObjCInterfaceDecl *getDefinition() { - return hasDefinition()? Data.getPointer()->Definition : 0; + 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 : 0; + return hasDefinition()? Data.getPointer()->Definition : nullptr; } /// \brief Starts the definition of this Objective-C class, taking it from @@ -911,7 +1025,7 @@ public: ObjCInterfaceDecl *getSuperClass() const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) - return 0; + return nullptr; if (data().ExternallyCompleted) LoadExternalDefinition(); @@ -943,7 +1057,7 @@ public: typedef std::ptrdiff_t difference_type; typedef std::input_iterator_tag iterator_category; - filtered_category_iterator() : Current(0) { } + filtered_category_iterator() : Current(nullptr) { } explicit filtered_category_iterator(ObjCCategoryDecl *Current) : Current(Current) { @@ -984,6 +1098,14 @@ public: 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 { @@ -1010,6 +1132,13 @@ 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. @@ -1039,6 +1168,14 @@ public: 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 { @@ -1065,6 +1202,13 @@ 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. @@ -1087,7 +1231,7 @@ public: ObjCCategoryDecl* getCategoryListRaw() const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) - return 0; + return nullptr; if (data().ExternallyCompleted) LoadExternalDefinition(); @@ -1104,14 +1248,14 @@ public: ObjCPropertyDecl *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const; - virtual void collectPropertiesToImplement(PropertyMap &PM, - PropertyDeclOrder &PO) 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 != NULL) { + while (I != nullptr) { if (declaresSameEntity(this, I)) return true; @@ -1141,15 +1285,18 @@ public: // 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, - const ObjCCategoryDecl *C= 0) const; - ObjCMethodDecl *lookupInstanceMethod(Selector Sel, - bool shallowCategoryLookup = false) const { - return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup); + 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*/); } - ObjCMethodDecl *lookupClassMethod(Selector Sel, - bool shallowCategoryLookup = false) const { - return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup); + + /// Lookup a class method for a given selector. + ObjCMethodDecl *lookupClassMethod(Selector Sel) const { + return lookupMethod(Sel, false/*isInstance*/); } ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); @@ -1167,7 +1314,9 @@ public: ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel, const ObjCCategoryDecl *Cat) const { return lookupMethod(Sel, true/*isInstance*/, - false/*shallowCategoryLookup*/, Cat); + false/*shallowCategoryLookup*/, + true /* followsSuper */, + Cat); } SourceLocation getEndOfDefinitionLoc() const { @@ -1196,15 +1345,17 @@ public: 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() { return getFirstDecl(); } + ObjCInterfaceDecl *getCanonicalDecl() override { return getFirstDecl(); } const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); } // Low-level accessor @@ -1217,6 +1368,10 @@ public: 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 @@ -1235,7 +1390,7 @@ public: /// } /// class ObjCIvarDecl : public FieldDecl { - virtual void anchor(); + void anchor() override; public: enum AccessControl { @@ -1246,21 +1401,18 @@ private: ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW, - bool synthesized, - bool backingIvarReferencedInAccessor) + bool synthesized) : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit), - NextIvar(0), DeclAccess(ac), Synthesized(synthesized), - BackingIvarReferencedInAccessor(backingIvarReferencedInAccessor) {} + 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 = NULL, - bool synthesized=false, - bool backingIvarReferencedInAccessor=false); + AccessControl ac, Expr *BW = nullptr, + bool synthesized=false); static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1282,13 +1434,6 @@ public: return DeclAccess == None ? Protected : AccessControl(DeclAccess); } - void setBackingIvarReferencedInAccessor(bool val) { - BackingIvarReferencedInAccessor = val; - } - bool getBackingIvarReferencedInAccessor() const { - return BackingIvarReferencedInAccessor; - } - void setSynthesize(bool synth) { Synthesized = synth; } bool getSynthesize() const { return Synthesized; } @@ -1303,18 +1448,17 @@ private: // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum unsigned DeclAccess : 3; unsigned Synthesized : 1; - unsigned BackingIvarReferencedInAccessor : 1; }; /// \brief Represents a field declaration created by an \@defs(...). class ObjCAtDefsFieldDecl : public FieldDecl { - virtual void anchor(); + void anchor() override; ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW) : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T, - /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ? + /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ? BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {} public: @@ -1362,7 +1506,7 @@ public: /// class ObjCProtocolDecl : public ObjCContainerDecl, public Redeclarable<ObjCProtocolDecl> { - virtual void anchor(); + void anchor() override; struct DefinitionData { // \brief The declaration that defines this protocol. @@ -1384,20 +1528,20 @@ class ObjCProtocolDecl : public ObjCContainerDecl, return *Data.getPointer(); } - ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id, + ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl); void allocateDefinitionData(); typedef Redeclarable<ObjCProtocolDecl> redeclarable_base; - virtual ObjCProtocolDecl *getNextRedeclaration() { - return RedeclLink.getNext(); + ObjCProtocolDecl *getNextRedeclarationImpl() override { + return getNextRedeclaration(); } - virtual ObjCProtocolDecl *getPreviousDeclImpl() { + ObjCProtocolDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } - virtual ObjCProtocolDecl *getMostRecentDeclImpl() { + ObjCProtocolDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } @@ -1409,12 +1553,17 @@ public: 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(); @@ -1428,6 +1577,11 @@ public: 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(); @@ -1486,12 +1640,12 @@ public: /// \brief Retrieve the definition of this protocol, if any. ObjCProtocolDecl *getDefinition() { - return hasDefinition()? Data.getPointer()->Definition : 0; + return hasDefinition()? Data.getPointer()->Definition : nullptr; } /// \brief Retrieve the definition of this protocol, if any. const ObjCProtocolDecl *getDefinition() const { - return hasDefinition()? Data.getPointer()->Definition : 0; + return hasDefinition()? Data.getPointer()->Definition : nullptr; } /// \brief Determine whether this particular declaration is also the @@ -1503,29 +1657,35 @@ public: /// \brief Starts the definition of this Objective-C protocol. void startDefinition(); - virtual SourceRange getSourceRange() const LLVM_READONLY { + /// 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() { return getFirstDecl(); } + ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); } const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); } - virtual void collectPropertiesToImplement(PropertyMap &PM, - PropertyDeclOrder &PO) const; - -void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property, - ProtocolPropertyMap &PM) const; + 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; } @@ -1553,7 +1713,7 @@ void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property, /// don't support this level of dynamism, which is both powerful and dangerous. /// class ObjCCategoryDecl : public ObjCContainerDecl { - virtual void anchor(); + void anchor() override; /// Interface belonging to this category ObjCInterfaceDecl *ClassInterface; @@ -1578,7 +1738,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl { SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()) : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc), - ClassInterface(IDecl), NextClassCategory(0), + ClassInterface(IDecl), NextClassCategory(nullptr), CategoryNameLoc(CategoryNameLoc), IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) { } @@ -1613,10 +1773,22 @@ public: } typedef ObjCProtocolList::iterator protocol_iterator; - protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} + 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(); } @@ -1632,9 +1804,12 @@ public: return NextClassCategory; } - bool IsClassExtension() const { return getIdentifier() == 0; } + 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()); } @@ -1664,7 +1839,7 @@ public: }; class ObjCImplDecl : public ObjCContainerDecl { - virtual void anchor(); + void anchor() override; /// Class interface for this class/category implementation ObjCInterfaceDecl *ClassInterface; @@ -1674,7 +1849,8 @@ protected: ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc) : ObjCContainerDecl(DK, DC, - classInterface? classInterface->getIdentifier() : 0, + classInterface? classInterface->getIdentifier() + : nullptr, nameLoc, atStartLoc), ClassInterface(classInterface) {} @@ -1701,6 +1877,12 @@ public: // 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()); } @@ -1728,7 +1910,7 @@ public: /// /// ObjCCategoryImplDecl class ObjCCategoryImplDecl : public ObjCImplDecl { - virtual void anchor(); + void anchor() override; // Category name IdentifierInfo *Id; @@ -1753,8 +1935,8 @@ public: /// getIdentifier - Get the identifier that names the category /// interface associated with this implementation. - /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier() - /// to mean something different. For example: + /// 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() @@ -1771,11 +1953,9 @@ public: /// 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 overriding the NamedDecl::getName, to mean - // something different. - StringRef getName() const { - return Id ? Id->getNameStart() : ""; - } + // 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. // @@ -1802,13 +1982,16 @@ raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID); /// \@end /// @endcode /// -/// Typically, instance variables are specified in the class interface, -/// *not* in the implementation. Nevertheless (for legacy reasons), we -/// allow instance variables to be specified in the implementation. When -/// specified, they need to be *identical* to the interface. +/// 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 { - virtual void anchor(); + void anchor() override; /// Implementation Class's super class. ObjCInterfaceDecl *SuperClass; SourceLocation SuperLoc; @@ -1839,7 +2022,7 @@ class ObjCImplementationDecl : public ObjCImplDecl { : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc), SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc), - IvarInitializers(0), NumIvarInitializers(0), + IvarInitializers(nullptr), NumIvarInitializers(0), HasNonZeroConstructors(false), HasDestructors(false) {} public: static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, @@ -1859,6 +2042,14 @@ public: /// 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() { return IvarInitializers; } /// begin() - Retrieve an iterator to the first initializer. @@ -1904,8 +2095,8 @@ public: /// 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 overriding the NamedDecl::getName, to mean - // something different. + // 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(); @@ -1917,6 +2108,10 @@ public: 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; } @@ -1930,6 +2125,9 @@ public: 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()); } @@ -1955,7 +2153,7 @@ 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 { - virtual void anchor(); + void anchor() override; /// Class that this is an alias of. ObjCInterfaceDecl *AliasedClass; @@ -1986,7 +2184,7 @@ public: /// \@property (assign, readwrite) int MyProperty; /// \endcode class ObjCPropertyDecl : public NamedDecl { - virtual void anchor(); + void anchor() override; public: enum PropertyAttributeKind { OBJC_PR_noattr = 0x00, @@ -2038,7 +2236,9 @@ private: PropertyImplementation(None), GetterName(Selector()), SetterName(Selector()), - GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {} + GetterMethodDecl(nullptr), SetterMethodDecl(nullptr), + PropertyIvarDecl(nullptr) {} + public: static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, @@ -2145,7 +2345,7 @@ public: return PropertyIvarDecl; } - virtual SourceRange getSourceRange() const LLVM_READONLY { + SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(AtLoc, getLocation()); } @@ -2202,7 +2402,7 @@ private: SourceLocation ivarLoc) : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc), IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl), - GetterCXXConstructor(0), SetterCXXAssignment(0) { + GetterCXXConstructor(nullptr), SetterCXXAssignment(nullptr) { assert (PK == Dynamic || PropertyIvarDecl); } @@ -2215,8 +2415,8 @@ public: SourceLocation ivarLoc); static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - virtual SourceRange getSourceRange() const LLVM_READONLY; + + SourceRange getSourceRange() const override LLVM_READONLY; SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } |