12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912 |
- #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/DenseMap.h"
- #include "llvm/ADT/DenseSet.h"
- #include "llvm/ADT/None.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::makeArrayRef(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 = llvm::None);
- // 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::DenseMap<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,
- PropertyDeclOrder &PO) 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;
- /// 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;
- /// 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) {}
- };
- /// 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();
- /// 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,
- PropertyDeclOrder &PO) const override;
- /// isSuperClassOf - Return true if this class is the specified class or is a
- /// super class of the specified interface class.
- bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
- // If RHS is derived from LHS it is OK; else it is not OK.
- while (I != nullptr) {
- if (declaresSameEntity(this, I))
- return true;
- I = I->getSuperClass();
- }
- return false;
- }
- /// isArcWeakrefUnavailable - Checks for a class or one of its super classes
- /// to be incompatible with __weak references. Returns true if it is.
- bool isArcWeakrefUnavailable() const;
- /// isObjCRequiresPropertyDefs - Checks that a class or one of its super
- /// classes must not be auto-synthesized. Returns class decl. if it must not
- /// be; 0, otherwise.
- const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const;
- ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
- ObjCInterfaceDecl *&ClassDeclared);
- ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
- ObjCInterfaceDecl *ClassDeclared;
- return lookupInstanceVariable(IVarName, ClassDeclared);
- }
- ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name);
- // Lookup a method. First, we search locally. If a method isn't
- // found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
- bool shallowCategoryLookup = false,
- bool followSuper = true,
- const ObjCCategoryDecl *C = nullptr) const;
- /// Lookup an instance method for a given selector.
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
- return lookupMethod(Sel, true/*isInstance*/);
- }
- /// Lookup a class method for a given selector.
- ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
- return lookupMethod(Sel, false/*isInstance*/);
- }
- ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
- /// 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; }
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCInterface; }
- private:
- const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
- bool inheritsDesignatedInitializers() const;
- };
- /// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
- /// instance variables are identical to C. The only exception is Objective-C
- /// supports C++ style access control. For example:
- ///
- /// \@interface IvarExample : NSObject
- /// {
- /// id defaultToProtected;
- /// \@public:
- /// id canBePublic; // same as C++.
- /// \@protected:
- /// id canBeProtected; // same as C++.
- /// \@package:
- /// id canBePackage; // framework visibility (not available in C++).
- /// }
- ///
- class ObjCIvarDecl : public FieldDecl {
- void anchor() override;
- public:
- enum AccessControl {
- None, Private, Protected, Public, Package
- };
- private:
- ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
- bool synthesized)
- : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
- /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
- 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.
- const ObjCInterfaceDecl *getContainingInterface() const;
- 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;
- };
- /// 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();
- }
- public:
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend class ASTReader;
- 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();
- /// 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,
- PropertyDeclOrder &PO) const override;
- void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
- ProtocolPropertySet &PS,
- PropertyDeclOrder &PO) const;
- 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->isUnconditionallyVisible();
- }
- inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension() && Cat->isUnconditionallyVisible();
- }
- inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension();
- }
- } // namespace clang
- #endif // LLVM_CLANG_AST_DECLOBJC_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|