- //===- DeclObjC.h - Classes for representing declarations -------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- //  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/DeclBase.h" 
- #include "clang/AST/DeclObjCCommon.h" 
- #include "clang/AST/ExternalASTSource.h" 
- #include "clang/AST/Redeclarable.h" 
- #include "clang/AST/SelectorLocationsKind.h" 
- #include "clang/AST/Type.h" 
- #include "clang/Basic/IdentifierTable.h" 
- #include "clang/Basic/LLVM.h" 
- #include "clang/Basic/SourceLocation.h" 
- #include "clang/Basic/Specifiers.h" 
- #include "llvm/ADT/ArrayRef.h" 
- #include "llvm/ADT/DenseSet.h" 
- #include "llvm/ADT/MapVector.h" 
- #include "llvm/ADT/PointerIntPair.h" 
- #include "llvm/ADT/STLExtras.h" 
- #include "llvm/ADT/StringRef.h" 
- #include "llvm/ADT/iterator_range.h" 
- #include "llvm/Support/Compiler.h" 
- #include "llvm/Support/TrailingObjects.h" 
- #include <cassert> 
- #include <cstddef> 
- #include <cstdint> 
- #include <iterator> 
- #include <string> 
- #include <utility> 
-   
- namespace clang { 
-   
- class ASTContext; 
- class CompoundStmt; 
- class CXXCtorInitializer; 
- class Expr; 
- class ObjCCategoryDecl; 
- class ObjCCategoryImplDecl; 
- class ObjCImplementationDecl; 
- class ObjCInterfaceDecl; 
- class ObjCIvarDecl; 
- class ObjCPropertyDecl; 
- class ObjCPropertyImplDecl; 
- class ObjCProtocolDecl; 
- class Stmt; 
-   
- class ObjCListBase { 
- protected: 
-   /// List is an array of pointers to objects that are not owned by this object. 
-   void **List = nullptr; 
-   unsigned NumElts = 0; 
-   
- public: 
-   ObjCListBase() = default; 
-   ObjCListBase(const ObjCListBase &) = delete; 
-   ObjCListBase &operator=(const ObjCListBase &) = delete; 
-   
-   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); 
-   } 
-   
-   using iterator = T* const *; 
-   
-   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]; 
-   } 
- }; 
-   
- /// A list of Objective-C protocols, along with the source 
- /// locations at which they were referenced. 
- class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> { 
-   SourceLocation *Locations = nullptr; 
-   
-   using ObjCList<ObjCProtocolDecl>::set; 
-   
- public: 
-   ObjCProtocolList() = default; 
-   
-   using loc_iterator = const SourceLocation *; 
-   
-   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 { 
-   // This class stores some data in DeclContext::ObjCMethodDeclBits 
-   // to save some space. Use the provided accessors to access it. 
-   
- public: 
-   enum ImplementationControl { None, Required, Optional }; 
-   
- private: 
-   /// Return type of this method. 
-   QualType MethodDeclType; 
-   
-   /// Type source information for the return type. 
-   TypeSourceInfo *ReturnTInfo; 
-   
-   /// Array of ParmVarDecls for the formal parameters of this method 
-   /// and optionally followed by selector locations. 
-   void *ParamsAndSelLocs = nullptr; 
-   unsigned NumParams = 0; 
-   
-   /// 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 = nullptr; 
-   
-   /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily 
-   /// constructed by createImplicitParams. 
-   ImplicitParamDecl *CmdDecl = nullptr; 
-   
-   ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, 
-                  Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, 
-                  DeclContext *contextDecl, bool isInstance = true, 
-                  bool isVariadic = false, bool isPropertyAccessor = false, 
-                  bool isSynthesizedAccessorStub = false,  
-                  bool isImplicitlyDeclared = false, bool isDefined = false, 
-                  ImplementationControl impControl = None, 
-                  bool HasRelatedResultType = false); 
-   
-   SelectorLocationsKind getSelLocsKind() const { 
-     return static_cast<SelectorLocationsKind>(ObjCMethodDeclBits.SelLocsKind); 
-   } 
-   
-   void setSelLocsKind(SelectorLocationsKind Kind) { 
-     ObjCMethodDeclBits.SelLocsKind = Kind; 
-   } 
-   
-   bool hasStandardSelLocs() const { 
-     return getSelLocsKind() != SelLoc_NonStandard; 
-   } 
-   
-   /// 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); 
-   } 
-   
-   /// 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); 
-   } 
-   
-   /// 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); 
-   
-   /// A definition will return its interface declaration. 
-   /// An interface declaration will return its definition. 
-   /// Otherwise it will return itself. 
-   ObjCMethodDecl *getNextRedeclarationImpl() override; 
-   
- public: 
-   friend class ASTDeclReader; 
-   friend class ASTDeclWriter; 
-   
-   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 isSynthesizedAccessorStub = 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 static_cast<ObjCDeclQualifier>(ObjCMethodDeclBits.objcDeclQualifier); 
-   } 
-   
-   void setObjCDeclQualifier(ObjCDeclQualifier QV) { 
-     ObjCMethodDeclBits.objcDeclQualifier = QV; 
-   } 
-   
-   /// Determine whether this method has a result type that is related 
-   /// to the message receiver's type. 
-   bool hasRelatedResultType() const { 
-     return ObjCMethodDeclBits.RelatedResultType; 
-   } 
-   
-   /// Note whether this method has a related result type. 
-   void setRelatedResultType(bool RRT = true) { 
-     ObjCMethodDeclBits.RelatedResultType = RRT; 
-   } 
-   
-   /// True if this is a method redeclaration in the same interface. 
-   bool isRedeclaration() const { return ObjCMethodDeclBits.IsRedeclaration; } 
-   void setIsRedeclaration(bool RD) { ObjCMethodDeclBits.IsRedeclaration = RD; } 
-   void setAsRedeclaration(const ObjCMethodDecl *PrevMethod); 
-   
-   /// True if redeclared in the same interface. 
-   bool hasRedeclaration() const { return ObjCMethodDeclBits.HasRedeclaration; } 
-   void setHasRedeclaration(bool HRD) const { 
-     ObjCMethodDeclBits.HasRedeclaration = HRD; 
-   } 
-   
-   /// 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 getBeginLoc() const LLVM_READONLY { return getLocation(); } 
-   SourceLocation getEndLoc() const LLVM_READONLY; 
-   SourceRange getSourceRange() const override LLVM_READONLY { 
-     return SourceRange(getLocation(), getEndLoc()); 
-   } 
-   
-   SourceLocation getSelectorStartLoc() const { 
-     if (isImplicit()) 
-       return getBeginLoc(); 
-     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(); 
-   } 
-   
-   /// If this method is declared or implemented in a category, return 
-   /// that category. 
-   ObjCCategoryDecl *getCategory(); 
-   const ObjCCategoryDecl *getCategory() const { 
-     return const_cast<ObjCMethodDecl*>(this)->getCategory(); 
-   } 
-   
-   Selector getSelector() const { return getDeclName().getObjCSelector(); } 
-   
-   QualType getReturnType() const { return MethodDeclType; } 
-   void setReturnType(QualType T) { MethodDeclType = T; } 
-   SourceRange getReturnTypeSourceRange() const; 
-   
-   /// 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; } 
-   
-   using param_const_iterator = const ParmVarDecl *const *; 
-   using param_iterator = ParmVarDecl *const *; 
-   using param_range = llvm::iterator_range<param_iterator>; 
-   using param_const_range = llvm::iterator_range<param_const_iterator>; 
-   
-   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::ArrayRef(const_cast<ParmVarDecl **>(getParams()), NumParams); 
-   } 
-   
-   ParmVarDecl *getParamDecl(unsigned Idx) { 
-     assert(Idx < NumParams && "Index out of bounds!"); 
-     return getParams()[Idx]; 
-   } 
-   const ParmVarDecl *getParamDecl(unsigned Idx) const { 
-     return const_cast<ObjCMethodDecl *>(this)->getParamDecl(Idx); 
-   } 
-   
-   /// 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 = std::nullopt); 
-   
-   // Iterator access to parameter types. 
-   struct GetTypeFn { 
-     QualType operator()(const ParmVarDecl *PD) const { return PD->getType(); } 
-   }; 
-   
-   using param_type_iterator = 
-       llvm::mapped_iterator<param_const_iterator, GetTypeFn>; 
-   
-   param_type_iterator param_type_begin() const { 
-     return llvm::map_iterator(param_begin(), GetTypeFn()); 
-   } 
-   
-   param_type_iterator param_type_end() const { 
-     return llvm::map_iterator(param_end(), GetTypeFn()); 
-   } 
-   
-   /// createImplicitParams - Used to lazily create the self and cmd 
-   /// implicit parameters. This must be called prior to using getSelfDecl() 
-   /// or getCmdDecl(). The call is ignored if the implicit parameters 
-   /// 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) const; 
-   
-   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 ObjCMethodDeclBits.IsInstance; } 
-   void setInstanceMethod(bool isInst) { 
-     ObjCMethodDeclBits.IsInstance = isInst; 
-   } 
-   
-   bool isVariadic() const { return ObjCMethodDeclBits.IsVariadic; } 
-   void setVariadic(bool isVar) { ObjCMethodDeclBits.IsVariadic = isVar; } 
-   
-   bool isClassMethod() const { return !isInstanceMethod(); } 
-   
-   bool isPropertyAccessor() const { 
-     return ObjCMethodDeclBits.IsPropertyAccessor; 
-   } 
-   
-   void setPropertyAccessor(bool isAccessor) { 
-     ObjCMethodDeclBits.IsPropertyAccessor = isAccessor; 
-   } 
-   
-   bool isSynthesizedAccessorStub() const { 
-     return ObjCMethodDeclBits.IsSynthesizedAccessorStub; 
-   } 
-   
-   void setSynthesizedAccessorStub(bool isSynthesizedAccessorStub) { 
-     ObjCMethodDeclBits.IsSynthesizedAccessorStub = isSynthesizedAccessorStub; 
-   } 
-   
-   bool isDefined() const { return ObjCMethodDeclBits.IsDefined; } 
-   void setDefined(bool isDefined) { ObjCMethodDeclBits.IsDefined = isDefined; } 
-   
-   /// 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 ObjCMethodDeclBits.IsOverriding; } 
-   void setOverriding(bool IsOver) { ObjCMethodDeclBits.IsOverriding = IsOver; } 
-   
-   /// 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; 
-   
-   /// True if the method was a definition but its body was skipped. 
-   bool hasSkippedBody() const { return ObjCMethodDeclBits.HasSkippedBody; } 
-   void setHasSkippedBody(bool Skipped = true) { 
-     ObjCMethodDeclBits.HasSkippedBody = Skipped; 
-   } 
-   
-   /// True if the method is tagged as objc_direct 
-   bool isDirectMethod() const; 
-   
-   /// True if the method has a parameter that's destroyed in the callee. 
-   bool hasParamDestroyedInCallee() const; 
-   
-   /// 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) { 
-     ObjCMethodDeclBits.DeclImplementation = ic; 
-   } 
-   
-   ImplementationControl getImplementationControl() const { 
-     return ImplementationControl(ObjCMethodDeclBits.DeclImplementation); 
-   } 
-   
-   bool isOptional() const { 
-     return getImplementationControl() == Optional; 
-   } 
-   
-   /// 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; 
-   
-   /// Determine whether this method has a body. 
-   bool hasBody() const override { return Body.isValid(); } 
-   
-   /// 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; } 
-   
-   /// Returns whether this specific method is a definition. 
-   bool isThisDeclarationADefinition() const { return hasBody(); } 
-   
-   /// Is this method defined in the NSObject base class? 
-   bool definedInNSObject(const ASTContext &) const; 
-   
-   // 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)); 
-   } 
- }; 
-   
- /// 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 { 
-   /// 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) {} 
-   
-   void anchor() override; 
-   
- public: 
-   friend class ASTDeclReader; 
-   friend class ASTDeclWriter; 
-   
-   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; } 
- }; 
-   
- /// 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 *> { 
-   /// Location of the left and right angle brackets. 
-   SourceRange Brackets; 
-   /// The number of parameters in the list, which are tail-allocated. 
-   unsigned NumParams; 
-   
-   ObjCTypeParamList(SourceLocation lAngleLoc, 
-                     ArrayRef<ObjCTypeParamDecl *> typeParams, 
-                     SourceLocation rAngleLoc); 
-   
- public: 
-   friend TrailingObjects; 
-   
-   /// 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. 
-   using iterator = ObjCTypeParamDecl **; 
-   
-   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. 
-   using const_iterator = ObjCTypeParamDecl * const *; 
-   
-   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 Brackets.getBegin(); } 
-   SourceLocation getRAngleLoc() const { return Brackets.getEnd(); } 
-   SourceRange getSourceRange() const { return Brackets; } 
-   
-   /// 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; 
- }; 
-   
- enum class ObjCPropertyQueryKind : uint8_t { 
-   OBJC_PR_query_unknown = 0x00, 
-   OBJC_PR_query_instance, 
-   OBJC_PR_query_class 
- }; 
-   
- /// 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 SetterKind { Assign, Retain, Copy, Weak }; 
-   enum PropertyControl { None, Required, Optional }; 
-   
- private: 
-   // location of \@property 
-   SourceLocation AtLoc; 
-   
-   // location of '(' starting attribute list or null. 
-   SourceLocation LParenLoc; 
-   
-   QualType DeclType; 
-   TypeSourceInfo *DeclTypeSourceInfo; 
-   unsigned PropertyAttributes : NumObjCPropertyAttrsBits; 
-   unsigned PropertyAttributesAsWritten : NumObjCPropertyAttrsBits; 
-   
-   // \@required/\@optional 
-   unsigned PropertyImplementation : 2; 
-   
-   // getter name of NULL if no getter 
-   Selector GetterName; 
-   
-   // setter name of NULL if no setter 
-   Selector SetterName; 
-   
-   // location of the getter attribute's value 
-   SourceLocation GetterNameLoc; 
-   
-   // location of the setter attribute's value 
-   SourceLocation SetterNameLoc; 
-   
-   // Declaration of getter instance method 
-   ObjCMethodDecl *GetterMethodDecl = nullptr; 
-   
-   // Declaration of setter instance method 
-   ObjCMethodDecl *SetterMethodDecl = nullptr; 
-   
-   // Synthesize ivar for this property 
-   ObjCIvarDecl *PropertyIvarDecl = nullptr; 
-   
-   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(ObjCPropertyAttribute::kind_noattr), 
-         PropertyAttributesAsWritten(ObjCPropertyAttribute::kind_noattr), 
-         PropertyImplementation(propControl) {} 
-   
- 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; 
-   
-   ObjCPropertyAttribute::Kind getPropertyAttributes() const { 
-     return ObjCPropertyAttribute::Kind(PropertyAttributes); 
-   } 
-   
-   void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal) { 
-     PropertyAttributes |= PRVal; 
-   } 
-   
-   void overwritePropertyAttributes(unsigned PRVal) { 
-     PropertyAttributes = PRVal; 
-   } 
-   
-   ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const { 
-     return ObjCPropertyAttribute::Kind(PropertyAttributesAsWritten); 
-   } 
-   
-   void setPropertyAttributesAsWritten(ObjCPropertyAttribute::Kind PRVal) { 
-     PropertyAttributesAsWritten = PRVal; 
-   } 
-   
-   // Helper methods for accessing attributes. 
-   
-   /// isReadOnly - Return true iff the property has a setter. 
-   bool isReadOnly() const { 
-     return (PropertyAttributes & ObjCPropertyAttribute::kind_readonly); 
-   } 
-   
-   /// isAtomic - Return true if the property is atomic. 
-   bool isAtomic() const { 
-     return (PropertyAttributes & ObjCPropertyAttribute::kind_atomic); 
-   } 
-   
-   /// isRetaining - Return true if the property retains its value. 
-   bool isRetaining() const { 
-     return (PropertyAttributes & (ObjCPropertyAttribute::kind_retain | 
-                                   ObjCPropertyAttribute::kind_strong | 
-                                   ObjCPropertyAttribute::kind_copy)); 
-   } 
-   
-   bool isInstanceProperty() const { return !isClassProperty(); } 
-   bool isClassProperty() const { 
-     return PropertyAttributes & ObjCPropertyAttribute::kind_class; 
-   } 
-   bool isDirectProperty() const; 
-   
-   ObjCPropertyQueryKind getQueryKind() const { 
-     return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class : 
-                                ObjCPropertyQueryKind::OBJC_PR_query_instance; 
-   } 
-   
-   static ObjCPropertyQueryKind getQueryKind(bool isClassProperty) { 
-     return isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class : 
-                              ObjCPropertyQueryKind::OBJC_PR_query_instance; 
-   } 
-   
-   /// 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 & ObjCPropertyAttribute::kind_strong) 
-       return getType()->isBlockPointerType() ? Copy : Retain; 
-     if (PropertyAttributes & ObjCPropertyAttribute::kind_retain) 
-       return Retain; 
-     if (PropertyAttributes & ObjCPropertyAttribute::kind_copy) 
-       return Copy; 
-     if (PropertyAttributes & ObjCPropertyAttribute::kind_weak) 
-       return Weak; 
-     return Assign; 
-   } 
-   
-   Selector getGetterName() const { return GetterName; } 
-   SourceLocation getGetterNameLoc() const { return GetterNameLoc; } 
-   
-   void setGetterName(Selector Sel, SourceLocation Loc = SourceLocation()) { 
-     GetterName = Sel; 
-     GetterNameLoc = Loc; 
-   } 
-   
-   Selector getSetterName() const { return SetterName; } 
-   SourceLocation getSetterNameLoc() const { return SetterNameLoc; } 
-   
-   void setSetterName(Selector Sel, SourceLocation Loc = SourceLocation()) { 
-     SetterName = Sel; 
-     SetterNameLoc = Loc; 
-   } 
-   
-   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); 
-   } 
-   
-   bool isOptional() const { 
-     return getPropertyImplementation() == PropertyControl::Optional; 
-   } 
-   
-   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, 
-                                             ObjCPropertyQueryKind queryKind); 
-   
-   static bool classof(const Decl *D) { return classofKind(D->getKind()); } 
-   static bool classofKind(Kind K) { return K == ObjCProperty; } 
- }; 
-   
- /// ObjCContainerDecl - Represents a container for method declarations. 
- /// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, 
- /// ObjCProtocolDecl, and ObjCImplDecl. 
- /// 
- class ObjCContainerDecl : public NamedDecl, public DeclContext { 
-   // This class stores some data in DeclContext::ObjCContainerDeclBits 
-   // to save some space. Use the provided accessors to access it. 
-   
-   // 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; 
-   
-   void anchor() override; 
-   
- public: 
-   ObjCContainerDecl(Kind DK, DeclContext *DC, IdentifierInfo *Id, 
-                     SourceLocation nameLoc, SourceLocation atStartLoc); 
-   
-   // Iterator access to instance/class properties. 
-   using prop_iterator = specific_decl_iterator<ObjCPropertyDecl>; 
-   using prop_range = 
-       llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>; 
-   
-   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()); 
-   } 
-   
-   using instprop_iterator = 
-       filtered_decl_iterator<ObjCPropertyDecl, 
-                              &ObjCPropertyDecl::isInstanceProperty>; 
-   using instprop_range = llvm::iterator_range<instprop_iterator>; 
-   
-   instprop_range instance_properties() const { 
-     return instprop_range(instprop_begin(), instprop_end()); 
-   } 
-   
-   instprop_iterator instprop_begin() const { 
-     return instprop_iterator(decls_begin()); 
-   } 
-   
-   instprop_iterator instprop_end() const { 
-     return instprop_iterator(decls_end()); 
-   } 
-   
-   using classprop_iterator = 
-       filtered_decl_iterator<ObjCPropertyDecl, 
-                              &ObjCPropertyDecl::isClassProperty>; 
-   using classprop_range = llvm::iterator_range<classprop_iterator>; 
-   
-   classprop_range class_properties() const { 
-     return classprop_range(classprop_begin(), classprop_end()); 
-   } 
-   
-   classprop_iterator classprop_begin() const { 
-     return classprop_iterator(decls_begin()); 
-   } 
-   
-   classprop_iterator classprop_end() const { 
-     return classprop_iterator(decls_end()); 
-   } 
-   
-   // Iterator access to instance/class methods. 
-   using method_iterator = specific_decl_iterator<ObjCMethodDecl>; 
-   using method_range = 
-       llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>; 
-   
-   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()); 
-   } 
-   
-   using instmeth_iterator = 
-       filtered_decl_iterator<ObjCMethodDecl, 
-                              &ObjCMethodDecl::isInstanceMethod>; 
-   using instmeth_range = llvm::iterator_range<instmeth_iterator>; 
-   
-   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()); 
-   } 
-   
-   using classmeth_iterator = 
-       filtered_decl_iterator<ObjCMethodDecl, 
-                              &ObjCMethodDecl::isClassMethod>; 
-   using classmeth_range = llvm::iterator_range<classmeth_iterator>; 
-   
-   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 *getProperty(const IdentifierInfo *Id, 
-                                 bool IsInstance) const; 
-   
-   ObjCPropertyDecl * 
-   FindPropertyDeclaration(const IdentifierInfo *PropertyId, 
-                           ObjCPropertyQueryKind QueryKind) const; 
-   
-   using PropertyMap = 
-       llvm::MapVector<std::pair<IdentifierInfo *, unsigned /*isClassProperty*/>, 
-                       ObjCPropertyDecl *>; 
-   using ProtocolPropertySet = llvm::SmallDenseSet<const ObjCProtocolDecl *, 8>; 
-   using PropertyDeclOrder = llvm::SmallVector<ObjCPropertyDecl *, 8>; 
-   
-   /// 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) const {} 
-   
-   SourceLocation getAtStartLoc() const { return ObjCContainerDeclBits.AtStart; } 
-   
-   void setAtStartLoc(SourceLocation Loc) { 
-     ObjCContainerDeclBits.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(getAtStartLoc(), 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)); 
-   } 
- }; 
-   
- /// 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> { 
-   friend class ASTContext; 
-   friend class ODRDiagsEmitter; 
-   
-   /// TypeForDecl - This indicates the Type object that represents this 
-   /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType 
-   mutable const Type *TypeForDecl = nullptr; 
-   
-   struct DefinitionData { 
-     /// The definition of this class, for quick access from any 
-     /// declaration. 
-     ObjCInterfaceDecl *Definition = nullptr; 
-   
-     /// When non-null, this is always an ObjCObjectType. 
-     TypeSourceInfo *SuperClassTInfo = nullptr; 
-   
-     /// Protocols referenced in the \@interface  declaration 
-     ObjCProtocolList ReferencedProtocols; 
-   
-     /// Protocols reference in both the \@interface and class extensions. 
-     ObjCList<ObjCProtocolDecl> AllReferencedProtocols; 
-   
-     /// 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 = nullptr; 
-   
-     /// IvarList - List of all ivars defined by this class; including class 
-     /// extensions and implementation. This list is built lazily. 
-     ObjCIvarDecl *IvarList = nullptr; 
-   
-     /// Indicates that the contents of this Objective-C class will be 
-     /// completed by the external AST source when required. 
-     mutable unsigned ExternallyCompleted : 1; 
-   
-     /// Indicates that the ivar cache does not yet include ivars 
-     /// declared in the implementation. 
-     mutable unsigned IvarListMissingImplementation : 1; 
-   
-     /// Indicates that this interface decl contains at least one initializer 
-     /// marked with the 'objc_designated_initializer' attribute. 
-     unsigned 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; 
-   
-     /// Tracks whether a ODR hash has been computed for this interface. 
-     unsigned HasODRHash : 1; 
-   
-     /// A hash of parts of the class to help in ODR checking. 
-     unsigned ODRHash = 0; 
-   
-     /// The location of the last location in this declaration, before 
-     /// the properties/methods. For example, this will be the '>', '}', or 
-     /// identifier, 
-     SourceLocation EndLoc; 
-   
-     DefinitionData() 
-         : ExternallyCompleted(false), IvarListMissingImplementation(true), 
-           HasDesignatedInitializers(false), 
-           InheritedDesignatedInitializers(IDI_Unknown), HasODRHash(false) {} 
-   }; 
-   
-   /// The type parameters associated with this class, if any. 
-   ObjCTypeParamList *TypeParamList = nullptr; 
-   
-   /// 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; 
-   
-   ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc, 
-                     IdentifierInfo *Id, ObjCTypeParamList *typeParamList, 
-                     SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, 
-                     bool IsInternal); 
-   
-   void anchor() override; 
-   
-   void LoadExternalDefinition() const; 
-   
-   DefinitionData &data() const { 
-     assert(Data.getPointer() && "Declaration has no definition!"); 
-     return *Data.getPointer(); 
-   } 
-   
-   /// Allocate the definition data for this class. 
-   void allocateDefinitionData(); 
-   
-   using redeclarable_base = Redeclarable<ObjCInterfaceDecl>; 
-   
-   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()); 
-   } 
-   
-   /// 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); 
-   } 
-   
-   using protocol_iterator = ObjCProtocolList::iterator; 
-   using protocol_range = llvm::iterator_range<protocol_iterator>; 
-   
-   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(); 
-   } 
-   
-   using protocol_loc_iterator = ObjCProtocolList::loc_iterator; 
-   using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>; 
-   
-   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(); 
-   } 
-   
-   using all_protocol_iterator = ObjCList<ObjCProtocolDecl>::iterator; 
-   using all_protocol_range = llvm::iterator_range<all_protocol_iterator>; 
-   
-   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(); 
-   } 
-   
-   using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>; 
-   using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>; 
-   
-   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; 
-   
-   /// Determine whether this particular declaration of this class is 
-   /// actually also a definition. 
-   bool isThisDeclarationADefinition() const { 
-     return getDefinition() == this; 
-   } 
-   
-   /// 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(); 
-   } 
-   
-   /// 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; 
-   } 
-   
-   /// 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; 
-   } 
-   
-   /// Starts the definition of this Objective-C class, taking it from 
-   /// a forward declaration (\@class) to a definition (\@interface). 
-   void startDefinition(); 
-   
-   /// Starts the definition without sharing it with other redeclarations. 
-   /// Such definition shouldn't be used for anything but only to compare if 
-   /// a duplicate is compatible with previous definition or if it is 
-   /// a distinct duplicate. 
-   void startDuplicateDefinitionForComparison(); 
-   void mergeDuplicateDefinitionWithCommon(const ObjCInterfaceDecl *Definition); 
-   
-   /// 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; 
-   } 
-   
-   /// 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 = nullptr; 
-   
-     void findAcceptableCategory(); 
-   
-   public: 
-     using value_type = ObjCCategoryDecl *; 
-     using reference = value_type; 
-     using pointer = value_type; 
-     using difference_type = std::ptrdiff_t; 
-     using iterator_category = std::input_iterator_tag; 
-   
-     filtered_category_iterator() = default; 
-     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: 
-   /// Test whether the given category is visible. 
-   /// 
-   /// Used in the \c visible_categories_iterator. 
-   static bool isVisibleCategory(ObjCCategoryDecl *Cat); 
-   
- public: 
-   /// Iterator that walks over the list of categories and extensions 
-   /// that are visible, i.e., not hidden in a non-imported submodule. 
-   using visible_categories_iterator = 
-       filtered_category_iterator<isVisibleCategory>; 
-   
-   using visible_categories_range = 
-       llvm::iterator_range<visible_categories_iterator>; 
-   
-   visible_categories_range visible_categories() const { 
-     return visible_categories_range(visible_categories_begin(), 
-                                     visible_categories_end()); 
-   } 
-   
-   /// Retrieve an iterator to the beginning of the visible-categories 
-   /// list. 
-   visible_categories_iterator visible_categories_begin() const { 
-     return visible_categories_iterator(getCategoryListRaw()); 
-   } 
-   
-   /// Retrieve an iterator to the end of the visible-categories list. 
-   visible_categories_iterator visible_categories_end() const { 
-     return visible_categories_iterator(); 
-   } 
-   
-   /// Determine whether the visible-categories list is empty. 
-   bool visible_categories_empty() const { 
-     return visible_categories_begin() == visible_categories_end(); 
-   } 
-   
- private: 
-   /// Test whether the given category... is a category. 
-   /// 
-   /// Used in the \c known_categories_iterator. 
-   static bool isKnownCategory(ObjCCategoryDecl *) { return true; } 
-   
- public: 
-   /// Iterator that walks over all of the known categories and 
-   /// extensions, including those that are hidden. 
-   using known_categories_iterator = filtered_category_iterator<isKnownCategory>; 
-   using known_categories_range = 
-      llvm::iterator_range<known_categories_iterator>; 
-   
-   known_categories_range known_categories() const { 
-     return known_categories_range(known_categories_begin(), 
-                                   known_categories_end()); 
-   } 
-   
-   /// Retrieve an iterator to the beginning of the known-categories 
-   /// list. 
-   known_categories_iterator known_categories_begin() const { 
-     return known_categories_iterator(getCategoryListRaw()); 
-   } 
-   
-   /// Retrieve an iterator to the end of the known-categories list. 
-   known_categories_iterator known_categories_end() const { 
-     return known_categories_iterator(); 
-   } 
-   
-   /// Determine whether the known-categories list is empty. 
-   bool known_categories_empty() const { 
-     return known_categories_begin() == known_categories_end(); 
-   } 
-   
- private: 
-   /// Test whether the given category is a visible extension. 
-   /// 
-   /// Used in the \c visible_extensions_iterator. 
-   static bool isVisibleExtension(ObjCCategoryDecl *Cat); 
-   
- public: 
-   /// Iterator that walks over all of the visible extensions, skipping 
-   /// any that are known but hidden. 
-   using visible_extensions_iterator = 
-       filtered_category_iterator<isVisibleExtension>; 
-   
-   using visible_extensions_range = 
-       llvm::iterator_range<visible_extensions_iterator>; 
-   
-   visible_extensions_range visible_extensions() const { 
-     return visible_extensions_range(visible_extensions_begin(), 
-                                     visible_extensions_end()); 
-   } 
-   
-   /// Retrieve an iterator to the beginning of the visible-extensions 
-   /// list. 
-   visible_extensions_iterator visible_extensions_begin() const { 
-     return visible_extensions_iterator(getCategoryListRaw()); 
-   } 
-   
-   /// Retrieve an iterator to the end of the visible-extensions list. 
-   visible_extensions_iterator visible_extensions_end() const { 
-     return visible_extensions_iterator(); 
-   } 
-   
-   /// Determine whether the visible-extensions list is empty. 
-   bool visible_extensions_empty() const { 
-     return visible_extensions_begin() == visible_extensions_end(); 
-   } 
-   
- private: 
-   /// Test whether the given category is an extension. 
-   /// 
-   /// Used in the \c known_extensions_iterator. 
-   static bool isKnownExtension(ObjCCategoryDecl *Cat); 
-   
- public: 
-   friend class ASTDeclReader; 
-   friend class ASTDeclWriter; 
-   friend class ASTReader; 
-   
-   /// Iterator that walks over all of the known extensions. 
-   using known_extensions_iterator = 
-       filtered_category_iterator<isKnownExtension>; 
-   using known_extensions_range = 
-       llvm::iterator_range<known_extensions_iterator>; 
-   
-   known_extensions_range known_extensions() const { 
-     return known_extensions_range(known_extensions_begin(), 
-                                   known_extensions_end()); 
-   } 
-   
-   /// Retrieve an iterator to the beginning of the known-extensions 
-   /// list. 
-   known_extensions_iterator known_extensions_begin() const { 
-     return known_extensions_iterator(getCategoryListRaw()); 
-   } 
-   
-   /// Retrieve an iterator to the end of the known-extensions list. 
-   known_extensions_iterator known_extensions_end() const { 
-     return known_extensions_iterator(); 
-   } 
-   
-   /// Determine whether the known-extensions list is empty. 
-   bool known_extensions_empty() const { 
-     return known_extensions_begin() == known_extensions_end(); 
-   } 
-   
-   /// 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; 
-   } 
-   
-   /// Set the raw pointer to the start of the category/extension 
-   /// list. 
-   void setCategoryListRaw(ObjCCategoryDecl *category) { 
-     data().CategoryList = category; 
-   } 
-   
-   ObjCPropertyDecl 
-     *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId, 
-                                        ObjCPropertyQueryKind QueryKind) const; 
-   
-   void collectPropertiesToImplement(PropertyMap &PM) 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); 
-   
-   /// 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); 
-   } 
-   
-   /// 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, 
-                                          bool IsClassProperty) const { 
-     return lookupMethod(Sel, !IsClassProperty/*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); 
-   
-   using redecl_range = redeclarable_base::redecl_range; 
-   using redecl_iterator = redeclarable_base::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; } 
-   
-   /// Get precomputed ODRHash or add a new one. 
-   unsigned getODRHash(); 
-   
-   static bool classof(const Decl *D) { return classofKind(D->getKind()); } 
-   static bool classofKind(Kind K) { return K == ObjCInterface; } 
-   
- private: 
-   /// True if a valid hash is stored in ODRHash. 
-   bool hasODRHash() const; 
-   void setHasODRHash(bool HasHash); 
-   
-   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), 
-         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); 
-   
-   /// 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. 
-   ObjCInterfaceDecl *getContainingInterface(); 
-   const ObjCInterfaceDecl *getContainingInterface() const { 
-     return const_cast<ObjCIvarDecl *>(this)->getContainingInterface(); 
-   } 
-   
-   ObjCIvarDecl *getNextIvar() { return NextIvar; } 
-   const ObjCIvarDecl *getNextIvar() const { return NextIvar; } 
-   void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; } 
-   
-   ObjCIvarDecl *getCanonicalDecl() override { 
-     return cast<ObjCIvarDecl>(FieldDecl::getCanonicalDecl()); 
-   } 
-   const ObjCIvarDecl *getCanonicalDecl() const { 
-     return const_cast<ObjCIvarDecl *>(this)->getCanonicalDecl(); 
-   } 
-   
-   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 = nullptr; 
-   
-   // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum 
-   unsigned DeclAccess : 3; 
-   unsigned Synthesized : 1; 
- }; 
-   
- /// Represents a field declaration created by an \@defs(...). 
- class ObjCAtDefsFieldDecl : public FieldDecl { 
-   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) {} 
-   
-   void anchor() override; 
-   
- 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; } 
- }; 
-   
- /// 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> { 
-   struct DefinitionData { 
-     // The declaration that defines this protocol. 
-     ObjCProtocolDecl *Definition; 
-   
-     /// Referenced protocols 
-     ObjCProtocolList ReferencedProtocols; 
-   
-     /// Tracks whether a ODR hash has been computed for this protocol. 
-     unsigned HasODRHash : 1; 
-   
-     /// A hash of parts of the class to help in ODR checking. 
-     unsigned ODRHash = 0; 
-   }; 
-   
-   /// 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; 
-   
-   ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, 
-                    SourceLocation nameLoc, SourceLocation atStartLoc, 
-                    ObjCProtocolDecl *PrevDecl); 
-   
-   void anchor() override; 
-   
-   DefinitionData &data() const { 
-     assert(Data.getPointer() && "Objective-C protocol has no definition!"); 
-     return *Data.getPointer(); 
-   } 
-   
-   void allocateDefinitionData(); 
-   
-   using redeclarable_base = Redeclarable<ObjCProtocolDecl>; 
-   
-   ObjCProtocolDecl *getNextRedeclarationImpl() override { 
-     return getNextRedeclaration(); 
-   } 
-   
-   ObjCProtocolDecl *getPreviousDeclImpl() override { 
-     return getPreviousDecl(); 
-   } 
-   
-   ObjCProtocolDecl *getMostRecentDeclImpl() override { 
-     return getMostRecentDecl(); 
-   } 
-   
-   /// True if a valid hash is stored in ODRHash. 
-   bool hasODRHash() const; 
-   void setHasODRHash(bool HasHash); 
-   
- public: 
-   friend class ASTDeclReader; 
-   friend class ASTDeclWriter; 
-   friend class ASTReader; 
-   friend class ODRDiagsEmitter; 
-   
-   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; 
-   } 
-   
-   using protocol_iterator = ObjCProtocolList::iterator; 
-   using protocol_range = llvm::iterator_range<protocol_iterator>; 
-   
-   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(); 
-   } 
-   
-   using protocol_loc_iterator = ObjCProtocolList::loc_iterator; 
-   using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>; 
-   
-   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); 
-   } 
-   
-   /// This is true iff the protocol is tagged with the 
-   /// `objc_non_runtime_protocol` attribute. 
-   bool isNonRuntimeProtocol() const; 
-   
-   /// Get the set of all protocols implied by this protocols inheritance 
-   /// hierarchy. 
-   void getImpliedProtocols(llvm::DenseSet<const ObjCProtocolDecl *> &IPs) const; 
-   
-   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*/); 
-   } 
-   
-   /// 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(); 
-   } 
-   
-   /// Retrieve the definition of this protocol, if any. 
-   ObjCProtocolDecl *getDefinition() { 
-     return hasDefinition()? Data.getPointer()->Definition : nullptr; 
-   } 
-   
-   /// Retrieve the definition of this protocol, if any. 
-   const ObjCProtocolDecl *getDefinition() const { 
-     return hasDefinition()? Data.getPointer()->Definition : nullptr; 
-   } 
-   
-   /// Determine whether this particular declaration is also the 
-   /// definition. 
-   bool isThisDeclarationADefinition() const { 
-     return getDefinition() == this; 
-   } 
-   
-   /// Starts the definition of this Objective-C protocol. 
-   void startDefinition(); 
-   
-   /// Starts the definition without sharing it with other redeclarations. 
-   /// Such definition shouldn't be used for anything but only to compare if 
-   /// a duplicate is compatible with previous definition or if it is 
-   /// a distinct duplicate. 
-   void startDuplicateDefinitionForComparison(); 
-   void mergeDuplicateDefinitionWithCommon(const ObjCProtocolDecl *Definition); 
-   
-   /// 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()); 
-   } 
-   
-   using redecl_range = redeclarable_base::redecl_range; 
-   using redecl_iterator = redeclarable_base::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) const override; 
-   
-   void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property, 
-                                           ProtocolPropertySet &PS, 
-                                           PropertyDeclOrder &PO) const; 
-   
-   /// Get precomputed ODRHash or add a new one. 
-   unsigned getODRHash(); 
-   
-   static bool classof(const Decl *D) { return classofKind(D->getKind()); } 
-   static bool classofKind(Kind K) { return K == ObjCProtocol; } 
- }; 
-   
- /// 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 { 
-   /// Interface belonging to this category 
-   ObjCInterfaceDecl *ClassInterface; 
-   
-   /// The type parameters associated with this category, if any. 
-   ObjCTypeParamList *TypeParamList = nullptr; 
-   
-   /// 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 = nullptr; 
-   
-   /// 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()); 
-   
-   void anchor() override; 
-   
- public: 
-   friend class ASTDeclReader; 
-   friend class ASTDeclWriter; 
-   
-   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; 
-   } 
-   
-   using protocol_iterator = ObjCProtocolList::iterator; 
-   using protocol_range = llvm::iterator_range<protocol_iterator>; 
-   
-   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(); } 
-   
-   using protocol_loc_iterator = ObjCProtocolList::loc_iterator; 
-   using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>; 
-   
-   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; } 
-   
-   /// 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; } 
-   
-   using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>; 
-   using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>; 
-   
-   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; } 
- }; 
-   
- class ObjCImplDecl : public ObjCContainerDecl { 
-   /// Class interface for this class/category implementation 
-   ObjCInterfaceDecl *ClassInterface; 
-   
-   void anchor() override; 
-   
- protected: 
-   ObjCImplDecl(Kind DK, DeclContext *DC, 
-                ObjCInterfaceDecl *classInterface, 
-                IdentifierInfo *Id, 
-                SourceLocation nameLoc, SourceLocation atStartLoc) 
-       : ObjCContainerDecl(DK, DC, Id, 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, 
-                             ObjCPropertyQueryKind queryKind) const; 
-   ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; 
-   
-   // Iterator access to properties. 
-   using propimpl_iterator = specific_decl_iterator<ObjCPropertyImplDecl>; 
-   using propimpl_range = 
-       llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>; 
-   
-   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 { 
-   // Category name location 
-   SourceLocation CategoryNameLoc; 
-   
-   ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id, 
-                        ObjCInterfaceDecl *classInterface, 
-                        SourceLocation nameLoc, SourceLocation atStartLoc, 
-                        SourceLocation CategoryNameLoc) 
-       : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id, 
-                      nameLoc, atStartLoc), 
-         CategoryNameLoc(CategoryNameLoc) {} 
-   
-   void anchor() override; 
-   
- public: 
-   friend class ASTDeclReader; 
-   friend class ASTDeclWriter; 
-   
-   static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, 
-                                       IdentifierInfo *Id, 
-                                       ObjCInterfaceDecl *classInterface, 
-                                       SourceLocation nameLoc, 
-                                       SourceLocation atStartLoc, 
-                                       SourceLocation CategoryNameLoc); 
-   static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); 
-   
-   ObjCCategoryDecl *getCategoryDecl() const; 
-   
-   SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } 
-   
-   static bool classof(const Decl *D) { return classofKind(D->getKind()); } 
-   static bool classofKind(Kind K) { return K == ObjCCategoryImpl;} 
- }; 
-   
- 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 { 
-   /// Implementation Class's super class. 
-   ObjCInterfaceDecl *SuperClass; 
-   SourceLocation SuperLoc; 
-   
-   /// \@implementation may have private ivars. 
-   SourceLocation IvarLBraceLoc; 
-   SourceLocation IvarRBraceLoc; 
-   
-   /// Support for ivar initialization. 
-   /// The arguments used to initialize the ivars 
-   LazyCXXCtorInitializersPtr IvarInitializers; 
-   unsigned NumIvarInitializers = 0; 
-   
-   /// 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, 
-                      classInterface ? classInterface->getIdentifier() 
-                                     : nullptr, 
-                      nameLoc, atStartLoc), 
-          SuperClass(superDecl), SuperLoc(superLoc), 
-          IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc), 
-          HasNonZeroConstructors(false), HasDestructors(false) {} 
-   
-   void anchor() override; 
-   
- public: 
-   friend class ASTDeclReader; 
-   friend class ASTDeclWriter; 
-   
-   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. 
-   using init_iterator = CXXCtorInitializer **; 
-   
-   /// init_const_iterator - Iterates through the ivar initializer list. 
-   using init_const_iterator = CXXCtorInitializer * const *; 
-   
-   using init_range = llvm::iterator_range<init_iterator>; 
-   using init_const_range = llvm::iterator_range<init_const_iterator>; 
-   
-   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(); 
-   } 
-   
-   /// Get the name of the class associated with this interface. 
-   // 
-   // FIXME: Move to StringRef API. 
-   std::string getNameAsString() const { return std::string(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; } 
-   
-   using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>; 
-   using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>; 
-   
-   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; } 
- }; 
-   
- 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 { 
-   /// 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) {} 
-   
-   void anchor() override; 
-   
- 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; } 
- }; 
-   
- /// 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 
-   
-   /// 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; 
-   
-   /// The getter's definition, which has an empty body if synthesized. 
-   ObjCMethodDecl *GetterMethodDecl = nullptr; 
-   /// The getter's definition, which has an empty body if synthesized. 
-   ObjCMethodDecl *SetterMethodDecl = nullptr; 
-   
-   /// Null for \@dynamic. Non-null if property must be copy-constructed in 
-   /// getter. 
-   Expr *GetterCXXConstructor = nullptr; 
-   
-   /// Null for \@dynamic. Non-null if property has assignment operator to call 
-   /// in Setter synthesis. 
-   Expr *SetterCXXAssignment = nullptr; 
-   
-   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) { 
-     assert(PK == Dynamic || PropertyIvarDecl); 
-   } 
-   
- public: 
-   friend class ASTDeclReader; 
-   
-   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 getBeginLoc() 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; 
-   } 
-   
-   /// 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(); 
-   } 
-   
-   ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } 
-   void setGetterMethodDecl(ObjCMethodDecl *MD) { GetterMethodDecl = MD; } 
-   
-   ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } 
-   void setSetterMethodDecl(ObjCMethodDecl *MD) { SetterMethodDecl = MD; } 
-   
-   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; } 
- }; 
-   
- 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->isInvalidDecl() && Cat->isUnconditionallyVisible(); 
- } 
-   
- inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) { 
-   return !Cat->isInvalidDecl() && Cat->IsClassExtension() && 
-          Cat->isUnconditionallyVisible(); 
- } 
-   
- inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) { 
-   return !Cat->isInvalidDecl() && Cat->IsClassExtension(); 
- } 
-   
- } // namespace clang 
-   
- #endif // LLVM_CLANG_AST_DECLOBJC_H 
-