//===- 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 { … }; /// 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 { … }; /// A list of Objective-C protocols, along with the source /// locations at which they were referenced. class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> { … }; enum class ObjCImplementationControl { … }; /// 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 { … }; /// Describes the variance of a given generic parameter. enum class ObjCTypeParamVariance : uint8_t { … }; /// 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 { … }; /// 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 *> { … }; enum class ObjCPropertyQueryKind : uint8_t { … }; /// Represents one property declaration in an Objective-C interface. /// /// For example: /// \code{.mm} /// \@property (assign, readwrite) int MyProperty; /// \endcode class ObjCPropertyDecl : public NamedDecl { … }; /// ObjCContainerDecl - Represents a container for method declarations. /// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, /// ObjCProtocolDecl, and ObjCImplDecl. /// class ObjCContainerDecl : public NamedDecl, public DeclContext { … }; /// 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> { … }; /// 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 { … }; /// Represents a field declaration created by an \@defs(...). class ObjCAtDefsFieldDecl : public FieldDecl { … }; /// 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> { … }; /// 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 { … }; class ObjCImplDecl : public ObjCContainerDecl { … }; /// 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 { … }; 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 { … }; 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 { … }; /// ObjCPropertyImplDecl - Represents implementation declaration of a property /// in a class or category implementation block. For example: /// \@synthesize prop1 = ivar1; /// class ObjCPropertyImplDecl : public Decl { … }; template<bool (*Filter)(ObjCCategoryDecl *)> void ObjCInterfaceDecl::filtered_category_iterator<Filter>:: findAcceptableCategory() { … } template<bool (*Filter)(ObjCCategoryDecl *)> inline ObjCInterfaceDecl::filtered_category_iterator<Filter> & ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() { … } inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) { … } inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) { … } inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) { … } } // namespace clang #endif // LLVM_CLANG_AST_DECLOBJC_H