123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- 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
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|